rosu_memory_lib/reader/user/stable/
memory.rs

1use crate::generate_offset_getter;
2use crate::reader::helpers::{read_f32, read_f64, read_i32, read_i64, read_string};
3use crate::reader::structs::State;
4use crate::reader::user::common::UserInfo;
5use crate::reader::user::stable::offset::USER_PROFILE_OFFSET;
6use crate::Error;
7use rosu_mem::process::{Process, ProcessTraits};
8use std::mem::size_of;
9
10pub fn user_base(p: &Process, state: &mut State) -> Result<i32, Error> {
11    Ok(p.read_i32(p.read_i32(state.addresses.user_profile + USER_PROFILE_OFFSET.ptr)?)?)
12}
13generate_offset_getter! {
14    id: i32 = read_i32(USER_PROFILE_OFFSET.id, user_base);
15    bancho_status: i32 = read_i32(USER_PROFILE_OFFSET.bancho_status, user_base);
16    country_code: i32 = read_i32(USER_PROFILE_OFFSET.country_code, user_base);
17    username: String = read_string(USER_PROFILE_OFFSET.username, user_base);
18    pp: i32 = read_i32(USER_PROFILE_OFFSET.pp, user_base);
19    rankedscore: i64 = read_i64(USER_PROFILE_OFFSET.rankedscore, user_base);
20    level: f32 = read_f32(USER_PROFILE_OFFSET.level, user_base);
21    playcount: i32 = read_i32(USER_PROFILE_OFFSET.playcount, user_base);
22    rank: i32 = read_i32(USER_PROFILE_OFFSET.rank, user_base);
23    playmode: i32 = read_i32(USER_PROFILE_OFFSET.playmode, user_base);
24    accuracy: f64 = read_f64(USER_PROFILE_OFFSET.accuracy, user_base);
25}
26
27pub fn info(p: &Process, state: &mut State) -> Result<UserInfo, Error> {
28    let user_profile_base = user_base(p, state)?;
29    let mut buffer = [0u8; size_of::<i32>() * 5];
30    p.read(
31        user_profile_base + USER_PROFILE_OFFSET.playcount,
32        size_of::<i32>() * 5,
33        &mut buffer,
34    )?;
35    let playcount = i32::from_le_bytes(buffer[0..4].try_into().unwrap());
36    let playmode = i32::from_le_bytes(buffer[4..8].try_into().unwrap());
37    let rank = i32::from_le_bytes(buffer[8..12].try_into().unwrap());
38    let pp = i32::from_le_bytes(buffer[12..16].try_into().unwrap());
39    let bancho_status = i32::from_le_bytes(buffer[16..20].try_into().unwrap());
40
41    let user_profile = UserInfo {
42        id: p.read_i32(user_profile_base + USER_PROFILE_OFFSET.id)?,
43        username: p.read_string(user_profile_base + USER_PROFILE_OFFSET.username)?,
44        pp,
45        rankedscore: p.read_i64(user_profile_base + USER_PROFILE_OFFSET.rankedscore)?,
46        level: p.read_f32(user_profile_base + USER_PROFILE_OFFSET.level)?,
47        playcount,
48        rank,
49        playmode,
50        accuracy: p.read_f64(user_profile_base + USER_PROFILE_OFFSET.accuracy)?,
51        country_code: p.read_i32(user_profile_base + USER_PROFILE_OFFSET.country_code)?,
52        bancho_status,
53    };
54    Ok(user_profile)
55}