From 7d24c5a40597021410934cdca59d9676bbb44b1f Mon Sep 17 00:00:00 2001 From: Huoji's <1296564236@qq.com> Date: Mon, 2 Oct 2023 05:03:37 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0pawn=E5=90=8D=E5=AD=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- csgo2/csgo2.vcxproj | 1 + csgo2/csgo2.vcxproj.filters | 3 + csgo2/events.cpp | 43 ++++++------ csgo2/global.cpp | 1 + csgo2/global.h | 1 + csgo2/hooks.cpp | 16 +++-- csgo2/native_sdk/entity/cbaseentity.cpp | 4 ++ csgo2/native_sdk/entity/cbaseentity.h | 55 ++++++++------- .../native_sdk/entity/cbaseplayercontroller.h | 25 ++++--- csgo2/native_sdk/handle/handle.h | 5 -- csgo2/offset.cpp | 7 ++ csgo2/offset.h | 3 + csgo2/pch.h | 1 + csgo2/player.h | 47 ++++++------- csgo2/player_manager.cpp | 68 +++++++++++++------ csgo2/player_manager.h | 14 ++-- 16 files changed, 167 insertions(+), 127 deletions(-) create mode 100644 csgo2/native_sdk/entity/cbaseentity.cpp diff --git a/csgo2/csgo2.vcxproj b/csgo2/csgo2.vcxproj index 49df0ad..897f09f 100644 --- a/csgo2/csgo2.vcxproj +++ b/csgo2/csgo2.vcxproj @@ -214,6 +214,7 @@ + diff --git a/csgo2/csgo2.vcxproj.filters b/csgo2/csgo2.vcxproj.filters index b360a79..8544c47 100644 --- a/csgo2/csgo2.vcxproj.filters +++ b/csgo2/csgo2.vcxproj.filters @@ -287,6 +287,9 @@ 源文件\players + + 源文件\native_sdk\entity + diff --git a/csgo2/events.cpp b/csgo2/events.cpp index bf9f76c..c1bef74 100644 --- a/csgo2/events.cpp +++ b/csgo2/events.cpp @@ -4,27 +4,30 @@ #include "player_manager.h" namespace events { - auto OnPlayerDeathEvent(IGameEvent* event) -> void { - UnkGameEventStruct_t userIdNameParams{ "userid" }; - UnkGameEventStruct_t attackerNameParams{ "attacker" }; +auto OnPlayerDeathEvent(IGameEvent* event) -> void { + UnkGameEventStruct_t userIdNameParams{"userid"}; + UnkGameEventStruct_t attackerNameParams{"attacker"}; - const auto victim = reinterpret_cast(event->GetPlayerPawn(&userIdNameParams)); - const auto attacker = reinterpret_cast(event->GetPlayerPawn(&attackerNameParams)); + const auto victim = reinterpret_cast( + event->GetPlayerPawn(&userIdNameParams)); + const auto attacker = reinterpret_cast( + event->GetPlayerPawn(&attackerNameParams)); - auto victimName = std::string(PlayerManager::GetPlayerNameByPlayerSlot(victim->GetRefEHandle().GetPlayerSlot())); - auto attackerName = std::string(PlayerManager::GetPlayerNameByPlayerSlot(attacker->GetRefEHandle().GetPlayerSlot())); - - printf("player %s killed %s\n", victimName.c_str(), attackerName.c_str()); + CGameEntitySystem* pEntitySystem = CGameEntitySystem::GetInstance(); + if (!pEntitySystem) return; + for (int i = 1; i <= 64; ++i) { + CBaseEntity* pEntity = pEntitySystem->GetBaseEntity(i); + if (!pEntity) continue; + if (pEntity->IsBasePlayerController()) { + const auto player = reinterpret_cast(pEntity); + if (player->m_hPawn().Get() == victim) { + printf("Found Pawn Player: %d %s \n", player->GetRefEHandle().GetEntryIndex(),&player->m_iszPlayerName()); + break; + } + } } - auto OnPlayerChat(IGameEvent* event) -> void - { - UnkGameEventStruct_t userIdNameParams{ "userid" }; - const auto chater = reinterpret_cast(event->GetPlayer(&userIdNameParams)); - const auto text = event->GetString("text"); - const auto chaterName = chater->m_iszPlayerName(); - - LOG("player: %s say: %s \n", chaterName, text); - - } -} \ No newline at end of file + //printf("player[%p] %s kill[%p] %llu\n", attacker, &attacker->m_iszPlayerName(), victim, &victim->m_steamID()); +} +auto OnPlayerChat(IGameEvent* event) -> void {} +} // namespace events diff --git a/csgo2/global.cpp b/csgo2/global.cpp index 61d0b21..0312374 100644 --- a/csgo2/global.cpp +++ b/csgo2/global.cpp @@ -1,4 +1,5 @@ #include "global.h" namespace global { bool Exit; + int MaxPlayers; } \ No newline at end of file diff --git a/csgo2/global.h b/csgo2/global.h index d592b77..a5cfaed 100644 --- a/csgo2/global.h +++ b/csgo2/global.h @@ -2,4 +2,5 @@ #include "pch.h" namespace global { extern bool Exit; + extern int MaxPlayers; } \ No newline at end of file diff --git a/csgo2/hooks.cpp b/csgo2/hooks.cpp index 08665d3..9bc805e 100644 --- a/csgo2/hooks.cpp +++ b/csgo2/hooks.cpp @@ -14,7 +14,10 @@ VMTHook* VMT_IServerGameClient; void __fastcall hook_ClientDisconnect(void* rcx, CPlayerSlot slot, int reason, const char* pszName, uint64_t xuid, const char* pszNetworkID) { - PlayerManager::RemovePlayerNameFromPlayerNameList(slot, pszName); + if (pszNetworkID != NULL && *pszNetworkID == '[') { + ExtendPlayerManager::RemovePlayerSlotBySteamId( + ExtendPlayerManager::SteamIDStringToUInt64(pszNetworkID)); + } return original_OnClientDisconnect(rcx, slot, reason, pszName, xuid, pszNetworkID); } @@ -24,10 +27,10 @@ void __fastcall hook_OnClientConnected(void* rcx, CPlayerSlot slot, const char* pszAddress, bool bFakePlayer) { if (bFakePlayer == false) { - LOG("%s %d %s %s %s %d", __FUNCTION__, slot.Get(), pszName, pszNetworkID, - pszAddress, bFakePlayer); + ExtendPlayerManager::AddSteamIdToPlayerSteamIdWithNameTable( + ExtendPlayerManager::SteamIDStringToUInt64(pszNetworkID), + slot.Get()); } - PlayerManager::AddPlayerNameToPlayerNameList(slot, pszName); return original_OnClientConnected(rcx, slot, pszName, xuid, pszNetworkID, pszAddress, bFakePlayer); @@ -43,9 +46,8 @@ void __fastcall hook_Host_Say(void* pEntity, void* args, bool teamonly, break; } auto message = std::string(theArgs->GetCommandString()); - auto playerName = PlayerManager::GetPlayerNameByPlayerSlot( - theEntity->GetRefEHandle().GetPlayerSlot()); - printf("player %s : %s \n", playerName.c_str(), message.c_str()); + printf("player[%d][%p] %s : %s \n", theEntity->GetRefEHandle().GetEntryIndex(),theEntity, &theEntity->m_iszPlayerName(), + message.c_str()); } while (false); /* if (*pMessage == '!' || *pMessage == '/') diff --git a/csgo2/native_sdk/entity/cbaseentity.cpp b/csgo2/native_sdk/entity/cbaseentity.cpp new file mode 100644 index 0000000..02f05ee --- /dev/null +++ b/csgo2/native_sdk/entity/cbaseentity.cpp @@ -0,0 +1,4 @@ +#include "cbaseentity.h" +bool CBaseEntity::IsBasePlayerController() { + return CALL_VIRTUAL(bool, 144, this); +} diff --git a/csgo2/native_sdk/entity/cbaseentity.h b/csgo2/native_sdk/entity/cbaseentity.h index 3526a1b..af8c2c2 100644 --- a/csgo2/native_sdk/entity/cbaseentity.h +++ b/csgo2/native_sdk/entity/cbaseentity.h @@ -6,38 +6,37 @@ #include "../cgameentitysystem.h" class CEntityIdentity; class CEntityInstance { -public: - DECLARE_CLASS(CEntityInstance); + public: + DECLARE_CLASS(CEntityInstance); - auto Schema_DynamicBinding() { - SchemaClassInfoData_t* rv = nullptr; - CALL_VIRTUAL(void, 34, this, &rv); - return rv; - } + auto Schema_DynamicBinding() { + SchemaClassInfoData_t* rv = nullptr; + CALL_VIRTUAL(void, 34, this, &rv); + return rv; + } - auto GetRefEHandle() { - char* pIdentity = (char*)m_pEntity(); - auto v3 = *(uint32_t*)(pIdentity + 16); - auto v4 = ENT_ENTRY_MASK; - auto v5 = ((v3 >> 15) - (*(uint32_t*)(pIdentity + 48) & 1)) << 15; - if (v3 != -1) { - v4 = *(uint32_t*)(pIdentity + 16) & ENT_ENTRY_MASK; - } + auto GetRefEHandle() { + char* pIdentity = (char*)m_pEntity(); + auto v3 = *(uint32_t*)(pIdentity + 16); + auto v4 = ENT_ENTRY_MASK; + auto v5 = ((v3 >> 15) - (*(uint32_t*)(pIdentity + 48) & 1)) << 15; + if (v3 != -1) { + v4 = *(uint32_t*)(pIdentity + 16) & ENT_ENTRY_MASK; + } - return CHandle(v4 | v5); - } - - SCHEMA_FIELD(CEntityIdentity*, m_pEntity); - SCHEMA_FIELD(const char*, m_designerName); + return CHandle(v4 | v5); + } + SCHEMA_FIELD(CEntityIdentity*, m_pEntity); + SCHEMA_FIELD(const char*, m_designerName); }; -class CBaseEntity : public CEntityInstance -{ -public: - DECLARE_CLASS(CBaseEntity); +class CBaseEntity : public CEntityInstance { + public: + DECLARE_CLASS(CBaseEntity); - SCHEMA_FIELD(int, m_iHealth) - //SCHEMA_FIELD(Vector, m_vecBaseVelocity) - SCHEMA_FIELD(CCollisionProperty*, m_pCollision) -}; \ No newline at end of file + SCHEMA_FIELD(int, m_iHealth) + // SCHEMA_FIELD(Vector, m_vecBaseVelocity) + SCHEMA_FIELD(CCollisionProperty*, m_pCollision) + bool IsBasePlayerController(); +}; diff --git a/csgo2/native_sdk/entity/cbaseplayercontroller.h b/csgo2/native_sdk/entity/cbaseplayercontroller.h index abd869e..e679377 100644 --- a/csgo2/native_sdk/entity/cbaseplayercontroller.h +++ b/csgo2/native_sdk/entity/cbaseplayercontroller.h @@ -2,23 +2,22 @@ #include "../../pch.h" #include "../handle/handle.h" #include "cbaseentity.h" -class CBasePlayerController : public CBaseEntity -{ -public: - DECLARE_CLASS(CBasePlayerController); - - SCHEMA_FIELD(uint64_t, m_steamID) - SCHEMA_FIELD(CHandle, m_hPawn) - SCHEMA_FIELD(char, m_iszPlayerName) +#include "sdk/tier1/UtlString.hpp" +class CBasePlayerController : public CBaseEntity { + public: + DECLARE_CLASS(CBasePlayerController); + SCHEMA_FIELD(uint64_t, m_steamID) + SCHEMA_FIELD(CHandle, m_hPawn) + SCHEMA_FIELD(char, m_iszPlayerName) + SCHEMA_FIELD(CUtlString, m_szNetworkIDString) }; class CCSPlayerController : public CBasePlayerController { -public: + public: DECLARE_CLASS(CCSPlayerController) - SCHEMA_FIELD(uint32_t, m_iPawnHealth) - SCHEMA_FIELD(bool, m_bPawnIsAlive) - SCHEMA_FIELD(const char*, m_szClanName) - + SCHEMA_FIELD(uint32_t, m_iPawnHealth) + SCHEMA_FIELD(bool, m_bPawnIsAlive) + SCHEMA_FIELD(const char*, m_szClanName) }; diff --git a/csgo2/native_sdk/handle/handle.h b/csgo2/native_sdk/handle/handle.h index 55ced4e..1e801aa 100644 --- a/csgo2/native_sdk/handle/handle.h +++ b/csgo2/native_sdk/handle/handle.h @@ -2,8 +2,6 @@ #include #define INVALID_EHANDLE_INDEX 0xFFFFFFFF #define ENT_ENTRY_MASK 0x7FFF -inline int PlayerSlot_to_EntityIndex(int PlayerSlot) { return PlayerSlot + 1; } -inline int EntityIndex_to_PlayerSlot(int EntityIndex) { return EntityIndex - 1; } class CBaseEntity; class CHandle @@ -22,8 +20,5 @@ public: { return reinterpret_cast(GetBaseEntity()); } - auto GetPlayerSlot() { - return m_Index - 1; - } uint32_t m_Index; }; \ No newline at end of file diff --git a/csgo2/offset.cpp b/csgo2/offset.cpp index d110b80..cbe2718 100644 --- a/csgo2/offset.cpp +++ b/csgo2/offset.cpp @@ -7,6 +7,8 @@ uint64_t NetworkStateChangedPtr; uint64_t CGameEventManagerPtr; uint64_t Host_SayPtr; uint64_t Module_tier0; +uint64_t MaxPlayerNumsPtr; + namespace InterFaces { CSchemaSystem* SchemaSystem; IGameEventManager2* GameEventManager; @@ -19,6 +21,8 @@ auto Init() -> bool { CModule server("server.dll"); CModule schemasystem("schemasystem.dll"); CModule engine("engine2.dll"); + // engine.dll + engine.FindPattern(pattern_MaxPlayerNumsPtr).ToAbsolute(3, 0).Get(MaxPlayerNumsPtr); // server.dll server.FindPattern(pattern_FireEventServerSide).Get(FireEventServerSidePtr); @@ -49,10 +53,13 @@ auto Init() -> bool { InterFaces::CGameEventManger = reinterpret_cast(CGameEventManagerPtr); + //global::MaxPlayers = *(int*)((char*)MaxPlayerNumsPtr + 2); // client.FindPattern(pattern_FireEventServerSide).Get(FireEventServerSidePtr); LOG("[huoji]FireEventServerSidePtr : %llx \n", FireEventServerSidePtr); LOG("[huoji]NetworkStateChangedPtr : %llx \n", NetworkStateChangedPtr); LOG("[huoji]Host_SayPtr : %llx \n", Host_SayPtr); + LOG("[huoji]Host_SayPtr : %llx \n", MaxPlayerNumsPtr); + LOG("[huoji]MaxGlobals : %d \n", global::MaxPlayers); LOG("[huoji]InterFaces::SchemaSystem : %llx \n", InterFaces::SchemaSystem); LOG("[huoji]InterFaces::GameEventManager : %llx \n", diff --git a/csgo2/offset.h b/csgo2/offset.h index 65b1c43..316b279 100644 --- a/csgo2/offset.h +++ b/csgo2/offset.h @@ -30,10 +30,13 @@ static const auto pattern_fnGetLocalPlayerController = //"\"Console<0>\" say \"%s\"\n" static const auto pattern_fnHost_SayPtr = THE_GAME_SIG("44 89 4C 24 ?? 44 88 44 24 ?? 55 53 56 57 41 54 41 55"); +static const auto pattern_MaxPlayerNumsPtr = + THE_GAME_SIG("41 3B 87 ?? ?? ?? ?? 0F 8E ?? ?? ?? ?? 8B 0D ?? ?? ?? ??"); extern uint64_t GameResourceServicePtr; extern uint64_t FireEventServerSidePtr; extern uint64_t Module_tier0; extern uint64_t NetworkStateChangedPtr; extern uint64_t Host_SayPtr; +extern uint64_t MaxPlayerNumsPtr; auto Init() -> bool; }; // namespace Offset diff --git a/csgo2/pch.h b/csgo2/pch.h index b37640d..9ebc366 100644 --- a/csgo2/pch.h +++ b/csgo2/pch.h @@ -11,6 +11,7 @@ #include #include #include +#include #include "framework.h" #include "stb.hh" diff --git a/csgo2/player.h b/csgo2/player.h index 2cc1ba5..b4b345a 100644 --- a/csgo2/player.h +++ b/csgo2/player.h @@ -2,37 +2,34 @@ #include "pch.h" #include "schema.h" #include "native_sdk/entity/cbaseentity.h" +#include "sdk/player/playerslot.h" + class CBasePlayer { -public: - auto ForceRespawn() -> void; + public: + auto ForceRespawn() -> void; }; -class CPlayer_MovementServices -{ -public: - DECLARE_CLASS(CPlayer_MovementServices); +class CPlayer_MovementServices { + public: + DECLARE_CLASS(CPlayer_MovementServices); }; -class CCSPlayerController_InGameMoneyServices -{ -public: - DECLARE_CLASS(CCSPlayerController_InGameMoneyServices); +class CCSPlayerController_InGameMoneyServices { + public: + DECLARE_CLASS(CCSPlayerController_InGameMoneyServices); - SCHEMA_FIELD(int, m_iAccount) + SCHEMA_FIELD(int, m_iAccount) }; -class CBasePlayerPawn : public CBaseEntity -{ -public: - DECLARE_CLASS(CBasePlayerPawn); +class CBasePlayerPawn : public CBaseEntity { + public: + DECLARE_CLASS(CBasePlayerPawn); - SCHEMA_FIELD(CPlayer_MovementServices*, m_pMovementServices) - SCHEMA_FIELD(uint8_t*, m_pWeaponServices) - SCHEMA_FIELD(uint8_t**, m_pItemServices) + SCHEMA_FIELD(CPlayer_MovementServices*, m_pMovementServices) + SCHEMA_FIELD(uint8_t*, m_pWeaponServices) + SCHEMA_FIELD(uint8_t**, m_pItemServices) +}; +class CCSPlayerPawn : public CBasePlayerPawn { + public: + DECLARE_CLASS(CCSPlayerPawn); + SCHEMA_FIELD(const char*, m_szLastPlaceName) }; -class CCSPlayerPawn : public CBasePlayerPawn -{ -public: - DECLARE_CLASS(CCSPlayerPawn); - SCHEMA_FIELD(const char*, m_szLastPlaceName) - -}; \ No newline at end of file diff --git a/csgo2/player_manager.cpp b/csgo2/player_manager.cpp index 4003159..d76d5b2 100644 --- a/csgo2/player_manager.cpp +++ b/csgo2/player_manager.cpp @@ -1,26 +1,50 @@ #include "player_manager.h" -namespace PlayerManager { -std::shared_mutex mutex_PlayerNameList; -std::unordered_map PlayerNameList; -auto AddPlayerNameToPlayerNameList(const CPlayerSlot PlayerSlot, - const char* PlayerName) -> void { - std::unique_lock lock(mutex_PlayerNameList); - PlayerNameList[PlayerSlot.Get()] = PlayerName; - LOG("%s PlayerNameList[%d] = %s \n", __FUNCTION__, PlayerSlot.Get(), - PlayerName); +#include "native_sdk/cgameentitysystem.h" +namespace ExtendPlayerManager { +std::shared_mutex mutex_Table_PlayerSteamIdPlayerSlot; + +std::unordered_map Table_PlayerSteamIdPlayerSlot; + +auto SteamIDStringToUInt64(const std::string& steamID) -> uint64_t { + std::istringstream iss( + steamID.substr(3, steamID.size() - 4)); // 去掉"[U:"和"]" + std::string tmp; + uint32_t instance, account_id; + + // 读取 Account Instance + std::getline(iss, tmp, ':'); + instance = std::stoi(tmp); + + // 读取 Account ID + std::getline(iss, tmp); + account_id = std::stoi(tmp); + + // 计算并返回结果 + return (uint64_t(account_id) << 1 | instance) + 76561197960265728ULL; } -auto RemovePlayerNameFromPlayerNameList(const CPlayerSlot PlayerSlot, - const char* PlayerName) -> void { - std::unique_lock lock(mutex_PlayerNameList); - PlayerNameList.erase(PlayerSlot.Get()); - LOG("%s PlayerNameList[%d] = %s \n", __FUNCTION__, PlayerSlot.Get(), - PlayerName); + +auto AddSteamIdToPlayerSteamIdWithNameTable(uint64_t SteamId, + uint64_t PlayerSlot) -> void { + std::unique_lock lock(mutex_Table_PlayerSteamIdPlayerSlot); + LOG("steamid: %llu playername: %ld \n", SteamId, PlayerSlot); + Table_PlayerSteamIdPlayerSlot.insert(std::make_pair(SteamId, PlayerSlot)); } -auto GetPlayerNameByPlayerSlot(const CPlayerSlot PlayerSlot) -> std::string { - std::shared_lock lock(mutex_PlayerNameList); - auto index = PlayerSlot.Get(); - auto name = PlayerNameList[index]; - LOG("get player name: %d %s \n", index, name.c_str()); - return name; +auto GetPlayerSlotBySteamId(uint64_t SteamId) -> uint64_t { + std::shared_lock lock(mutex_Table_PlayerSteamIdPlayerSlot); + LOG("steamid: %llu \n", SteamId); + + auto it = Table_PlayerSteamIdPlayerSlot.find(SteamId); + if (it != Table_PlayerSteamIdPlayerSlot.end()) { + return it->second; + } + return -1; } -}; // namespace PlayerManager +auto RemovePlayerSlotBySteamId(uint64_t SteamId) -> void { + std::unique_lock lock(mutex_Table_PlayerSteamIdPlayerSlot); + LOG("steamid: %llu \n", SteamId); + if (Table_PlayerSteamIdPlayerSlot.find(SteamId) != + Table_PlayerSteamIdPlayerSlot.end()) { + Table_PlayerSteamIdPlayerSlot.erase(SteamId); + } +} +}; // namespace ExtendPlayerManager diff --git a/csgo2/player_manager.h b/csgo2/player_manager.h index ab4300b..2dc739c 100644 --- a/csgo2/player_manager.h +++ b/csgo2/player_manager.h @@ -1,10 +1,10 @@ #pragma once #include "pch.h" #include "sdk/player/playerslot.h" -namespace PlayerManager { -auto AddPlayerNameToPlayerNameList(const CPlayerSlot PlayerSlot, - const char* PlayerName) -> void; -auto RemovePlayerNameFromPlayerNameList(const CPlayerSlot PlayerSlot, - const char* PlayerName) -> void; -auto GetPlayerNameByPlayerSlot(const CPlayerSlot PlayerSlot) -> std::string; -}; // namespace PlayerManager +namespace ExtendPlayerManager { +auto AddSteamIdToPlayerSteamIdWithNameTable(uint64_t SteamId, + uint64_t PlayerSlot) -> void; +auto GetPlayerSlotBySteamId(uint64_t SteamId) -> uint64_t; +auto SteamIDStringToUInt64(const std::string& steamID) -> uint64_t; +auto RemovePlayerSlotBySteamId(uint64_t SteamId) -> void; +}; // namespace ExtendPlayerManager