This commit is contained in:
Huoji's
2023-10-04 06:01:28 +08:00
parent e356220383
commit 06acf8b24d
21 changed files with 773 additions and 457 deletions

View File

@@ -87,6 +87,7 @@
"*.rh": "cpp", "*.rh": "cpp",
"random": "cpp", "random": "cpp",
"hash_map": "cpp", "hash_map": "cpp",
"hash_set": "cpp" "hash_set": "cpp",
"filesystem": "cpp"
} }
} }

View File

@@ -230,6 +230,7 @@
<ClInclude Include="sdk\tier1\UtlVector.hpp" /> <ClInclude Include="sdk\tier1\UtlVector.hpp" />
<ClInclude Include="sdk_tools.h" /> <ClInclude Include="sdk_tools.h" />
<ClInclude Include="stb.hh" /> <ClInclude Include="stb.hh" />
<ClInclude Include="timer.h" />
<ClInclude Include="tools.h" /> <ClInclude Include="tools.h" />
<ClInclude Include="vector.h" /> <ClInclude Include="vector.h" />
<ClInclude Include="vmt.h" /> <ClInclude Include="vmt.h" />
@@ -297,6 +298,7 @@
<ClCompile Include="sdk\convar\convar.cpp" /> <ClCompile Include="sdk\convar\convar.cpp" />
<ClCompile Include="sdk\tier1\UtlString.cpp" /> <ClCompile Include="sdk\tier1\UtlString.cpp" />
<ClCompile Include="sdk_tools.cpp" /> <ClCompile Include="sdk_tools.cpp" />
<ClCompile Include="timer.cpp" />
<ClCompile Include="tools.cpp" /> <ClCompile Include="tools.cpp" />
<ClCompile Include="vmthook.cpp" /> <ClCompile Include="vmthook.cpp" />
</ItemGroup> </ItemGroup>

View File

@@ -76,6 +76,12 @@
<Filter Include="头文件\lua"> <Filter Include="头文件\lua">
<UniqueIdentifier>{d58fcaf6-b1d7-484d-9ec4-d6b67ff46cf5}</UniqueIdentifier> <UniqueIdentifier>{d58fcaf6-b1d7-484d-9ec4-d6b67ff46cf5}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="源文件\game_time_system">
<UniqueIdentifier>{ccc753a5-6730-455d-b12b-9fa7e9a4cf03}</UniqueIdentifier>
</Filter>
<Filter Include="头文件\game_time_system">
<UniqueIdentifier>{f26913ae-881a-43da-a215-8c0c7a9173cd}</UniqueIdentifier>
</Filter>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="framework.h"> <ClInclude Include="framework.h">
@@ -318,6 +324,9 @@
<ClInclude Include="vector.h"> <ClInclude Include="vector.h">
<Filter>头文件\native_sdk</Filter> <Filter>头文件\native_sdk</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="timer.h">
<Filter>头文件\game_time_system</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="dllmain.cpp"> <ClCompile Include="dllmain.cpp">
@@ -491,6 +500,9 @@
<ClCompile Include="script_callbacks.cpp"> <ClCompile Include="script_callbacks.cpp">
<Filter>源文件\script_engine</Filter> <Filter>源文件\script_engine</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="timer.cpp">
<Filter>源文件\game_time_system</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="cpp.hint" /> <None Include="cpp.hint" />

View File

