From dcb5c5d2e929c8dd727cadcabf6faa0c62e0d896 Mon Sep 17 00:00:00 2001 From: 486c Date: Thu, 22 Jan 2026 16:29:42 +0300 Subject: [PATCH 1/2] fix: update rosu-mem version --- Cargo.lock | 5 +++-- Cargo.toml | 2 +- src/reading_loop.rs | 25 +++++++++++-------------- 3 files changed, 15 insertions(+), 17 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f67f94c..4030817 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -970,13 +970,14 @@ checksum = "6b92ea634d8b3eaa4d7fba7bd12045dda1a50ce81401c96af0d9c851b0737544" [[package]] name = "rosu-mem" -version = "2.0.0" +version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89d042a2c2c1b66ea482e6e3633415cc14e68829353d977c6db5c0f100d791c5" +checksum = "c0fd038ccf7c39a60eac35956b1a65295bad007322d622e0e19b51e99ca22959" dependencies = [ "cfg-if", "nix", "paste", + "thiserror", "windows", ] diff --git a/Cargo.toml b/Cargo.toml index 7729016..e82270b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,7 +4,7 @@ version = "2.0.1" edition = "2021" [dependencies] -rosu-mem = "2.0.0" +rosu-mem = "3.0.0" async-tungstenite = "0.29.1" cfg-if = "1.0.0" clap = { version = "4.5.32", default-features = false, features = ["std", "derive", "env"] } diff --git a/src/reading_loop.rs b/src/reading_loop.rs index bd0f84a..e69a416 100644 --- a/src/reading_loop.rs +++ b/src/reading_loop.rs @@ -96,7 +96,7 @@ pub fn process_gameplay( values.gameplay.hit_100 = p.read_i16(score_base + 0x88)?; values.gameplay.hit_50 = p.read_i16(score_base + 0x8c)?; - values.gameplay.username = p.read_string(score_base + 0x28)?; + values.gameplay.username = p.read_string_from_ptr(score_base + 0x28)?; // TODO batch values.gameplay.hit_geki = p.read_i16(score_base + 0x8e)?; @@ -193,20 +193,17 @@ pub fn process_reading_loop(p: &Process, state: &mut State) -> Result<()> { // and filled with zeros, the worst case scenario is // ar, cs, od, hp going to be zero's values.beatmap.ar = f32::from_le_bytes(beatmap_stats_buff[0..4].try_into().unwrap()); - values.beatmap.cs = f32::from_le_bytes(beatmap_stats_buff[4..8].try_into().unwrap()); - values.beatmap.hp = f32::from_le_bytes(beatmap_stats_buff[8..12].try_into().unwrap()); - values.beatmap.od = f32::from_le_bytes(beatmap_stats_buff[12..].try_into().unwrap()); let plays_addr = p.read_i32(state.addresses.base - 0x33)? + 0xC; values.plays = p.read_i32(plays_addr)?; - values.beatmap.artist = p.read_string(beatmap_addr + 0x18)?; - values.beatmap.title = p.read_string(beatmap_addr + 0x24)?; - values.beatmap.creator = p.read_string(beatmap_addr + 0x7C)?; - values.beatmap.difficulty = p.read_string(beatmap_addr + 0xAC)?; + values.beatmap.artist = p.read_string_from_ptr(beatmap_addr + 0x18)?; + values.beatmap.title = p.read_string_from_ptr(beatmap_addr + 0x24)?; + values.beatmap.creator = p.read_string_from_ptr(beatmap_addr + 0x7C)?; + values.beatmap.difficulty = p.read_string_from_ptr(beatmap_addr + 0xAC)?; values.beatmap.map_id = p.read_i32(beatmap_addr + 0xC8)?; // TODO batch values.beatmap.mapset_id = p.read_i32(beatmap_addr + 0xCC)?; // TODO batch } @@ -222,7 +219,7 @@ pub fn process_reading_loop(p: &Process, state: &mut State) -> Result<()> { let skin_osu_ptr = p.read_i32(state.addresses.skin + 0x7)?; let skin_osu_base = p.read_i32(skin_osu_ptr)?; - let skin_name = p.read_string(skin_osu_base + 0x44)?; + let skin_name = p.read_string_from_ptr(skin_osu_base + 0x44)?; values.skin_folder = values.osu_path.join("Skin").join(&skin_name); values.skin = skin_name; @@ -233,9 +230,9 @@ pub fn process_reading_loop(p: &Process, state: &mut State) -> Result<()> { { let menu_mode_addr = p.read_i32(state.addresses.base - 0x33)?; - let beatmap_file = p.read_string(beatmap_addr + 0x90)?; - let beatmap_folder = p.read_string(beatmap_addr + 0x78)?; - let audio_file = p.read_string(beatmap_addr + 0x64)?; + let beatmap_file = p.read_string_from_ptr(beatmap_addr + 0x90)?; + let beatmap_folder = p.read_string_from_ptr(beatmap_addr + 0x78)?; + let audio_file = p.read_string_from_ptr(beatmap_addr + 0x64)?; values.menu_mode = p.read_i32(menu_mode_addr)?; values.beatmap.paths.beatmap_full_path = values.osu_path.join("Songs/"); @@ -243,7 +240,7 @@ pub fn process_reading_loop(p: &Process, state: &mut State) -> Result<()> { values.beatmap.paths.beatmap_full_path.push(&beatmap_folder); values.beatmap.paths.beatmap_full_path.push(&beatmap_file); - values.beatmap.md5 = p.read_string(beatmap_addr + 0x6C)?; + values.beatmap.md5 = p.read_string_from_ptr(beatmap_addr + 0x6C)?; // Check if beatmap changed if (beatmap_folder != values.beatmap.paths.beatmap_folder @@ -322,7 +319,7 @@ pub fn process_reading_loop(p: &Process, state: &mut State) -> Result<()> { if values.state == GameState::ResultScreen { let result_base = p.read_i32(ruleset_addr + 0x38)?; - values.result_screen.username = p.read_string(result_base + 0x28)?; + values.result_screen.username = p.read_string_from_ptr(result_base + 0x28)?; let mods_xor_base = p.read_i32(result_base + 0x1C)?; From 8ac472732522cee0f0796186c2ba2f1d25f446c4 Mon Sep 17 00:00:00 2001 From: 486c Date: Thu, 22 Jan 2026 17:28:37 +0300 Subject: [PATCH 2/2] fix: apply string limits where possible --- src/reading_loop.rs | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/src/reading_loop.rs b/src/reading_loop.rs index e69a416..bd0c0e0 100644 --- a/src/reading_loop.rs +++ b/src/reading_loop.rs @@ -96,7 +96,7 @@ pub fn process_gameplay( values.gameplay.hit_100 = p.read_i16(score_base + 0x88)?; values.gameplay.hit_50 = p.read_i16(score_base + 0x8c)?; - values.gameplay.username = p.read_string_from_ptr(score_base + 0x28)?; + values.gameplay.username = p.read_string_with_limit_from_ptr(score_base + 0x28, 30)?; // TODO batch values.gameplay.hit_geki = p.read_i16(score_base + 0x8e)?; @@ -200,10 +200,10 @@ pub fn process_reading_loop(p: &Process, state: &mut State) -> Result<()> { let plays_addr = p.read_i32(state.addresses.base - 0x33)? + 0xC; values.plays = p.read_i32(plays_addr)?; - values.beatmap.artist = p.read_string_from_ptr(beatmap_addr + 0x18)?; - values.beatmap.title = p.read_string_from_ptr(beatmap_addr + 0x24)?; - values.beatmap.creator = p.read_string_from_ptr(beatmap_addr + 0x7C)?; - values.beatmap.difficulty = p.read_string_from_ptr(beatmap_addr + 0xAC)?; + values.beatmap.artist = p.read_string_with_limit_from_ptr(beatmap_addr + 0x18, 100)?; + values.beatmap.title = p.read_string_with_limit_from_ptr(beatmap_addr + 0x24, 150)?; + values.beatmap.creator = p.read_string_with_limit_from_ptr(beatmap_addr + 0x7C, 30)?; + values.beatmap.difficulty = p.read_string_with_limit_from_ptr(beatmap_addr + 0xAC, 30)?; values.beatmap.map_id = p.read_i32(beatmap_addr + 0xC8)?; // TODO batch values.beatmap.mapset_id = p.read_i32(beatmap_addr + 0xCC)?; // TODO batch } @@ -219,7 +219,7 @@ pub fn process_reading_loop(p: &Process, state: &mut State) -> Result<()> { let skin_osu_ptr = p.read_i32(state.addresses.skin + 0x7)?; let skin_osu_base = p.read_i32(skin_osu_ptr)?; - let skin_name = p.read_string_from_ptr(skin_osu_base + 0x44)?; + let skin_name = p.read_string_with_limit_from_ptr(skin_osu_base + 0x44, 300)?; values.skin_folder = values.osu_path.join("Skin").join(&skin_name); values.skin = skin_name; @@ -230,9 +230,9 @@ pub fn process_reading_loop(p: &Process, state: &mut State) -> Result<()> { { let menu_mode_addr = p.read_i32(state.addresses.base - 0x33)?; - let beatmap_file = p.read_string_from_ptr(beatmap_addr + 0x90)?; - let beatmap_folder = p.read_string_from_ptr(beatmap_addr + 0x78)?; - let audio_file = p.read_string_from_ptr(beatmap_addr + 0x64)?; + let beatmap_file = p.read_string_with_limit_from_ptr(beatmap_addr + 0x90, 300)?; + let beatmap_folder = p.read_string_with_limit_from_ptr(beatmap_addr + 0x78, 300)?; + let audio_file = p.read_string_with_limit_from_ptr(beatmap_addr + 0x64, 150)?; values.menu_mode = p.read_i32(menu_mode_addr)?; values.beatmap.paths.beatmap_full_path = values.osu_path.join("Songs/"); @@ -240,7 +240,7 @@ pub fn process_reading_loop(p: &Process, state: &mut State) -> Result<()> { values.beatmap.paths.beatmap_full_path.push(&beatmap_folder); values.beatmap.paths.beatmap_full_path.push(&beatmap_file); - values.beatmap.md5 = p.read_string_from_ptr(beatmap_addr + 0x6C)?; + values.beatmap.md5 = p.read_string_with_limit_from_ptr(beatmap_addr + 0x6C, 50)?; // Check if beatmap changed if (beatmap_folder != values.beatmap.paths.beatmap_folder @@ -319,7 +319,8 @@ pub fn process_reading_loop(p: &Process, state: &mut State) -> Result<()> { if values.state == GameState::ResultScreen { let result_base = p.read_i32(ruleset_addr + 0x38)?; - values.result_screen.username = p.read_string_from_ptr(result_base + 0x28)?; + values.result_screen.username = + p.read_string_with_limit_from_ptr(result_base + 0x28, 30)?; let mods_xor_base = p.read_i32(result_base + 0x1C)?;