feat: add native mode
- Add native mode - Fix bomb holder search and wrong bomb holder on round starts
This commit is contained in:
@@ -40,7 +40,9 @@ fn version() -> String {
|
||||
let commit_date = option_env!("VERGEN_GIT_COMMIT_DATE").unwrap_or("unknown");
|
||||
let avail_cons = {
|
||||
let inventory = Inventory::scan();
|
||||
inventory.available_connectors().join(", ")
|
||||
let mut avail = inventory.available_connectors();
|
||||
avail.push("native".into());
|
||||
avail.join(", ")
|
||||
};
|
||||
|
||||
format!(" {pkg_ver} (rev {git_hash})\nCommit Date: {commit_date}\nAvailable Connectors: {avail_cons}")
|
||||
|
||||
@@ -3,7 +3,8 @@ pub enum Connector {
|
||||
#[default]
|
||||
Qemu,
|
||||
Kvm,
|
||||
Pcileech
|
||||
Pcileech,
|
||||
Native
|
||||
}
|
||||
|
||||
impl ToString for Connector {
|
||||
@@ -12,6 +13,7 @@ impl ToString for Connector {
|
||||
Connector::Qemu => String::from("qemu"),
|
||||
Connector::Kvm => String::from("kvm"),
|
||||
Connector::Pcileech => String::from("pcileech"),
|
||||
Connector::Native => String::from("native"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,11 +46,13 @@ impl DmaCtx {
|
||||
.args(connector_args)
|
||||
.os("win32")
|
||||
.build()?
|
||||
} else {
|
||||
} else if connector != Connector::Native {
|
||||
inventory.builder()
|
||||
.connector(&connector.to_string())
|
||||
.os("win32")
|
||||
.build()?
|
||||
.connector(&connector.to_string())
|
||||
.os("win32")
|
||||
.build()?
|
||||
} else {
|
||||
memflow_native::create_os(&Default::default(), Default::default())?
|
||||
}
|
||||
};
|
||||
|
||||
@@ -234,43 +236,6 @@ impl DmaCtx {
|
||||
None => None,
|
||||
}
|
||||
}
|
||||
|
||||
// Todo: Optimize this function: find another way to do this
|
||||
pub fn has_c4(&mut self, pawn: Address, entity_list: Address) -> anyhow::Result<bool> {
|
||||
let mut has_c4 = false;
|
||||
let wep_services = self.process.read_addr64(pawn + cs2dumper::client::C_BasePlayerPawn::m_pWeaponServices)?;
|
||||
let wep_count: i32 = self.process.read(wep_services + cs2dumper::client::CPlayer_WeaponServices::m_hMyWeapons)?;
|
||||
let wep_base = self.process.read_addr64(wep_services + cs2dumper::client::CPlayer_WeaponServices::m_hMyWeapons + 0x8)?;
|
||||
|
||||
for wep_idx in 0..wep_count {
|
||||
let handle: i32 = self.process.read(wep_base + wep_idx * 0x4)?;
|
||||
if handle == -1 {
|
||||
continue;
|
||||
}
|
||||
|
||||
let list_entry = self.process.read_addr64(entity_list + 0x8 * ((handle & 0x7FFF) >> 9) + 16)?;
|
||||
if let Some(wep_ptr) = {
|
||||
if list_entry.is_null() || !list_entry.is_valid() {
|
||||
None
|
||||
} else {
|
||||
let ptr = self.process.read_addr64(list_entry + 120 * (handle & 0x1FF))?;
|
||||
Some(ptr)
|
||||
}
|
||||
}
|
||||
{
|
||||
let wep_data = self.process.read_addr64(wep_ptr + cs2dumper::client::C_BaseEntity::m_nSubclassID + 0x8)?;
|
||||
let id: i32 = self.process.read(wep_data + cs2dumper::client::CCSWeaponBaseVData::m_WeaponType)?;
|
||||
|
||||
if id == 7 {
|
||||
has_c4 = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(has_c4)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use std::{thread, time::{Duration, Instant}};
|
||||
|
||||
use memflow::{os::Process, mem::MemoryView};
|
||||
use memflow::{mem::MemoryView, os::Process, types::Address};
|
||||
|
||||
use crate::{enums::PlayerType, comms::{EntityData, PlayerData, RadarData, ArcRwlockRadarData, BombData}};
|
||||
|
||||
@@ -19,6 +19,8 @@ pub async fn run(radar_data: ArcRwlockRadarData, connector: Connector, pcileech_
|
||||
// For read timing
|
||||
let mut last_bomb_dropped = false;
|
||||
let mut last_bomb_planted = false;
|
||||
let mut last_freeze_period = false;
|
||||
let mut last_round_start_count = 0u8;
|
||||
let mut last_tick_count = 0;
|
||||
let mut last_big_read = Instant::now();
|
||||
|
||||
@@ -50,12 +52,33 @@ pub async fn run(radar_data: ArcRwlockRadarData, connector: Connector, pcileech_
|
||||
data.update_bomb(&mut ctx);
|
||||
}
|
||||
|
||||
if !data.bomb_dropped && last_bomb_dropped && !data.bomb_planted {
|
||||
if data.bomb_dropped != last_bomb_dropped && !data.bomb_planted {
|
||||
log::debug!("Bomb holder recheck due to bomb drop status");
|
||||
data.recheck_bomb_holder = true;
|
||||
}
|
||||
|
||||
if last_freeze_period != data.freeze_period {
|
||||
log::debug!("Bomb holder recheck due to freeze time");
|
||||
data.recheck_bomb_holder = true;
|
||||
}
|
||||
|
||||
if last_round_start_count != data.round_start_count {
|
||||
log::debug!("Bomb holder recheck due to round start");
|
||||
data.recheck_bomb_holder = true;
|
||||
}
|
||||
|
||||
last_freeze_period = data.freeze_period;
|
||||
last_round_start_count = data.round_start_count;
|
||||
|
||||
if data.recheck_bomb_holder {
|
||||
let pawns = data.players.clone().into_iter().map(|(_, pawn)| pawn).collect();
|
||||
let mut pawns: Vec<Address> = data.players
|
||||
.clone()
|
||||
.into_iter()
|
||||
.map(|(_, pawn)| pawn)
|
||||
.collect();
|
||||
|
||||
pawns.push(data.local_pawn.into());
|
||||
|
||||
data.bomb_holder = ctx.get_c4_holder(pawns, data.entity_list.into());
|
||||
data.recheck_bomb_holder = false;
|
||||
}
|
||||
|
||||
@@ -23,6 +23,12 @@ pub struct CsData {
|
||||
pub local_pawn: u64,
|
||||
pub is_dead: bool,
|
||||
pub tick_count: i32,
|
||||
pub freeze_period: bool,
|
||||
pub round_start_count: u8,
|
||||
pub highest_index: i32,
|
||||
pub map: String,
|
||||
|
||||
// Bomb
|
||||
pub bomb_dropped: bool,
|
||||
pub bomb_planted: bool,
|
||||
pub bomb_planted_stamp: Option<Instant>,
|
||||
@@ -32,8 +38,6 @@ pub struct CsData {
|
||||
pub bomb_defuse_length: f32,
|
||||
pub bomb_exploded: bool,
|
||||
pub bomb_defused: bool,
|
||||
pub highest_index: i32,
|
||||
pub map: String
|
||||
}
|
||||
|
||||
|
||||
@@ -161,7 +165,7 @@ impl CsData {
|
||||
let mut bomb_being_defused = 0u8;
|
||||
let mut bomb_exploded = 0u8;
|
||||
let mut bomb_defused = 0u8;
|
||||
|
||||
let mut freeze_period = 0u8;
|
||||
{
|
||||
// Globals
|
||||
let tick_count_addr = (self.globals + 0x40).into();
|
||||
@@ -170,6 +174,8 @@ impl CsData {
|
||||
// Gamerules
|
||||
let bomb_dropped_addr = (self.gamerules + cs2dumper::client::C_CSGameRules::m_bBombDropped as u64).into();
|
||||
let bomb_planted_addr = (self.gamerules + cs2dumper::client::C_CSGameRules::m_bBombPlanted as u64).into();
|
||||
let total_rounds_addr = (self.gamerules + cs2dumper::client::C_CSGameRules::m_bFreezePeriod as u64).into();
|
||||
let round_start_count_addr = (self.gamerules + cs2dumper::client::C_CSGameRules::m_nRoundStartCount as u64).into();
|
||||
|
||||
// Game Entity System
|
||||
let highest_index_addr = (self.game_ent_sys + cs2dumper::offsets::client_dll::dwGameEntitySystem_getHighestEntityIndex as u64).into();
|
||||
@@ -187,6 +193,8 @@ impl CsData {
|
||||
batcher.read_into(tick_count_addr, &mut self.tick_count);
|
||||
batcher.read_into(bomb_dropped_addr, &mut bomb_dropped);
|
||||
batcher.read_into(bomb_planted_addr, &mut bomb_planted);
|
||||
batcher.read_into(total_rounds_addr, &mut freeze_period);
|
||||
batcher.read_into(round_start_count_addr, &mut self.round_start_count);
|
||||
batcher.read_into(highest_index_addr, &mut self.highest_index);
|
||||
batcher.read_into(map_addr, &mut map_ptr);
|
||||
}
|
||||
@@ -237,6 +245,7 @@ impl CsData {
|
||||
self.bomb_exploded = bomb_exploded != 0;
|
||||
self.bomb_being_defused = bomb_being_defused != 0;
|
||||
self.bomb_defused = bomb_defused != 0;
|
||||
self.freeze_period = freeze_period != 0;
|
||||
}
|
||||
|
||||
pub fn update_pointers(&mut self, ctx: &mut DmaCtx) {
|
||||
|
||||
Reference in New Issue
Block a user