Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add support for depot and operbox recognition #284

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
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
28 changes: 28 additions & 0 deletions maa-cli/src/command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,14 @@ pub(crate) enum Command {
#[command(flatten)]
common: run::CommonArgs,
},
Depot {
#[command(flatten)]
common: run::CommonArgs,
},
Operbox {
#[command(flatten)]
common: run::CommonArgs,
},
/// Convert file format between TOML, YAML and JSON
///
/// This command will convert a file from TOML, YAML or JSON format to another format.
Expand Down Expand Up @@ -673,6 +681,26 @@ mod test {
);
}

#[test]
fn depot() {
assert_matches!(
parse_from(["maa", "depot"]).command,
Command::Depot {
common: run::CommonArgs { .. }
}
);
}

#[test]
fn operbox() {
assert_matches!(
parse_from(["maa", "operbox"]).command,
Command::Operbox {
common: run::CommonArgs { .. }
}
);
}

#[test]
fn convert() {
assert_matches!(
Expand Down
2 changes: 2 additions & 0 deletions maa-cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,8 @@
Command::Roguelike { theme, common } => {
run::run(|_| run::preset::roguelike(theme), common)?
}
Command::Depot { common } => run::run(|_| run::preset::depot(), common)?,
Command::Operbox { common } => run::run(|_| run::preset::oper_box(), common)?,

Check warning on line 99 in maa-cli/src/main.rs

View check run for this annotation

Codecov / codecov/patch

maa-cli/src/main.rs#L98-L99

Added lines #L98 - L99 were not covered by tests
Command::Convert {
input,
output,
Expand Down
89 changes: 76 additions & 13 deletions maa-cli/src/run/callback/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -339,24 +339,87 @@
}
fn process_subtask_extra_info(message: &Map<String, Value>) -> Option<()> {
let taskchain = message.get("taskchain")?.as_str()?;
let what = message.get("what")?.as_str()?;
let details = message.get("details")?;

Check warning on line 343 in maa-cli/src/run/callback/mod.rs

View check run for this annotation

Codecov / codecov/patch

maa-cli/src/run/callback/mod.rs#L342-L343

Added lines #L342 - L343 were not covered by tests

match taskchain {
"Depot" => info!(
"{}: {}",
"Depot",
serde_json::to_string_pretty(message).unwrap()
),
"OperBox" => info!(
"{}: {}",
"OperBox",
serde_json::to_string_pretty(message).unwrap()
),
"Depot" => {
if !details.get("done")?.as_bool()? {
return Some(());

Check warning on line 348 in maa-cli/src/run/callback/mod.rs

View check run for this annotation

Codecov / codecov/patch

maa-cli/src/run/callback/mod.rs#L346-L348

Added lines #L346 - L348 were not covered by tests
}

let items = details

Check warning on line 351 in maa-cli/src/run/callback/mod.rs

View check run for this annotation

Codecov / codecov/patch

maa-cli/src/run/callback/mod.rs#L351

Added line #L351 was not covered by tests
.get("arkplanner")?
.get("object")?
.get("items")?
.as_array()?;

let mut all_items = summary::Map::new();

Check warning on line 357 in maa-cli/src/run/callback/mod.rs

View check run for this annotation

Codecov / codecov/patch

maa-cli/src/run/callback/mod.rs#L357

Added line #L357 was not covered by tests

for item in items {
let name = item.get("name")?.as_str()?;
let have = item.get("have")?.as_i64()?;
all_items.insert(name.to_owned(), have);

Check warning on line 362 in maa-cli/src/run/callback/mod.rs

View check run for this annotation

Codecov / codecov/patch

maa-cli/src/run/callback/mod.rs#L359-L362

Added lines #L359 - L362 were not covered by tests
}

debug!(
"Depot: {}",
serde_json::to_string_pretty(&all_items).unwrap()

Check warning on line 367 in maa-cli/src/run/callback/mod.rs

View check run for this annotation

Codecov / codecov/patch

maa-cli/src/run/callback/mod.rs#L365-L367

Added lines #L365 - L367 were not covered by tests
);

edit_current_task_detail(|detail| {
if let Some(detail) = detail.as_depot_mut() {
detail.set_depot(all_items);

Check warning on line 372 in maa-cli/src/run/callback/mod.rs

View check run for this annotation

Codecov / codecov/patch

maa-cli/src/run/callback/mod.rs#L370-L372

Added lines #L370 - L372 were not covered by tests
}
});
}
"OperBox" => {
if !details.get("done")?.as_bool()? {
return Some(());

Check warning on line 378 in maa-cli/src/run/callback/mod.rs

View check run for this annotation

Codecov / codecov/patch

maa-cli/src/run/callback/mod.rs#L376-L378

Added lines #L376 - L378 were not covered by tests
}

let all_opers = details.get("all_opers")?.as_array()?;
let owned_opers = details.get("own_opers")?.as_array()?;

Check warning on line 382 in maa-cli/src/run/callback/mod.rs

View check run for this annotation

Codecov / codecov/patch

maa-cli/src/run/callback/mod.rs#L381-L382

Added lines #L381 - L382 were not covered by tests

use summary::OperInfo;

let mut opers_by_rarity = Vec::with_capacity(6);
for _ in 0..6 {
let opers = summary::Map::<String, Option<OperInfo>>::new();
opers_by_rarity.push(opers);

Check warning on line 389 in maa-cli/src/run/callback/mod.rs

View check run for this annotation

Codecov / codecov/patch

maa-cli/src/run/callback/mod.rs#L386-L389

Added lines #L386 - L389 were not covered by tests
}

for oper in all_opers {
let oper_info = oper.as_object()?;
let name = oper_info.get("name")?.as_str()?;
let rarity = oper_info.get("rarity")?.as_i64()? as usize;
opers_by_rarity[rarity - 1].insert(name.to_owned(), None);

Check warning on line 396 in maa-cli/src/run/callback/mod.rs

View check run for this annotation

Codecov / codecov/patch

maa-cli/src/run/callback/mod.rs#L392-L396

Added lines #L392 - L396 were not covered by tests
}

for oper in owned_opers {
let oper_info = oper.as_object()?;
let name = oper_info.get("name")?.as_str()?;
let rarity = oper_info.get("rarity")?.as_i64()? as usize;

Check warning on line 402 in maa-cli/src/run/callback/mod.rs

View check run for this annotation

Codecov / codecov/patch

maa-cli/src/run/callback/mod.rs#L399-L402

Added lines #L399 - L402 were not covered by tests

opers_by_rarity[rarity - 1]
.get_mut(name)

Check warning on line 405 in maa-cli/src/run/callback/mod.rs

View check run for this annotation

Codecov / codecov/patch

maa-cli/src/run/callback/mod.rs#L404-L405

Added lines #L404 - L405 were not covered by tests
.unwrap()
.replace(OperInfo {
potential: oper_info.get("potential")?.as_i64()?,
elite: oper_info.get("elite")?.as_i64()?,
level: oper_info.get("level")?.as_i64()?,

Check warning on line 410 in maa-cli/src/run/callback/mod.rs

View check run for this annotation

Codecov / codecov/patch

maa-cli/src/run/callback/mod.rs#L407-L410

Added lines #L407 - L410 were not covered by tests
});
}

edit_current_task_detail(|detail| {
if let Some(detail) = detail.as_operbox_mut() {
detail.set_operbox(opers_by_rarity);

Check warning on line 416 in maa-cli/src/run/callback/mod.rs

View check run for this annotation

Codecov / codecov/patch

maa-cli/src/run/callback/mod.rs#L414-L416

Added lines #L414 - L416 were not covered by tests
}
});
}
_ => {}
}

let what = message.get("what")?.as_str()?;
let details = message.get("details")?;

match what {
"StageDrops" => {
let drops = details.get("drops")?.as_array()?;
Expand Down
125 changes: 125 additions & 0 deletions maa-cli/src/run/callback/summary.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,8 @@
Infrast => Detail::Infrast(InfrastDetail::new()),
Recruit => Detail::Recruit(RecruitDetail::new()),
Roguelike => Detail::Roguelike(RoguelikeDetail::new()),
Depot => Detail::Depot(DepotDetail::new()),
OperBox => Detail::OperBox(OperBoxDetail::new()),

Check warning on line 120 in maa-cli/src/run/callback/summary.rs

View check run for this annotation

Codecov / codecov/patch

maa-cli/src/run/callback/summary.rs#L119-L120

Added lines #L119 - L120 were not covered by tests
_ => Detail::None,
};

Expand Down Expand Up @@ -243,6 +245,8 @@
Fight(FightDetail),
Recruit(RecruitDetail),
Roguelike(RoguelikeDetail),
Depot(DepotDetail),
OperBox(OperBoxDetail),
}

impl Detail {
Expand Down Expand Up @@ -277,6 +281,22 @@
None
}
}

pub fn as_depot_mut(&mut self) -> Option<&mut DepotDetail> {
if let Detail::Depot(detail) = self {
Some(detail)

Check warning on line 287 in maa-cli/src/run/callback/summary.rs

View check run for this annotation

Codecov / codecov/patch

maa-cli/src/run/callback/summary.rs#L285-L287

Added lines #L285 - L287 were not covered by tests
} else {
None

Check warning on line 289 in maa-cli/src/run/callback/summary.rs

View check run for this annotation

Codecov / codecov/patch

maa-cli/src/run/callback/summary.rs#L289

Added line #L289 was not covered by tests
}
}

pub fn as_operbox_mut(&mut self) -> Option<&mut OperBoxDetail> {
if let Detail::OperBox(detail) = self {
Some(detail)

Check warning on line 295 in maa-cli/src/run/callback/summary.rs

View check run for this annotation

Codecov / codecov/patch

maa-cli/src/run/callback/summary.rs#L293-L295

Added lines #L293 - L295 were not covered by tests
} else {
None

Check warning on line 297 in maa-cli/src/run/callback/summary.rs

View check run for this annotation

Codecov / codecov/patch

maa-cli/src/run/callback/summary.rs#L297

Added line #L297 was not covered by tests
}
}
}

impl std::fmt::Display for Detail {
Expand All @@ -287,6 +307,8 @@
Detail::Infrast(detail) => detail.fmt(f)?,
Detail::Recruit(detail) => detail.fmt(f)?,
Detail::Roguelike(detail) => detail.fmt(f)?,
Detail::Depot(detail) => detail.fmt(f)?,

Check warning on line 310 in maa-cli/src/run/callback/summary.rs

View check run for this annotation

Codecov / codecov/patch

maa-cli/src/run/callback/summary.rs#L310

Added line #L310 was not covered by tests
Detail::OperBox(detail) => detail.fmt(f)?,
}

Ok(())
Expand Down Expand Up @@ -798,6 +820,68 @@
}
}

