Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 42 additions & 12 deletions crates/maa-cli/src/config/asst.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,10 @@ pub struct ConnectionConfig {
pub(super) address: Option<String>,
#[serde(default)]
pub(super) config: Option<String>,
#[serde(default)]
pub(super) emulator_path: Option<String>,
#[serde(default)]
pub(super) emulator_index: Option<i32>,
}

impl ConnectionConfig {
Expand Down Expand Up @@ -115,6 +119,10 @@ impl ConnectionConfig {

(adb_path, address, config)
}

pub fn extra_args(&self) -> (&Option<String>, &Option<i32>) {
(&self.emulator_path, &self.emulator_index)
}
}

#[cfg_attr(test, derive(Debug, PartialEq))]
Expand All @@ -123,6 +131,8 @@ pub enum Preset {
MuMuPro,
PlayCover,
Waydroid,
MuMuEmulator12,
LDPlayer,
#[default]
Adb,
}
Expand Down Expand Up @@ -150,6 +160,8 @@ impl<'de> Deserialize<'de> for Preset {
"PlayCover" | "PlayTools" => Ok(Preset::PlayCover),
"ADB" | "Adb" | "adb" => Ok(Preset::Adb),
"Waydroid" | "waydroid" => Ok(Preset::Waydroid),
"MuMuEmulator12" | "MuMuEmulator" => Ok(Preset::MuMuEmulator12),
"LDPlayer" => Ok(Preset::LDPlayer),
_ => {
warn!("Unknown connection preset: {value}, ignoring");
Ok(Preset::Adb)
Expand All @@ -169,31 +181,35 @@ impl Preset {
"/Applications/MuMuPlayer.app/Contents/MacOS/MuMuEmulator.app/Contents/MacOS/tools/adb"
}
Preset::PlayCover => "",
Preset::Waydroid | Preset::Adb => "adb",
Preset::Waydroid | Preset::Adb | Preset::MuMuEmulator12 | Preset::LDPlayer => "adb",
}
}

fn default_address(self, adb_path: &str) -> Cow<'static, str> {
match self {
Preset::MuMuPro => "127.0.0.1:16384".into(),
Preset::PlayCover => "127.0.0.1:1717".into(),
Preset::Waydroid | Preset::Adb => std::process::Command::new(adb_path)
.arg("devices")
.output()
.ok()
.and_then(|output| String::from_utf8(output.stdout).ok())
.and_then(parse_adb_devices)
.map(Cow::Owned)
.unwrap_or_else(|| {
warn!("Failed to detect device address, using emulator-5554");
"emulator-5554".into()
}),
Preset::Waydroid | Preset::Adb | Preset::MuMuEmulator12 | Preset::LDPlayer => {
std::process::Command::new(adb_path)
.arg("devices")
.output()
.ok()
.and_then(|output| String::from_utf8(output.stdout).ok())
.and_then(parse_adb_devices)
.map(Cow::Owned)
.unwrap_or_else(|| {
warn!("Failed to detect device address, using emulator-5554");
"emulator-5554".into()
})
}
}
}

