From cb9462ce9b64918c8d517377d9ee71740c9ab8a5 Mon Sep 17 00:00:00 2001 From: Wizzard <rich@bandaholics.cash> Date: Sat, 15 Mar 2025 17:50:46 -0400 Subject: [PATCH] Add: Show money on radar --- src/comms.rs | 37 ++++++++++++++++++-- src/dma/context/mod.rs | 13 +++++++ src/dma/mod.rs | 11 +++--- webradar/index.html | 4 +++ webradar/script.js | 79 ++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 138 insertions(+), 6 deletions(-) diff --git a/src/comms.rs b/src/comms.rs index a310690..67963ba 100755 --- a/src/comms.rs +++ b/src/comms.rs @@ -23,11 +23,40 @@ pub struct PlayerData { #[serde(rename = "weaponId")] weapon_id: i16, + + #[serde(rename = "money", default)] + money: i32, } impl PlayerData { - pub fn new(pos: Vec3, yaw: f32, player_type: PlayerType, has_bomb: bool, has_awp: bool, is_scoped: bool, player_name: String, weapon_id: i16) -> PlayerData { - PlayerData { pos, yaw, player_type, has_bomb, has_awp, is_scoped, player_name, weapon_id } + pub fn new(pos: Vec3, yaw: f32, player_type: PlayerType, has_bomb: bool, has_awp: bool, + is_scoped: bool, player_name: String, weapon_id: i16) -> PlayerData { + PlayerData { + pos, + yaw, + player_type, + has_bomb, + has_awp, + is_scoped, + player_name, + weapon_id, + money: 0 + } + } + + pub fn new_with_money(pos: Vec3, yaw: f32, player_type: PlayerType, has_bomb: bool, has_awp: bool, + is_scoped: bool, player_name: String, weapon_id: i16, money: i32) -> PlayerData { + PlayerData { + pos, + yaw, + player_type, + has_bomb, + has_awp, + is_scoped, + player_name, + weapon_id, + money + } } } @@ -55,12 +84,16 @@ pub enum EntityData { pub struct CheatOptions { #[serde(rename = "revealMoney")] pub reveal_money: bool, + + #[serde(rename = "displayMoney")] + pub display_money: bool, } impl Default for CheatOptions { fn default() -> Self { Self { reveal_money: false, + display_money: true, } } } diff --git a/src/dma/context/mod.rs b/src/dma/context/mod.rs index 27b1d11..43498a3 100755 --- a/src/dma/context/mod.rs +++ b/src/dma/context/mod.rs @@ -98,6 +98,8 @@ impl DmaCtx { let mut clipping_weapon = 0u64; let mut is_scoped = 0u8; let mut player_name_ptr = 0u64; + let mut money = 0i32; + let mut money_services_ptr = 0u64; { let mut batcher = MemoryViewBatcher::new(&mut self.process); @@ -108,6 +110,15 @@ impl DmaCtx { batcher.read_into(pawn + cs2dumper::client::C_CSPlayerPawnBase::m_pClippingWeapon, &mut clipping_weapon); batcher.read_into(pawn + cs2dumper::client::C_CSPlayerPawn::m_bIsScoped, &mut is_scoped); batcher.read_into(controller + cs2dumper::client::CCSPlayerController::m_sSanitizedPlayerName, &mut player_name_ptr); + + batcher.read_into(controller + cs2dumper::client::CCSPlayerController::m_pInGameMoneyServices, &mut money_services_ptr); + } + + if money_services_ptr != 0 { + let money_addr: Address = money_services_ptr.into(); + money = self.process.read(money_addr + cs2dumper::client::CCSPlayerController_InGameMoneyServices::m_iAccount)?; + + log::debug!("Read money value: {} for player", money); } let player_name = if player_name_ptr != 0 { @@ -145,6 +156,7 @@ impl DmaCtx { is_scoped: is_scoped != 0, player_name, weapon_id, + money, }) } @@ -273,4 +285,5 @@ pub struct BatchedPlayerData { pub is_scoped: bool, pub player_name: String, pub weapon_id: i16, + pub money: i32, } \ No newline at end of file diff --git a/src/dma/mod.rs b/src/dma/mod.rs index 7e4bc42..0a97471 100755 --- a/src/dma/mod.rs +++ b/src/dma/mod.rs @@ -196,7 +196,7 @@ pub async fn run(radar_data: ArcRwlockRadarData, connector: Connector, pcileech_ entity_data.push( EntityData::Player( - PlayerData::new( + PlayerData::new_with_money( local_data.pos, local_data.yaw, PlayerType::Local, @@ -204,10 +204,12 @@ pub async fn run(radar_data: ArcRwlockRadarData, connector: Connector, pcileech_ local_data.has_awp, local_data.is_scoped, local_data.player_name, - local_data.weapon_id + local_data.weapon_id, + local_data.money ) ) ); + log::debug!("Added local player with money: {}", local_data.money); } // Other players @@ -235,7 +237,7 @@ pub async fn run(radar_data: ArcRwlockRadarData, connector: Connector, pcileech_ entity_data.push( EntityData::Player( - PlayerData::new( + PlayerData::new_with_money( player_data.pos, player_data.yaw, player_type, @@ -243,7 +245,8 @@ pub async fn run(radar_data: ArcRwlockRadarData, connector: Connector, pcileech_ player_data.has_awp, player_data.is_scoped, player_data.player_name, - player_data.weapon_id + player_data.weapon_id, + player_data.money ) ) ); diff --git a/webradar/index.html b/webradar/index.html index 8682068..26d3f73 100644 --- a/webradar/index.html +++ b/webradar/index.html @@ -36,6 +36,10 @@ <input type="checkbox" onclick="toggleCentered()" id="centerCheck" name="center" checked /> <label for="centerCheck">Player Centered</label> </div> + <div> + <input type="checkbox" onclick="toggleDisplayMoney()" id="moneyDisplay" name="money-display" checked /> + <label for="moneyDisplay">Display Money</label> + </div> <button id="showDangerousBtn" onclick="toggleDangerousOptions()">Show Dangerous Options</button> diff --git a/webradar/script.js b/webradar/script.js index b5fd4ae..410e43d 100644 --- a/webradar/script.js +++ b/webradar/script.js @@ -13,6 +13,7 @@ playerCentered = true drawStats = true drawNames = true drawGuns = true +drawMoney = true; // Common canvas = null @@ -274,6 +275,16 @@ function render() { data.Player.playerType ); } + + if (drawMoney && !data.Player.isDormant && typeof data.Player.money === 'number') { + console.log(`[radarflow] Drawing money for ${data.Player.playerName}: $${data.Player.money}`); + drawPlayerMoney( + data.Player.pos, + data.Player.playerType, + data.Player.money, + data.Player.hasBomb + ); + } } }); } @@ -457,6 +468,64 @@ function drawPlayerName(pos, playerName, playerType, hasAwp, hasBomb, isScoped) ctx.fillText(displayName, mapPos.x, textY); } +function drawPlayerMoney(pos, playerType, money, hasBomb) { + if (!map) return; + + console.log(`[radarflow] Drawing money: $${money} for ${playerType}`); + + let mapPos = mapCoordinates(pos); + let textSize; + + if (zoomSet) { + mapPos = boundingCoordinates(mapPos, boundingRect); + textSize = boundingScale(10, boundingRect); + } else if (playerCentered && localPlayerPos) { + const playerMapPos = mapCoordinates(localPlayerPos); + const zoomLevel = 0.5; + const viewWidth = image.width * zoomLevel; + const viewHeight = image.height * zoomLevel; + + mapPos.x = (mapPos.x - (playerMapPos.x - viewWidth / 2)) * canvas.width / viewWidth; + mapPos.y = (mapPos.y - (playerMapPos.y - viewHeight / 2)) * canvas.height / viewHeight; + textSize = 10; + } else { + mapPos.x = mapPos.x * canvas.width / image.width; + mapPos.y = mapPos.y * canvas.height / image.height; + textSize = 10; + } + + if (rotateMap) { + const canvasCenter = { x: canvas.width / 2, y: canvas.height / 2 }; + mapPos = rotatePoint(canvasCenter.x, canvasCenter.y, mapPos.x, mapPos.y, localYaw + 270); + } + + let extraOffset = 0; + if (drawNames) extraOffset += 15; + if (drawGuns) extraOffset += 15; + if (hasBomb) extraOffset += 15; + + let textY = mapPos.y + 20 + extraOffset; + + const formattedMoney = '$' + (money || 0).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ","); + + if (money >= 10000) { + ctx.fillStyle = "#32CD32"; + } else if (money >= 4500) { + ctx.fillStyle = "#FFFF00"; + } else { + ctx.fillStyle = "#FF4500"; + } + + ctx.font = `${textSize}px Arial`; + ctx.textAlign = "center"; + ctx.textBaseline = "top"; + + ctx.lineWidth = 2; + ctx.strokeStyle = "black"; + ctx.strokeText(formattedMoney, mapPos.x, textY); + ctx.fillText(formattedMoney, mapPos.x, textY); +} + function drawPlayerWeapon(pos, playerType, weaponId) { if (!map) return; @@ -853,6 +922,7 @@ addEventListener("DOMContentLoaded", (e) => { document.getElementById("moneyReveal").checked = false; document.getElementById("rotateCheck").checked = true; document.getElementById("centerCheck").checked = true; + document.getElementById("moneyDisplay").checked = true; canvas = document.getElementById('canvas'); canvas.width = 1024; @@ -892,4 +962,13 @@ function toggleMoneyReveal() { if (websocket && websocket.readyState === WebSocket.OPEN) { websocket.send("toggleMoneyReveal"); } +} + +function toggleDisplayMoney() { + drawMoney = !drawMoney; + update = true; + + console.log("[radarflow] Money display toggled:", drawMoney); + + localStorage.setItem('drawMoney', drawMoney ? 'true' : 'false'); } \ No newline at end of file