Update
csflow: - Create structs for gamerules and global vars radarflow: - new dma loop with less frequent cache invalidation - The new loop tries to run at a fixed 128 hz. Thats the max tickrate in cs2. The data is also only updated when a tick change is detected, so that should keep data fetching to a minimum. - todo: more testing for cache invalidation
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "csflow"
|
||||
version = "0.1.1"
|
||||
version = "0.1.2"
|
||||
authors = ["Janek S <development@superyu.xyz>"]
|
||||
edition = "2021"
|
||||
description = "SDK for CS2 cheats utilizing memflow"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use memflow::{plugins::{IntoProcessInstanceArcBox, Inventory, ConnectorArgs, args::Args}, os::{ModuleInfo, Os, Process}, mem::MemoryView, types::Address};
|
||||
|
||||
use crate::{error::Error, structs::{CPlayerController, CBaseEntity}, cs2dumper, traits::MemoryClass};
|
||||
use crate::{error::Error, structs::{CPlayerController, CBaseEntity, GlobalVars, GameRules}, cs2dumper, traits::MemoryClass};
|
||||
|
||||
pub struct CheatCtx {
|
||||
pub process: IntoProcessInstanceArcBox<'static>,
|
||||
@@ -71,39 +71,30 @@ impl CheatCtx {
|
||||
Ok(CBaseEntity::new(ptr2))
|
||||
}
|
||||
|
||||
pub fn is_bomb_planted(&mut self) -> Result<bool, Error> {
|
||||
let game_rules = self.process.read_addr64(self.client_module.base + cs2dumper::offsets::client_dll::dwGameRules)?;
|
||||
let data: u8 = self.process.read(game_rules + cs2dumper::client::C_CSGameRules::m_bBombPlanted)?;
|
||||
Ok(data != 0)
|
||||
}
|
||||
|
||||
pub fn is_bomb_dropped(&mut self) -> Result<bool, Error> {
|
||||
let game_rules = self.process.read_addr64(self.client_module.base + cs2dumper::offsets::client_dll::dwGameRules)?;
|
||||
let data: u8 = self.process.read(game_rules + cs2dumper::client::C_CSGameRules::m_bBombDropped)?;
|
||||
Ok(data != 0)
|
||||
pub fn get_globals(&mut self) -> Result<GlobalVars, Error> {
|
||||
let ptr = self.process.read_addr64(self.client_module.base + cs2dumper::offsets::client_dll::dwGlobalVars)?;
|
||||
Ok(GlobalVars::new(ptr))
|
||||
}
|
||||
|
||||
pub fn get_gamerules(&mut self) -> Result<GameRules, Error> {
|
||||
let ptr = self.process.read_addr64(self.client_module.base + cs2dumper::offsets::client_dll::dwGameRules)?;
|
||||
Ok(GameRules::new(ptr))
|
||||
}
|
||||
|
||||
// todo: seperate into own class
|
||||
pub fn get_entity_list(&mut self) -> Result<Address, Error> {
|
||||
let ptr = self.process.read_addr64(self.client_module.base + cs2dumper::offsets::client_dll::dwEntityList)?;
|
||||
Ok(ptr)
|
||||
}
|
||||
|
||||
pub fn get_globals(&mut self) -> Result<Address, Error> {
|
||||
let ptr = self.process.read_addr64(self.client_module.base + cs2dumper::offsets::client_dll::dwGlobalVars)?;
|
||||
Ok(ptr)
|
||||
}
|
||||
|
||||
pub fn map_name(&mut self, global_vars: Address) -> Result<String, Error> {
|
||||
let ptr = self.process.read_addr64(global_vars + 0x188)?;
|
||||
Ok(self.process.read_char_string_n(ptr, 32)?)
|
||||
}
|
||||
|
||||
// todo: seperate into own class
|
||||
pub fn highest_entity_index(&mut self) -> Result<i32, Error> {
|
||||
let game_entity_system = self.process.read_addr64(self.client_module.base + cs2dumper::offsets::client_dll::dwGameEntitySystem)?;
|
||||
let highest_index = self.process.read(game_entity_system + cs2dumper::offsets::client_dll::dwGameEntitySystem_getHighestEntityIndex)?;
|
||||
Ok(highest_index)
|
||||
}
|
||||
|
||||
// todo: seperate into own class
|
||||
pub fn network_is_ingame(&mut self) -> Result<bool, Error> {
|
||||
let ptr = self.process.read_addr64(self.engine_module.base + cs2dumper::offsets::engine2_dll::dwNetworkGameClient)?;
|
||||
let signonstate: i32 = self.process.read(ptr + cs2dumper::offsets::engine2_dll::dwNetworkGameClient_signOnState)?;
|
||||
|
||||
@@ -28,6 +28,9 @@ pub enum Error {
|
||||
#[error("memflow partial error when reading u32: {0}")]
|
||||
MemflowPartialu32(#[from] memflow::error::PartialError<u32>),
|
||||
|
||||
#[error("memflow partial error when reading f32: {0}")]
|
||||
MemflowPartialf32(#[from] memflow::error::PartialError<f32>),
|
||||
|
||||
#[error("memflow partial error when reading u8: {0}")]
|
||||
MemflowPartialu8(#[from] memflow::error::PartialError<u8>)
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
use memflow::{types::Address, mem::MemoryView};
|
||||
use crate::{CheatCtx, Error, cs2dumper, traits::{BaseEntity, MemoryClass}, structs::Vec3};
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct CBaseEntity(Address);
|
||||
|
||||
impl MemoryClass for CBaseEntity {
|
||||
|
||||
@@ -3,6 +3,7 @@ use num_traits::FromPrimitive;
|
||||
|
||||
use crate::{CheatCtx, Error, cs2dumper, structs::Vec3, traits::{MemoryClass, BaseEntity}, enums::{TeamID, PlayerType}};
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct CPlayerController(Address);
|
||||
|
||||
impl MemoryClass for CPlayerController {
|
||||
|
||||
@@ -2,6 +2,7 @@ use memflow::{types::Address, mem::MemoryView};
|
||||
|
||||
use crate::{Error, CheatCtx, cs2dumper, structs::Vec3, traits::MemoryClass};
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct CPlayerPawn(Address);
|
||||
|
||||
impl MemoryClass for CPlayerPawn {
|
||||
|
||||
35
csflow/src/structs/gamerules.rs
Normal file
35
csflow/src/structs/gamerules.rs
Normal file
@@ -0,0 +1,35 @@
|
||||
use memflow::{types::Address, mem::MemoryView};
|
||||
use crate::{traits::MemoryClass, CheatCtx, Error, cs2dumper};
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct GameRules(Address);
|
||||
|
||||
impl MemoryClass for GameRules {
|
||||
fn ptr(&self) -> memflow::types::Address {
|
||||
self.0
|
||||
}
|
||||
|
||||
fn new(ptr: memflow::types::Address) -> Self {
|
||||
Self(ptr)
|
||||
}
|
||||
}
|
||||
|
||||
impl GameRules {
|
||||
pub fn bomb_dropped(&self, ctx: &mut CheatCtx) -> Result<bool, Error> {
|
||||
let data: u8 = ctx.process.read(self.0 + cs2dumper::client::C_CSGameRules::m_bBombDropped)?;
|
||||
Ok(data != 0)
|
||||
}
|
||||
|
||||
pub fn total_rounds_played(&self, ctx: &mut CheatCtx) -> Result<i32, Error> {
|
||||
Ok(ctx.process.read(self.0 + cs2dumper::client::C_CSGameRules::m_totalRoundsPlayed)?)
|
||||
}
|
||||
|
||||
pub fn game_phase(&self, ctx: &mut CheatCtx) -> Result<i32, Error> {
|
||||
Ok(ctx.process.read(self.0 + cs2dumper::client::C_CSGameRules::m_gamePhase)?)
|
||||
}
|
||||
|
||||
pub fn bomb_planted(&self, ctx: &mut CheatCtx) -> Result<bool, Error> {
|
||||
let data: u8 = ctx.process.read(self.0 + cs2dumper::client::C_CSGameRules::m_bBombPlanted)?;
|
||||
Ok(data != 0)
|
||||
}
|
||||
}
|
||||
67
csflow/src/structs/global_vars.rs
Normal file
67
csflow/src/structs/global_vars.rs
Normal file
@@ -0,0 +1,67 @@
|
||||
use memflow::{types::Address, mem::MemoryView};
|
||||
use crate::{traits::MemoryClass, CheatCtx, Error};
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct GlobalVars(Address);
|
||||
|
||||
impl MemoryClass for GlobalVars {
|
||||
fn ptr(&self) -> memflow::types::Address {
|
||||
self.0
|
||||
}
|
||||
|
||||
fn new(ptr: memflow::types::Address) -> Self {
|
||||
Self(ptr)
|
||||
}
|
||||
}
|
||||
|
||||
impl GlobalVars {
|
||||
pub fn real_time(&self, ctx: &mut CheatCtx) -> Result<f32, Error> {
|
||||
Ok(ctx.process.read(self.0)?)
|
||||
}
|
||||
|
||||
pub fn frame_count(&self, ctx: &mut CheatCtx) -> Result<i32, Error> {
|
||||
Ok(ctx.process.read(self.0 + 0x4)?)
|
||||
}
|
||||
|
||||
pub fn frame_time(&self, ctx: &mut CheatCtx) -> Result<f32, Error> {
|
||||
Ok(ctx.process.read(self.0 + 0x8)?)
|
||||
}
|
||||
|
||||
pub fn absolute_frame_time(&self, ctx: &mut CheatCtx) -> Result<f32, Error> {
|
||||
Ok(ctx.process.read(self.0 + 0xC)?)
|
||||
}
|
||||
|
||||
pub fn max_clients(&self, ctx: &mut CheatCtx) -> Result<i32, Error> {
|
||||
Ok(ctx.process.read(self.0 + 0x10)?)
|
||||
}
|
||||
|
||||
pub fn tick_count(&self, ctx: &mut CheatCtx) -> Result<i32, Error> {
|
||||
Ok(ctx.process.read(self.0 + 0x40)?)
|
||||
}
|
||||
|
||||
pub fn map_name(&self, ctx: &mut CheatCtx) -> Result<String, Error> {
|
||||
let ptr = ctx.process.read_addr64(self.0 + 0x188)?;
|
||||
Ok(ctx.process.read_char_string_n(ptr, 32)?)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
struct GlobalVarsBase {
|
||||
real_time: f32, // 0x0000
|
||||
frame_count: i32, // 0x0004
|
||||
frame_time: f32, // 0x0008
|
||||
absolute_frame_time: f32, // 0x000C
|
||||
max_clients: i32, // 0x0010
|
||||
pad_0: [u8; 0x14], // 0x0014
|
||||
frame_time_2: f32, // 0x0028
|
||||
current_time: f32, // 0x002C
|
||||
current_time_2: f32, // 0x0030
|
||||
pad_1: [u8; 0xC], // 0x0034
|
||||
tick_count: f32, // 0x0040 // NO fucking idea why the fuck this "should" be an f32????
|
||||
pad_2: [u8; 0x4], // 0x0044
|
||||
network_channel: *const c_void, // 0x0048
|
||||
pad_3: [u8; 0x130], // 0x0050
|
||||
current_map: *const c_char, // 0x0180
|
||||
current_map_name: *const c_char, // 0x0188
|
||||
}
|
||||
*/
|
||||
@@ -1,5 +1,9 @@
|
||||
mod vec3;
|
||||
mod global_vars;
|
||||
mod gamerules;
|
||||
mod entity;
|
||||
|
||||
pub use vec3::Vec3;
|
||||
pub use global_vars::GlobalVars;
|
||||
pub use gamerules::GameRules;
|
||||
pub use entity::{CBaseEntity, CPlayerController, CPlayerPawn};
|
||||
Reference in New Issue
Block a user