1use crate::Error;
2use rayon::prelude::*;
3use rosu_mem::{
4 process::{Process, ProcessTraits},
5 signature::Signature,
6};
7use std::collections::HashMap;
8use std::str::FromStr;
9use std::time::Instant;
10
11#[derive(Default, Clone)]
12pub struct StaticAddresses {
13 pub base: i32,
14 pub status: i32,
15 pub menu_mods: i32,
16 pub rulesets: i32,
17 pub playtime: i32,
18 pub skin: i32,
19 pub chat_checker: i32,
20 pub audio_time_base: i32,
21 pub ig_time_base: i32,
22 pub settings: i32,
23 pub user_profile: i32,
24}
25
26#[derive(Debug, Default, Clone)]
27pub struct Hit {
28 pub _geki: i16,
29 pub _300: i16,
30 pub _katu: i16,
31 pub _100: i16,
32 pub _50: i16,
33 pub _miss: i16,
34}
35
36#[derive(Debug, Clone)]
37pub(crate) struct SignatureBase {
38 base_sig: &'static str,
39 status_sig: &'static str,
40 menu_mods_sig: &'static str,
41 rulesets_sig: &'static str,
42 playtime_sig: &'static str,
43 skin_sig: &'static str,
44 chat_checker_sig: &'static str,
45 audio_time_base_sig: &'static str,
46 ig_time_base_sig: &'static str,
47 settings_sig: &'static str,
48 user_profile_sig: &'static str,
49}
50
51pub(crate) const SIGNATURES: SignatureBase = SignatureBase {
52 base_sig: "F8 01 74 04 83 65",
53 status_sig: "48 83 F8 04 73 1E",
54 menu_mods_sig: "C8 FF ?? ?? ?? ?? ?? 81 0D ?? ?? ?? ?? 00 08 00 00",
55 rulesets_sig: "7D 15 A1 ?? ?? ?? ?? 85 C0",
56 playtime_sig: "5E 5F 5D C3 A1 ?? ?? ?? ?? 89 ?? 04",
57 skin_sig: "75 21 8B 1D",
58 chat_checker_sig: "0A D7 23 3C 00 00 ?? 01",
59 audio_time_base_sig: "DB 5C 24 34 8B 44 24 34",
60 ig_time_base_sig: "EB 0A A1 ?? ?? ?? ?? A3",
61 settings_sig: "83 E0 20 85 C0 7E 2F",
62 user_profile_sig: "FF 15 ?? ?? ?? ?? A1 ?? ?? ?? ?? 8B 48 54 33 D2",
63};
64
65impl StaticAddresses {
66 pub fn new(p: &Process) -> Result<Self, Error> {
67 let start = Instant::now();
68 println!("Reading signatures in parallel with rayon...");
69
70 let signatures = [
71 ("base", SIGNATURES.base_sig),
72 ("status", SIGNATURES.status_sig),
73 ("menu_mods", SIGNATURES.menu_mods_sig),
74 ("rulesets", SIGNATURES.rulesets_sig),
75 ("playtime", SIGNATURES.playtime_sig),
76 ("skin", SIGNATURES.skin_sig),
77 ("chat_checker", SIGNATURES.chat_checker_sig),
78 ("audio_time_base", SIGNATURES.audio_time_base_sig),
79 ("ig_time_base", SIGNATURES.ig_time_base_sig),
80 ("settings", SIGNATURES.settings_sig),
81 ("user_profile", SIGNATURES.user_profile_sig),
82 ];
83
84 let results: HashMap<&str, i32> = signatures
85 .par_iter()
86 .map(|(name, sig)| {
87 let signature = Signature::from_str(sig)?;
88 let addr = p.read_signature(&signature)?;
89 Ok::<_, Error>((*name, addr))
90 })
91 .collect::<Result<_, Error>>()?;
92
93 println!("Rayon time taken: {:?}", start.elapsed());
94
95 Ok(Self {
96 base: results["base"],
97 status: results["status"],
98 menu_mods: results["menu_mods"],
99 rulesets: results["rulesets"],
100 playtime: results["playtime"],
101 skin: results["skin"],
102 chat_checker: results["chat_checker"],
103 audio_time_base: results["audio_time_base"],
104 ig_time_base: results["ig_time_base"],
105 settings: results["settings"],
106 user_profile: results["user_profile"],
107 })
108 }
109}
110
111#[derive(Default, Clone)]
112pub struct State {
113 pub addresses: StaticAddresses,
114}