11
This commit is contained in:
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
@@ -87,6 +87,7 @@
|
||||
"*.rh": "cpp",
|
||||
"random": "cpp",
|
||||
"hash_map": "cpp",
|
||||
"hash_set": "cpp"
|
||||
"hash_set": "cpp",
|
||||
"filesystem": "cpp"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -230,6 +230,7 @@
|
||||
<ClInclude Include="sdk\tier1\UtlVector.hpp" />
|
||||
<ClInclude Include="sdk_tools.h" />
|
||||
<ClInclude Include="stb.hh" />
|
||||
<ClInclude Include="timer.h" />
|
||||
<ClInclude Include="tools.h" />
|
||||
<ClInclude Include="vector.h" />
|
||||
<ClInclude Include="vmt.h" />
|
||||
@@ -297,6 +298,7 @@
|
||||
<ClCompile Include="sdk\convar\convar.cpp" />
|
||||
<ClCompile Include="sdk\tier1\UtlString.cpp" />
|
||||
<ClCompile Include="sdk_tools.cpp" />
|
||||
<ClCompile Include="timer.cpp" />
|
||||
<ClCompile Include="tools.cpp" />
|
||||
<ClCompile Include="vmthook.cpp" />
|
||||
</ItemGroup>
|
||||
|
||||
@@ -76,6 +76,12 @@
|
||||
<Filter Include="头文件\lua">
|
||||
<UniqueIdentifier>{d58fcaf6-b1d7-484d-9ec4-d6b67ff46cf5}</UniqueIdentifier>
|
||||
</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>
|
||||
<ClInclude Include="framework.h">
|
||||
@@ -318,6 +324,9 @@
|
||||
<ClInclude Include="vector.h">
|
||||
<Filter>头文件\native_sdk</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="timer.h">
|
||||
<Filter>头文件\game_time_system</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="dllmain.cpp">
|
||||
@@ -491,6 +500,9 @@
|
||||
<ClCompile Include="script_callbacks.cpp">
|
||||
<Filter>源文件\script_engine</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="timer.cpp">
|
||||
<Filter>源文件\game_time_system</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="cpp.hint" />
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -2,4 +2,9 @@
|
||||
namespace global {
|
||||
bool Exit;
|
||||
int MaxPlayers;
|
||||
CGameEntitySystem* EntitySystem;
|
||||
bool HasTicked;
|
||||
CGlobalVars* GlobalVars;
|
||||
float m_flUniversalTime;
|
||||
float m_flLastTickedTime;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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"
|
||||
|
||||
@@ -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<void*>(
|
||||
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>(
|
||||
VMT_IServerGameClient->Hook(11, hook_OnClientConnected));
|
||||
original_OnClientDisconnect = reinterpret_cast<OnClientDisconnect_t>(
|
||||
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 {
|
||||
bool isSuccess = initMinHook() && initVmtHook();
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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<CCSPlayerController*>(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<uint32_t, SchemaKey>;
|
||||
using SchemaTableMap_t = CUtlMap<uint32_t, SchemaKeyValueMap_t*>;
|
||||
|
||||
|
||||
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);
|
||||
};
|
||||
|
||||
@@ -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<type> 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<std::add_pointer_t<type>>( \
|
||||
(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<std::add_pointer_t<type>>((uintptr_t)(this) + m_key.offset + extra_offset) = val; \
|
||||
}
|
||||
#define SCHEMA_FIELD_OFFSET(type, varName, extra_offset) \
|
||||
std::add_lvalue_reference_t<type> 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<std::add_pointer_t<type>>( \
|
||||
(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<std::add_pointer_t<type>>( \
|
||||
(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<std::add_pointer_t<type>>( \
|
||||
(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<std::add_pointer_t<type>>( \
|
||||
(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 <typename T>
|
||||
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 <typename T = CBaseEntity>
|
||||
T* Get() const
|
||||
{
|
||||
return reinterpret_cast<T*>(GetBaseEntity());
|
||||
}
|
||||
uint32_t m_Index;
|
||||
template <typename T = CBaseEntity>
|
||||
T* Get() const {
|
||||
return reinterpret_cast<T*>(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<const char**>((uintptr_t)(this) + 0xD8);
|
||||
}
|
||||
auto GetModelName() {
|
||||
return *reinterpret_cast<const char**>((uintptr_t)(this) + 0xD8);
|
||||
}
|
||||
|
||||
auto GetStickersSupportedCount() {
|
||||
return *reinterpret_cast<int*>((uintptr_t)(this) + 0x100);
|
||||
}
|
||||
auto GetStickersSupportedCount() {
|
||||
return *reinterpret_cast<int*>((uintptr_t)(this) + 0x100);
|
||||
}
|
||||
|
||||
auto GetSimpleWeaponName() {
|
||||
return *reinterpret_cast<const char**>((uintptr_t)(this) + 0x210);
|
||||
}
|
||||
auto GetSimpleWeaponName() {
|
||||
return *reinterpret_cast<const char**>((uintptr_t)(this) + 0x210);
|
||||
}
|
||||
|
||||
auto GetLoadoutSlot() {
|
||||
return *reinterpret_cast<int*>((uintptr_t)(this) + 0x2E8);
|
||||
}
|
||||
auto GetLoadoutSlot() {
|
||||
return *reinterpret_cast<int*>((uintptr_t)(this) + 0x2E8);
|
||||
}
|
||||
|
||||
char pad0[0x8]; // vtable
|
||||
void* m_pKVItem;
|
||||
uint16_t m_nDefIndex;
|
||||
CUtlVector_NativeSdk<uint16_t> 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<void*> 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<uint16_t> 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<void*> 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<CGameEntitySystem**>((uintptr_t)(this) + 0x58);
|
||||
}
|
||||
class CGameResourceService {
|
||||
public:
|
||||
CGameEntitySystem* GetGameEntitySystem() {
|
||||
return *reinterpret_cast<CGameEntitySystem**>((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)
|
||||
};
|
||||
|
||||
@@ -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<CSchemaSystem*>(
|
||||
schemasystem.FindInterface("SchemaSystem_001").Get());
|
||||
//InterFaces::GameEventManager = reinterpret_cast<IGameEventManager2*>(
|
||||
// engine.FindInterface("GameEventSystemServerV001").Get());
|
||||
InterFaces::ILocalize = reinterpret_cast<CLocalize*>(localize.FindInterface("Localize_001").Get());
|
||||
// InterFaces::GameEventManager = reinterpret_cast<IGameEventManager2*>(
|
||||
// engine.FindInterface("GameEventSystemServerV001").Get());
|
||||
InterFaces::ILocalize = reinterpret_cast<CLocalize*>(
|
||||
localize.FindInterface("Localize_001").Get());
|
||||
InterFaces::GameResourceServiceServer =
|
||||
reinterpret_cast<CGameResourceService*>(
|
||||
engine.FindInterface("GameResourceServiceServerV001").Get());
|
||||
InterFaces::IVEngineServer = reinterpret_cast<IVEngineServer2*>(
|
||||
engine.FindInterface("Source2EngineToServer001").Get());
|
||||
InterFaces::INetworkServerServiceInteFace = reinterpret_cast<INetworkServerService*>(
|
||||
engine.FindInterface("NetworkServerService_001").Get());
|
||||
InterFaces::INetworkServerServiceInteFace =
|
||||
reinterpret_cast<INetworkServerService*>(
|
||||
engine.FindInterface("NetworkServerService_001").Get());
|
||||
InterFaces::IServerGameClient = reinterpret_cast<IServerGameClients*>(
|
||||
server.FindInterface("Source2GameClients001").Get());
|
||||
InterFaces::ISource2ServerInterFace = reinterpret_cast<ISource2Server*>(
|
||||
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<CGameEventManager*>(CGameEventManagerPtr);
|
||||
|
||||
//global::MaxPlayers = *(int*)((char*)MaxPlayerNumsPtr + 2);
|
||||
// client.FindPattern(pattern_FireEventServerSide).Get(FireEventServerSidePtr);
|
||||
InterFaces::CCSGameRulesInterFace =
|
||||
reinterpret_cast<CCSGameRules*>(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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
// <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 {
|
||||
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 playerPawn = playerController->m_hPawn().Get<CCSPlayerPawn>();
|
||||
|
||||
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<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 {
|
||||
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);
|
||||
// <20>Ҳ<EFBFBD>ϲ<EFBFBD><CFB2><EFBFBD><EFBFBD>
|
||||
luabridge::getGlobalNamespace(luaVm)
|
||||
.beginClass<_luaApi_WeaponInfo>("WeaponInfo")
|
||||
|
||||
@@ -8,7 +8,9 @@ std::unordered_map<uint32_t, _CallbackNames> 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
|
||||
|
||||
@@ -6,7 +6,8 @@ enum class _CallbackNames {
|
||||
kError,
|
||||
kOnPlayerConnect,
|
||||
kOnPlayerDisconnect,
|
||||
kOnPlayerDeath
|
||||
kOnPlayerDeath,
|
||||
kOnPlayerSpeak
|
||||
};
|
||||
extern std::unordered_map<lua_State*, std::unordered_map<_CallbackNames, int>>
|
||||
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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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;
|
||||
|
||||
43
csgo2/timer.cpp
Normal file
43
csgo2/timer.cpp
Normal 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
18
csgo2/timer.h
Normal 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
|
||||
@@ -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];
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user