pub struct DepotDetail(Option<Map<String, i64>>);

impl DepotDetail {
pub fn new() -> Self {
Self(None)
}

pub fn set_depot(&mut self, map: Map<String, i64>) {
self.0 = Some(map);
}
}

impl std::fmt::Display for DepotDetail {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
if let Some(map) = &self.0 {
writeln!(f, "ITEM\tCOUNT")?;
for (item, count) in map {
writeln!(f, "{}\t{}", item, count)?;
}
}
Ok(())
}
}

pub struct OperBoxDetail(Vec<Map<String, Option<OperInfo>>>);

impl OperBoxDetail {
pub fn new() -> Self {
Self(Vec::with_capacity(6))
}

pub fn set_operbox(&mut self, operbox: Vec<Map<String, Option<OperInfo>>>) {
self.0.extend(operbox);
}
}

impl std::fmt::Display for OperBoxDetail {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
writeln!(f, "NAME\tPOTENTIAL\tELITE\tLEVEL")?;
for map in self.0.iter().rev() {
if !map.is_empty() {
for (name, info) in map {
write!(f, "{}\t", name)?;
if let Some(info) = info {
write!(f, "{}\t{}\t{}", info.potential, info.elite, info.level)?;
} else {
write!(f, "\t\t")?;
}
writeln!(f)?;
}
}
}
Ok(())
}
}

