From 06acf8b24dca150e1994ecbbffabd178fdafa395 Mon Sep 17 00:00:00 2001
From: Huoji's <1296564236@qq.com>
Date: Wed, 4 Oct 2023 06:01:28 +0800
Subject: [PATCH] 11
---
.vscode/settings.json | 3 +-
csgo2/csgo2.vcxproj | 2 +
csgo2/csgo2.vcxproj.filters | 12 +
csgo2/events.cpp | 9 +-
csgo2/global.cpp | 5 +
csgo2/global.h | 7 +
csgo2/head.h | 1 +
csgo2/hooks.cpp | 64 +++-
csgo2/hooks.h | 2 +
csgo2/native_sdk.cpp | 125 ++++---
csgo2/native_sdk.h | 655 +++++++++++++++++-------------------
csgo2/offset.cpp | 50 ++-
csgo2/offset.h | 56 +--
csgo2/script_apis.cpp | 139 +++++++-
csgo2/script_callbacks.cpp | 27 +-
csgo2/script_callbacks.h | 5 +-
csgo2/sdk/public/eiface.h | 2 +
csgo2/sdk/public/iserver.h | 3 +
csgo2/timer.cpp | 43 +++
csgo2/timer.h | 18 +
csgo2/vmthook.cpp | 2 +-
21 files changed, 773 insertions(+), 457 deletions(-)
create mode 100644 csgo2/timer.cpp
create mode 100644 csgo2/timer.h
diff --git a/.vscode/settings.json b/.vscode/settings.json
index 601b48d..ad52f84 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -87,6 +87,7 @@
"*.rh": "cpp",
"random": "cpp",
"hash_map": "cpp",
- "hash_set": "cpp"
+ "hash_set": "cpp",
+ "filesystem": "cpp"
}
}
diff --git a/csgo2/csgo2.vcxproj b/csgo2/csgo2.vcxproj
index 14f57d5..4de1031 100644
--- a/csgo2/csgo2.vcxproj
+++ b/csgo2/csgo2.vcxproj
@@ -230,6 +230,7 @@
+
@@ -297,6 +298,7 @@
+
diff --git a/csgo2/csgo2.vcxproj.filters b/csgo2/csgo2.vcxproj.filters
index 907a65b..d4b9b37 100644
--- a/csgo2/csgo2.vcxproj.filters
+++ b/csgo2/csgo2.vcxproj.filters
@@ -76,6 +76,12 @@
{d58fcaf6-b1d7-484d-9ec4-d6b67ff46cf5}
+
+ {ccc753a5-6730-455d-b12b-9fa7e9a4cf03}
+
+
+ {f26913ae-881a-43da-a215-8c0c7a9173cd}
+
@@ -318,6 +324,9 @@
头文件\native_sdk
+
+ 头文件\game_time_system
+
@@ -491,6 +500,9 @@
源文件\script_engine
+
+ 源文件\game_time_system
+
diff --git a/csgo2/events.cpp b/csgo2/events.cpp
index 8990846..307a817 100644
--- a/csgo2/events.cpp
+++ b/csgo2/events.cpp
@@ -28,7 +28,8 @@ auto OnPlayerDeathEvent(IGameEvent* event) -> void {
}
const auto victimIndex = victim->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,
// &attacker->m_iszPlayerName(), victim, &victim->m_steamID());
}
@@ -38,10 +39,8 @@ auto OnPlayerChat(CCSPlayerController* player, std::string message) -> bool {
if (procesChatSuccess == false) {
return false;
}
- if (chatCtx.at(0) == '/' || chatCtx.at(0) == '!') {
- return true;
- }
- return false;
+ return ScriptCallBacks::luaCall_onPlayerSpeak(
+ player->GetRefEHandle().GetEntryIndex(), chatType, chatCtx);
}
auto OnPlayerConnect(int slot, const char* pszName, uint64_t xuid,
const char* pszNetworkID, const char* pszAddress,
diff --git a/csgo2/global.cpp b/csgo2/global.cpp
index 0312374..1c49f54 100644
--- a/csgo2/global.cpp
+++ b/csgo2/global.cpp
@@ -2,4 +2,9 @@
namespace global {
bool Exit;
int MaxPlayers;
+ CGameEntitySystem* EntitySystem;
+ bool HasTicked;
+ CGlobalVars* GlobalVars;
+ float m_flUniversalTime;
+ float m_flLastTickedTime;
}
\ No newline at end of file
diff --git a/csgo2/global.h b/csgo2/global.h
index b6797cd..41ccf18 100644
--- a/csgo2/global.h
+++ b/csgo2/global.h
@@ -1,6 +1,13 @@
#pragma once
#include "head.h"
+class CGlobalVars;
+class CGameEntitySystem;
namespace global {
extern bool Exit;
extern int MaxPlayers;
+ extern CGameEntitySystem* EntitySystem;
+ extern bool HasTicked;
+ extern CGlobalVars* GlobalVars;
+ extern float m_flUniversalTime;
+ extern float m_flLastTickedTime;
}
\ No newline at end of file
diff --git a/csgo2/head.h b/csgo2/head.h
index 474ad4f..9d4a975 100644
--- a/csgo2/head.h
+++ b/csgo2/head.h
@@ -79,3 +79,4 @@ static void DebugPrintA(const char* format, ...) {
#include "script_engine.h"
#include "script_apis.h"
#include "script_callbacks.h"
+#include "timer.h"
diff --git a/csgo2/hooks.cpp b/csgo2/hooks.cpp
index 8cddb34..6a1d0b5 100644
--- a/csgo2/hooks.cpp
+++ b/csgo2/hooks.cpp
@@ -1,13 +1,58 @@
#include "hooks.h"
-
+extern auto GetGameGlobals() -> CGlobalVars*;
FireEventServerSide_t original_FireEventServerSide = NULL;
OnClientConnect_t original_OnClientConnected = NULL;
OnClientDisconnect_t original_OnClientDisconnect = NULL;
Host_Say_t original_Host_Say = NULL;
-
+StartupServer_t origin_StartServer = NULL;
+GameFrame_t origin_GameFrame = NULL;
namespace hooks {
// "player_connect"
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,
const char* pszName, uint64_t xuid,
const char* pszNetworkID) {
@@ -134,11 +179,24 @@ auto initMinHook() -> bool {
auto initVmtHook() -> bool {
VMT_IServerGameClient = new VMTHook(Memory::read(
reinterpret_cast(Offset::InterFaces::IServerGameClient)));
+ VMT_INetworkServerServiceInteFace =
+ new VMTHook(Memory::read(reinterpret_cast(
+ Offset::InterFaces::INetworkServerServiceInteFace)));
+ VMT_ISource2ServerInterFace =
+ new VMTHook(Memory::read(reinterpret_cast(
+ Offset::InterFaces::ISource2ServerInterFace)));
+
original_OnClientConnected = reinterpret_cast(
VMT_IServerGameClient->Hook(11, hook_OnClientConnected));
original_OnClientDisconnect = reinterpret_cast(
VMT_IServerGameClient->Hook(16, hook_ClientDisconnect));
- return original_OnClientConnected && original_OnClientDisconnect;
+
+ origin_StartServer = reinterpret_cast(
+ VMT_INetworkServerServiceInteFace->Hook(27, hook_StartServer));
+ origin_GameFrame = reinterpret_cast(
+ VMT_ISource2ServerInterFace->Hook(19, hook_GameFrame));
+ return original_OnClientConnected && original_OnClientDisconnect &&
+ origin_StartServer && origin_GameFrame;
}
auto init() -> bool {
bool isSuccess = initMinHook() && initVmtHook();
diff --git a/csgo2/hooks.h b/csgo2/hooks.h
index f41ad1a..d1c0447 100644
--- a/csgo2/hooks.h
+++ b/csgo2/hooks.h
@@ -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* 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* StartupServer_t)(void*, const GameSessionConfiguration_t&, ISource2WorldSession*, const char*);
+typedef void(__fastcall* GameFrame_t)(void*, bool, bool, bool);
extern FireEventServerSide_t original_FireEventServerSide;
extern Host_Say_t original_Host_Say;
diff --git a/csgo2/native_sdk.cpp b/csgo2/native_sdk.cpp
index 180f51b..d4f7414 100644
--- a/csgo2/native_sdk.cpp
+++ b/csgo2/native_sdk.cpp
@@ -1,10 +1,8 @@
#include "native_sdk.h"
-CBaseEntity* CHandle::GetBaseEntity() const
-{
+CBaseEntity* CHandle::GetBaseEntity() const {
CGameEntitySystem* pEntitySystem = CGameEntitySystem::GetInstance();
- if (!pEntitySystem)
- return nullptr;
+ if (!pEntitySystem) return nullptr;
return pEntitySystem->GetBaseEntity(GetEntryIndex());
}
@@ -12,29 +10,27 @@ CGameEntitySystem* CGameEntitySystem::GetInstance() {
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;
CALL_VIRTUAL(void, 2, this, &rv, pClass);
return rv;
}
-auto CSchemaSystem::FindTypeScopeForModule(const char* module) -> CSchemaSystemTypeScope*
-{
+auto CSchemaSystem::FindTypeScopeForModule(const char* module)
+ -> CSchemaSystemTypeScope* {
return CALL_VIRTUAL(CSchemaSystemTypeScope*, 13, this, module, nullptr);
}
-bool CBaseEntity::IsBasePlayerController() {
+auto CBaseEntity::IsBasePlayerController() -> bool {
return CALL_VIRTUAL(bool, 144, this);
}
-
-auto CBasePlayer::ForceRespawn() -> void
-{
+auto CBaseEntity::SpawnClientEntity() -> void { CALL_VIRTUAL(void, 19, this); }
+auto CBasePlayer::ForceRespawn() -> void {
return CALL_VIRTUAL(void, 26, this);
}
-auto CCSPlayerPawn::GetPlayerController() -> CCSPlayerController*
-{
+auto CCSPlayerPawn::GetPlayerController() -> CCSPlayerController* {
CGameEntitySystem* pEntitySystem = CGameEntitySystem::GetInstance();
if (!pEntitySystem) {
return nullptr;
@@ -45,7 +41,9 @@ auto CCSPlayerPawn::GetPlayerController() -> CCSPlayerController*
if (pEntity->IsBasePlayerController()) {
const auto player = reinterpret_cast(pEntity);
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;
}
}
@@ -56,11 +54,8 @@ auto CCSPlayerPawn::GetPlayerController() -> CCSPlayerController*
using SchemaKeyValueMap_t = CUtlMap;
using SchemaTableMap_t = CUtlMap;
-
-static bool IsFieldNetworked(SchemaClassFieldData_t& field)
-{
- for (int i = 0; i < field.m_metadata_size; i++)
- {
+static bool IsFieldNetworked(SchemaClassFieldData_t& field) {
+ for (int i = 0; i < field.m_metadata_size; i++) {
static auto networkEnabled = hash_32_fnv1a_const("MNetworkEnable");
if (networkEnabled == hash_32_fnv1a_const(field.m_metadata[i].m_name))
return true;
@@ -69,18 +64,18 @@ static bool IsFieldNetworked(SchemaClassFieldData_t& field)
return false;
}
-static bool InitSchemaFieldsForClass(SchemaTableMap_t* tableMap, const char* className, uint32_t classKey)
-{
- CSchemaSystemTypeScope* pType = Offset::InterFaces::SchemaSystem->FindTypeScopeForModule("server.dll");
+static bool InitSchemaFieldsForClass(SchemaTableMap_t* tableMap,
+ const char* className, uint32_t classKey) {
+ CSchemaSystemTypeScope* pType =
+ Offset::InterFaces::SchemaSystem->FindTypeScopeForModule("server.dll");
- if (!pType)
- return false;
+ if (!pType) return false;
SchemaClassInfoData_t* pClassInfo = pType->FindDeclaredClass(className);
- if (!pClassInfo)
- {
- SchemaKeyValueMap_t* map = new SchemaKeyValueMap_t(0, 0, DefLessFunc(uint32_t));
+ if (!pClassInfo) {
+ SchemaKeyValueMap_t* map =
+ new SchemaKeyValueMap_t(0, 0, DefLessFunc(uint32_t));
tableMap->Insert(classKey, map);
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();
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);
tableMap->Insert(classKey, keyValueMap);
- for (int i = 0; i < fieldsSize; ++i)
- {
+ for (int i = 0; i < fieldsSize; ++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;
}
-int16_t schema::FindChainOffset(const char* className)
-{
-
- CSchemaSystemTypeScope* pType = Offset::InterFaces::SchemaSystem->FindTypeScopeForModule("server.dll");
+int16_t schema::FindChainOffset(const char* className) {
+ CSchemaSystemTypeScope* pType =
+ Offset::InterFaces::SchemaSystem->FindTypeScopeForModule("server.dll");
- if (!pType)
- return false;
+ if (!pType) return false;
SchemaClassInfoData_t* pClassInfo = pType->FindDeclaredClass(className);
- do
- {
+ do {
SchemaClassFieldData_t* pFields = pClassInfo->GetFields();
short fieldsSize = pClassInfo->GetFieldsSize();
- for (int i = 0; i < fieldsSize; ++i)
- {
+ for (int i = 0; i < fieldsSize; ++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;
}
}
@@ -132,24 +125,23 @@ int16_t schema::FindChainOffset(const char* className)
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));
int16_t tableMapIndex = schemaTableMap.Find(classKey);
- if (!schemaTableMap.IsValidIndex(tableMapIndex))
- {
+ if (!schemaTableMap.IsValidIndex(tableMapIndex)) {
if (InitSchemaFieldsForClass(&schemaTableMap, className, classKey))
return GetOffset(className, classKey, memberName, memberKey);
- return { 0, 0 };
+ return {0, 0};
}
SchemaKeyValueMap_t* tableMap = schemaTableMap[tableMapIndex];
int16_t memberIndex = tableMap->Find(memberKey);
- if (!tableMap->IsValidIndex(memberIndex))
- {
- LOG("schema::GetOffset(): '%s' was not found in '%s'!\n", memberName, className);
- return { 0, 0 };
+ if (!tableMap->IsValidIndex(memberIndex)) {
+ LOG("schema::GetOffset(): '%s' was not found in '%s'!\n", memberName,
+ className);
+ return {0, 0};
}
return tableMap->Element(memberIndex);
@@ -177,27 +169,26 @@ bool CEconItemDefinition::IsGlove(bool excludeDefault) {
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);
}
-auto GetGameGlobals() -> CGlobalVars*
-{
- INetworkGameServer* server = Offset::InterFaces::INetworkServerServiceInteFace->GetIGameServer();
+auto GetGameGlobals() -> CGlobalVars* {
+ INetworkGameServer* server =
+ Offset::InterFaces::INetworkServerServiceInteFace->GetIGameServer();
- if (!server)
- return nullptr;
+ if (!server) return nullptr;
- return Offset::InterFaces::INetworkServerServiceInteFace->GetIGameServer()->GetGlobals();
+ return Offset::InterFaces::INetworkServerServiceInteFace->GetIGameServer()
+ ->GetGlobals();
}
-auto SetStateChanged(Z_CBaseEntity* pEntity, int offset) -> void
-{
- Offset::FnStateChanged(pEntity->m_NetworkTransmitComponent(), pEntity, offset, -1, -1);
- auto vars = GetGameGlobals();
+auto SetStateChanged(Z_CBaseEntity* pEntity, int offset) -> void {
+ Offset::FnStateChanged(pEntity->m_NetworkTransmitComponent(), pEntity,
+ offset, -1, -1);
+ // auto vars = GetGameGlobals();
+ auto vars = global::GlobalVars;
- if (vars)
- pEntity->m_lastNetworkChange(vars->curtime);
+ if (vars) pEntity->m_lastNetworkChange(vars->curtime);
pEntity->m_isSteadyState(0);
};
diff --git a/csgo2/native_sdk.h b/csgo2/native_sdk.h
index a7ed4e0..3f495bd 100644
--- a/csgo2/native_sdk.h
+++ b/csgo2/native_sdk.h
@@ -1,313 +1,287 @@
#pragma once
#include "head.h"
class CEntityInstance;
-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* 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);
namespace Offset {
- extern StateChanged_t FnStateChanged;
- extern NetworkStateChanged_t FnNetworkStateChanged;
-}
+extern StateChanged_t FnStateChanged;
+extern NetworkStateChanged_t FnNetworkStateChanged;
+} // namespace Offset
struct SchemaKey {
- int16_t offset;
- bool networked;
+ int16_t offset;
+ bool networked;
};
class Z_CBaseEntity;
extern auto SetStateChanged(Z_CBaseEntity* pEntity, int offset) -> void;
#define MAX_ENTITIES_IN_LIST 512
-#define MAX_ENTITY_LISTS 64
-#define MAX_TOTAL_ENTITIES MAX_ENTITIES_IN_LIST *MAX_ENTITY_LISTS
+#define MAX_ENTITY_LISTS 64
+#define MAX_TOTAL_ENTITIES MAX_ENTITIES_IN_LIST* MAX_ENTITY_LISTS
#define INVALID_EHANDLE_INDEX 0xFFFFFFFF
-#define ENT_ENTRY_MASK 0x7FFF
+#define ENT_ENTRY_MASK 0x7FFF
-#define DECLARE_SCHEMA_CLASS_BASE(className, isStruct) \
- static constexpr const char *ThisClass = #className; \
- static constexpr bool OffsetIsStruct = isStruct;
+#define DECLARE_SCHEMA_CLASS_BASE(className, isStruct) \
+ static constexpr const char* ThisClass = #className; \
+ static constexpr bool OffsetIsStruct = isStruct;
#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) \
- DECLARE_SCHEMA_CLASS_BASE(className, true)
+ DECLARE_SCHEMA_CLASS_BASE(className, true)
-#define SCHEMA_FIELD_OFFSET(type, varName, extra_offset) \
- std::add_lvalue_reference_t varName() \
- { \
- static constexpr auto datatable_hash = hash_32_fnv1a_const(ThisClass); \
- static constexpr auto prop_hash = hash_32_fnv1a_const(#varName); \
- \
- static const auto m_key = \
- schema::GetOffset(ThisClass, datatable_hash, #varName, prop_hash); \
- \
- return *reinterpret_cast>( \
- (uintptr_t)(this) + m_key.offset + extra_offset); \
- } \
- void varName(type val) \
- { \
- static constexpr auto datatable_hash = hash_32_fnv1a_const(ThisClass); \
- static constexpr auto prop_hash = hash_32_fnv1a_const(#varName); \
- \
- static const auto m_key = \
- schema::GetOffset(ThisClass, datatable_hash, #varName, prop_hash); \
- \
- static const auto m_chain = \
- schema::FindChainOffset(ThisClass); \
- \
- if (m_chain != 0 && m_key.networked) \
- { \
- LOG("Found chain offset %d for %s::%s\n", m_chain, ThisClass, #varName); \
- Offset::FnNetworkStateChanged((uintptr_t)(this) + m_chain, m_key.offset + extra_offset, 0xFFFFFFFF); \
- } \
- else if(m_key.networked) \
- { \
- /* WIP: Works fine for most props, but inlined classes in the middle of a class will
- need to have their this pointer corrected by the offset .*/ \
- LOG("Attempting to call SetStateChanged on on %s::%s\n", ThisClass, #varName); \
- if (!OffsetIsStruct) \
- SetStateChanged((Z_CBaseEntity*)this, m_key.offset + extra_offset); \
- else \
- CALL_VIRTUAL(void, 1, this, m_key.offset + extra_offset, 0xFFFFFFFF, 0xFFFF); \
- \
- } \
- * reinterpret_cast>((uintptr_t)(this) + m_key.offset + extra_offset) = val; \
-}
+#define SCHEMA_FIELD_OFFSET(type, varName, extra_offset) \
+ std::add_lvalue_reference_t varName() { \
+ static constexpr auto datatable_hash = hash_32_fnv1a_const(ThisClass); \
+ static constexpr auto prop_hash = hash_32_fnv1a_const(#varName); \
+ \
+ static const auto m_key = \
+ schema::GetOffset(ThisClass, datatable_hash, #varName, prop_hash); \
+ \
+ return *reinterpret_cast>( \
+ (uintptr_t)(this) + m_key.offset + extra_offset); \
+ } \
+ void varName(type val) { \
+ static constexpr auto datatable_hash = hash_32_fnv1a_const(ThisClass); \
+ static constexpr auto prop_hash = hash_32_fnv1a_const(#varName); \
+ \
+ static const auto m_key = \
+ schema::GetOffset(ThisClass, datatable_hash, #varName, prop_hash); \
+ \
+ static const auto m_chain = schema::FindChainOffset(ThisClass); \
+ \
+ if (m_chain != 0 && m_key.networked) { \
+ LOG("Found chain offset %d for %s::%s\n", m_chain, ThisClass, \
+ #varName); \
+ Offset::FnNetworkStateChanged((uintptr_t)(this) + m_chain, \
+ m_key.offset + extra_offset, \
+ 0xFFFFFFFF); \
+ } else if (m_key.networked) { \
+ /* WIP: Works fine for most props, but inlined classes in the \
+ middle of a class will need to have their this pointer \
+ corrected by the offset .*/ \
+ LOG("Attempting to call SetStateChanged on on %s::%s\n", \
+ ThisClass, #varName); \
+ if (!OffsetIsStruct) \
+ SetStateChanged((Z_CBaseEntity*)this, \
+ m_key.offset + extra_offset); \
+ else \
+ CALL_VIRTUAL(void, 1, this, m_key.offset + extra_offset, \
+ 0xFFFFFFFF, 0xFFFF); \
+ } \
+ *reinterpret_cast>( \
+ (uintptr_t)(this) + m_key.offset + extra_offset) = val; \
+ }
-#define SCHEMA_FIELD(type, varName) \
- SCHEMA_FIELD_OFFSET(type, varName, 0)
+#define SCHEMA_FIELD(type, varName) SCHEMA_FIELD_OFFSET(type, varName, 0)
+#define PSCHEMA_FIELD_OFFSET(type, varName, extra_offset) \
+ auto varName() { \
+ static constexpr auto datatable_hash = hash_32_fnv1a_const(ThisClass); \
+ static constexpr auto prop_hash = hash_32_fnv1a_const(#varName); \
+ \
+ static const auto m_key = \
+ schema::GetOffset(ThisClass, datatable_hash, #varName, prop_hash); \
+ \
+ return reinterpret_cast>( \
+ (uintptr_t)(this) + m_key.offset + extra_offset); \
+ }
-#define PSCHEMA_FIELD_OFFSET(type, varName, extra_offset) \
- auto varName() \
- { \
- static constexpr auto datatable_hash = hash_32_fnv1a_const(ThisClass); \
- static constexpr auto prop_hash = hash_32_fnv1a_const(#varName); \
- \
- static const auto m_key = \
- schema::GetOffset(ThisClass, datatable_hash, #varName, prop_hash); \
- \
- return reinterpret_cast>( \
- (uintptr_t)(this) + m_key.offset + extra_offset); \
- }
+#define PSCHEMA_FIELD(type, varName) PSCHEMA_FIELD_OFFSET(type, varName, 0)
-#define PSCHEMA_FIELD(type, varName) \
- PSCHEMA_FIELD_OFFSET(type, varName, 0)
-
-
-
-namespace schema
-{
- int16_t FindChainOffset(const char* className);
- SchemaKey GetOffset(const char* className, uint32_t classKey, const char* memberName, uint32_t memberKey);
-}
+namespace schema {
+int16_t FindChainOffset(const char* className);
+SchemaKey GetOffset(const char* className, uint32_t classKey,
+ const char* memberName, uint32_t memberKey);
+} // namespace schema
struct CSchemaNetworkValue {
- union {
- const char* m_sz_value;
- int m_n_value;
- float m_f_value;
- std::uintptr_t m_p_value;
- };
+ union {
+ const char* m_sz_value;
+ int m_n_value;
+ float m_f_value;
+ std::uintptr_t m_p_value;
+ };
};
struct SchemaMetadataEntryData_t {
- const char* m_name;
- CSchemaNetworkValue* m_value;
+ const char* m_name;
+ CSchemaNetworkValue* m_value;
};
-struct SchemaClassFieldData_t
-{
- const char* m_name;
- char pad0[0x8];
- short m_offset;
- int32_t m_metadata_size;
- SchemaMetadataEntryData_t* m_metadata;
+struct SchemaClassFieldData_t {
+ const char* m_name;
+ char pad0[0x8];
+ short m_offset;
+ int32_t m_metadata_size;
+ SchemaMetadataEntryData_t* m_metadata;
};
-
class SchemaClassInfoData_t;
-struct SchemaBaseClassInfoData_t
-{
- unsigned int m_offset;
- SchemaClassInfoData_t* m_class;
+struct SchemaBaseClassInfoData_t {
+ unsigned int m_offset;
+ SchemaClassInfoData_t* m_class;
};
-class SchemaClassInfoData_t
-{
-public:
- auto GetName()
- {
- return m_name;
- }
+class SchemaClassInfoData_t {
+ public:
+ auto GetName() { return m_name; }
- auto GetFieldsSize()
- {
- return m_align;
- }
+ auto GetFieldsSize() { return m_align; }
- auto GetFields()
- {
- return m_fields;
- }
+ auto GetFields() { return m_fields; }
- auto GetParent() -> SchemaClassInfoData_t*
- {
- if (!m_schema_parent)
- return nullptr;
+ auto GetParent() -> SchemaClassInfoData_t* {
+ if (!m_schema_parent) return nullptr;
- return m_schema_parent->m_class;
- }
+ return m_schema_parent->m_class;
+ }
-private:
- char pad_0x0000[0x8]; // 0x0000
+ private:
+ char pad_0x0000[0x8]; // 0x0000
- const char* m_name; // 0x0008
- char* m_module; // 0x0010
+ const char* m_name; // 0x0008
+ char* m_module; // 0x0010
- int m_size; // 0x0018
- std::int16_t m_align; // 0x001C
+ int m_size; // 0x0018
+ std::int16_t m_align; // 0x001C
- std::int16_t m_static_size; // 0x001E
- std::int16_t m_metadata_size; // 0x0020
- std::int16_t m_i_unk1; // 0x0022
- std::int16_t m_i_unk2; // 0x0024
- std::int16_t m_i_unk3; // 0x0026
+ std::int16_t m_static_size; // 0x001E
+ std::int16_t m_metadata_size; // 0x0020
+ std::int16_t m_i_unk1; // 0x0022
+ std::int16_t m_i_unk2; // 0x0024
+ std::int16_t m_i_unk3; // 0x0026
- SchemaClassFieldData_t* m_fields; // 0x0028
+ SchemaClassFieldData_t* m_fields; // 0x0028
- char pad_0x0030[0x8]; // 0x0030
- SchemaBaseClassInfoData_t* m_schema_parent; // 0x0038
+ char pad_0x0030[0x8]; // 0x0030
+ SchemaBaseClassInfoData_t* m_schema_parent; // 0x0038
- char pad_0x0038[0x10]; // 0x0038
+ char pad_0x0038[0x10]; // 0x0038
};
-class CSchemaSystemTypeScope
-{
-public:
- auto FindDeclaredClass(const char* pClass) -> SchemaClassInfoData_t*;
+class CSchemaSystemTypeScope {
+ public:
+ auto FindDeclaredClass(const char* pClass) -> SchemaClassInfoData_t*;
};
-class CSchemaSystem
-{
-public:
- auto FindTypeScopeForModule(const char* module) -> CSchemaSystemTypeScope*;
+class CSchemaSystem {
+ public:
+ auto FindTypeScopeForModule(const char* module) -> CSchemaSystemTypeScope*;
};
template
class CUtlVector_NativeSdk {
-public:
- auto begin() const { return m_data; }
- auto end() const { return m_data + m_size; }
+ public:
+ auto begin() const { return m_data; }
+ auto end() const { return m_data + m_size; }
- bool Exists(T val) const {
- for (const auto& it : *this)
- if (it == val) return true;
- return false;
- }
- bool Empty() const { return m_size == 0; }
+ bool Exists(T val) const {
+ for (const auto& it : *this)
+ if (it == val) return true;
+ return false;
+ }
+ bool Empty() const { return m_size == 0; }
- int m_size;
- char pad0[0x4]; // no idea
- T* m_data;
- char pad1[0x8]; // no idea
+ int m_size;
+ char pad0[0x4]; // no idea
+ T* m_data;
+ char pad1[0x8]; // no idea
};
-
class CBaseEntity;
-class CEntityIdentity
-{
-public:
- CBaseEntity* entity; //0
- void* dunno; //8
- int64_t unk0; //12
- int64_t unk1; //16
- const char* internalName;
- const char* entityName;
- void* unk2;
- void* unk3;
- void* unk4;
- void* unk5;
- CEntityIdentity* prevValid;
- CEntityIdentity* nextValid;
- void* unkptr;
- void* unkptr2;
- void* unkptr3;
+class CEntityIdentity {
+ public:
+ CBaseEntity* entity; // 0
+ void* dunno; // 8
+ int64_t unk0; // 12
+ int64_t unk1; // 16
+ const char* internalName;
+ const char* entityName;
+ void* unk2;
+ void* unk3;
+ void* unk4;
+ void* unk5;
+ CEntityIdentity* prevValid;
+ CEntityIdentity* nextValid;
+ void* unkptr;
+ void* unkptr2;
+ void* unkptr3;
};
-class CEntityIdentities
-{
-public:
- CEntityIdentity m_pIdentities[MAX_ENTITIES_IN_LIST];
+class CEntityIdentities {
+ public:
+ CEntityIdentity m_pIdentities[MAX_ENTITIES_IN_LIST];
};
-class EntityIdentityList
-{
-public:
- CEntityIdentities* m_pIdentityList;
+class EntityIdentityList {
+ public:
+ CEntityIdentities* m_pIdentityList;
};
-class CGameEntitySystem
-{
-public:
- virtual void n_0();
- void* unk;
- CEntityIdentities* m_pEntityList[MAX_ENTITY_LISTS];
+class CGameEntitySystem {
+ public:
+ virtual void n_0();
+ void* unk;
+ CEntityIdentities* m_pEntityList[MAX_ENTITY_LISTS];
- CBaseEntity* GetBaseEntity(int index)
- {
- if (index <= -1 || index >= MAX_TOTAL_ENTITIES)
- return nullptr;
+ CBaseEntity* GetBaseEntity(int index) {
+ if (index <= -1 || index >= MAX_TOTAL_ENTITIES) return nullptr;
- int listToUse = (index / MAX_ENTITIES_IN_LIST);
- if (!m_pEntityList[listToUse])
- return nullptr;
+ int listToUse = (index / MAX_ENTITIES_IN_LIST);
+ if (!m_pEntityList[listToUse]) return nullptr;
- if (m_pEntityList[listToUse]->m_pIdentities[index % MAX_ENTITIES_IN_LIST].entity)
- return m_pEntityList[listToUse]->m_pIdentities[index % MAX_ENTITIES_IN_LIST].entity;
- else
- return nullptr;
- }
+ if (m_pEntityList[listToUse]
+ ->m_pIdentities[index % MAX_ENTITIES_IN_LIST]
+ .entity)
+ return m_pEntityList[listToUse]
+ ->m_pIdentities[index % MAX_ENTITIES_IN_LIST]
+ .entity;
+ else
+ return nullptr;
+ }
- static CGameEntitySystem* GetInstance();
+ static CGameEntitySystem* GetInstance();
};
-struct VPhysicsCollisionAttribute_t
-{
- DECLARE_CLASS(VPhysicsCollisionAttribute_t)
+struct VPhysicsCollisionAttribute_t {
+ DECLARE_CLASS(VPhysicsCollisionAttribute_t)
- SCHEMA_FIELD(uint8_t, m_nCollisionGroup)
+ SCHEMA_FIELD(uint8_t, m_nCollisionGroup)
};
-class CCollisionProperty
-{
-public:
- DECLARE_CLASS(CCollisionProperty)
+class CCollisionProperty {
+ public:
+ DECLARE_CLASS(CCollisionProperty)
- SCHEMA_FIELD(VPhysicsCollisionAttribute_t, m_collisionAttribute)
- //SCHEMA_FIELD(SolidType_t, m_nSolidType)
- SCHEMA_FIELD(uint8_t, m_usSolidFlags)
- SCHEMA_FIELD(uint8_t, m_CollisionGroup)
+ SCHEMA_FIELD(VPhysicsCollisionAttribute_t, m_collisionAttribute)
+ // SCHEMA_FIELD(SolidType_t, m_nSolidType)
+ SCHEMA_FIELD(uint8_t, m_usSolidFlags)
+ SCHEMA_FIELD(uint8_t, m_CollisionGroup)
};
-class CHandle
-{
- CBaseEntity* GetBaseEntity() const;
+class CHandle {
+ CBaseEntity* GetBaseEntity() const;
-public:
- bool operator==(CHandle rhs) const { return m_Index == rhs.m_Index; }
+ public:
+ bool operator==(CHandle rhs) const { return m_Index == rhs.m_Index; }
- bool IsValid() const { return m_Index != INVALID_EHANDLE_INDEX; }
+ bool IsValid() const { return m_Index != INVALID_EHANDLE_INDEX; }
- int GetEntryIndex() const { return m_Index & ENT_ENTRY_MASK; }
+ int GetEntryIndex() const { return m_Index & ENT_ENTRY_MASK; }
- template
- T* Get() const
- {
- return reinterpret_cast(GetBaseEntity());
- }
- uint32_t m_Index;
+ template
+ T* Get() const {
+ return reinterpret_cast(GetBaseEntity());
+ }
+ uint32_t m_Index;
};
class CEntityInstance {
-public:
+ public:
DECLARE_CLASS(CEntityInstance);
auto Schema_DynamicBinding() {
@@ -333,18 +307,19 @@ public:
};
class CBaseEntity : public CEntityInstance {
-public:
+ public:
DECLARE_CLASS(CBaseEntity);
SCHEMA_FIELD(int, m_iHealth)
+ SCHEMA_FIELD(int, m_iTeamNum)
// SCHEMA_FIELD(Vector, m_vecBaseVelocity)
SCHEMA_FIELD(CCollisionProperty*, m_pCollision)
- bool IsBasePlayerController();
+ auto IsBasePlayerController() -> bool;
+ auto SpawnClientEntity() -> void;
};
-
class CBasePlayerController : public CBaseEntity {
-public:
+ public:
DECLARE_CLASS(CBasePlayerController);
SCHEMA_FIELD(uint64_t, m_steamID)
@@ -354,7 +329,7 @@ public:
};
class CCSPlayerController : public CBasePlayerController {
-public:
+ public:
DECLARE_CLASS(CCSPlayerController)
SCHEMA_FIELD(uint32_t, m_iPawnHealth)
@@ -363,159 +338,157 @@ public:
};
class CEconItemDefinition {
-public:
- bool IsWeapon();
- bool IsKnife(bool excludeDefault);
- bool IsGlove(bool excludeDefault);
+ public:
+ bool IsWeapon();
+ bool IsKnife(bool excludeDefault);
+ bool IsGlove(bool excludeDefault);
- auto GetModelName() {
- return *reinterpret_cast((uintptr_t)(this) + 0xD8);
- }
+ auto GetModelName() {
+ return *reinterpret_cast((uintptr_t)(this) + 0xD8);
+ }
- auto GetStickersSupportedCount() {
- return *reinterpret_cast((uintptr_t)(this) + 0x100);
- }
+ auto GetStickersSupportedCount() {
+ return *reinterpret_cast((uintptr_t)(this) + 0x100);
+ }
- auto GetSimpleWeaponName() {
- return *reinterpret_cast((uintptr_t)(this) + 0x210);
- }
+ auto GetSimpleWeaponName() {
+ return *reinterpret_cast((uintptr_t)(this) + 0x210);
+ }
- auto GetLoadoutSlot() {
- return *reinterpret_cast((uintptr_t)(this) + 0x2E8);
- }
+ auto GetLoadoutSlot() {
+ return *reinterpret_cast((uintptr_t)(this) + 0x2E8);
+ }
- char pad0[0x8]; // vtable
- void* m_pKVItem;
- uint16_t m_nDefIndex;
- CUtlVector_NativeSdk m_nAssociatedItemsDefIndexes;
- bool m_bEnabled;
- const char* m_szPrefab;
- uint8_t m_unMinItemLevel;
- uint8_t m_unMaxItemLevel;
- uint8_t m_nItemRarity;
- uint8_t m_nItemQuality;
- uint8_t m_nForcedItemQuality;
- uint8_t m_nDefaultDropItemQuality;
- uint8_t m_nDefaultDropQuantity;
- CUtlVector_NativeSdk m_vecStaticAttributes;
- uint8_t m_nPopularitySeed;
- void* m_pPortraitsKV;
- const char* m_pszItemBaseName;
- bool m_bProperName;
- const char* m_pszItemTypeName;
- uint32_t m_unItemTypeID;
- const char* m_pszItemDesc;
+ char pad0[0x8]; // vtable
+ void* m_pKVItem;
+ uint16_t m_nDefIndex;
+ CUtlVector_NativeSdk m_nAssociatedItemsDefIndexes;
+ bool m_bEnabled;
+ const char* m_szPrefab;
+ uint8_t m_unMinItemLevel;
+ uint8_t m_unMaxItemLevel;
+ uint8_t m_nItemRarity;
+ uint8_t m_nItemQuality;
+ uint8_t m_nForcedItemQuality;
+ uint8_t m_nDefaultDropItemQuality;
+ uint8_t m_nDefaultDropQuantity;
+ CUtlVector_NativeSdk m_vecStaticAttributes;
+ uint8_t m_nPopularitySeed;
+ void* m_pPortraitsKV;
+ const char* m_pszItemBaseName;
+ bool m_bProperName;
+ const char* m_pszItemTypeName;
+ uint32_t m_unItemTypeID;
+ const char* m_pszItemDesc;
};
class CEconItemView {
-public:
- DECLARE_CLASS(CEconItemView);
- auto GetCustomPaintKitIndex() { return CALL_VIRTUAL(int, 2, this); }
- auto GetStaticData() {
- return CALL_VIRTUAL(CEconItemDefinition*, 13, this);
- }
+ public:
+ DECLARE_CLASS(CEconItemView);
+ auto GetCustomPaintKitIndex() { return CALL_VIRTUAL(int, 2, this); }
+ auto GetStaticData() {
+ return CALL_VIRTUAL(CEconItemDefinition*, 13, this);
+ }
};
-class CAttributeContainer
-{
-public:
- DECLARE_CLASS(CAttributeContainer);
+class CAttributeContainer {
+ public:
+ DECLARE_CLASS(CAttributeContainer);
- PSCHEMA_FIELD(CEconItemView, m_Item);
+ PSCHEMA_FIELD(CEconItemView, m_Item);
};
class CEconEntity {
-public:
- DECLARE_CLASS(CEconEntity);
+ public:
+ DECLARE_CLASS(CEconEntity);
- PSCHEMA_FIELD(CAttributeContainer, m_AttributeManager);
+ PSCHEMA_FIELD(CAttributeContainer, m_AttributeManager);
};
-class CBasePlayerWeapon : public CEconEntity
-{
-public:
- DECLARE_CLASS(CBasePlayerWeapon);
+class CBasePlayerWeapon : public CEconEntity {
+ public:
+ DECLARE_CLASS(CBasePlayerWeapon);
- SCHEMA_FIELD(int, m_iClip1);
- SCHEMA_FIELD(int, m_iClip2);
- SCHEMA_FIELD(int, m_pReserveAmmo);
+ SCHEMA_FIELD(int, m_iClip1);
+ SCHEMA_FIELD(int, m_iClip2);
+ SCHEMA_FIELD(int, m_pReserveAmmo);
};
class CPlayer_WeaponServices {
-public:
- DECLARE_CLASS(CPlayer_WeaponServices)
-
- SCHEMA_FIELD(CHandle, m_hActiveWeapon);
- SCHEMA_FIELD(uint16_t, m_iAmmo);
+ public:
+ DECLARE_CLASS(CPlayer_WeaponServices)
+ SCHEMA_FIELD(CHandle, m_hActiveWeapon);
+ SCHEMA_FIELD(uint16_t, m_iAmmo);
};
-
class CBasePlayer {
-public:
- auto ForceRespawn() -> void;
+ public:
+ auto ForceRespawn() -> void;
};
class CPlayer_MovementServices {
-public:
- DECLARE_CLASS(CPlayer_MovementServices);
+ public:
+ DECLARE_CLASS(CPlayer_MovementServices);
};
class CCSPlayerController_InGameMoneyServices {
-public:
- DECLARE_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);
+ public:
+ DECLARE_CLASS(CBasePlayerPawn);
- SCHEMA_FIELD(CPlayer_MovementServices*, m_pMovementServices)
- SCHEMA_FIELD(CPlayer_WeaponServices*, m_pWeaponServices)
- SCHEMA_FIELD(uint8_t**, m_pItemServices)
+ SCHEMA_FIELD(CPlayer_MovementServices*, m_pMovementServices)
+ SCHEMA_FIELD(CPlayer_WeaponServices*, m_pWeaponServices)
+ SCHEMA_FIELD(uint8_t**, m_pItemServices)
+ // m_hController
+ SCHEMA_FIELD(CBasePlayerController*, m_hController)
};
// Size: 0x1568
-class CCSPlayerPawnBase : public CBasePlayerPawn
-{
-public:
- DECLARE_CLASS(CCSPlayerPawnBase);
- SCHEMA_FIELD(bool, m_bRespawning)
- SCHEMA_FIELD(int, m_ArmorValue)
-
+class CCSPlayerPawnBase : public CBasePlayerPawn {
+ public:
+ DECLARE_CLASS(CCSPlayerPawnBase);
+ SCHEMA_FIELD(bool, m_bRespawning)
+ SCHEMA_FIELD(int, m_ArmorValue)
};
class CCSPlayerPawn : public CCSPlayerPawnBase {
-public:
- DECLARE_CLASS(CCSPlayerPawn);
- SCHEMA_FIELD(const char*, m_szLastPlaceName)
- auto GetPlayerController() -> CCSPlayerController*;
+ public:
+ DECLARE_CLASS(CCSPlayerPawn);
+ SCHEMA_FIELD(const char*, m_szLastPlaceName)
+ auto GetPlayerController() -> CCSPlayerController*;
};
class CGameEntitySystem;
-class CGameResourceService
-{
-public:
- CGameEntitySystem* GetGameEntitySystem()
- {
- return *reinterpret_cast((uintptr_t)(this) + 0x58);
- }
+class CGameResourceService {
+ public:
+ CGameEntitySystem* GetGameEntitySystem() {
+ return *reinterpret_cast((uintptr_t)(this) + 0x58);
+ }
};
class CLocalize {
-public:
- auto FindSafe(const char* tokenName) -> const char*;
+ public:
+ auto FindSafe(const char* tokenName) -> const char*;
};
-class Z_CBaseEntity : public CBaseEntity
-{
-public:
- DECLARE_CLASS(CBaseEntity)
+class Z_CBaseEntity : public CBaseEntity {
+ public:
+ DECLARE_CLASS(CBaseEntity)
- SCHEMA_FIELD(CBitVec<64>, m_isSteadyState)
- SCHEMA_FIELD(float, m_lastNetworkChange)
- PSCHEMA_FIELD(void*, m_NetworkTransmitComponent)
- SCHEMA_FIELD(int, m_iHealth)
- SCHEMA_FIELD(int, m_iTeamNum)
- SCHEMA_FIELD(Vector, m_vecBaseVelocity)
- SCHEMA_FIELD(CCollisionProperty*, m_pCollision)
+ SCHEMA_FIELD(CBitVec<64>, m_isSteadyState)
+ SCHEMA_FIELD(float, m_lastNetworkChange)
+ PSCHEMA_FIELD(void*, m_NetworkTransmitComponent)
+ SCHEMA_FIELD(int, m_iHealth)
+ SCHEMA_FIELD(int, m_iTeamNum)
+ SCHEMA_FIELD(Vector, m_vecBaseVelocity)
+ SCHEMA_FIELD(CCollisionProperty*, m_pCollision)
+};
+class CCSGameRules {
+ public:
+ DECLARE_CLASS(CCSGameRules)
+ SCHEMA_FIELD(bool, m_bForceTeamChangeSilent)
};
diff --git a/csgo2/offset.cpp b/csgo2/offset.cpp
index 4a8937d..b6d2b00 100644
--- a/csgo2/offset.cpp
+++ b/csgo2/offset.cpp
@@ -4,12 +4,15 @@ namespace Offset {
uint64_t GameResourceServicePtr;
uint64_t FireEventServerSidePtr;
uint64_t CGameEventManagerPtr;
+uint64_t CCSGameRulesInterFacePtr;
uint64_t Host_SayPtr;
uint64_t Module_tier0;
uint64_t MaxPlayerNumsPtr;
HashFunction_t FnServerHashFunction;
StateChanged_t FnStateChanged;
NetworkStateChanged_t FnNetworkStateChanged;
+//CreateGameRuleInterFace_t FnCreateCCSGameRulesInterFace;
+
namespace InterFaces {
CSchemaSystem* SchemaSystem;
IGameEventManager2* GameEventManager;
@@ -20,7 +23,9 @@ IVEngineServer2* IVEngineServer;
ISource2Server* ISource2ServerInterFace;
CLocalize* ILocalize;
INetworkServerService* INetworkServerServiceInteFace;
+CCSGameRules* CCSGameRulesInterFace;
}; // namespace InterFaces
+
auto Init() -> bool {
CModule server("server.dll");
CModule schemasystem("schemasystem.dll");
@@ -28,43 +33,55 @@ auto Init() -> bool {
CModule localize("localize.dll");
// engine.dll
- engine.FindPattern(pattern_MaxPlayerNumsPtr).ToAbsolute(3, 0).Get(MaxPlayerNumsPtr);
+ engine.FindPattern(pattern_MaxPlayerNumsPtr)
+ .ToAbsolute(3, 0)
+ .Get(MaxPlayerNumsPtr);
// server.dll
server.FindPattern(pattern_FireEventServerSide).Get(FireEventServerSidePtr);
server.FindPattern(pattern_NetworkStateChanged).Get(FnNetworkStateChanged);
server.FindPattern(pattern_FnStateChangedPtr).Get(FnStateChanged);
- // 48 8D 05 4A 30 82 00 lea rax, ??_7CGameEventManager@@6B@
server.FindPattern(pattern_CGameEventManager)
.ToAbsolute(3, 0)
.Get(CGameEventManagerPtr);
+ server.FindPattern(pattern_CreateCCSGameRulesInterFacePtr)
+ .ToAbsolute(10, 0)
+ .Get(CCSGameRulesInterFacePtr);
+
server.FindPattern(pattern_fnHost_SayPtr).Get(Host_SayPtr);
server.FindPattern(pattern_ServerHashFunctionPtr).Get(FnServerHashFunction);
InterFaces::SchemaSystem = reinterpret_cast(
schemasystem.FindInterface("SchemaSystem_001").Get());
- //InterFaces::GameEventManager = reinterpret_cast(
- // engine.FindInterface("GameEventSystemServerV001").Get());
- InterFaces::ILocalize = reinterpret_cast(localize.FindInterface("Localize_001").Get());
+ // InterFaces::GameEventManager = reinterpret_cast(
+ // engine.FindInterface("GameEventSystemServerV001").Get());
+ InterFaces::ILocalize = reinterpret_cast(
+ localize.FindInterface("Localize_001").Get());
InterFaces::GameResourceServiceServer =
reinterpret_cast(
engine.FindInterface("GameResourceServiceServerV001").Get());
InterFaces::IVEngineServer = reinterpret_cast(
engine.FindInterface("Source2EngineToServer001").Get());
- InterFaces::INetworkServerServiceInteFace = reinterpret_cast(
- engine.FindInterface("NetworkServerService_001").Get());
+ InterFaces::INetworkServerServiceInteFace =
+ reinterpret_cast(
+ engine.FindInterface("NetworkServerService_001").Get());
InterFaces::IServerGameClient = reinterpret_cast(
server.FindInterface("Source2GameClients001").Get());
InterFaces::ISource2ServerInterFace = reinterpret_cast(
server.FindInterface("Source2Server001").Get());
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 =
reinterpret_cast(CGameEventManagerPtr);
-
- //global::MaxPlayers = *(int*)((char*)MaxPlayerNumsPtr + 2);
- // client.FindPattern(pattern_FireEventServerSide).Get(FireEventServerSidePtr);
+ InterFaces::CCSGameRulesInterFace =
+ reinterpret_cast(CCSGameRulesInterFacePtr + (8 * 2));
+ // global::MaxPlayers = *(int*)((char*)MaxPlayerNumsPtr + 2);
+ // client.FindPattern(pattern_FireEventServerSide).Get(FireEventServerSidePtr);
global::MaxPlayers = 64;
LOG("[huoji]FireEventServerSidePtr : %llx \n", FireEventServerSidePtr);
@@ -87,14 +104,17 @@ auto Init() -> bool {
InterFaces::IVEngineServer);
LOG("[huoji]InterFaces::ISource2ServerInterFace : %llx \n",
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("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 &&
InterFaces::GameResourceServiceServer &&
InterFaces::IServerGameClient && InterFaces::GameEventManager &&
- InterFaces::SchemaSystem && FireEventServerSidePtr &&
- FnNetworkStateChanged;
+ InterFaces::SchemaSystem && FireEventServerSidePtr && FnNetworkStateChanged;
}
} // namespace Offset
diff --git a/csgo2/offset.h b/csgo2/offset.h
index 17e9dc5..f50f325 100644
--- a/csgo2/offset.h
+++ b/csgo2/offset.h
@@ -2,27 +2,38 @@
#include "head.h"
#define SERVER_HASH_FUCNTION_KEY 0x31415926
class CEntityInstance;
-typedef uint64_t(__fastcall* HashFunction_t)(const char*, unsigned int, unsigned int);
-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 uint64_t(__fastcall* HashFunction_t)(const char*, unsigned int,
+ unsigned int);
+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 CGameResourceService;
class CLocalize;
+class CCSGameRules;
namespace Offset {
namespace InterFaces {
- extern CSchemaSystem* SchemaSystem;
- extern IGameEventManager2* GameEventManager;
- extern CGameEventManager* CGameEventManger;
- extern CGameResourceService* GameResourceServiceServer;
- extern IServerGameClients* IServerGameClient;
- extern IVEngineServer2* IVEngineServer;
- extern CLocalize* ILocalize;
- extern INetworkServerService* INetworkServerServiceInteFace;
-};
-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");
+extern CSchemaSystem* SchemaSystem;
+extern IGameEventManager2* GameEventManager;
+extern CGameEventManager* CGameEventManger;
+extern CGameResourceService* GameResourceServiceServer;
+extern IServerGameClients* IServerGameClient;
+extern IVEngineServer2* IVEngineServer;
+extern CLocalize* ILocalize;
+extern INetworkServerService* INetworkServerServiceInteFace;
+extern ISource2Server* ISource2ServerInterFace;
+extern CCSGameRules* CCSGameRulesInterFace;
+}; // namespace InterFaces
+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(
"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 "
@@ -37,10 +48,16 @@ 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_ServerHashFunctionPtr =
- 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");
-static const auto pattern_MaxPlayerNumsPtr =
+static const auto pattern_ServerHashFunctionPtr = 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");
+static const auto pattern_MaxPlayerNumsPtr =
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 FireEventServerSidePtr;
extern uint64_t Module_tier0;
@@ -50,6 +67,5 @@ extern HashFunction_t FnServerHashFunction;
extern StateChanged_t FnStateChanged;
extern NetworkStateChanged_t FnNetworkStateChanged;
-
auto Init() -> bool;
}; // namespace Offset
diff --git a/csgo2/script_apis.cpp b/csgo2/script_apis.cpp
index 1ed7841..f1bac3f 100644
--- a/csgo2/script_apis.cpp
+++ b/csgo2/script_apis.cpp
@@ -12,6 +12,16 @@ struct _luaApi_WeaponInfo {
int weaponType;
};
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);
+ }
+}
// Ƿֵ,ֵҪԼpushstack
auto luaApi_ListenToGameEvent(lua_State* luaVm) -> int {
const auto eventName = lua_tostring(luaVm, 1);
@@ -99,6 +109,7 @@ auto luaApi_RespawnPlayer(lua_State* luaVm) -> int {
}
auto playerController = reinterpret_cast(player);
auto playerPawn = playerController->m_hPawn().Get();
+
playerPawn->m_bRespawning(false);
} while (false);
lua_pop(luaVm, 1);
@@ -256,9 +267,128 @@ auto luaApi_GetPlayerCurrentWeaponInfo(lua_State* luaVm) -> _luaApi_WeaponInfo {
: (itemStaticData->IsWeapon() ? _luaApi_WeaponType::kGun
: _luaApi_WeaponType::kOther));
} while (false);
-
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(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(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(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 {
lua_register(luaVm, "ListenToGameEvent", luaApi_ListenToGameEvent);
lua_register(luaVm, "luaApi_SetPlayerCurrentWeaponAmmo",
@@ -270,7 +400,12 @@ auto initFunciton(lua_State* luaVm) -> void {
lua_register(luaVm, "luaApi_SetPlayerArmorValue",
luaApi_SetPlayerArmorValue);
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);
// Ҳϲ
luabridge::getGlobalNamespace(luaVm)
.beginClass<_luaApi_WeaponInfo>("WeaponInfo")
diff --git a/csgo2/script_callbacks.cpp b/csgo2/script_callbacks.cpp
index 72864c6..f923877 100644
--- a/csgo2/script_callbacks.cpp
+++ b/csgo2/script_callbacks.cpp
@@ -8,7 +8,9 @@ std::unordered_map callbackNameWithEnumMap{
{hash_32_fnv1a_const("player_connect"), _CallbackNames::kOnPlayerConnect},
{hash_32_fnv1a_const("player_disconnect"),
_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 {
if (name == nullptr) {
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
diff --git a/csgo2/script_callbacks.h b/csgo2/script_callbacks.h
index d5f4d22..180e374 100644
--- a/csgo2/script_callbacks.h
+++ b/csgo2/script_callbacks.h
@@ -6,7 +6,8 @@ enum class _CallbackNames {
kError,
kOnPlayerConnect,
kOnPlayerDisconnect,
- kOnPlayerDeath
+ kOnPlayerDeath,
+ kOnPlayerSpeak
};
extern std::unordered_map>
callbackList;
@@ -19,4 +20,6 @@ auto luaCall_onPlayerDisconnect(int player, int slot, const char* pszName,
const char* pszAddress, bool bFakePlayer)
-> void;
auto luaCall_onPlayerDeath(int victim, int killer, bool isHeadShot) -> void;
+auto luaCall_onPlayerSpeak(int speaker, int chatType, std::string message)
+ -> bool;
} // namespace ScriptCallBacks
diff --git a/csgo2/sdk/public/eiface.h b/csgo2/sdk/public/eiface.h
index a5dd3d3..0296e55 100644
--- a/csgo2/sdk/public/eiface.h
+++ b/csgo2/sdk/public/eiface.h
@@ -193,6 +193,7 @@ public:
class ISource2Server : public IAppSystem
{
public:
+ //vmt index 11
virtual bool Unknown0() const = 0;
virtual void SetGlobals(CGlobalVars* pGlobals) = 0;
@@ -213,6 +214,7 @@ public:
// The server should run physics/think on all edicts
// One of these bools is 'simulating'... probably
+ // index 19
virtual void GameFrame(bool simulating, bool bFirstTick, bool bLastTick) = 0;
// Returns true if the game DLL wants the server not to be made public.
diff --git a/csgo2/sdk/public/iserver.h b/csgo2/sdk/public/iserver.h
index f64bdeb..ba6e4d1 100644
--- a/csgo2/sdk/public/iserver.h
+++ b/csgo2/sdk/public/iserver.h
@@ -91,6 +91,7 @@ public:
class IEngineService : public IAppSystem
{
public:
+ //vmt index 11
virtual void* GetServiceDependencies(void) = 0;
virtual const char* GetName(void) const = 0;
virtual bool ShouldActivate(const char*) = 0;
@@ -107,10 +108,12 @@ public:
class INetworkServerService : public IEngineService
{
public:
+ //vmt index 22
virtual ~INetworkServerService() {}
virtual INetworkGameServer * GetIGameServer(void) = 0;
virtual bool IsActiveInGame(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 SetGameSpawnGroupMgr(IGameSpawnGroupMgr* pMgr) = 0;
virtual void AddServerPrerequisites(const GameSessionConfiguration_t&, const char*, void*, bool) = 0;
diff --git a/csgo2/timer.cpp b/csgo2/timer.cpp
new file mode 100644
index 0000000..7bc0d9f
--- /dev/null
+++ b/csgo2/timer.cpp
@@ -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 lock(mutex_timerList);
+ timerList.push_back(timer);
+ return timerList.size() - 1;
+};
+auto CleanUpTimers() -> void {
+ std::unique_lock 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 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
diff --git a/csgo2/timer.h b/csgo2/timer.h
new file mode 100644
index 0000000..a5b79e6
--- /dev/null
+++ b/csgo2/timer.h
@@ -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
diff --git a/csgo2/vmthook.cpp b/csgo2/vmthook.cpp
index f233ccb..4fe104e 100644
--- a/csgo2/vmthook.cpp
+++ b/csgo2/vmthook.cpp
@@ -9,13 +9,13 @@ void* VMTHook::Hook(int index, void* hk)
{
// Store the index and original function address
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
DWORD old;
VirtualProtect(&vmt[index], sizeof(void*), PAGE_EXECUTE_READWRITE, &old);
vmt[index] = hk;
VirtualProtect(&vmt[index], sizeof(void*), old, NULL);
-
return hooked_funcs[index];
}