1use std::str::FromStr;
2use rosu_mem::{
3 process::{Process, ProcessTraits},
4 signature::Signature,
5};
6use rayon::prelude::*;
7use eyre::Result;
8use std::collections::HashMap;
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
65
66
67
68impl StaticAddresses {
69 pub fn new(p: &Process) -> Result<Self> {
70 let start = Instant::now();
71 println!("Reading signatures in parallel with rayon...");
72
73 let signatures = [
74 ("base", SIGNATURES.base_sig),
75 ("status", SIGNATURES.status_sig),
76 ("menu_mods", SIGNATURES.menu_mods_sig),
77 ("rulesets", SIGNATURES.rulesets_sig),
78 ("playtime", SIGNATURES.playtime_sig),
79 ("skin", SIGNATURES.skin_sig),
80 ("chat_checker", SIGNATURES.chat_checker_sig),
81 ("audio_time_base", SIGNATURES.audio_time_base_sig),
82 ("ig_time_base", SIGNATURES.ig_time_base_sig),
83 ("settings", SIGNATURES.settings_sig),
84 ("user_profile", SIGNATURES.user_profile_sig),
85 ];
86
87 let results: HashMap<&str, i32> = signatures.par_iter()
88 .map(|(name, sig)| {
89 let signature = Signature::from_str(sig)?;
90 let addr = p.read_signature(&signature)?;
91 Ok::<_, eyre::Error>((*name, addr))
92 })
93 .collect::<Result<_>>()?;
94
95 println!("Rayon time taken: {:?}", start.elapsed());
96
97 Ok(Self {
98 base: results["base"],
99 status: results["status"],
100 menu_mods: results["menu_mods"],
101 rulesets: results["rulesets"],
102 playtime: results["playtime"],
103 skin: results["skin"],
104 chat_checker: results["chat_checker"],
105 audio_time_base: results["audio_time_base"],
106 ig_time_base: results["ig_time_base"],
107 settings: results["settings"],
108 user_profile: results["user_profile"],
109 })
110 }
111
112
113
114}
115
116
117#[derive(Default,Clone)]
118pub struct State {
119 pub addresses: StaticAddresses,
120}
121
122
123