pub struct OperInfo {
pub(super) potential: i64,
pub(super) elite: i64,
pub(super) level: i64,
}

pub fn insert_or_add_by_ref(map: &mut Map<String, i64>, key: &str, value: i64) {
if let Some(old) = map.get_mut(key) {
*old += value;
Expand Down Expand Up @@ -1139,5 +1223,46 @@
Total gained 300 exp\n",
);
}

#[test]
fn depot() {
let mut detail = DepotDetail::new();
detail.set_depot(
[("A", 1), ("B", 2)]
.into_iter()
.map(|(k, v)| (k.to_owned(), v))
.collect(),
);
assert_eq!(detail.to_string(), "ITEM\tCOUNT\nA\t1\nB\t2\n");
}

#[test]
fn operbox() {
let mut detail = OperBoxDetail::new();
detail.set_operbox(vec![
[(
"A",
Some(OperInfo {
potential: 1,
elite: 0,
level: 1,
}),
)]
.into_iter()
.map(|(k, v)| (k.to_owned(), v))
.collect(),
[("B", None)]
.into_iter()
.map(|(k, v)| (k.to_owned(), v))
.collect(),
]);
assert_eq!(
detail.to_string(),
"NAME\tPOTENTIAL\tELITE\tLEVEL\n\
B\t\t\t\n\
A\t1\t0\t1\n\
",
);
}
}
}
38 changes: 38 additions & 0 deletions maa-cli/src/run/preset/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,22 @@ pub fn fight(stage: String, medicine: Option<i32>) -> Result<TaskConfig> {
Ok(task_config)
}

pub fn depot() -> Result<TaskConfig> {
let mut task_config = TaskConfig::new();

task_config.push(Task::new_with_default(Depot, object!()));

Ok(task_config)
}

pub fn oper_box() -> Result<TaskConfig> {
let mut task_config = TaskConfig::new();

task_config.push(Task::new_with_default(OperBox, object!()));

Ok(task_config)
}

mod copilot;
pub use copilot::copilot;

Expand Down Expand Up @@ -156,4 +172,26 @@ mod tests {
1
);
}

#[test]
fn test_depot() {
let task_config = depot().unwrap();
let tasks = task_config.tasks();

assert_eq!(tasks.len(), 1);
let depot_task = tasks.first().unwrap();

assert_eq!(depot_task.task_type(), Depot);
}

#[test]
fn test_oper_box() {
let task_config = oper_box().unwrap();
let tasks = task_config.tasks();

assert_eq!(tasks.len(), 1);
let oper_box_task = tasks.first().unwrap();

assert_eq!(oper_box_task.task_type(), OperBox);
}
}