@@ -28,7 +28,8 @@ auto OnPlayerDeathEvent(IGameEvent* event) -> void {
} }
const auto victimIndex = victim->GetRefEHandle().GetEntryIndex(); const auto victimIndex = victim->GetRefEHandle().GetEntryIndex();
const auto attackerIndex = attacker->GetRefEHandle().GetEntryIndex(); const auto attackerIndex = attacker->GetRefEHandle().GetEntryIndex();
ScriptCallBacks::luaCall_onPlayerDeath(victimIndex, attackerIndex, isHeadShot); ScriptCallBacks::luaCall_onPlayerDeath(victimIndex, attackerIndex,
isHeadShot);
// printf("player[%p] %s kill[%p] %llu\n", attacker, // printf("player[%p] %s kill[%p] %llu\n", attacker,
// &attacker->m_iszPlayerName(), victim, &victim->m_steamID()); // &attacker->m_iszPlayerName(), victim, &victim->m_steamID());
} }
@@ -38,10 +39,8 @@ auto OnPlayerChat(CCSPlayerController* player, std::string message) -> bool {
if (procesChatSuccess == false) { if (procesChatSuccess == false) {
return false; return false;
} }
if (chatCtx.at(0) == '/' || chatCtx.at(0) == '!') { return ScriptCallBacks::luaCall_onPlayerSpeak(
return true; player->GetRefEHandle().GetEntryIndex(), chatType, chatCtx);
}
return false;
} }
auto OnPlayerConnect(int slot, const char* pszName, uint64_t xuid, auto OnPlayerConnect(int slot, const char* pszName, uint64_t xuid,
const char* pszNetworkID, const char* pszAddress, const char* pszNetworkID, const char* pszAddress,

View File

@@ -2,4 +2,9 @@
namespace global { namespace global {
bool Exit; bool Exit;
int MaxPlayers; int MaxPlayers;
CGameEntitySystem* EntitySystem;
bool HasTicked;
CGlobalVars* GlobalVars;
float m_flUniversalTime;
float m_flLastTickedTime;
} }

View File

@@ -1,6 +1,13 @@
#pragma once #pragma once
#include "head.h" #include "head.h"
class CGlobalVars;
class CGameEntitySystem;
namespace global { namespace global {
extern bool Exit; extern bool Exit;
extern int MaxPlayers; extern int MaxPlayers;
extern CGameEntitySystem* EntitySystem;
extern bool HasTicked;
extern CGlobalVars* GlobalVars;
extern float m_flUniversalTime;
extern float m_flLastTickedTime;
} }

View File

@@ -79,3 +79,4 @@ static void DebugPrintA(const char* format, ...) {
#include "script_engine.h" #include "script_engine.h"
#include "script_apis.h" #include "script_apis.h"
#include "script_callbacks.h" #include "script_callbacks.h"
#include "timer.h"

View File

@@ -1,13 +1,58 @@
#include "hooks.h" #include "hooks.h"
extern auto GetGameGlobals() -> CGlobalVars*;
FireEventServerSide_t original_FireEventServerSide = NULL; FireEventServerSide_t original_FireEventServerSide = NULL;
OnClientConnect_t original_OnClientConnected = NULL; OnClientConnect_t original_OnClientConnected = NULL;
OnClientDisconnect_t original_OnClientDisconnect = NULL; OnClientDisconnect_t original_OnClientDisconnect = NULL;
Host_Say_t original_Host_Say = NULL; Host_Say_t original_Host_Say = NULL;
StartupServer_t origin_StartServer = NULL;
GameFrame_t origin_GameFrame = NULL;
namespace hooks { namespace hooks {
// "player_connect" // "player_connect"
VMTHook* VMT_IServerGameClient; VMTHook* VMT_IServerGameClient;
VMTHook* VMT_INetworkServerServiceInteFace;
VMTHook* VMT_ISource2ServerInterFace;
void __fastcall hook_GameFrame(void* rcx, bool simulating, bool bFirstTick,
bool bLastTick) {
/**
* simulating:
* ***********
* true | game is ticking
* false | game is not ticking
*/
if (simulating && global::HasTicked) {
global::m_flUniversalTime +=
global::GlobalVars->curtime - global::m_flLastTickedTime;
} else {
global::m_flUniversalTime += global::GlobalVars->interval_per_tick;
}
global::m_flLastTickedTime = global::GlobalVars->curtime;
global::HasTicked = true;
if (global::EntitySystem == nullptr) {
global::EntitySystem = Offset::InterFaces::GameResourceServiceServer
->GetGameEntitySystem();
}
GameTimer::ExcuteTimers();
return origin_GameFrame(rcx, simulating, bFirstTick, bLastTick);
}
void __fastcall hook_StartServer(void* rcx,
const GameSessionConfiguration_t& config,
ISource2WorldSession* pWorldSession,
const char* a1) {
if (global::HasTicked) {
GameTimer::CleanUpTimers();
}
global::HasTicked = false;
global::GlobalVars = GetGameGlobals();
global::EntitySystem =
Offset::InterFaces::GameResourceServiceServer->GetGameEntitySystem();
return origin_StartServer(rcx, config, pWorldSession, a1);
}
void __fastcall hook_ClientDisconnect(void* rcx, CPlayerSlot slot, int reason, void __fastcall hook_ClientDisconnect(void* rcx, CPlayerSlot slot, int reason,
const char* pszName, uint64_t xuid, const char* pszName, uint64_t xuid,
const char* pszNetworkID) { const char* pszNetworkID) {
@@ -134,11 +179,24 @@ auto initMinHook() -> bool {
auto initVmtHook() -> bool { auto initVmtHook() -> bool {
VMT_IServerGameClient = new VMTHook(Memory::read<void*>( VMT_IServerGameClient = new VMTHook(Memory::read<void*>(
reinterpret_cast<uint64_t>(Offset::InterFaces::IServerGameClient))); reinterpret_cast<uint64_t>(Offset::InterFaces::IServerGameClient)));
VMT_INetworkServerServiceInteFace =
new VMTHook(Memory::read<void*>(reinterpret_cast<uint64_t>(
Offset::InterFaces::INetworkServerServiceInteFace)));
VMT_ISource2ServerInterFace =
new VMTHook(Memory::read<void*>(reinterpret_cast<uint64_t>(
Offset::InterFaces::ISource2ServerInterFace)));
original_OnClientConnected = reinterpret_cast<OnClientConnect_t>( original_OnClientConnected = reinterpret_cast<OnClientConnect_t>(
VMT_IServerGameClient->Hook(11, hook_OnClientConnected)); VMT_IServerGameClient->Hook(11, hook_OnClientConnected));
original_OnClientDisconnect = reinterpret_cast<OnClientDisconnect_t>( original_OnClientDisconnect = reinterpret_cast<OnClientDisconnect_t>(
VMT_IServerGameClient->Hook(16, hook_ClientDisconnect)); VMT_IServerGameClient->Hook(16, hook_ClientDisconnect));
return original_OnClientConnected && original_OnClientDisconnect;
origin_StartServer = reinterpret_cast<StartupServer_t>(
VMT_INetworkServerServiceInteFace->Hook(27, hook_StartServer));
origin_GameFrame = reinterpret_cast<GameFrame_t>(
VMT_ISource2ServerInterFace->Hook(19, hook_GameFrame));
return original_OnClientConnected && original_OnClientDisconnect &&
origin_StartServer && origin_GameFrame;
} }
auto init() -> bool { auto init() -> bool {
bool isSuccess = initMinHook() && initVmtHook(); bool isSuccess = initMinHook() && initVmtHook();

View File

@@ -5,6 +5,8 @@ typedef bool(__fastcall* FireEventServerSide_t)(CGameEventManager*, IGameEvent*,
typedef void(__fastcall* Host_Say_t)(void*, void*, bool, int, const char*); typedef void(__fastcall* Host_Say_t)(void*, void*, bool, int, const char*);
typedef void(__fastcall* OnClientConnect_t)(void*, CPlayerSlot, const char*, uint64_t, const char*, const char*, bool); typedef void(__fastcall* OnClientConnect_t)(void*, CPlayerSlot, const char*, uint64_t, const char*, const char*, bool);
typedef void(__fastcall* OnClientDisconnect_t)(void*, CPlayerSlot, int, const char*, uint64_t, const char*); typedef void(__fastcall* OnClientDisconnect_t)(void*, CPlayerSlot, int, const char*, uint64_t, const char*);
typedef void(__fastcall* StartupServer_t)(void*, const GameSessionConfiguration_t&, ISource2WorldSession*, const char*);
typedef void(__fastcall* GameFrame_t)(void*, bool, bool, bool);
extern FireEventServerSide_t original_FireEventServerSide; extern FireEventServerSide_t original_FireEventServerSide;
extern Host_Say_t original_Host_Say; extern Host_Say_t original_Host_Say;

View File

@@ -1,10 +1,8 @@
#include "native_sdk.h" #include "native_sdk.h"
CBaseEntity* CHandle::GetBaseEntity() const CBaseEntity* CHandle::GetBaseEntity() const {
{
CGameEntitySystem* pEntitySystem = CGameEntitySystem::GetInstance(); CGameEntitySystem* pEntitySystem = CGameEntitySystem::GetInstance();
if (!pEntitySystem) if (!pEntitySystem) return nullptr;
return nullptr;
return pEntitySystem->GetBaseEntity(GetEntryIndex()); return pEntitySystem->GetBaseEntity(GetEntryIndex());
} }
@@ -12,29 +10,27 @@ CGameEntitySystem* CGameEntitySystem::GetInstance() {
return Offset::InterFaces::GameResourceServiceServer->GetGameEntitySystem(); return Offset::InterFaces::GameResourceServiceServer->GetGameEntitySystem();
} }
auto CSchemaSystemTypeScope::FindDeclaredClass(const char* pClass) -> SchemaClassInfoData_t* auto CSchemaSystemTypeScope::FindDeclaredClass(const char* pClass)
{ -> SchemaClassInfoData_t* {
SchemaClassInfoData_t* rv = nullptr; SchemaClassInfoData_t* rv = nullptr;
CALL_VIRTUAL(void, 2, this, &rv, pClass); CALL_VIRTUAL(void, 2, this, &rv, pClass);
return rv; return rv;
} }
auto CSchemaSystem::FindTypeScopeForModule(const char* module) -> CSchemaSystemTypeScope* auto CSchemaSystem::FindTypeScopeForModule(const char* module)
{ -> CSchemaSystemTypeScope* {
return CALL_VIRTUAL(CSchemaSystemTypeScope*, 13, this, module, nullptr); return CALL_VIRTUAL(CSchemaSystemTypeScope*, 13, this, module, nullptr);
} }
bool CBaseEntity::IsBasePlayerController() { auto CBaseEntity::IsBasePlayerController() -> bool {
return CALL_VIRTUAL(bool, 144, this); return CALL_VIRTUAL(bool, 144, this);
} }
auto CBaseEntity::SpawnClientEntity() -> void { CALL_VIRTUAL(void, 19, this); }
auto CBasePlayer::ForceRespawn() -> void auto CBasePlayer::ForceRespawn() -> void {
{
return CALL_VIRTUAL(void, 26, this); return CALL_VIRTUAL(void, 26, this);
} }
auto CCSPlayerPawn::GetPlayerController() -> CCSPlayerController* auto CCSPlayerPawn::GetPlayerController() -> CCSPlayerController* {
{
CGameEntitySystem* pEntitySystem = CGameEntitySystem::GetInstance(); CGameEntitySystem* pEntitySystem = CGameEntitySystem::GetInstance();
if (!pEntitySystem) { if (!pEntitySystem) {
return nullptr; return nullptr;
@@ -45,7 +41,9 @@ auto CCSPlayerPawn::GetPlayerController() -> CCSPlayerController*
if (pEntity->IsBasePlayerController()) { if (pEntity->IsBasePlayerController()) {
const auto player = reinterpret_cast<CCSPlayerController*>(pEntity); const auto player = reinterpret_cast<CCSPlayerController*>(pEntity);
if (player->m_hPawn().Get() == this) { if (player->m_hPawn().Get() == this) {
//printf("Found Pawn Player: %d %s \n", player->GetRefEHandle().GetEntryIndex(), &player->m_iszPlayerName()); // printf("Found Pawn Player: %d %s \n",
// player->GetRefEHandle().GetEntryIndex(),
// &player->m_iszPlayerName());
return player; return player;
} }
} }
@@ -56,11 +54,8 @@ auto CCSPlayerPawn::GetPlayerController() -> CCSPlayerController*
using SchemaKeyValueMap_t = CUtlMap<uint32_t, SchemaKey>; using SchemaKeyValueMap_t = CUtlMap<uint32_t, SchemaKey>;
using SchemaTableMap_t = CUtlMap<uint32_t, SchemaKeyValueMap_t*>; using SchemaTableMap_t = CUtlMap<uint32_t, SchemaKeyValueMap_t*>;
static bool IsFieldNetworked(SchemaClassFieldData_t& field) {
static bool IsFieldNetworked(SchemaClassFieldData_t& field) for (int i = 0; i < field.m_metadata_size; i++) {
{
for (int i = 0; i < field.m_metadata_size; i++)
{
static auto networkEnabled = hash_32_fnv1a_const("MNetworkEnable"); static auto networkEnabled = hash_32_fnv1a_const("MNetworkEnable");
if (networkEnabled == hash_32_fnv1a_const(field.m_metadata[i].m_name)) if (networkEnabled == hash_32_fnv1a_const(field.m_metadata[i].m_name))
return true; return true;
@@ -69,18 +64,18 @@ static bool IsFieldNetworked(SchemaClassFieldData_t& field)
return false; return false;
} }
static bool InitSchemaFieldsForClass(SchemaTableMap_t* tableMap, const char* className, uint32_t classKey) static bool InitSchemaFieldsForClass(SchemaTableMap_t* tableMap,
{ const char* className, uint32_t classKey) {
CSchemaSystemTypeScope* pType = Offset::InterFaces::SchemaSystem->FindTypeScopeForModule("server.dll"); CSchemaSystemTypeScope* pType =
Offset::InterFaces::SchemaSystem->FindTypeScopeForModule("server.dll");
if (!pType) if (!pType) return false;
return false;
SchemaClassInfoData_t* pClassInfo = pType->FindDeclaredClass(className); SchemaClassInfoData_t* pClassInfo = pType->FindDeclaredClass(className);
if (!pClassInfo) if (!pClassInfo) {
{ SchemaKeyValueMap_t* map =
SchemaKeyValueMap_t* map = new SchemaKeyValueMap_t(0, 0, DefLessFunc(uint32_t)); new SchemaKeyValueMap_t(0, 0, DefLessFunc(uint32_t));
tableMap->Insert(classKey, map); tableMap->Insert(classKey, map);
LOG("InitSchemaFieldsForClass(): '%s' was not found!\n", className); LOG("InitSchemaFieldsForClass(): '%s' was not found!\n", className);
@@ -90,40 +85,38 @@ static bool InitSchemaFieldsForClass(SchemaTableMap_t* tableMap, const char* cla
short fieldsSize = pClassInfo->GetFieldsSize(); short fieldsSize = pClassInfo->GetFieldsSize();
SchemaClassFieldData_t* pFields = pClassInfo->GetFields(); SchemaClassFieldData_t* pFields = pClassInfo->GetFields();
SchemaKeyValueMap_t* keyValueMap = new SchemaKeyValueMap_t(0, 0, DefLessFunc(uint32_t)); SchemaKeyValueMap_t* keyValueMap =
new SchemaKeyValueMap_t(0, 0, DefLessFunc(uint32_t));
keyValueMap->EnsureCapacity(fieldsSize); keyValueMap->EnsureCapacity(fieldsSize);
tableMap->Insert(classKey, keyValueMap); tableMap->Insert(classKey, keyValueMap);
for (int i = 0; i < fieldsSize; ++i) for (int i = 0; i < fieldsSize; ++i) {
{
SchemaClassFieldData_t& field = pFields[i]; SchemaClassFieldData_t& field = pFields[i];
// LOG("%s::%s found at -> 0x%X - %llx\n", className, field.m_name,
// field.m_offset, &field);
keyValueMap->Insert(hash_32_fnv1a_const(field.m_name), { field.m_offset, IsFieldNetworked(field) }); keyValueMap->Insert(hash_32_fnv1a_const(field.m_name),
{field.m_offset, IsFieldNetworked(field)});
} }
return true; return true;
} }
int16_t schema::FindChainOffset(const char* className) int16_t schema::FindChainOffset(const char* className) {
{ CSchemaSystemTypeScope* pType =
Offset::InterFaces::SchemaSystem->FindTypeScopeForModule("server.dll");
CSchemaSystemTypeScope* pType = Offset::InterFaces::SchemaSystem->FindTypeScopeForModule("server.dll"); if (!pType) return false;
if (!pType)
return false;
SchemaClassInfoData_t* pClassInfo = pType->FindDeclaredClass(className); SchemaClassInfoData_t* pClassInfo = pType->FindDeclaredClass(className);
do do {
{
SchemaClassFieldData_t* pFields = pClassInfo->GetFields(); SchemaClassFieldData_t* pFields = pClassInfo->GetFields();
short fieldsSize = pClassInfo->GetFieldsSize(); short fieldsSize = pClassInfo->GetFieldsSize();
for (int i = 0; i < fieldsSize; ++i) for (int i = 0; i < fieldsSize; ++i) {
{
SchemaClassFieldData_t& field = pFields[i]; SchemaClassFieldData_t& field = pFields[i];
if (strcmp(field.m_name, "__m_pChainEntity") == 0) if (strcmp(field.m_name, "__m_pChainEntity") == 0) {
{
return field.m_offset; return field.m_offset;
} }
} }
@@ -132,12 +125,11 @@ int16_t schema::FindChainOffset(const char* className)
return 0; return 0;
} }
SchemaKey schema::GetOffset(const char* className, uint32_t classKey, const char* memberName, uint32_t memberKey) SchemaKey schema::GetOffset(const char* className, uint32_t classKey,
{ const char* memberName, uint32_t memberKey) {
static SchemaTableMap_t schemaTableMap(0, 0, DefLessFunc(uint32_t)); static SchemaTableMap_t schemaTableMap(0, 0, DefLessFunc(uint32_t));
int16_t tableMapIndex = schemaTableMap.Find(classKey); int16_t tableMapIndex = schemaTableMap.Find(classKey);
if (!schemaTableMap.IsValidIndex(tableMapIndex)) if (!schemaTableMap.IsValidIndex(tableMapIndex)) {
{
if (InitSchemaFieldsForClass(&schemaTableMap, className, classKey)) if (InitSchemaFieldsForClass(&schemaTableMap, className, classKey))
return GetOffset(className, classKey, memberName, memberKey); return GetOffset(className, classKey, memberName, memberKey);
@@ -146,9 +138,9 @@ SchemaKey schema::GetOffset(const char* className, uint32_t classKey, const char
SchemaKeyValueMap_t* tableMap = schemaTableMap[tableMapIndex]; SchemaKeyValueMap_t* tableMap = schemaTableMap[tableMapIndex];
int16_t memberIndex = tableMap->Find(memberKey); int16_t memberIndex = tableMap->Find(memberKey);
if (!tableMap->IsValidIndex(memberIndex)) if (!tableMap->IsValidIndex(memberIndex)) {
{ LOG("schema::GetOffset(): '%s' was not found in '%s'!\n", memberName,
LOG("schema::GetOffset(): '%s' was not found in '%s'!\n", memberName, className); className);
return {0, 0}; return {0, 0};
} }
@@ -177,27 +169,26 @@ bool CEconItemDefinition::IsGlove(bool excludeDefault) {
return excludeDefault ? !defaultGlove : true; return excludeDefault ? !defaultGlove : true;
} }
auto CLocalize::FindSafe(const char* tokenName) -> const char* auto CLocalize::FindSafe(const char* tokenName) -> const char* {
{
return CALL_VIRTUAL(const char*, 17, this, tokenName); return CALL_VIRTUAL(const char*, 17, this, tokenName);
} }
auto GetGameGlobals() -> CGlobalVars* auto GetGameGlobals() -> CGlobalVars* {
{ INetworkGameServer* server =
INetworkGameServer* server = Offset::InterFaces::INetworkServerServiceInteFace->GetIGameServer(); Offset::InterFaces::INetworkServerServiceInteFace->GetIGameServer();
if (!server) if (!server) return nullptr;
return nullptr;
return Offset::InterFaces::INetworkServerServiceInteFace->GetIGameServer()->GetGlobals(); return Offset::InterFaces::INetworkServerServiceInteFace->GetIGameServer()
->GetGlobals();
} }
auto SetStateChanged(Z_CBaseEntity* pEntity, int offset) -> void auto SetStateChanged(Z_CBaseEntity* pEntity, int offset) -> void {
{ Offset::FnStateChanged(pEntity->m_NetworkTransmitComponent(), pEntity,
Offset::FnStateChanged(pEntity->m_NetworkTransmitComponent(), pEntity, offset, -1, -1); offset, -1, -1);
auto vars = GetGameGlobals(); // auto vars = GetGameGlobals();
auto vars = global::GlobalVars;
if (vars) if (vars) pEntity->m_lastNetworkChange(vars->curtime);
pEntity->m_lastNetworkChange(vars->curtime);
pEntity->m_isSteadyState(0); pEntity->m_isSteadyState(0);
}; };

View File

@@ -1,12 +1,15 @@
#pragma once #pragma once
#include "head.h" #include "head.h"
class CEntityInstance; class CEntityInstance;
typedef void(__fastcall* StateChanged_t)(void* networkTransmitComponent, CEntityInstance* ent, uint64_t offset, int a4, int a5); typedef void(__fastcall* StateChanged_t)(void* networkTransmitComponent,
typedef void(__fastcall* NetworkStateChanged_t)(uintptr_t chainEntity, uintptr_t offset, uintptr_t a3); CEntityInstance* ent, uint64_t offset,
int a4, int a5);
typedef void(__fastcall* NetworkStateChanged_t)(uintptr_t chainEntity,
uintptr_t offset, uintptr_t a3);
namespace Offset { namespace Offset {
extern StateChanged_t FnStateChanged; extern StateChanged_t FnStateChanged;
extern NetworkStateChanged_t FnNetworkStateChanged; extern NetworkStateChanged_t FnNetworkStateChanged;
} } // namespace Offset
struct SchemaKey { struct SchemaKey {
int16_t offset; int16_t offset;
bool networked; bool networked;
@@ -26,13 +29,13 @@ extern auto SetStateChanged(Z_CBaseEntity* pEntity, int offset) -> void;
#define DECLARE_CLASS(className) DECLARE_SCHEMA_CLASS_BASE(className, false) #define DECLARE_CLASS(className) DECLARE_SCHEMA_CLASS_BASE(className, false)
// Use this for classes that can be wholly included within other classes (like CCollisionProperty within CBaseModelEntity) // Use this for classes that can be wholly included within other classes (like
// CCollisionProperty within CBaseModelEntity)
#define DECLARE_SCHEMA_CLASS_INLINE(className) \ #define DECLARE_SCHEMA_CLASS_INLINE(className) \
DECLARE_SCHEMA_CLASS_BASE(className, true) DECLARE_SCHEMA_CLASS_BASE(className, true)
#define SCHEMA_FIELD_OFFSET(type, varName, extra_offset) \ #define SCHEMA_FIELD_OFFSET(type, varName, extra_offset) \
std::add_lvalue_reference_t<type> varName() \ std::add_lvalue_reference_t<type> varName() { \
{ \
static constexpr auto datatable_hash = hash_32_fnv1a_const(ThisClass); \ static constexpr auto datatable_hash = hash_32_fnv1a_const(ThisClass); \
static constexpr auto prop_hash = hash_32_fnv1a_const(#varName); \ static constexpr auto prop_hash = hash_32_fnv1a_const(#varName); \
\ \
@@ -42,43 +45,42 @@ extern auto SetStateChanged(Z_CBaseEntity* pEntity, int offset) -> void;
return *reinterpret_cast<std::add_pointer_t<type>>( \ return *reinterpret_cast<std::add_pointer_t<type>>( \
(uintptr_t)(this) + m_key.offset + extra_offset); \ (uintptr_t)(this) + m_key.offset + extra_offset); \
} \ } \
void varName(type val) \ void varName(type val) { \
{ \
static constexpr auto datatable_hash = hash_32_fnv1a_const(ThisClass); \ static constexpr auto datatable_hash = hash_32_fnv1a_const(ThisClass); \
static constexpr auto prop_hash = hash_32_fnv1a_const(#varName); \ static constexpr auto prop_hash = hash_32_fnv1a_const(#varName); \
\ \
static const auto m_key = \ static const auto m_key = \
schema::GetOffset(ThisClass, datatable_hash, #varName, prop_hash); \ schema::GetOffset(ThisClass, datatable_hash, #varName, prop_hash); \
\ \
static const auto m_chain = \ static const auto m_chain = schema::FindChainOffset(ThisClass); \
schema::FindChainOffset(ThisClass); \
\ \
if (m_chain != 0 && m_key.networked) \ if (m_chain != 0 && m_key.networked) { \
{ \ LOG("Found chain offset %d for %s::%s\n", m_chain, ThisClass, \
LOG("Found chain offset %d for %s::%s\n", m_chain, ThisClass, #varName); \ #varName); \
Offset::FnNetworkStateChanged((uintptr_t)(this) + m_chain, m_key.offset + extra_offset, 0xFFFFFFFF); \ Offset::FnNetworkStateChanged((uintptr_t)(this) + m_chain, \
} \ m_key.offset + extra_offset, \
else if(m_key.networked) \ 0xFFFFFFFF); \
{ \ } else if (m_key.networked) { \
/* WIP: Works fine for most props, but inlined classes in the middle of a class will /* WIP: Works fine for most props, but inlined classes in the \
need to have their this pointer corrected by the offset .*/ \ middle of a class will need to have their this pointer \
LOG("Attempting to call SetStateChanged on on %s::%s\n", ThisClass, #varName); \ corrected by the offset .*/ \
LOG("Attempting to call SetStateChanged on on %s::%s\n", \
ThisClass, #varName); \
if (!OffsetIsStruct) \ if (!OffsetIsStruct) \
SetStateChanged((Z_CBaseEntity*)this, m_key.offset + extra_offset); \ SetStateChanged((Z_CBaseEntity*)this, \
m_key.offset + extra_offset); \
else \ else \
CALL_VIRTUAL(void, 1, this, m_key.offset + extra_offset, 0xFFFFFFFF, 0xFFFF); \ CALL_VIRTUAL(void, 1, this, m_key.offset + extra_offset, \
\ 0xFFFFFFFF, 0xFFFF); \
} \ } \
* reinterpret_cast<std::add_pointer_t<type>>((uintptr_t)(this) + m_key.offset + extra_offset) = val; \ *reinterpret_cast<std::add_pointer_t<type>>( \
(uintptr_t)(this) + m_key.offset + extra_offset) = val; \
} }
#define SCHEMA_FIELD(type, varName) \ #define SCHEMA_FIELD(type, varName) SCHEMA_FIELD_OFFSET(type, varName, 0)
SCHEMA_FIELD_OFFSET(type, varName, 0)
#define PSCHEMA_FIELD_OFFSET(type, varName, extra_offset) \ #define PSCHEMA_FIELD_OFFSET(type, varName, extra_offset) \
auto varName() \ auto varName() { \
{ \
static constexpr auto datatable_hash = hash_32_fnv1a_const(ThisClass); \ static constexpr auto datatable_hash = hash_32_fnv1a_const(ThisClass); \
static constexpr auto prop_hash = hash_32_fnv1a_const(#varName); \ static constexpr auto prop_hash = hash_32_fnv1a_const(#varName); \
\ \
@@ -89,16 +91,13 @@ extern auto SetStateChanged(Z_CBaseEntity* pEntity, int offset) -> void;
(uintptr_t)(this) + m_key.offset + extra_offset); \ (uintptr_t)(this) + m_key.offset + extra_offset); \
} }
#define PSCHEMA_FIELD(type, varName) \ #define PSCHEMA_FIELD(type, varName) PSCHEMA_FIELD_OFFSET(type, varName, 0)
PSCHEMA_FIELD_OFFSET(type, varName, 0)
namespace schema {
namespace schema
{
int16_t FindChainOffset(const char* className); int16_t FindChainOffset(const char* className);
SchemaKey GetOffset(const char* className, uint32_t classKey, const char* memberName, uint32_t memberKey); SchemaKey GetOffset(const char* className, uint32_t classKey,
} const char* memberName, uint32_t memberKey);
} // namespace schema
struct CSchemaNetworkValue { struct CSchemaNetworkValue {
union { union {
@@ -114,8 +113,7 @@ struct SchemaMetadataEntryData_t {
CSchemaNetworkValue* m_value; CSchemaNetworkValue* m_value;
}; };
struct SchemaClassFieldData_t struct SchemaClassFieldData_t {
{
const char* m_name; const char* m_name;
char pad0[0x8]; char pad0[0x8];
short m_offset; short m_offset;
@@ -123,37 +121,23 @@ struct SchemaClassFieldData_t
SchemaMetadataEntryData_t* m_metadata; SchemaMetadataEntryData_t* m_metadata;
}; };
class SchemaClassInfoData_t; class SchemaClassInfoData_t;
struct SchemaBaseClassInfoData_t struct SchemaBaseClassInfoData_t {
{
unsigned int m_offset; unsigned int m_offset;
SchemaClassInfoData_t* m_class; SchemaClassInfoData_t* m_class;
}; };
class SchemaClassInfoData_t class SchemaClassInfoData_t {
{
public: public:
auto GetName() auto GetName() { return m_name; }
{
return m_name;
}
auto GetFieldsSize() auto GetFieldsSize() { return m_align; }
{
return m_align;
}
auto GetFields() auto GetFields() { return m_fields; }
{
return m_fields;
}
auto GetParent() -> SchemaClassInfoData_t* auto GetParent() -> SchemaClassInfoData_t* {
{ if (!m_schema_parent) return nullptr;
if (!m_schema_parent)
return nullptr;
return m_schema_parent->m_class; return m_schema_parent->m_class;
} }
@@ -181,14 +165,12 @@ private:
char pad_0x0038[0x10]; // 0x0038 char pad_0x0038[0x10]; // 0x0038
}; };
class CSchemaSystemTypeScope class CSchemaSystemTypeScope {
{
public: public:
auto FindDeclaredClass(const char* pClass) -> SchemaClassInfoData_t*; auto FindDeclaredClass(const char* pClass) -> SchemaClassInfoData_t*;
}; };
class CSchemaSystem class CSchemaSystem {
{
public: public:
auto FindTypeScopeForModule(const char* module) -> CSchemaSystemTypeScope*; auto FindTypeScopeForModule(const char* module) -> CSchemaSystemTypeScope*;
}; };
@@ -212,10 +194,8 @@ public:
char pad1[0x8]; // no idea char pad1[0x8]; // no idea
}; };
class CBaseEntity; class CBaseEntity;
class CEntityIdentity class CEntityIdentity {
{
public: public:
CBaseEntity* entity; // 0 CBaseEntity* entity; // 0
void* dunno; // 8 void* dunno; // 8
@@ -234,51 +214,47 @@ public:
void* unkptr3; void* unkptr3;
}; };
class CEntityIdentities class CEntityIdentities {
{
public: public:
CEntityIdentity m_pIdentities[MAX_ENTITIES_IN_LIST]; CEntityIdentity m_pIdentities[MAX_ENTITIES_IN_LIST];
}; };
class EntityIdentityList class EntityIdentityList {
{
public: public:
CEntityIdentities* m_pIdentityList; CEntityIdentities* m_pIdentityList;
}; };
class CGameEntitySystem class CGameEntitySystem {
{
public: public:
virtual void n_0(); virtual void n_0();
void* unk; void* unk;
CEntityIdentities* m_pEntityList[MAX_ENTITY_LISTS]; CEntityIdentities* m_pEntityList[MAX_ENTITY_LISTS];
CBaseEntity* GetBaseEntity(int index) CBaseEntity* GetBaseEntity(int index) {
{ if (index <= -1 || index >= MAX_TOTAL_ENTITIES) return nullptr;
if (index <= -1 || index >= MAX_TOTAL_ENTITIES)
return nullptr;
int listToUse = (index / MAX_ENTITIES_IN_LIST); int listToUse = (index / MAX_ENTITIES_IN_LIST);
if (!m_pEntityList[listToUse]) if (!m_pEntityList[listToUse]) return nullptr;
return nullptr;
if (m_pEntityList[listToUse]->m_pIdentities[index % MAX_ENTITIES_IN_LIST].entity) if (m_pEntityList[listToUse]
return m_pEntityList[listToUse]->m_pIdentities[index % MAX_ENTITIES_IN_LIST].entity; ->m_pIdentities[index % MAX_ENTITIES_IN_LIST]
.entity)
return m_pEntityList[listToUse]
->m_pIdentities[index % MAX_ENTITIES_IN_LIST]
.entity;
else else
return nullptr; return nullptr;
} }
static CGameEntitySystem* GetInstance(); static CGameEntitySystem* GetInstance();
}; };
struct VPhysicsCollisionAttribute_t struct VPhysicsCollisionAttribute_t {
{
DECLARE_CLASS(VPhysicsCollisionAttribute_t) DECLARE_CLASS(VPhysicsCollisionAttribute_t)
SCHEMA_FIELD(uint8_t, m_nCollisionGroup) SCHEMA_FIELD(uint8_t, m_nCollisionGroup)
}; };
class CCollisionProperty class CCollisionProperty {
{
public: public:
DECLARE_CLASS(CCollisionProperty) DECLARE_CLASS(CCollisionProperty)
@@ -288,8 +264,7 @@ public:
SCHEMA_FIELD(uint8_t, m_CollisionGroup) SCHEMA_FIELD(uint8_t, m_CollisionGroup)
}; };
class CHandle class CHandle {
{
CBaseEntity* GetBaseEntity() const; CBaseEntity* GetBaseEntity() const;
public: public:
@@ -300,8 +275,7 @@ public:
int GetEntryIndex() const { return m_Index & ENT_ENTRY_MASK; } int GetEntryIndex() const { return m_Index & ENT_ENTRY_MASK; }
template <typename T = CBaseEntity> template <typename T = CBaseEntity>
T* Get() const T* Get() const {
{
return reinterpret_cast<T*>(GetBaseEntity()); return reinterpret_cast<T*>(GetBaseEntity());
} }
uint32_t m_Index; uint32_t m_Index;
@@ -337,12 +311,13 @@ public:
DECLARE_CLASS(CBaseEntity); DECLARE_CLASS(CBaseEntity);
SCHEMA_FIELD(int, m_iHealth) SCHEMA_FIELD(int, m_iHealth)
SCHEMA_FIELD(int, m_iTeamNum)
// SCHEMA_FIELD(Vector, m_vecBaseVelocity) // SCHEMA_FIELD(Vector, m_vecBaseVelocity)
SCHEMA_FIELD(CCollisionProperty*, m_pCollision) SCHEMA_FIELD(CCollisionProperty*, m_pCollision)
bool IsBasePlayerController(); auto IsBasePlayerController() -> bool;
auto SpawnClientEntity() -> void;
}; };
class CBasePlayerController : public CBaseEntity { class CBasePlayerController : public CBaseEntity {
public: public:
DECLARE_CLASS(CBasePlayerController); DECLARE_CLASS(CBasePlayerController);
@@ -415,8 +390,7 @@ public:
return CALL_VIRTUAL(CEconItemDefinition*, 13, this); return CALL_VIRTUAL(CEconItemDefinition*, 13, this);
} }
}; };
class CAttributeContainer class CAttributeContainer {
{
public: public:
DECLARE_CLASS(CAttributeContainer); DECLARE_CLASS(CAttributeContainer);
@@ -429,8 +403,7 @@ public:
PSCHEMA_FIELD(CAttributeContainer, m_AttributeManager); PSCHEMA_FIELD(CAttributeContainer, m_AttributeManager);
}; };
class CBasePlayerWeapon : public CEconEntity class CBasePlayerWeapon : public CEconEntity {
{
public: public:
DECLARE_CLASS(CBasePlayerWeapon); DECLARE_CLASS(CBasePlayerWeapon);
@@ -445,10 +418,8 @@ public:
SCHEMA_FIELD(CHandle, m_hActiveWeapon); SCHEMA_FIELD(CHandle, m_hActiveWeapon);
SCHEMA_FIELD(uint16_t, m_iAmmo); SCHEMA_FIELD(uint16_t, m_iAmmo);
}; };
class CBasePlayer { class CBasePlayer {
public: public:
auto ForceRespawn() -> void; auto ForceRespawn() -> void;
@@ -473,15 +444,15 @@ public:
SCHEMA_FIELD(CPlayer_MovementServices*, m_pMovementServices) SCHEMA_FIELD(CPlayer_MovementServices*, m_pMovementServices)
SCHEMA_FIELD(CPlayer_WeaponServices*, m_pWeaponServices) SCHEMA_FIELD(CPlayer_WeaponServices*, m_pWeaponServices)
SCHEMA_FIELD(uint8_t**, m_pItemServices) SCHEMA_FIELD(uint8_t**, m_pItemServices)
// m_hController
SCHEMA_FIELD(CBasePlayerController*, m_hController)
}; };
// Size: 0x1568 // Size: 0x1568
class CCSPlayerPawnBase : public CBasePlayerPawn class CCSPlayerPawnBase : public CBasePlayerPawn {
{
public: public:
DECLARE_CLASS(CCSPlayerPawnBase); DECLARE_CLASS(CCSPlayerPawnBase);
SCHEMA_FIELD(bool, m_bRespawning) SCHEMA_FIELD(bool, m_bRespawning)
SCHEMA_FIELD(int, m_ArmorValue) SCHEMA_FIELD(int, m_ArmorValue)
}; };
class CCSPlayerPawn : public CCSPlayerPawnBase { class CCSPlayerPawn : public CCSPlayerPawnBase {
public: public:
@@ -492,11 +463,9 @@ public:
class CGameEntitySystem; class CGameEntitySystem;
class CGameResourceService class CGameResourceService {
{
public: public:
CGameEntitySystem* GetGameEntitySystem() CGameEntitySystem* GetGameEntitySystem() {
{
return *reinterpret_cast<CGameEntitySystem**>((uintptr_t)(this) + 0x58); return *reinterpret_cast<CGameEntitySystem**>((uintptr_t)(this) + 0x58);
} }
}; };
@@ -506,8 +475,7 @@ public:
auto FindSafe(const char* tokenName) -> const char*; auto FindSafe(const char* tokenName) -> const char*;
}; };
class Z_CBaseEntity : public CBaseEntity class Z_CBaseEntity : public CBaseEntity {
{
public: public:
DECLARE_CLASS(CBaseEntity) DECLARE_CLASS(CBaseEntity)
@@ -519,3 +487,8 @@ public:
SCHEMA_FIELD(Vector, m_vecBaseVelocity) SCHEMA_FIELD(Vector, m_vecBaseVelocity)
SCHEMA_FIELD(CCollisionProperty*, m_pCollision) SCHEMA_FIELD(CCollisionProperty*, m_pCollision)
}; };
class CCSGameRules {
public:
DECLARE_CLASS(CCSGameRules)
SCHEMA_FIELD(bool, m_bForceTeamChangeSilent)
};

View File

@@ -4,12 +4,15 @@ namespace Offset {
uint64_t GameResourceServicePtr; uint64_t GameResourceServicePtr;
uint64_t FireEventServerSidePtr; uint64_t FireEventServerSidePtr;
uint64_t CGameEventManagerPtr; uint64_t CGameEventManagerPtr;
uint64_t CCSGameRulesInterFacePtr;
uint64_t Host_SayPtr; uint64_t Host_SayPtr;
uint64_t Module_tier0; uint64_t Module_tier0;
uint64_t MaxPlayerNumsPtr; uint64_t MaxPlayerNumsPtr;
HashFunction_t FnServerHashFunction; HashFunction_t FnServerHashFunction;
StateChanged_t FnStateChanged; StateChanged_t FnStateChanged;
NetworkStateChanged_t FnNetworkStateChanged; NetworkStateChanged_t FnNetworkStateChanged;
//CreateGameRuleInterFace_t FnCreateCCSGameRulesInterFace;
namespace InterFaces { namespace InterFaces {
CSchemaSystem* SchemaSystem; CSchemaSystem* SchemaSystem;
IGameEventManager2* GameEventManager; IGameEventManager2* GameEventManager;
@@ -20,7 +23,9 @@ IVEngineServer2* IVEngineServer;
ISource2Server* ISource2ServerInterFace; ISource2Server* ISource2ServerInterFace;
CLocalize* ILocalize; CLocalize* ILocalize;
INetworkServerService* INetworkServerServiceInteFace; INetworkServerService* INetworkServerServiceInteFace;
CCSGameRules* CCSGameRulesInterFace;
}; // namespace InterFaces }; // namespace InterFaces
auto Init() -> bool { auto Init() -> bool {
CModule server("server.dll"); CModule server("server.dll");
CModule schemasystem("schemasystem.dll"); CModule schemasystem("schemasystem.dll");
@@ -28,41 +33,53 @@ auto Init() -> bool {
CModule localize("localize.dll"); CModule localize("localize.dll");
// engine.dll // engine.dll
engine.FindPattern(pattern_MaxPlayerNumsPtr).ToAbsolute(3, 0).Get(MaxPlayerNumsPtr); engine.FindPattern(pattern_MaxPlayerNumsPtr)
.ToAbsolute(3, 0)
.Get(MaxPlayerNumsPtr);
// server.dll // server.dll
server.FindPattern(pattern_FireEventServerSide).Get(FireEventServerSidePtr); server.FindPattern(pattern_FireEventServerSide).Get(FireEventServerSidePtr);
server.FindPattern(pattern_NetworkStateChanged).Get(FnNetworkStateChanged); server.FindPattern(pattern_NetworkStateChanged).Get(FnNetworkStateChanged);
server.FindPattern(pattern_FnStateChangedPtr).Get(FnStateChanged); server.FindPattern(pattern_FnStateChangedPtr).Get(FnStateChanged);
// 48 8D 05 4A 30 82 00 lea rax, ??_7CGameEventManager@@6B@
server.FindPattern(pattern_CGameEventManager) server.FindPattern(pattern_CGameEventManager)
.ToAbsolute(3, 0) .ToAbsolute(3, 0)
.Get(CGameEventManagerPtr); .Get(CGameEventManagerPtr);
server.FindPattern(pattern_CreateCCSGameRulesInterFacePtr)
.ToAbsolute(10, 0)
.Get(CCSGameRulesInterFacePtr);
server.FindPattern(pattern_fnHost_SayPtr).Get(Host_SayPtr); server.FindPattern(pattern_fnHost_SayPtr).Get(Host_SayPtr);
server.FindPattern(pattern_ServerHashFunctionPtr).Get(FnServerHashFunction); server.FindPattern(pattern_ServerHashFunctionPtr).Get(FnServerHashFunction);
InterFaces::SchemaSystem = reinterpret_cast<CSchemaSystem*>( InterFaces::SchemaSystem = reinterpret_cast<CSchemaSystem*>(
schemasystem.FindInterface("SchemaSystem_001").Get()); schemasystem.FindInterface("SchemaSystem_001").Get());
// InterFaces::GameEventManager = reinterpret_cast<IGameEventManager2*>( // InterFaces::GameEventManager = reinterpret_cast<IGameEventManager2*>(
// engine.FindInterface("GameEventSystemServerV001").Get()); // engine.FindInterface("GameEventSystemServerV001").Get());
InterFaces::ILocalize = reinterpret_cast<CLocalize*>(localize.FindInterface("Localize_001").Get()); InterFaces::ILocalize = reinterpret_cast<CLocalize*>(
localize.FindInterface("Localize_001").Get());
InterFaces::GameResourceServiceServer = InterFaces::GameResourceServiceServer =
reinterpret_cast<CGameResourceService*>( reinterpret_cast<CGameResourceService*>(
engine.FindInterface("GameResourceServiceServerV001").Get()); engine.FindInterface("GameResourceServiceServerV001").Get());
InterFaces::IVEngineServer = reinterpret_cast<IVEngineServer2*>( InterFaces::IVEngineServer = reinterpret_cast<IVEngineServer2*>(
engine.FindInterface("Source2EngineToServer001").Get()); engine.FindInterface("Source2EngineToServer001").Get());
InterFaces::INetworkServerServiceInteFace = reinterpret_cast<INetworkServerService*>( InterFaces::INetworkServerServiceInteFace =
reinterpret_cast<INetworkServerService*>(
engine.FindInterface("NetworkServerService_001").Get()); engine.FindInterface("NetworkServerService_001").Get());
InterFaces::IServerGameClient = reinterpret_cast<IServerGameClients*>( InterFaces::IServerGameClient = reinterpret_cast<IServerGameClients*>(
server.FindInterface("Source2GameClients001").Get()); server.FindInterface("Source2GameClients001").Get());
InterFaces::ISource2ServerInterFace = reinterpret_cast<ISource2Server*>( InterFaces::ISource2ServerInterFace = reinterpret_cast<ISource2Server*>(
server.FindInterface("Source2Server001").Get()); server.FindInterface("Source2Server001").Get());
if (InterFaces::ISource2ServerInterFace) { if (InterFaces::ISource2ServerInterFace) {
InterFaces::GameEventManager = (IGameEventManager2*)(CALL_VIRTUAL(uintptr_t, 91, InterFaces::ISource2ServerInterFace) - 8); InterFaces::GameEventManager =
(IGameEventManager2*)(CALL_VIRTUAL(
uintptr_t, 91,
InterFaces::ISource2ServerInterFace) -
8);
} }
InterFaces::CGameEventManger = InterFaces::CGameEventManger =
reinterpret_cast<CGameEventManager*>(CGameEventManagerPtr); reinterpret_cast<CGameEventManager*>(CGameEventManagerPtr);
InterFaces::CCSGameRulesInterFace =
reinterpret_cast<CCSGameRules*>(CCSGameRulesInterFacePtr + (8 * 2));
// global::MaxPlayers = *(int*)((char*)MaxPlayerNumsPtr + 2); // global::MaxPlayers = *(int*)((char*)MaxPlayerNumsPtr + 2);
// client.FindPattern(pattern_FireEventServerSide).Get(FireEventServerSidePtr); // client.FindPattern(pattern_FireEventServerSide).Get(FireEventServerSidePtr);
global::MaxPlayers = 64; global::MaxPlayers = 64;
@@ -87,14 +104,17 @@ auto Init() -> bool {
InterFaces::IVEngineServer); InterFaces::IVEngineServer);
LOG("[huoji]InterFaces::ISource2ServerInterFace : %llx \n", LOG("[huoji]InterFaces::ISource2ServerInterFace : %llx \n",
InterFaces::ISource2ServerInterFace); InterFaces::ISource2ServerInterFace);
LOG("[huoji]InterFaces::CCSGameRulesInterFace : %llx \n", InterFaces::CCSGameRulesInterFace);
//LOG("m_bForceTeamChangeSilent: %d \n", InterFaces::CCSGameRulesInterFace->m_bForceTeamChangeSilent());
// GetOffsets();
LOG("init offset success !\n"); LOG("init offset success !\n");
//LOG("FnServerHashFunction: %llx \n", FnServerHashFunction("here", sizeof("here") - 1, 0x31415926));
// LOG("FnServerHashFunction: %llx \n", FnServerHashFunction("here",
// sizeof("here") - 1, 0x31415926));
return FnServerHashFunction && Host_SayPtr && InterFaces::IVEngineServer && return FnServerHashFunction && Host_SayPtr && InterFaces::IVEngineServer &&
InterFaces::GameResourceServiceServer && InterFaces::GameResourceServiceServer &&
InterFaces::IServerGameClient && InterFaces::GameEventManager && InterFaces::IServerGameClient && InterFaces::GameEventManager &&
InterFaces::SchemaSystem && FireEventServerSidePtr && InterFaces::SchemaSystem && FireEventServerSidePtr && FnNetworkStateChanged;
FnNetworkStateChanged;
} }
} // namespace Offset } // namespace Offset

View File

@@ -2,13 +2,18 @@
#include "head.h" #include "head.h"
#define SERVER_HASH_FUCNTION_KEY 0x31415926 #define SERVER_HASH_FUCNTION_KEY 0x31415926
class CEntityInstance; class CEntityInstance;
typedef uint64_t(__fastcall* HashFunction_t)(const char*, unsigned int, unsigned int); typedef uint64_t(__fastcall* HashFunction_t)(const char*, unsigned int,
typedef void(__fastcall* StateChanged_t)(void* networkTransmitComponent, CEntityInstance* ent, uint64_t offset, int a4, int a5); unsigned int);
typedef void(__fastcall* NetworkStateChanged_t)(uintptr_t chainEntity, uintptr_t offset, uintptr_t a3); typedef void(__fastcall* StateChanged_t)(void* networkTransmitComponent,
CEntityInstance* ent, uint64_t offset,
int a4, int a5);
typedef void(__fastcall* NetworkStateChanged_t)(uintptr_t chainEntity,
uintptr_t offset, uintptr_t a3);
typedef void*(__fastcall* CreateGameRuleInterFace_t)();
class CSchemaSystem; class CSchemaSystem;
class CGameResourceService; class CGameResourceService;
class CLocalize; class CLocalize;
class CCSGameRules;
namespace Offset { namespace Offset {
namespace InterFaces { namespace InterFaces {
extern CSchemaSystem* SchemaSystem; extern CSchemaSystem* SchemaSystem;
@@ -19,10 +24,16 @@ namespace InterFaces {
extern IVEngineServer2* IVEngineServer; extern IVEngineServer2* IVEngineServer;
extern CLocalize* ILocalize; extern CLocalize* ILocalize;
extern INetworkServerService* INetworkServerServiceInteFace; extern INetworkServerService* INetworkServerServiceInteFace;
}; extern ISource2Server* ISource2ServerInterFace;
static const auto pattern_CGameEventManager = THE_GAME_SIG("48 ?? ?? ?? ?? ?? ?? 48 89 ?? ?? ?? 48 89 01 48 8B D9 48 ?? ?? ?? ?? ?? ?? 48 89 ?? ?? E8 ?? ?? ?? ?? 48 ?? ?? ?? ?? ?? ??"); extern CCSGameRules* CCSGameRulesInterFace;
static const auto pattern_NetworkStateChanged = THE_GAME_SIG("4C 8B C9 48 8B 09 48 85 C9 74 ? 48 8B 41 10"); }; // namespace InterFaces
static const auto pattern_FnStateChangedPtr = THE_GAME_SIG("48 89 54 24 10 55 53 57 41 55"); static const auto pattern_CGameEventManager = THE_GAME_SIG(
"48 ?? ?? ?? ?? ?? ?? 48 89 ?? ?? ?? 48 89 01 48 8B D9 48 ?? ?? ?? ?? ?? "
"?? 48 89 ?? ?? E8 ?? ?? ?? ?? 48 ?? ?? ?? ?? ?? ??");
static const auto pattern_NetworkStateChanged =
THE_GAME_SIG("4C 8B C9 48 8B 09 48 85 C9 74 ? 48 8B 41 10");
static const auto pattern_FnStateChangedPtr =
THE_GAME_SIG("48 89 54 24 10 55 53 57 41 55");
static const auto pattern_FireEventServerSide = THE_GAME_SIG( static const auto pattern_FireEventServerSide = THE_GAME_SIG(
"40 53 57 41 54 41 55 41 56 48 ?? ?? ?? 4C 8B F2 4C 8B E1 BA ?? ?? ?? " "40 53 57 41 54 41 55 41 56 48 ?? ?? ?? 4C 8B F2 4C 8B E1 BA ?? ?? ?? "
"?? 48 ?? ?? ?? ?? ?? ?? 45 0F B6 E8 E8 ?? ?? ?? ?? 48 85 C0 75 ?? 48 " "?? 48 ?? ?? ?? ?? ?? ?? 45 0F B6 E8 E8 ?? ?? ?? ?? 48 85 C0 75 ?? 48 "
@@ -37,10 +48,16 @@ static const auto pattern_fnGetLocalPlayerController =
//"\"Console<0>\" say \"%s\"\n" //"\"Console<0>\" say \"%s\"\n"
static const auto pattern_fnHost_SayPtr = 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"); THE_GAME_SIG("44 89 4C 24 ?? 44 88 44 24 ?? 55 53 56 57 41 54 41 55");
static const auto pattern_ServerHashFunctionPtr = static const auto pattern_ServerHashFunctionPtr = THE_GAME_SIG(
THE_GAME_SIG("48 89 ?? ?? ?? 57 48 ?? ?? ?? ?? ?? ?? 33 C0 8B DA 41 8B F8 48 89 ?? ?? ?? 4C 8B C1 C7 44 ?? ?? ?? ?? ?? ?? 44 8B CA 89 44 ?? ?? 48 8D ?? ?? ?? 88 44 ?? ?? 33 D2"); "48 89 ?? ?? ?? 57 48 ?? ?? ?? ?? ?? ?? 33 C0 8B DA 41 8B F8 48 89 ?? ?? "
"?? 4C 8B C1 C7 44 ?? ?? ?? ?? ?? ?? 44 8B CA 89 44 ?? ?? 48 8D ?? ?? ?? "
"88 44 ?? ?? 33 D2");
static const auto pattern_MaxPlayerNumsPtr = static const auto pattern_MaxPlayerNumsPtr =
THE_GAME_SIG("41 3B 87 ?? ?? ?? ?? 0F 8E ?? ?? ?? ?? 8B 0D ?? ?? ?? ??"); THE_GAME_SIG("41 3B 87 ?? ?? ?? ?? 0F 8E ?? ?? ?? ?? 8B 0D ?? ?? ?? ??");
static const auto pattern_CreateCCSGameRulesInterFacePtr = THE_GAME_SIG(
"40 53 48 ?? ?? ?? B9 ?? ?? ?? ?? E8 ?? ?? ?? ?? 33 D2 41 ?? ?? ?? ?? ?? "
"48 8B C8 48 8B D8 E8 ?? ?? ?? ?? 48 85 DB");
extern uint64_t GameResourceServicePtr; extern uint64_t GameResourceServicePtr;
extern uint64_t FireEventServerSidePtr; extern uint64_t FireEventServerSidePtr;
extern uint64_t Module_tier0; extern uint64_t Module_tier0;
@@ -50,6 +67,5 @@ extern HashFunction_t FnServerHashFunction;
extern StateChanged_t FnStateChanged; extern StateChanged_t FnStateChanged;
extern NetworkStateChanged_t FnNetworkStateChanged; extern NetworkStateChanged_t FnNetworkStateChanged;
auto Init() -> bool; auto Init() -> bool;
}; // namespace Offset }; // namespace Offset

View File

@@ -12,6 +12,16 @@ struct _luaApi_WeaponInfo {
int weaponType; int weaponType;
}; };
namespace ScriptApis { namespace ScriptApis {
auto TimerCallBack(_GameTimer* timer) -> void {
LOG("excute timer: %d %d m_bRepeat: %d\n", timer->m_iLuaCallBackFn, timer->m_iParamIndex, timer->m_bRepeat);
lua_rawgeti(timer->m_luaVm, LUA_REGISTRYINDEX, timer->m_iLuaCallBackFn);
lua_rawgeti(timer->m_luaVm, LUA_REGISTRYINDEX, timer->m_iParamIndex);
lua_pcall(timer->m_luaVm, 1, 0, 0);
if (timer->m_bRepeat == false) {
luaL_unref(timer->m_luaVm, LUA_REGISTRYINDEX, timer->m_iLuaCallBackFn);
luaL_unref(timer->m_luaVm, LUA_REGISTRYINDEX, timer->m_iParamIndex);
}
}
// <20><><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD><C7B7><EFBFBD>ֵ<EFBFBD><D6B5><EFBFBD><EFBFBD>,<2C><><EFBFBD><EFBFBD>ֵ<EFBFBD><D6B5><EFBFBD><EFBFBD>Ҫ<EFBFBD>Լ<EFBFBD>push<73><68>stack<63><6B> // <20><><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD><C7B7><EFBFBD>ֵ<EFBFBD><D6B5><EFBFBD><EFBFBD>,<2C><><EFBFBD><EFBFBD>ֵ<EFBFBD><D6B5><EFBFBD><EFBFBD>Ҫ<EFBFBD>Լ<EFBFBD>push<73><68>stack<63><6B>
auto luaApi_ListenToGameEvent(lua_State* luaVm) -> int { auto luaApi_ListenToGameEvent(lua_State* luaVm) -> int {
const auto eventName = lua_tostring(luaVm, 1); const auto eventName = lua_tostring(luaVm, 1);
@@ -99,6 +109,7 @@ auto luaApi_RespawnPlayer(lua_State* luaVm) -> int {
} }
auto playerController = reinterpret_cast<CCSPlayerController*>(player); auto playerController = reinterpret_cast<CCSPlayerController*>(player);
auto playerPawn = playerController->m_hPawn().Get<CCSPlayerPawn>(); auto playerPawn = playerController->m_hPawn().Get<CCSPlayerPawn>();
playerPawn->m_bRespawning(false); playerPawn->m_bRespawning(false);
} while (false); } while (false);
lua_pop(luaVm, 1); lua_pop(luaVm, 1);
@@ -256,9 +267,128 @@ auto luaApi_GetPlayerCurrentWeaponInfo(lua_State* luaVm) -> _luaApi_WeaponInfo {
: (itemStaticData->IsWeapon() ? _luaApi_WeaponType::kGun : (itemStaticData->IsWeapon() ? _luaApi_WeaponType::kGun
: _luaApi_WeaponType::kOther)); : _luaApi_WeaponType::kOther));
} while (false); } while (false);
return info; return info;
} }
auto luaApi_CreateTimer(lua_State* luaVm) -> int {
// param: time:float, callback:function, params:lua_table
const auto time = lua_tonumber(luaVm, 1);
const auto repeat = lua_toboolean(luaVm, 2);
const auto preserveMapChange = lua_toboolean(luaVm, 3);
auto timerHandle = 0;
do {
const auto params = lua_gettable(luaVm, 4);
const auto callback = luaL_ref(luaVm, LUA_REGISTRYINDEX);
LOG("luaApi_CreateTimer: params: %d callback: %d \n", params, callback);
timerHandle = GameTimer::AddTimer(new _GameTimer{
.m_flTime = (float)time,
.m_bRepeat = (bool)repeat,
.m_bPreserveMapChange = (bool)preserveMapChange,
.m_luaVm = luaVm,
.m_iParamIndex = params,
.m_iLuaCallBackFn = callback
});
} while (false);
lua_pop(luaVm, 5);
lua_pushinteger(luaVm, timerHandle);
return 1;
}
auto luaApi_CheckPlayerIsAlive(lua_State* luaVm) -> int {
// param: playerIndex:int
const auto playerIndex = lua_tointeger(luaVm, 1);
auto isAlive = false;
CGameEntitySystem* EntitySystem = CGameEntitySystem::GetInstance();
do {
if (EntitySystem == nullptr || playerIndex == 0) {
break;
}
auto player = EntitySystem->GetBaseEntity(playerIndex);
if (player == nullptr) {
break;
}
if (player->IsBasePlayerController() == false) {
break;
}
auto playerController = reinterpret_cast<CCSPlayerController*>(player);
isAlive = playerController->m_bPawnIsAlive();
} while (false);
lua_pop(luaVm, 1);
lua_pushboolean(luaVm, isAlive);
return 1;
}
auto luaApi_GetPlayerTeam(lua_State* luaVm) -> int {
// param: playerIndex:int
const auto playerIndex = lua_tointeger(luaVm, 1);
auto team = 0;
CGameEntitySystem* EntitySystem = CGameEntitySystem::GetInstance();
do {
if (EntitySystem == nullptr || playerIndex == 0) {
break;
}
auto player = EntitySystem->GetBaseEntity(playerIndex);
if (player == nullptr) {
break;
}
if (player->IsBasePlayerController() == false) {
break;
}
auto playerController = reinterpret_cast<CCSPlayerController*>(player);
team = playerController->m_iTeamNum();
} while (false);
lua_pop(luaVm, 1);
lua_pushinteger(luaVm, team);
return 1;
}
auto luaApi_SetPlayerTeam(lua_State* luaVm) -> int {
// param: playerIndex:int, team:int
const auto playerIndex = lua_tointeger(luaVm, 1);
const auto team = lua_tointeger(luaVm, 2);
auto isSuccess = false;
CGameEntitySystem* EntitySystem = CGameEntitySystem::GetInstance();
do {
if (EntitySystem == nullptr || playerIndex == 0) {
break;
}
auto player = EntitySystem->GetBaseEntity(playerIndex);
if (player == nullptr) {
break;
}
if (player->IsBasePlayerController() == false) {
break;
}
auto playerController = reinterpret_cast<CCSPlayerController*>(player);
playerController->m_iTeamNum() = team;
isSuccess = true;
} while (false);
lua_pop(luaVm, 2);
lua_pushboolean(luaVm, isSuccess);
return 1;
}
auto luaApi_CheckPlayerIsInServer(lua_State* luaVm) -> int {
// param: playerIndex:int
const auto playerIndex = lua_tointeger(luaVm, 1);
auto isInServer = false;
CGameEntitySystem* EntitySystem = CGameEntitySystem::GetInstance();
do {
if (EntitySystem == nullptr || playerIndex == 0) {
break;
}
auto player = EntitySystem->GetBaseEntity(playerIndex);
if (player == nullptr) {
break;
}
if (player->IsBasePlayerController() == false) {
break;
}
isInServer = true;
} while (false);
lua_pop(luaVm, 1);
lua_pushboolean(luaVm, isInServer);
return 1;
}
auto initFunciton(lua_State* luaVm) -> void { auto initFunciton(lua_State* luaVm) -> void {
lua_register(luaVm, "ListenToGameEvent", luaApi_ListenToGameEvent); lua_register(luaVm, "ListenToGameEvent", luaApi_ListenToGameEvent);
lua_register(luaVm, "luaApi_SetPlayerCurrentWeaponAmmo", lua_register(luaVm, "luaApi_SetPlayerCurrentWeaponAmmo",
@@ -270,7 +400,12 @@ auto initFunciton(lua_State* luaVm) -> void {
lua_register(luaVm, "luaApi_SetPlayerArmorValue", lua_register(luaVm, "luaApi_SetPlayerArmorValue",
luaApi_SetPlayerArmorValue); luaApi_SetPlayerArmorValue);
lua_register(luaVm, "luaApi_RespawnPlayer", luaApi_RespawnPlayer); lua_register(luaVm, "luaApi_RespawnPlayer", luaApi_RespawnPlayer);
lua_register(luaVm, "luaApi_CreateTimer", luaApi_CreateTimer);
lua_register(luaVm, "luaApi_CheckPlayerIsAlive", luaApi_CheckPlayerIsAlive);
lua_register(luaVm, "luaApi_GetPlayerTeam", luaApi_GetPlayerTeam);
lua_register(luaVm, "luaApi_SetPlayerTeam", luaApi_SetPlayerTeam);
lua_register(luaVm, "luaApi_CheckPlayerIsInServer",
luaApi_CheckPlayerIsInServer);
// <20>Ҳ<EFBFBD>ϲ<EFBFBD><CFB2><EFBFBD><EFBFBD> // <20>Ҳ<EFBFBD>ϲ<EFBFBD><CFB2><EFBFBD><EFBFBD>
luabridge::getGlobalNamespace(luaVm) luabridge::getGlobalNamespace(luaVm)
.beginClass<_luaApi_WeaponInfo>("WeaponInfo") .beginClass<_luaApi_WeaponInfo>("WeaponInfo")

View File

@@ -8,7 +8,9 @@ std::unordered_map<uint32_t, _CallbackNames> callbackNameWithEnumMap{
{hash_32_fnv1a_const("player_connect"), _CallbackNames::kOnPlayerConnect}, {hash_32_fnv1a_const("player_connect"), _CallbackNames::kOnPlayerConnect},
{hash_32_fnv1a_const("player_disconnect"), {hash_32_fnv1a_const("player_disconnect"),
_CallbackNames::kOnPlayerDisconnect}, _CallbackNames::kOnPlayerDisconnect},
{hash_32_fnv1a_const("player_death"), _CallbackNames::kOnPlayerDeath}}; {hash_32_fnv1a_const("player_death"), _CallbackNames::kOnPlayerDeath},
{hash_32_fnv1a_const("player_chat"), _CallbackNames::kOnPlayerSpeak},
};
auto CallBackNameToEnum(const char* name) -> _CallbackNames { auto CallBackNameToEnum(const char* name) -> _CallbackNames {
if (name == nullptr) { if (name == nullptr) {
return _CallbackNames::kError; return _CallbackNames::kError;
@@ -104,4 +106,27 @@ auto luaCall_onPlayerDeath(int victim, int killer, bool isHeadShot) -> void {
} }
}); });
} }
auto luaCall_onPlayerSpeak(int speaker, int chatType, std::string message)
-> bool {
bool result = false;
ExcuteCallbackInAllLuaVm(_CallbackNames::kOnPlayerSpeak,
[&](lua_State* luaVm, int refIndex) -> void {
lua_rawgeti(luaVm, LUA_REGISTRYINDEX,
refIndex);
if (lua_isfunction(luaVm, -1)) {
lua_pushinteger(luaVm, speaker);
lua_pushinteger(luaVm, chatType);
lua_pushstring(luaVm, message.c_str());
if (lua_pcall(luaVm, 3, 1, 0) != LUA_OK) {
LOG("Error calling Lua callback: %s\n",
lua_tostring(luaVm, -1));
lua_pop(luaVm, 1);
}
if (lua_isboolean(luaVm, -1)) {
result = lua_toboolean(luaVm, -1);
}
}
});
return result;
}
} // namespace ScriptCallBacks } // namespace ScriptCallBacks

View File

@@ -6,7 +6,8 @@ enum class _CallbackNames {
kError, kError,
kOnPlayerConnect, kOnPlayerConnect,
kOnPlayerDisconnect, kOnPlayerDisconnect,
kOnPlayerDeath kOnPlayerDeath,
kOnPlayerSpeak
}; };
extern std::unordered_map<lua_State*, std::unordered_map<_CallbackNames, int>> extern std::unordered_map<lua_State*, std::unordered_map<_CallbackNames, int>>
callbackList; callbackList;
@@ -19,4 +20,6 @@ auto luaCall_onPlayerDisconnect(int player, int slot, const char* pszName,
const char* pszAddress, bool bFakePlayer) const char* pszAddress, bool bFakePlayer)
-> void; -> void;
auto luaCall_onPlayerDeath(int victim, int killer, bool isHeadShot) -> void; auto luaCall_onPlayerDeath(int victim, int killer, bool isHeadShot) -> void;
auto luaCall_onPlayerSpeak(int speaker, int chatType, std::string message)
-> bool;
} // namespace ScriptCallBacks } // namespace ScriptCallBacks

View File

@@ -193,6 +193,7 @@ public:
class ISource2Server : public IAppSystem class ISource2Server : public IAppSystem
{ {
public: public:
//vmt index 11
virtual bool Unknown0() const = 0; virtual bool Unknown0() const = 0;
virtual void SetGlobals(CGlobalVars* pGlobals) = 0; virtual void SetGlobals(CGlobalVars* pGlobals) = 0;
@@ -213,6 +214,7 @@ public:
// The server should run physics/think on all edicts // The server should run physics/think on all edicts
// One of these bools is 'simulating'... probably // One of these bools is 'simulating'... probably
// index 19
virtual void GameFrame(bool simulating, bool bFirstTick, bool bLastTick) = 0; virtual void GameFrame(bool simulating, bool bFirstTick, bool bLastTick) = 0;
// Returns true if the game DLL wants the server not to be made public. // Returns true if the game DLL wants the server not to be made public.

View File

@@ -91,6 +91,7 @@ public:
class IEngineService : public IAppSystem class IEngineService : public IAppSystem
{ {
public: public:
//vmt index 11
virtual void* GetServiceDependencies(void) = 0; virtual void* GetServiceDependencies(void) = 0;
virtual const char* GetName(void) const = 0; virtual const char* GetName(void) const = 0;
virtual bool ShouldActivate(const char*) = 0; virtual bool ShouldActivate(const char*) = 0;
@@ -107,10 +108,12 @@ public:
class INetworkServerService : public IEngineService class INetworkServerService : public IEngineService
{ {
public: public:
//vmt index 22
virtual ~INetworkServerService() {} virtual ~INetworkServerService() {}
virtual INetworkGameServer * GetIGameServer(void) = 0; virtual INetworkGameServer * GetIGameServer(void) = 0;
virtual bool IsActiveInGame(void) const = 0; virtual bool IsActiveInGame(void) const = 0;
virtual bool IsMultiplayer(void) const = 0; virtual bool IsMultiplayer(void) const = 0;
//vmt index 26
virtual void StartupServer(const GameSessionConfiguration_t& config, ISource2WorldSession* pWorldSession, const char*) = 0; virtual void StartupServer(const GameSessionConfiguration_t& config, ISource2WorldSession* pWorldSession, const char*) = 0;
virtual void SetGameSpawnGroupMgr(IGameSpawnGroupMgr* pMgr) = 0; virtual void SetGameSpawnGroupMgr(IGameSpawnGroupMgr* pMgr) = 0;
virtual void AddServerPrerequisites(const GameSessionConfiguration_t&, const char*, void*, bool) = 0; virtual void AddServerPrerequisites(const GameSessionConfiguration_t&, const char*, void*, bool) = 0;

43
csgo2/timer.cpp Normal file
View File

@@ -0,0 +1,43 @@
#include "timer.h"
namespace ScriptApis {
extern auto TimerCallBack(_GameTimer* timer) -> void;
};
namespace GameTimer {
std::shared_mutex mutex_timerList;
std::vector<_GameTimer*> timerList;
auto AddTimer(_GameTimer* timer) -> int {
std::unique_lock<std::shared_mutex> lock(mutex_timerList);
timerList.push_back(timer);
return timerList.size() - 1;
};
auto CleanUpTimers() -> void {
std::unique_lock<std::shared_mutex> lock(mutex_timerList);
for (auto it = timerList.begin(); it != timerList.end();) {
if ((*it)->m_bPreserveMapChange) {
++it;
} else {
delete (*it);
it = timerList.erase(it);
}
}
};
auto ExcuteTimers() -> void {
std::shared_lock<std::shared_mutex> lock(mutex_timerList);
for (auto it = timerList.begin(); it != timerList.end();) {
if ((*it)->m_flLastExecute == -1) {
(*it)->m_flLastExecute = global::m_flUniversalTime;
}
if ((*it)->m_flLastExecute + (*it)->m_flTime <= global::m_flUniversalTime) {
ScriptApis::TimerCallBack(*it);
if ((*it)->m_bRepeat) {
(*it)->m_flLastExecute = global::m_flUniversalTime;
} else {
delete (*it);
it = timerList.erase(it);
continue;
}
}
++it;
}
}
}; // namespace GameTimer

18
csgo2/timer.h Normal file
View File

@@ -0,0 +1,18 @@
#pragma once
#include "head.h"
class _GameTimer {
public:
float m_flTime;
float m_flLastExecute = -1;
bool m_bRepeat;
bool m_bPreserveMapChange;
lua_State* m_luaVm;
int m_iParamIndex;
int m_iLuaCallBackFn;
};
namespace GameTimer {
auto AddTimer(_GameTimer* timer) -> int;
auto CleanUpTimers() -> void;
auto ExcuteTimers() -> void;
}; // namespace GameTimer

View File

@@ -9,13 +9,13 @@ void* VMTHook::Hook(int index, void* hk)
{ {
// Store the index and original function address // Store the index and original function address
hooked_funcs.insert(std::make_pair(index, vmt[index])); hooked_funcs.insert(std::make_pair(index, vmt[index]));
printf("vmt hook at: %p \n", vmt[index]);
// Change the memory's access rights, patch the address to our hook, restore original rights // Change the memory's access rights, patch the address to our hook, restore original rights
DWORD old; DWORD old;
VirtualProtect(&vmt[index], sizeof(void*), PAGE_EXECUTE_READWRITE, &old); VirtualProtect(&vmt[index], sizeof(void*), PAGE_EXECUTE_READWRITE, &old);
vmt[index] = hk; vmt[index] = hk;
VirtualProtect(&vmt[index], sizeof(void*), old, NULL); VirtualProtect(&vmt[index], sizeof(void*), old, NULL);
return hooked_funcs[index]; return hooked_funcs[index];
} }