Skip to content

Commit

Permalink
feat: add support for depot and operbox recognition
Browse files Browse the repository at this point in the history
  • Loading branch information
wangl-cc committed Aug 18, 2024
1 parent e68329e commit 67fe54c
Show file tree
Hide file tree
Showing 5 changed files with 249 additions and 13 deletions.
8 changes: 8 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
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 @@ fn main() -> Result<()> {
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)?,
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_completed(_: &Map<String, Value>) -> Option<()> {
}
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")?;

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(());
}

let items = details
.get("arkplanner")?
.get("object")?
.get("items")?
.as_array()?;

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

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);
}

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

edit_current_task_detail(|detail| {
if let Some(detail) = detail.as_depot_mut() {
detail.set_depot(all_items);
}
});
}
"OperBox" => {
if !details.get("done")?.as_bool()? {
return Some(());
}

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

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);
}

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);
}

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;

opers_by_rarity[rarity - 1]
.get_mut(name)
.unwrap()
.replace(OperInfo {
potential: oper_info.get("potential")?.as_i64()?,
elite: oper_info.get("elite")?.as_i64()?,
level: oper_info.get("level")?.as_i64()?,
});
}

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

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 @@ impl TaskSummary {
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()),
_ => Detail::None,
};

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

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

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

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

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

Ok(())
Expand Down Expand Up @@ -798,6 +820,68 @@ impl std::fmt::Display for ExplorationDetail {
}
}

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 @@ mod tests {
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);
}
}

0 comments on commit 67fe54c

Please sign in to comment.