fn default_config(self) -> &'static str {
match self {
Preset::Waydroid => "Waydroid",
Preset::MuMuEmulator12 => "MuMuEmulator12",
Preset::LDPlayer => "LDPlayer",
// May be preset specific in the future
Preset::MuMuPro | Preset::PlayCover | Preset::Adb => config_based_on_os(),
}
Expand Down Expand Up @@ -540,6 +556,8 @@ mod tests {
adb_path: Some(String::from("adb")),
address: Some(String::from("emulator-5554")),
config: Some(String::from("CompatMac")),
emulator_path: None,
emulator_index: None,
},
resource: ResourceConfig {
resource_base_dirs: {
Expand Down Expand Up @@ -616,6 +634,8 @@ mod tests {
adb_path: Some(String::from("/path/to/adb")),
address: Some(String::from("127.0.0.1:5555")),
config: Some(String::from("SomeConfig")),
emulator_path: None,
emulator_index: None,
},
&[
Token::Map { len: Some(4) },
Expand Down Expand Up @@ -821,6 +841,8 @@ mod tests {
adb_path: None,
address: None,
config: None,
emulator_path: None,
emulator_index: None,
});
}

Expand Down Expand Up @@ -880,6 +902,8 @@ mod tests {
adb_path: None,
address: None,
config: None,
emulator_path: None,
emulator_index: None,
}
.connect_args(),
(
Expand All @@ -895,6 +919,8 @@ mod tests {
adb_path: None,
address: None,
config: None,
emulator_path: None,
emulator_index: None,
}
.connect_args(),
("", "127.0.0.1:1717", config_based_on_os()),
Expand All @@ -906,6 +932,8 @@ mod tests {
adb_path: None,
address: None,
config: None,
emulator_path: None,
emulator_index: None,
}
.connect_args(),
("adb", &device, "Waydroid"),
Expand All @@ -917,6 +945,8 @@ mod tests {
adb_path: Some("/path/to/adb".to_owned()),
address: Some("127.0.0.1:11111".to_owned()),
config: Some("SomeConfig".to_owned()),
emulator_path: None,
emulator_index: None,
}
.connect_args(),
("/path/to/adb", "127.0.0.1:11111", "SomeConfig"),
Expand Down
52 changes: 52 additions & 0 deletions crates/maa-cli/src/run/extra/ldplayer.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
use std::process::Command;

use serde_json;

pub fn ld_extra(
emulator_path: &Option<String>,
emulator_index: &Option<i32>,
) -> anyhow::Result<String> {
let path = emulator_path
.as_ref()
.ok_or_else(|| anyhow::anyhow!("emulator_path is required for LDPlayer"))?;
let index = emulator_index.unwrap_or(0);
let mut ldconsole_path = std::path::PathBuf::from(path);
ldconsole_path.push("ldconsole.exe");
if !ldconsole_path.exists() {
return Err(anyhow::anyhow!(
"ldconsole.exe not found in the specified emulator_path"
));
}
let output = match Command::new(&ldconsole_path).arg("list2").output() {
Ok(output) => output,
Err(e) => {
return Err(anyhow::anyhow!(
"Failed to execute ldconsole.exe: {}",
e.to_string()
));
}
};
let stdout = String::from_utf8_lossy(&output.stdout);
let mut pid_found: Option<i32> = None;
let index_str = index.to_string();
for line in stdout.lines() {
let parts: Vec<&str> = line.split(',').collect();
if parts.len() >= 6 && parts[0] == index_str {
pid_found = parts[5].parse::<i32>().ok();
break;
}
}
if let Some(pid) = pid_found {
let object = serde_json::json!({
"path": path,
"index": index,
"pid": pid,
});
Ok(serde_json::to_string(&object)?)
} else {
Err(anyhow::anyhow!(
"No running instance found for LDPlayer with index {}",
index
))
}
}
11 changes: 11 additions & 0 deletions crates/maa-cli/src/run/extra/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#[cfg(target_os = "windows")]
pub mod mumu;

#[cfg(target_os = "windows")]
pub use mumu::mumu_extra;

#[cfg(target_os = "windows")]
pub mod ldplayer;

#[cfg(target_os = "windows")]
pub use ldplayer::ld_extra;
18 changes: 18 additions & 0 deletions crates/maa-cli/src/run/extra/mumu.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
use anyhow::{Result, anyhow};
use serde_json;

pub fn mumu_extra(emulator_path: &Option<String>, emulator_index: &Option<i32>) -> Result<String> {
let mut json_map = serde_json::Map::new();
if let Some(path) = &emulator_path {
json_map.insert("path".to_string(), serde_json::Value::String(path.clone()));
} else {
return Err(anyhow!("emulator_path is required for MuMu emulator"));
}
if let Some(index) = &emulator_index {
json_map.insert(
"index".to_string(),
serde_json::Value::Number(serde_json::Number::from(*index)),
);
}
Ok(serde_json::to_string(&json_map)?)
}
20 changes: 20 additions & 0 deletions crates/maa-cli/src/run/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ mod callback;
use callback::summary;

mod external;
mod extra;

pub mod preset;

Expand Down Expand Up @@ -177,6 +178,7 @@ where
if !args.dry_run {
// Prepare connection
let (adb_path, address, config) = asst_config.connection.connect_args();
let (emulator_path, emulator_index) = asst_config.connection.extra_args();

// Launch external apps
let app: Option<Box<dyn external::ExternalApp>> = match asst_config.connection.preset() {
Expand All @@ -192,6 +194,24 @@ where
_ => None,
};

match asst_config.connection.preset() {
#[cfg(target_os = "windows")]
crate::config::asst::Preset::MuMuEmulator12 => {
Assistant::set_connection_extras(
"MuMuEmulator12",
extra::mumu_extra(emulator_path, emulator_index)?.as_str(),
)?;
}
#[cfg(target_os = "windows")]
crate::config::asst::Preset::LDPlayer => {
Assistant::set_connection_extras(
"LDPlayer",
extra::ld_extra(emulator_path, emulator_index)?.as_str(),
)?;
}
_ => {}
}

// Startup external app
let need_reconfigure = if let (Some(app), true) = (app.as_deref(), task_config.start_app) {
!app.open().context("Failed to open external app")?
Expand Down
Loading