From bf31cd7e62876526975fdc3c851e06477e820f69 Mon Sep 17 00:00:00 2001 From: Vauff Date: Sat, 10 Oct 2026 01:53:25 -0400 Subject: [PATCH 1/7] Fix/replace game_player_equip TriggerFor input hooks We were hooking the wrong function post 2026-09-22 CS2 update, but we don't need to rely on signatures anyways Co-authored-by: tilgep --- gamedata/cs2fixes.jsonc | 12 ------------ src/cs2_sdk/entity/cbaseentity.h | 9 +++++++++ src/detours.cpp | 23 ++++++++--------------- src/detours.h | 4 ---- src/entities.cpp | 11 +++++------ src/entities.h | 7 +++++-- 6 files changed, 27 insertions(+), 39 deletions(-) diff --git a/gamedata/cs2fixes.jsonc b/gamedata/cs2fixes.jsonc index 508ccd73..5eb164ae 100644 --- a/gamedata/cs2fixes.jsonc +++ b/gamedata/cs2fixes.jsonc @@ -229,18 +229,6 @@ "windows": "48 8B C4 44 88 48 20 44 89 40 18 48 89 50 10 53", "linux": "55 48 89 E5 41 57 41 56 41 55 41 54 53 48 89 FB 48 83 EC ? 89 4D" }, - "CGamePlayerEquip_InputTriggerForAllPlayers": - { - "library": "server", - "windows": "48 89 5C 24 ? 48 89 74 24 ? 55 57 41 54 41 56 41 57 48 8B EC 48 83 EC ? 4C 8B F1", - "linux": "55 48 89 E5 41 57 41 56 41 55 41 54 49 89 FC 53 48 83 EC ? E8 ? ? ? ? C7 45 ? ? ? ? ? 89 C7 66 89 45 ? 66 83 F8 ? 75 ? 48 C7 45 ? ? ? ? ? 66 83 FF ? 0F 84 ? ? ? ? 0F B7 7D ? E8 ? ? ? ? 66 89 45 ? 66 83 F8 ? 0F 84 ? ? ? ? 89 C7 E8 ? ? ? ? 0F B7 7D ? 48 89 C3 48 85 C0 74 ? 48 89 C7 E8 ? ? ? ? 48 8D 7D ? 48 89 C6 E8 ? ? ? ? 0F B7 7D ? 84 C0 0F 85 ? ? ? ? EB ? 66 0F 1F 44 00 ? E8 ? ? ? ? 48 89 C3 48 85 C0 0F 84 ? ? ? ? 48 89 C7 E8 ? ? ? ? 48 8D 7D ? 48 89 C6 E8 ? ? ? ? 84 C0 0F 84 ? ? ? ? 0F B7 7D ? 48 89 5D ? 66 83 FF" - }, - "CGamePlayerEquip_InputTriggerForActivatedPlayer": - { - "library": "server", - "windows": "48 89 5C 24 ? 56 48 83 EC ? 48 8B 1A", - "linux": "55 48 89 E5 41 56 41 55 41 54 53 48 8B 1E 48 85 DB 74" - }, // Return value of this function is used to determine whether "NETWORK_DISCONNECT_REJECT_SERVERFULL to %s: Cannot get free client\n" gets printed "GetFreeClient": { diff --git a/src/cs2_sdk/entity/cbaseentity.h b/src/cs2_sdk/entity/cbaseentity.h index f4685cfd..765bd168 100644 --- a/src/cs2_sdk/entity/cbaseentity.h +++ b/src/cs2_sdk/entity/cbaseentity.h @@ -34,6 +34,7 @@ class CGameUI; class CEnvHudHint; class CPointViewControl; class CBasePlayerWeapon; +class CGamePlayerEquip; class CGameSceneNode { @@ -331,6 +332,14 @@ class CBaseEntity : public CEntityInstance return nullptr; } + [[nodiscard]] CGamePlayerEquip* AsGamePlayerEquip() + { + if (V_strcasecmp(GetClassname(), "game_player_equip") == 0) + return reinterpret_cast(this); + + return nullptr; + } + /* End Custom Entities Cast */ }; diff --git a/src/detours.cpp b/src/detours.cpp index d57120c9..32410ab6 100644 --- a/src/detours.cpp +++ b/src/detours.cpp @@ -37,6 +37,7 @@ #include "entity/ccsplayerpawn.h" #include "entity/ccsweaponbase.h" #include "entity/cenvhudhint.h" +#include "entity/cgameplayerequip.h" #include "entity/cgamerules.h" #include "entity/cpointviewcontrol.h" #include "entity/ctakedamageinfo.h" @@ -69,8 +70,6 @@ KHOOK_MEMBER(CEntityIdentity_AcceptInput, Detour_CEntityIdentity_AcceptInput, nu KHOOK_MEMBER(CNavMesh_GetNearestNavArea, Detour_CNavMesh_GetNearestNavArea, nullptr); KHOOK_MEMBER(ProcessMovement, Detour_ProcessMovement, Detour_ProcessMovement_Post); KHOOK_MEMBER(ProcessUsercmds, Detour_ProcessUsercmds, nullptr); -KHOOK_MEMBER(CGamePlayerEquip_InputTriggerForAllPlayers, Detour_CGamePlayerEquip_InputTriggerForAllPlayers, nullptr); -KHOOK_MEMBER(CGamePlayerEquip_InputTriggerForActivatedPlayer, Detour_CGamePlayerEquip_InputTriggerForActivatedPlayer, nullptr); KHOOK_MEMBER(CTriggerGravity_GravityTouch, Detour_CTriggerGravity_GravityTouch, nullptr); KHOOK_FUNCTION(GetFreeClient, Detour_GetFreeClient, nullptr); #ifdef __linux__ @@ -532,6 +531,13 @@ KHook::Return Detour_CEntityIdentity_AcceptInput(CEntityIdentity* pThis, C if (!V_strcasecmp(pInputName->String(), "DisableCameraAll")) return {KHook::Action::Supersede, CPointViewControlHandler::OnDisableAll(pViewControl)}; } + else if (const auto pGamePlayerEquip = reinterpret_cast(pThis->m_pInstance)->AsGamePlayerEquip()) + { + if (!V_strcasecmp(pInputName->String(), "TriggerForActivatedPlayer") && !CGamePlayerEquipHandler::TriggerForActivatedPlayer(pGamePlayerEquip, reinterpret_cast(pActivator), value)) + return {KHook::Action::Supersede, true}; + if (!V_strcasecmp(pInputName->String(), "TriggerForAllPlayers")) + CGamePlayerEquipHandler::TriggerForAllPlayers(pGamePlayerEquip); + } if (g_pMapMigrations->Detour_CEntityIdentity_AcceptInput(pThis, pInputName, pActivator, pCaller, value)) return {KHook::Action::Supersede, true}; @@ -661,19 +667,6 @@ KHook::Return Detour_ProcessUsercmds(CCSPlayerController* pController, CU return {KHook::Action::Ignore}; } -KHook::Return Detour_CGamePlayerEquip_InputTriggerForAllPlayers(CGamePlayerEquip* pEntity, InputData_t* pInput) -{ - CGamePlayerEquipHandler::TriggerForAllPlayers(pEntity, pInput); - return {KHook::Action::Ignore}; -} -KHook::Return Detour_CGamePlayerEquip_InputTriggerForActivatedPlayer(CGamePlayerEquip* pEntity, InputData_t* pInput) -{ - if (CGamePlayerEquipHandler::TriggerForActivatedPlayer(pEntity, pInput)) - return {KHook::Action::Ignore}; - - return {KHook::Action::Supersede}; -} - KHook::Return Detour_CTriggerGravity_GravityTouch(CTriggerGravity* pEntity, CBaseEntity* pOther) { // no need to call original function here diff --git a/src/detours.h b/src/detours.h index 73f3d27c..9a1d22e4 100644 --- a/src/detours.h +++ b/src/detours.h @@ -45,8 +45,6 @@ class CServerSideClient; class INetChannel; class CBasePlayerPawn; class CUserCmd; -class CGamePlayerEquip; -class InputData_t; class CCSPlayerPawn; class CCSPlayer_UseServices; class CTraceFilter; @@ -92,8 +90,6 @@ KHook::Return Detour_CNavMesh_GetNearestNavArea(CNavMesh* pNavMesh, float KHook::Return Detour_ProcessMovement(CCSPlayer_MovementServices* pThis, void* pMove); KHook::Return Detour_ProcessMovement_Post(CCSPlayer_MovementServices* pThis, void* pMove); KHook::Return Detour_ProcessUsercmds(CCSPlayerController* pController, CUserCmd* cmds, int numcmds, bool paused, float margin); -KHook::Return Detour_CGamePlayerEquip_InputTriggerForAllPlayers(CGamePlayerEquip*, InputData_t*); -KHook::Return Detour_CGamePlayerEquip_InputTriggerForActivatedPlayer(CGamePlayerEquip*, InputData_t*); KHook::Return Detour_CTriggerGravity_GravityTouch(CTriggerGravity* pEntity, CBaseEntity* pOther); KHook::Return Detour_GetFreeClient(int64_t unk1, const __m128i* unk2, unsigned int unk3, int64_t unk4, char unk5, void* unk6); KHook::Return Detour_CCSPlayerPawn_GetMaxSpeed(CCSPlayerPawn*); diff --git a/src/entities.cpp b/src/entities.cpp index 29c67b87..3770f604 100644 --- a/src/entities.cpp +++ b/src/entities.cpp @@ -190,7 +190,7 @@ namespace CGamePlayerEquipHandler } } - void TriggerForAllPlayers(CGamePlayerEquip* pEntity, InputData_t* pInput) + void TriggerForAllPlayers(CGamePlayerEquip* pEntity) { const auto flags = pEntity->m_spawnflags(); @@ -214,15 +214,14 @@ namespace CGamePlayerEquipHandler } } - bool TriggerForActivatedPlayer(CGamePlayerEquip* pEntity, InputData_t* pInput) + bool TriggerForActivatedPlayer(CGamePlayerEquip* pEntity, CBaseEntity* pActivator, variant_t* value) { - const auto pCaller = pInput->pActivator; - const auto pszWeapon = ((pInput->value.m_type == FIELD_CSTRING || pInput->value.m_type == FIELD_STRING) && pInput->value.m_pszString) ? pInput->value.m_pszString : nullptr; + const auto pszWeapon = ((value->m_type == FIELD_CSTRING || value->m_type == FIELD_STRING) && value->m_pszString) ? value->m_pszString : nullptr; - if (!pCaller || !pCaller->IsPawn()) + if (!pActivator || !pActivator->IsPawn()) return true; - const auto pPawn = reinterpret_cast(pCaller); + const auto pPawn = reinterpret_cast(pActivator); const auto flags = pEntity->m_spawnflags(); if (flags & CGamePlayerEquip::SF_PLAYEREQUIP_STRIPFIRST) diff --git a/src/entities.h b/src/entities.h index a32771e9..d18b4f6a 100644 --- a/src/entities.h +++ b/src/entities.h @@ -19,6 +19,9 @@ #pragma once +#include +#include "variant.h" + class InputData_t; class CGamePlayerEquip; class CBaseEntity; @@ -38,8 +41,8 @@ namespace CTriggerGravityHandler namespace CGamePlayerEquipHandler { void Use(CGamePlayerEquip* pEntity, InputData_t* pInput); - void TriggerForAllPlayers(CGamePlayerEquip* pEntity, InputData_t* pInput); - bool TriggerForActivatedPlayer(CGamePlayerEquip* pEntity, InputData_t* pInput); + void TriggerForAllPlayers(CGamePlayerEquip* pEntity); + bool TriggerForActivatedPlayer(CGamePlayerEquip* pEntity, CBaseEntity* pActivator, variant_t* value); void OnPrecache(CGamePlayerEquip* pEntity, const CEntityKeyValues* kv); } // namespace CGamePlayerEquipHandler From 8f6d29ca2217a5f9d73a5d1a175113774fe96a6e Mon Sep 17 00:00:00 2001 From: Vauff Date: Sat, 10 Oct 2026 19:59:29 -0400 Subject: [PATCH 2/7] Remove default hud disconnect callback Game now automatically cleans up player states on player connect (which is close enough) --- src/commands.cpp | 1 - src/cs2_sdk/entity/customhudlayout.cpp | 12 +++--------- src/cs2_sdk/entity/customhudlayout.h | 1 - 3 files changed, 3 insertions(+), 11 deletions(-) diff --git a/src/commands.cpp b/src/commands.cpp index 36ffad41..6210eb35 100644 --- a/src/commands.cpp +++ b/src/commands.cpp @@ -1219,7 +1219,6 @@ CON_COMMAND_CHAT(uitest, " () - Spawn UI panel") hLayout->SetDialogVariableString("MyLabel", "CustomText", args[2], player); hLayout->SetDisconnectCallback([](CCSCustomHudLayout* pHud, int slot) { - CCSCustomHudLayout::DefaultOnDisconnect(pHud, slot); Message("Custom disconnect callback called\n"); }); diff --git a/src/cs2_sdk/entity/customhudlayout.cpp b/src/cs2_sdk/entity/customhudlayout.cpp index 72f25a87..79991709 100644 --- a/src/cs2_sdk/entity/customhudlayout.cpp +++ b/src/cs2_sdk/entity/customhudlayout.cpp @@ -37,7 +37,6 @@ CCSCustomHudLayout* CCSCustomHudLayout::Create(std::string sLayout, std::string pKeyValues->SetString("targetname", sTargetName.c_str()); pLayout->DispatchSpawn(pKeyValues); - pLayout->SetDisconnectCallback(&DefaultOnDisconnect); return pLayout; } @@ -67,18 +66,13 @@ void CCSCustomHudLayout::OnClientDisconnect(int slot) continue; } - iterator->second.m_OnDisconnect(pLayout, slot); + if (iterator->second.m_OnDisconnect) + iterator->second.m_OnDisconnect(pLayout, slot); + iterator++; } } -void CCSCustomHudLayout::DefaultOnDisconnect(CCSCustomHudLayout* pLayout, int slot) -{ - pLayout->ClearClasses(slot); - pLayout->ClearDialogVariables(slot); - pLayout->SetInputCaptureEnabled(false, slot); -} - void CCSCustomHudLayout::OnEntityDeleted() { sm_mapCustomLayoutCallbacks.erase(GetHandle().ToInt()); diff --git a/src/cs2_sdk/entity/customhudlayout.h b/src/cs2_sdk/entity/customhudlayout.h index 1df3374d..6559a068 100644 --- a/src/cs2_sdk/entity/customhudlayout.h +++ b/src/cs2_sdk/entity/customhudlayout.h @@ -139,7 +139,6 @@ class CCSCustomHudLayout : public CBaseEntity // which clears all classes and variables for a slot, so only use this if you want custom logic void SetDisconnectCallback(CustomHudDisconnectCallback_t callback); static void OnClientDisconnect(int nSlot); - static void DefaultOnDisconnect(CCSCustomHudLayout* pLayout, int nSlot); void OnEntityDeleted(); From 1c411f75a24bd98993d03f08e5d670c7e497f3d8 Mon Sep 17 00:00:00 2001 From: Vauff Date: Wed, 14 Oct 2026 19:30:17 -0400 Subject: [PATCH 3/7] Update Windows sm_mapGcBanInformation signature --- gamedata/cs2fixes.jsonc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gamedata/cs2fixes.jsonc b/gamedata/cs2fixes.jsonc index 5eb164ae..dc022bbf 100644 --- a/gamedata/cs2fixes.jsonc +++ b/gamedata/cs2fixes.jsonc @@ -288,7 +288,7 @@ "CCSGameRules__sm_mapGcBanInformation": { "library": "server", - "windows": "48 8D 0D ? ? ? ? 0F 11 44 24 ? 0F 11 44 24 ? E8", + "windows": "48 8D 0D ? ? ? ? 45 33 C0 4C 89 74 24 ? 0F 11 44 24", "linux": "48 8D 35 ? ? ? ? 89 C2 48 63 46" }, // Called right before "%d spawn groups:\n" From 9d6d4990bf69b6aaf4c219ac5e969c50b4341824 Mon Sep 17 00:00:00 2001 From: Alex Date: Thu, 15 Oct 2026 03:01:01 -0400 Subject: [PATCH 4/7] Update SDK & sync build scripts (#469) * test sdk update * full pass * Clean up stale includes * fix msvc min/max bullshit for good * Update build scripts * Resolve some suppressed warnings * finish WIP fix * Remove unused offset * Switch to new range-based for loops on SDK containers * woke is dead * Match new variant_t behaviour more closely --- .gitmodules | 2 +- AMBuildScript | 339 +++++++++-------- AMBuilder | 12 +- CS2Fixes.vcxproj | 16 +- CS2Fixes.vcxproj.filters | 16 +- PackageScript | 2 +- gamedata/cs2fixes.jsonc | 5 - hl2sdk-manifests | 2 +- plugin-metadata.json | 2 +- sdk | 2 +- src/addresses.cpp | 2 +- src/addresses.h | 7 +- src/adminsystem.cpp | 53 ++- src/adminsystem.h | 1 + src/buttonwatch.cpp | 7 - src/buttonwatch.h | 1 + src/cfgparser.h | 2 +- src/commands.cpp | 27 +- src/commands.h | 2 +- src/common.h | 13 +- src/cs2_sdk/cchecktransmitinfo.h | 30 -- src/cs2_sdk/clientframe.h | 55 --- src/cs2_sdk/entity/cbaseentity.h | 4 +- src/cs2_sdk/entity/cbaseplayerpawn.h | 4 +- src/cs2_sdk/entity/ccsplayercontroller.h | 2 +- src/cs2_sdk/entity/ctakedamageinfo.h | 48 +-- src/cs2_sdk/entity/customhudlayout.h | 1 - src/cs2_sdk/entity/globaltypes.h | 74 +--- src/cs2_sdk/entity/services.h | 7 +- src/cs2_sdk/entityio.h | 44 +-- src/cs2_sdk/map.h | 2 +- src/cs2_sdk/netmessages.h | 83 ----- src/cs2_sdk/schema.cpp | 2 +- src/cs2_sdk/schema.h | 17 +- src/cs2_sdk/serversideclient.h | 451 ----------------------- src/cs2fixes.cpp | 14 +- src/cs2fixes.h | 9 +- src/ctimer.h | 1 + src/customio.h | 8 +- src/cvars.cpp | 2 +- src/cvarwhitelist.h | 2 +- src/detours.cpp | 46 +-- src/detours.h | 4 +- src/discord.cpp | 3 +- src/entities.cpp | 9 +- src/entities.h | 2 +- src/entitylistener.cpp | 2 - src/entitylistener.h | 4 +- src/entwatch.cpp | 21 +- src/eventlistener.h | 1 - src/events.cpp | 4 +- src/gamesystem.cpp | 9 +- src/gamesystem.h | 22 +- src/idlemanager.cpp | 1 + src/idlemanager.h | 2 +- src/leader.cpp | 14 +- src/map_votes.cpp | 20 +- src/map_votes.h | 10 +- src/mapmigrations.cpp | 12 +- src/mapmigrations.h | 4 +- src/mempatch.cpp | 3 +- src/panoramavote.cpp | 11 +- src/panoramavote.h | 14 +- src/patches.cpp | 8 +- src/patches.h | 1 - src/playermanager.cpp | 39 +- src/playermanager.h | 8 +- src/recipientfilters.h | 2 +- src/topdefender.cpp | 3 +- src/user_preferences.cpp | 2 +- src/user_preferences.h | 10 +- src/utils/entity.h | 4 +- src/utils/hud_manager.cpp | 2 +- src/utils/khook_helpers.h | 1 + src/utils/module.h | 2 +- src/utils/plat_unix.cpp | 5 +- src/utils/utils.cpp | 1 + src/utils/utils.h | 2 +- src/utils/vscript_function.cpp | 3 +- src/virtual_hooks.cpp | 29 +- src/virtual_hooks.h | 12 +- src/votemanager.cpp | 4 +- src/zombiereborn.cpp | 25 +- src/zombiereborn.h | 2 +- 84 files changed, 450 insertions(+), 1306 deletions(-) delete mode 100644 src/cs2_sdk/cchecktransmitinfo.h delete mode 100644 src/cs2_sdk/clientframe.h delete mode 100644 src/cs2_sdk/netmessages.h delete mode 100644 src/cs2_sdk/serversideclient.h diff --git a/.gitmodules b/.gitmodules index 096b58f9..e7195329 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,6 +1,6 @@ [submodule "sdk"] path = sdk - url = https://github.com/alliedmodders/hl2sdk.git + url = https://github.com/alliedmodders/s2sdk.git branch = cs2 [submodule "hl2sdk-manifests"] path = hl2sdk-manifests diff --git a/AMBuildScript b/AMBuildScript index eb9bcac7..1801065b 100644 --- a/AMBuildScript +++ b/AMBuildScript @@ -1,6 +1,7 @@ # vim: set sts=2 ts=8 sw=2 tw=99 et ft=python: -import os, json, re, subprocess +import os, json, re, subprocess, shutil, sys from ambuild2.frontend.v2_2.cpp.builders import TargetSuffix +from ambuild2.util import ConsoleRed, ConsoleNormal # Edit the functions below for the extra functionality, the return should be # a list of path's to wanted locations @@ -23,6 +24,12 @@ def additionalIncludes(context, binary, sdk): # 'D:/absolute/path/to/include/folder/' ] +def hasLLDLinker(): + result = shutil.which('lld') + if not result: + result = shutil.which('ld.lld') + return result != None + def getGitHeadPath(): curr_source = builder.currentSourcePath direct_head = os.path.join(curr_source, '.git', 'HEAD') @@ -47,7 +54,7 @@ def runAndReturn(argv): output, ignored = p.communicate() rval = p.poll() if rval: - raise subprocess.CalledProcessError(rval, argv) + return None text = output.decode('utf8') return text.strip() @@ -77,8 +84,6 @@ def resolveMMSRoot(): prenormalized_path = resolveEnvPath('MMSOURCE_DEV', 'metamod-source') if not prenormalized_path: prenormalized_path = resolveEnvPath('MMSOURCE_DEV', 'mmsource-central') - if not prenormalized_path: # Legacy fallback to avoid breakages, even though 1.12 is not supported, many old dev setups are likely using this env variable - prenormalized_path = resolveEnvPath('MMSOURCE112', 'mmsource-1.12') if not prenormalized_path or not os.path.isdir(prenormalized_path): raise Exception('Could not find a source copy of Metamod:Source') @@ -108,7 +113,7 @@ class MMSPluginConfig(object): self.sdk_manifests = [] self.sdks = {} self.sdk_targets = [] - self.binaries = [] + self.tasks = [] self.mms_root = mms_root self.version_header_deps = [] self.versionlib_deps = dict() @@ -116,15 +121,15 @@ class MMSPluginConfig(object): self.target_archs = set() self.metadata = { - 'name': 'cs2fixes', - 'alias': 'cs2fixes', - 'display_name': 'CS2Fixes', - 'description': 'A Metamod plugin with fixes and features aimed but not limited to zombie escape', - 'author': 'xen, Poggu, Vauff, Ice, lonefang, Kxnrl, tilgep, EasterLee and various contributors', - 'url': 'https://github.com/Source2ZE/CS2Fixes', - 'log_tag': 'CS2Fixes', - 'license': 'GPL v3 License', - 'version': '{{parsed-version}}', + 'name': 'sample_mm', + 'alias': 'sample', + 'display_name': 'Sample Plugin', + 'description': 'Sample basic plugin', + 'author': 'AlliedModders LLC', + 'url': 'http://www.sourcemm.net/', + 'log_tag': 'SAMPLE', + 'license': 'Public Domain', + 'version': '1.0.0.{{git-shorthash}}', } if builder.options.targets: @@ -167,10 +172,6 @@ class MMSPluginConfig(object): self.sdks = SdkHelpers.sdks self.sdk_manifests = SdkHelpers.sdk_manifests self.sdk_targets = SdkHelpers.sdk_targets - - for sdk_target in self.sdk_targets: - if not sdk_target.sdk['source2']: - raise Exception('Only Source2 games are supported by this script.') def addVersioning(self, cxx): cxx.includes += [ @@ -209,6 +210,9 @@ class MMSPluginConfig(object): #define PLUGIN_LICENSE \"{self.metadata['license']}\" extern const char* PLUGIN_FULL_VERSION; +extern const char* PLUGIN_REVISION_SHORT; +extern const char* PLUGIN_REVISION_LONG; +extern const char* PLUGIN_REVISION_COUNT; #endif /* _PLUGIN_METADATA_INFORMATION_H_ */ """.encode('utf-8')) @@ -220,30 +224,47 @@ extern const char* PLUGIN_FULL_VERSION; version = self.metadata['version'] direct_head, git_head_path = getGitHeadPath() - parsed_version = 'DEV-untracked' + shorthash = longhash = revision_count = '0' if direct_head and git_head_path: # Force track head changes to trigger recompilation builder.AddConfigureFile(git_head_path) builder.AddConfigureFile(direct_head) - try: - parsed_version = runAndReturn(['git', 'describe', '--tags', '--long']) - except subprocess.SubprocessError as e: - print("git describe failed to find any tags") - try: - parsed_version = runAndReturn(['git', 'log', '--pretty=format:%h:%H', '-n', '1']) - parsed_version = parsed_version.split(':')[0] - except subprocess.SubprocessError as e: - print("git log failed to find any commit hash, falling back to placeholder version") + tag = runAndReturn(['git', 'describe', '--tags']) or 'MISSING_TAG' + commits_after_tag = '0' + + tag_match = re.match(r'(.+?)\-(\d+)\-g[a-f\d]+$', tag, re.MULTILINE) + if tag_match is not None: + tag = tag_match.group(1) + commits_after_tag = tag_match.group(2) + + revision_count = runAndReturn(['git', 'rev-list', '--count', 'HEAD']) or 'MISSING_COUNT' + revision_hash = runAndReturn(['git', 'log', '--pretty=format:%h:%H', '-n', '1']) or 'MISSING_SHORTHASH:MISSING_LONGHASH' + shorthash, longhash = revision_hash.split(':') + + if '{{git-shorthash}}' in version: + version = version.replace('{{git-shorthash}}', shorthash) + + if '{{git-longhash}}' in version: + version = version.replace('{{git-longhash}}', longhash) + + if '{{git-count}}' in version: + version = version.replace('{{git-count}}', revision_count) + + if '{{git-tag}}' in version: + version = version.replace('{{git-tag}}', tag) - if '{{parsed-version}}' in version: - version = version.replace('{{parsed-version}}', parsed_version) + if '{{git-commits-after-tag}}' in version: + version = version.replace('{{git-commits-after-tag}}', commits_after_tag) # For the version strings and git hashes compile that to a static library instead, # to prevent a full recompilation on version/git changes which would only trigger this cpp # and linking to be performed versionlib_cpp = builder.AddOutputFile(os.path.join('versioning', 'versionlib.cpp'), f""" const char *PLUGIN_FULL_VERSION = \"{version}\"; +const char *PLUGIN_REVISION_SHORT = \"{shorthash}\"; +const char *PLUGIN_REVISION_LONG = \"{longhash}\"; +const char *PLUGIN_REVISION_COUNT = \"{revision_count}\"; """.encode('utf-8')) for cxx in self.all_targets: @@ -290,155 +311,152 @@ const char *PLUGIN_FULL_VERSION = \"{version}\"; def configureCXX(self, cxx): if cxx.behavior == 'gcc': - cxx.defines += [ - 'stricmp=strcasecmp', - '_stricmp=strcasecmp', - '_snprintf=snprintf', - '_vsnprintf=vsnprintf', - 'HAVE_STDINT_H', - 'GNUC', - ] - cxx.cflags += [ - '-pipe', - '-fno-strict-aliasing', - '-Wall', - '-Wno-sign-compare', - '-Wno-uninitialized', - '-Wno-unused', - '-Wno-switch', - '-msse', - '-fPIC', - ] + self.configureGCC(cxx) + elif cxx.like('msvc'): + self.configureMSVC(cxx) - cxx.cxxflags += ['-std=c++20'] - if (builder.options.asan != '1') and ((cxx.version >= 'gcc-4.0') or cxx.family == 'clang'): - cxx.cflags += ['-fvisibility=hidden'] - cxx.cxxflags += ['-fvisibility-inlines-hidden'] - cxx.cxxflags += [ - '-fno-exceptions', - '-fno-threadsafe-statics', - '-Wno-non-virtual-dtor', - '-Wno-overloaded-virtual', - '-Wno-register', - '-Wno-invalid-offsetof', - ] - if (builder.options.asan == '1'): - cxx.cxxflags += [ - '-fsanitize=address', - '-fsanitize-address-use-after-scope', - '-fno-omit-frame-pointer', - '-g', - ] - cxx.linkflags += [ - '-fsanitize=address', - '-fsanitize-address-use-after-scope', - ] - if (cxx.version >= 'gcc-4.7' or cxx.family == 'clang'): - cxx.cxxflags += ['-Wno-delete-non-virtual-dtor'] + # Platform-specifics + if cxx.target.platform == 'linux': + cxx.defines += ['LINUX', '_LINUX', 'POSIX', '_FILE_OFFSET_BITS=64'] if cxx.family == 'gcc': - cxx.cflags += ['-mfpmath=sse'] - if cxx.family == 'clang': - cxx.cxxflags += ['-Wno-implicit-exception-spec-mismatch'] - if cxx.version >= 'clang-3.9': - cxx.cxxflags += ['-Wno-expansion-to-defined'] - if cxx.version >= 'clang-3.6': - cxx.cxxflags += ['-Wno-inconsistent-missing-override'] - if cxx.version >= 'clang-3.4': - cxx.cxxflags += ['-Wno-deprecated-register'] - else: - cxx.cxxflags += ['-Wno-deprecated'] + cxx.linkflags += ['-static-libgcc'] + elif cxx.family == 'clang': + cxx.linkflags += ['-lgcc_eh'] + cxx.linkflags += ['-static-libstdc++'] + + if hasLLDLinker(): + # This prevents STB_GNU_UNIQUE symbols from appearing in resulting binary + # as these cause it to not unload on dlclose which metamod relies on to unload its plugins + # as a result this messes with static/global variable destruction & causes other various effects + # like server crashes on server exit + cxx.linkflags += ['-fuse-ld=lld', '-Wl,--no-gnu-unique'] - # Work around SDK warnings. - if cxx.version >= 'clang-10.0': - cxx.cflags += [ - '-Wno-implicit-int-float-conversion', - '-Wno-tautological-overlap-compare', - ] + elif cxx.target.platform == 'windows': + cxx.defines += ['WIN32', '_WINDOWS', 'NOMINMAX'] + + def configureGCC(self, cxx): + cxx.defines += [ + 'stricmp=strcasecmp', + '_stricmp=strcasecmp', + '_snprintf=snprintf', + '_vsnprintf=vsnprintf', + 'HAVE_STDINT_H', + 'GNUC', + ] - elif cxx.like('msvc'): - if builder.options.debug == '1': - cxx.cflags += ['/MTd'] - cxx.linkflags += ['/NODEFAULTLIB:libcmt'] - else: - cxx.cflags += ['/MT'] - cxx.defines += [ - '_CRT_SECURE_NO_DEPRECATE', - '_CRT_SECURE_NO_WARNINGS', - '_CRT_NONSTDC_NO_DEPRECATE', - ] - cxx.cflags += [ - '/W3', - '/Zi', - '/std:c++20', + cxx.cflags += [ + '-pipe', + '-fno-strict-aliasing', + '-Wall', + '-Werror', + '-Wno-sign-compare', + '-Wno-unused', + '-Wno-switch', + '-Wno-unknown-pragmas', + '-Wno-dangling-else', + '-msse', + '-fPIC', + ] + + cxx.cxxflags += [ + '-std=c++20', + '-Wno-non-virtual-dtor', + '-Wno-overloaded-virtual', + '-Wno-invalid-offsetof', + ] + + if builder.options.asan == '1': + cxx.cxxflags += [ + '-fsanitize=address', + '-fsanitize-address-use-after-scope', + '-fno-omit-frame-pointer', + '-g', ] - cxx.cxxflags += ['/TP'] - cxx.linkflags += [ - '/SUBSYSTEM:WINDOWS', - 'kernel32.lib', - 'user32.lib', - 'gdi32.lib', - 'winspool.lib', - 'comdlg32.lib', - 'advapi32.lib', - 'shell32.lib', - 'ole32.lib', - 'oleaut32.lib', - 'uuid.lib', - 'odbc32.lib', - 'odbccp32.lib', + '-fsanitize=address', + '-fsanitize-address-use-after-scope', + ] + else: + cxx.cflags += ['-fvisibility=hidden'] + cxx.cxxflags += ['-fvisibility-inlines-hidden'] + + # Clang only flags + if cxx.family == 'clang': + cxx.cxxflags += [ + '-Wno-implicit-exception-spec-mismatch', + '-Wno-expansion-to-defined', + '-Wno-inconsistent-missing-override' ] # Optimization if builder.options.opt == '1': cxx.defines += ['NDEBUG'] - if cxx.behavior == 'gcc': - cxx.cflags += ['-O3'] - elif cxx.behavior == 'msvc': - cxx.cflags += ['/Ox', '/Zo'] - cxx.linkflags += ['/OPT:ICF', '/OPT:REF'] - + cxx.cflags += ['-O3'] # Debugging - if builder.options.debug == '1': + elif builder.options.debug == '1': cxx.defines += ['DEBUG', '_DEBUG'] - if cxx.behavior == 'gcc': - cxx.cflags += ['-g3'] - elif cxx.behavior == 'msvc': - cxx.cflags += ['/Od', '/RTC1'] + cxx.cflags += ['-g3'] # Don't omit the frame pointer. # This needs to be after our optimization flags which could otherwise disable it. - if cxx.behavior == 'gcc': - cxx.cflags += ['-fno-omit-frame-pointer'] - elif cxx.behavior == 'msvc': - cxx.cflags += ['/Oy-'] + cxx.cflags += ['-fno-omit-frame-pointer'] - # Platform-specifics - if cxx.target.platform == 'linux': - cxx.defines += ['LINUX', '_LINUX', 'POSIX', '_FILE_OFFSET_BITS=64'] - if cxx.family == 'gcc': - cxx.linkflags += ['-static-libgcc'] - elif cxx.family == 'clang': - cxx.linkflags += ['-lgcc_eh'] - cxx.linkflags += ['-static-libstdc++'] - elif cxx.target.platform == 'windows': - cxx.defines += ['WIN32', '_WINDOWS'] + def configureMSVC(self, cxx): + cxx.defines += [ + '_CRT_SECURE_NO_DEPRECATE', + '_CRT_SECURE_NO_WARNINGS', + '_CRT_NONSTDC_NO_DEPRECATE', + ] + cxx.cflags += [ + '/W3', + '/Zi', + '/std:c++20', + ] + cxx.cxxflags += ['/TP'] + cxx.linkflags += [ + '/SUBSYSTEM:WINDOWS', + 'kernel32.lib', + 'user32.lib', + 'gdi32.lib', + 'winspool.lib', + 'comdlg32.lib', + 'advapi32.lib', + 'shell32.lib', + 'ole32.lib', + 'oleaut32.lib', + 'uuid.lib', + 'odbc32.lib', + 'odbccp32.lib', + ] - def Library(self, cxx, name): - binary = cxx.Library(name) - return binary + # Optimization + if builder.options.opt == '1': + cxx.defines += ['NDEBUG'] + cxx.cflags += ['/Ox', '/Zo'] + cxx.linkflags += ['/OPT:ICF', '/OPT:REF'] + + # Debugging + if builder.options.debug == '1': + cxx.defines += ['DEBUG', '_DEBUG'] + cxx.cflags += ['/Od', '/RTC1', '/MTd'] + cxx.linkflags += ['/NODEFAULTLIB:libcmt'] + else: + cxx.cflags += ['/MT'] + + # Don't omit the frame pointer. + # This needs to be after our optimization flags which could otherwise disable it. + cxx.cflags += ['/Oy-'] - def HL2Library(self, context, compiler, name, sdk): - binary = self.Library(compiler, name) - mms_core_path = os.path.join(self.mms_root, 'core') + def HL2Library(self, context, compiler, project, sdk): + binary = project.Configure(compiler, '{0}.{1}'.format(project.name, sdk['extension']), '{0} {1}'.format(sdk['name'], compiler.target.arch)) cxx = binary.compiler self.addVersioning(cxx) cxx.cxxincludes += [ os.path.join(context.currentSourcePath), - os.path.join(mms_core_path), - os.path.join(self.mms_root, 'third_party', 'khook', 'include'), + os.path.join(self.mms_root, 'core'), + os.path.join(self.mms_root, 'third_party', 'khook', 'include') ] for other_sdk in self.sdk_manifests: @@ -448,7 +466,7 @@ const char *PLUGIN_FULL_VERSION = \"{version}\"; cxx.defines += ['META_IS_SOURCE2'] binary.sources += [ os.path.join(sdk['path'], 'public', 'tier0', 'memoverride.cpp'), - os.path.join(sdk['path'], 'tier1', 'convar.cpp'), + os.path.join(sdk['path'], 'tier0_perproject', 'convar.cpp'), ] SdkHelpers.configureCxx(context, binary, sdk) @@ -461,13 +479,20 @@ const char *PLUGIN_FULL_VERSION = \"{version}\"; return binary MMSPlugin = MMSPluginConfig() -MMSPlugin.detectSDKs() MMSPlugin.configurePluginMetadata() MMSPlugin.configure() +MMSPlugin.detectSDKs() + +if os.name == 'posix' and not hasLLDLinker(): + ConsoleRed(sys.stdout) + print('[!] LLD linker not found, using systems default.') + print('[!] This might result in a binary that is not unloadable at runtime and will potentially cause issues/crashes!') + print('[!] Please do install LLD linker for better binary stability. (apt install lld)') + ConsoleNormal(sys.stdout) BuildScripts = [ 'AMBuilder', 'PackageScript', ] -builder.Build(BuildScripts, { 'MMSPlugin': MMSPlugin }) +builder.Build(BuildScripts, { 'MMSPlugin': MMSPlugin }) \ No newline at end of file diff --git a/AMBuilder b/AMBuilder index 66d4347d..6abb84fb 100644 --- a/AMBuilder +++ b/AMBuilder @@ -1,12 +1,13 @@ -# vim: set sts=2 ts=8 sw=2 tw=99 et ft=python: +# vim: set sts=2 ts=8 sw=2 tw=99 et ft=python: import os -import subprocess + +project = builder.LibraryProject(MMSPlugin.metadata["name"]) for sdk_target in MMSPlugin.sdk_targets: sdk = sdk_target.sdk cxx = sdk_target.cxx - binary = MMSPlugin.HL2Library(builder, cxx, f'{MMSPlugin.metadata["name"]}.{sdk["name"]}', sdk) + binary = MMSPlugin.HL2Library(builder, cxx, project, sdk) binary.compiler.cxxincludes += [ os.path.join(builder.sourcePath, 'src', 'cs2_sdk'), @@ -72,7 +73,7 @@ for sdk_target in MMSPlugin.sdk_targets: 'sdk/entity2/entitysystem.cpp', 'sdk/entity2/entityidentity.cpp', 'sdk/entity2/entitykeyvalues.cpp', - 'sdk/tier1/keyvalues3.cpp', + 'sdk/tier0_perproject/keyvalues3.cpp', ] protoc_builder = builder.tools.Protoc(protoc = sdk_target.protoc, sources = [ @@ -100,5 +101,4 @@ for sdk_target in MMSPlugin.sdk_targets: binary.custom = [protoc_builder] - nodes = builder.Add(binary) - MMSPlugin.binaries += [nodes] +MMSPlugin.tasks += builder.Add(project) \ No newline at end of file diff --git a/CS2Fixes.vcxproj b/CS2Fixes.vcxproj index 797abd0e..5e73c528 100644 --- a/CS2Fixes.vcxproj +++ b/CS2Fixes.vcxproj @@ -85,7 +85,7 @@ Level3 true - WIN32;_DEBUG;DLL1_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + WIN32;NOMINMAX;_DEBUG;DLL1_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) true Use pch.h @@ -102,7 +102,7 @@ true true true - WIN32;NDEBUG;DLL1_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + WIN32;NOMINMAX;NDEBUG;DLL1_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) true Use pch.h @@ -119,7 +119,7 @@ Level3 true - __STDC_LIMIT_MACROS;X64BITS;WIN32;COMPILER_MSVC;COMPILER_MSVC64;_CRT_NO_VA_START_VALIDATION;_ITERATOR_DEBUG_LEVEL=0;_DEBUG;CS2Fixes_EXPORTS;_WINDOWS;_USRDLL;META_IS_SOURCE2;%(PreprocessorDefinitions) + __STDC_LIMIT_MACROS;X64BITS;WIN32;NOMINMAX;COMPILER_MSVC;COMPILER_MSVC64;_CRT_NO_VA_START_VALIDATION;_ITERATOR_DEBUG_LEVEL=0;_DEBUG;CS2Fixes_EXPORTS;_WINDOWS;_USRDLL;META_IS_SOURCE2;%(PreprocessorDefinitions) true NotUsing pch.h @@ -145,7 +145,7 @@ true true true - __STDC_LIMIT_MACROS;X64BITS;WIN32;COMPILER_MSVC;COMPILER_MSVC64;_CRT_NO_VA_START_VALIDATION;_ITERATOR_DEBUG_LEVEL=0;NDEBUG;_WINDOWS;CS2Fixes_EXPORTS;_USRDLL;META_IS_SOURCE2;%(PreprocessorDefinitions) + __STDC_LIMIT_MACROS;X64BITS;WIN32;NOMINMAX;COMPILER_MSVC;COMPILER_MSVC64;_CRT_NO_VA_START_VALIDATION;_ITERATOR_DEBUG_LEVEL=0;NDEBUG;_WINDOWS;CS2Fixes_EXPORTS;_USRDLL;META_IS_SOURCE2;%(PreprocessorDefinitions) Default NotUsing pch.h @@ -184,7 +184,7 @@ - + @@ -217,7 +217,7 @@ - + @@ -270,7 +270,6 @@ - @@ -290,8 +289,6 @@ - - @@ -308,7 +305,6 @@ - diff --git a/CS2Fixes.vcxproj.filters b/CS2Fixes.vcxproj.filters index d03d6a9b..6f6d191c 100644 --- a/CS2Fixes.vcxproj.filters +++ b/CS2Fixes.vcxproj.filters @@ -86,7 +86,7 @@ Source Files - + Source Files\sdk @@ -125,7 +125,7 @@ Source Files - + Source Files\sdk @@ -376,12 +376,6 @@ Header Files - - Header Files\cs2_sdk - - - Header Files\cs2_sdk - Header Files @@ -406,12 +400,6 @@ Header Files\cs2_sdk\entity - - Header Files\cs2_sdk - - - Header Files\cs2_sdk - Header Files\cs2_sdk diff --git a/PackageScript b/PackageScript index b68cbc84..e69702c8 100644 --- a/PackageScript +++ b/PackageScript @@ -94,7 +94,7 @@ for sdk_target in MMSPlugin.sdk_targets: packages[sdk['name']] = SDKPackage(cxx, sdk['name']) pdb_list = [] -for task in MMSPlugin.binaries: +for task in MMSPlugin.tasks: # Determine which sdk this binary belongs to since we encode it in its name binary_filename = os.path.splitext(os.path.basename(task.binary.path))[0] sdk_name = binary_filename.split('.')[-1] diff --git a/gamedata/cs2fixes.jsonc b/gamedata/cs2fixes.jsonc index dc022bbf..8e6877ce 100644 --- a/gamedata/cs2fixes.jsonc +++ b/gamedata/cs2fixes.jsonc @@ -429,11 +429,6 @@ "windows": 387, "linux": 387 }, - "GameEntitySystem": - { - "windows": 88, - "linux": 80 - }, // In the function with "[%03d] Found: %s, firing\n", you'll find a call into a pointer offset just a bit higher, that's the offset * 8 "CGameRules_FindPickerEntity": { diff --git a/hl2sdk-manifests b/hl2sdk-manifests index 20b3a014..ebd6e106 160000 --- a/hl2sdk-manifests +++ b/hl2sdk-manifests @@ -1 +1 @@ -Subproject commit 20b3a014264b38908c4a5d4eb263ba2c488f3dc1 +Subproject commit ebd6e1064d64c89b19afca236656640a5ac6fde8 diff --git a/plugin-metadata.json b/plugin-metadata.json index d0e24426..2e83f165 100644 --- a/plugin-metadata.json +++ b/plugin-metadata.json @@ -7,5 +7,5 @@ "url": "https://github.com/Source2ZE/CS2Fixes", "log_tag": "CS2Fixes", "license": "GPL v3 License", - "version": "{{parsed-version}}" + "version": "{{git-tag}}-{{git-commits-after-tag}}-{{git-shorthash}}" } \ No newline at end of file diff --git a/sdk b/sdk index 625bfd4e..809a2d48 160000 --- a/sdk +++ b/sdk @@ -1 +1 @@ -Subproject commit 625bfd4e39816ad0e1eae3b3144a3b5425c5c7a0 +Subproject commit 809a2d48b5e0e6cddb1678c0f0b86a8fec604241 diff --git a/src/addresses.cpp b/src/addresses.cpp index 9b4ce84d..e49c4fcd 100644 --- a/src/addresses.cpp +++ b/src/addresses.cpp @@ -22,7 +22,7 @@ #include "utils/module.h" #include "entityinstance.h" -#include "tier1/strtools.h" +#include "tier0/tier0_strtools.h" #include "vscript/ivscript.h" #include "tier0/memdbgon.h" diff --git a/src/addresses.h b/src/addresses.h index a168a8b1..6bbce1e1 100644 --- a/src/addresses.h +++ b/src/addresses.h @@ -18,12 +18,13 @@ */ #pragma once +#include "entity2/entityclass.h" +#include "entity2/variant.h" #include "platform.h" #include "stdint.h" +#include "tier0/utlmap.h" #include "utils/module.h" #include "utils/vscript_function.h" -#include "utlstring.h" -#include "variant.h" namespace modules { @@ -87,7 +88,7 @@ namespace addresses inline void(FASTCALL* CCSPlayerController_SwitchTeam)(CCSPlayerController* pController, uint32 team); inline void(FASTCALL* CBasePlayerController_SetPawn)(CBasePlayerController* pController, CCSPlayerPawn* pPawn, bool a3, bool a4, bool a5, bool a6); inline void(FASTCALL* CBaseModelEntity_SetModel)(CBaseModelEntity* pModel, const char* pszModel); - inline void(FASTCALL* UTIL_Remove)(CEntityInstance*); + inline BASEPTR UTIL_Remove; inline void(FASTCALL* CEntitySystem_AddEntityIOEvent)(CEntitySystem* pEntitySystem, CEntityInstance* pTarget, const char* pszInput, CEntityInstance* pActivator, CEntityInstance* pCaller, variant_t* value, float flDelay, CPulseArgumentPack* pArgumentPack, CPulseInputParamMap* pParamMap); diff --git a/src/adminsystem.cpp b/src/adminsystem.cpp index 49424d5f..16a00f39 100644 --- a/src/adminsystem.cpp +++ b/src/adminsystem.cpp @@ -18,22 +18,19 @@ */ #include "adminsystem.h" -#include "KeyValues.h" #include "commands.h" -#include "ctimer.h" -#include "detours.h" #include "discord.h" +#include "engine2/ivengineserver2.h" #include "entity/cbaseentity.h" #include "entity/cgamerules.h" -#include "entity/cparticlesystem.h" #include "entwatch.h" -#include "filesystem.h" -#include "gamesystem.h" +#include "filesystem/ifilesystem.h" #include "hud_manager.h" -#include "icvar.h" #include "interfaces/interfaces.h" #include "map_votes.h" #include "playermanager.h" +#include "tier0/icvar.h" +#include "tier0/keyvalues.h" #include "utils/entity.h" #include "votemanager.h" #include @@ -118,14 +115,12 @@ CON_COMMAND_CHAT_FLAGS(debugclientlist, "- Debug client list", ADMFLAG_ROOT) return; } - for (int i = 0; i < GetClientList()->Count(); i++) + for (CServerSideClient* pClient : *GetClientList()) { - CServerSideClient* pClient = (*GetClientList())[i]; - if (!pClient) continue; - ClientPrint(player, HUD_PRINTCONSOLE, "slot: %i address: %s signonstate: %i spawngroups: %i name: %s", pClient->GetPlayerSlot().Get(), pClient->GetRemoteAddress()->ToString(), pClient->GetSignonState(), pClient->m_vecLoadedSpawnGroups.Count(), pClient->GetClientName()); + ClientPrint(player, HUD_PRINTCONSOLE, "slot: %i address: %s signonstate: %i spawngroups: %i name: %s", pClient->GetPlayerSlot().Get(), pClient->GetRemoteAddress()->ToString(), pClient->GetSignonState(), pClient->m_LoadedSpawnGroups.Count(), pClient->GetClientName()); } } @@ -239,7 +234,7 @@ CON_COMMAND_CHAT_FLAGS(kick, " - Kick a player", ADMFLAG_KICK) } int iNumClients = 0; - int pSlots[MAXPLAYERS]; + int pSlots[MAX_PLAYERS]; ETargetType nType; if (!g_playerManager->CanTargetPlayers(player, args[1], iNumClients, pSlots, NO_TARGET_BLOCKS, nType)) @@ -270,7 +265,7 @@ CON_COMMAND_CHAT_FLAGS(slay, " - Slay a player", ADMFLAG_SLAY) } int iNumClients = 0; - int pSlots[MAXPLAYERS]; + int pSlots[MAX_PLAYERS]; ETargetType nType; if (!g_playerManager->CanTargetPlayers(player, args[1], iNumClients, pSlots, NO_DEAD, nType)) @@ -300,7 +295,7 @@ CON_COMMAND_CHAT_FLAGS(slap, " [damage] - Slap a player", ADMFLAG_SLAY) } int iNumClients = 0; - int pSlots[MAXPLAYERS]; + int pSlots[MAX_PLAYERS]; ETargetType nType; if (!g_playerManager->CanTargetPlayers(player, args[1], iNumClients, pSlots, NO_DEAD, nType)) @@ -361,7 +356,7 @@ CON_COMMAND_CHAT_FLAGS(goto, " - Teleport to a player", ADMFLAG_SLAY) } int iNumClients = 0; - int pSlots[MAXPLAYERS]; + int pSlots[MAX_PLAYERS]; if (!g_playerManager->CanTargetPlayers(player, args[1], iNumClients, pSlots, NO_SELF | NO_MULTIPLE | NO_DEAD | NO_IMMUNITY)) return; @@ -390,7 +385,7 @@ CON_COMMAND_CHAT_FLAGS(bring, " - Bring a player", ADMFLAG_SLAY) } int iNumClients = 0; - int pSlots[MAXPLAYERS]; + int pSlots[MAX_PLAYERS]; ETargetType nType; if (!g_playerManager->CanTargetPlayers(player, args[1], iNumClients, pSlots, NO_SELF | NO_DEAD, nType)) @@ -415,7 +410,7 @@ CON_COMMAND_CHAT_FLAGS(bring, " - Bring a player", ADMFLAG_SLAY) CON_COMMAND_CHAT_FLAGS(noclip, "[name] - Toggle noclip on a player", ADMFLAG_CHEATS) { int iNumClients = 0; - int pSlots[MAXPLAYERS]; + int pSlots[MAX_PLAYERS]; if (!g_playerManager->CanTargetPlayers(player, args.ArgC() < 2 ? "@me" : args[1], iNumClients, pSlots, NO_MULTIPLE | NO_DEAD | NO_SPECTATOR)) return; @@ -515,7 +510,7 @@ CON_COMMAND_CHAT_FLAGS(entfirepawn, " [parameter] - Fire outputs a } int iNumClients = 0; - int pSlots[MAXPLAYERS]; + int pSlots[MAX_PLAYERS]; ETargetType nType; if (!g_playerManager->CanTargetPlayers(player, args[1], iNumClients, pSlots, NO_TARGET_BLOCKS, nType)) @@ -546,7 +541,7 @@ CON_COMMAND_CHAT_FLAGS(entfirecontroller, " [parameter] - Fire out } int iNumClients = 0; - int pSlots[MAXPLAYERS]; + int pSlots[MAX_PLAYERS]; ETargetType nType; if (!g_playerManager->CanTargetPlayers(player, args[1], iNumClients, pSlots, NO_TARGET_BLOCKS, nType)) @@ -700,7 +695,7 @@ CON_COMMAND_CHAT_FLAGS(pm, " - Private message a player. This wi } int iNumClients = 0; - int pSlots[MAXPLAYERS]; + int pSlots[MAX_PLAYERS]; ETargetType nType; if (!g_playerManager->CanTargetPlayers(player, args[1], iNumClients, pSlots, NO_MULTIPLE | NO_IMMUNITY | NO_BOT, nType)) @@ -932,7 +927,7 @@ CON_COMMAND_CHAT_FLAGS(who, "- List the flags of all online players", ADMFLAG_GE CON_COMMAND_CHAT(status, " - Checks a player's active punishments. Non-admins may only check their own punishments") { int iNumClients = 0; - int pSlots[MAXPLAYERS]; + int pSlots[MAX_PLAYERS]; ETargetType nType; ZEPlayer* pTargetPlayer = nullptr; bool bIsAdmin = !player || player->GetZEPlayer()->IsAdminFlagSet(ADMFLAG_GENERIC); @@ -993,7 +988,7 @@ CON_COMMAND_CHAT_FLAGS(money, " - Set a player's amount of money" } int iNumClients = 0; - int pSlots[MAXPLAYERS]; + int pSlots[MAX_PLAYERS]; ETargetType nType; if (!g_playerManager->CanTargetPlayers(player, args[1], iNumClients, pSlots, NO_TARGET_BLOCKS, nType)) @@ -1038,7 +1033,7 @@ CON_COMMAND_CHAT_FLAGS(health, " - Set a player's health", ADMFLA } int iNumClients = 0; - int pSlots[MAXPLAYERS]; + int pSlots[MAX_PLAYERS]; ETargetType nType; if (!g_playerManager->CanTargetPlayers(player, args[1], iNumClients, pSlots, NO_DEAD | NO_SPECTATOR, nType)) @@ -1112,7 +1107,7 @@ CON_COMMAND_CHAT_FLAGS(strip, " - Strip all the weapons/items of a player" } int iNumClients = 0; - int pSlots[MAXPLAYERS]; + int pSlots[MAX_PLAYERS]; ETargetType nType; if (!g_playerManager->CanTargetPlayers(player, args[1], iNumClients, pSlots, NO_DEAD | NO_SPECTATOR, nType)) @@ -1164,7 +1159,7 @@ CON_COMMAND_CHAT_FLAGS(give, " - Give a weapon/item to a player", } int iNumClients = 0; - int pSlots[MAXPLAYERS]; + int pSlots[MAX_PLAYERS]; ETargetType nType; if (!g_playerManager->CanTargetPlayers(player, args[1], iNumClients, pSlots, NO_DEAD | NO_SPECTATOR, nType)) @@ -1197,9 +1192,9 @@ CON_COMMAND_CHAT_FLAGS(give, " - Give a weapon/item to a player", { CUtlVector>* weapons = pWeaponServices->m_hMyWeapons(); - FOR_EACH_VEC(*weapons, i) + for (const auto& hWeapon : *weapons) { - CBasePlayerWeapon* weapon = (*weapons)[i].Get(); + CBasePlayerWeapon* weapon = hWeapon.Get(); if (!weapon) continue; @@ -1266,7 +1261,7 @@ CON_COMMAND_CHAT_FLAGS(setteam, " - Set a player's team", ADM } int iNumClients = 0; - int pSlots[MAXPLAYERS]; + int pSlots[MAX_PLAYERS]; ETargetType nType; if (!g_playerManager->CanTargetPlayers(player, args[1], iNumClients, pSlots, NO_TARGET_BLOCKS, nType)) @@ -1854,7 +1849,7 @@ void ParseInfraction(const CCommand& args, CCSPlayerController* pAdmin, bool bAd } int iNumClients = 0; - int pSlots[MAXPLAYERS]; + int pSlots[MAX_PLAYERS]; ETargetType nType; uint64 iBlockedFlags = NO_RANDOM | NO_SELF | NO_BOT | NO_UNAUTHENTICATED; diff --git a/src/adminsystem.h b/src/adminsystem.h index 34c3f311..b6361abf 100644 --- a/src/adminsystem.h +++ b/src/adminsystem.h @@ -77,6 +77,7 @@ class CInfractionBase else m_iTimestamp = duration; } + virtual ~CInfractionBase() = default; enum EInfractionType { Ban, diff --git a/src/buttonwatch.cpp b/src/buttonwatch.cpp index d92d1968..995fcaa2 100644 --- a/src/buttonwatch.cpp +++ b/src/buttonwatch.cpp @@ -22,15 +22,8 @@ #include "commands.h" #include "cs2fixes.h" #include "ctimer.h" -#include "detours.h" -#include "entity.h" -#include "entity/cbaseplayercontroller.h" #include "entity/ccsplayercontroller.h" #include "entity/ccsplayerpawn.h" -#include "entity/cgameplayerequip.h" -#include "entity/cgamerules.h" -#include "entity/clogiccase.h" -#include "entity/cpointviewcontrol.h" CConVar g_cvarEnableButtonWatch("cs2f_enable_button_watch", FCVAR_NONE, "Whether to enable button watch or not.", false); diff --git a/src/buttonwatch.h b/src/buttonwatch.h index bb72ffa2..d22a72a0 100644 --- a/src/buttonwatch.h +++ b/src/buttonwatch.h @@ -19,6 +19,7 @@ #pragma once #include "detours.h" +#include "tier0/convar.h" extern CConVar g_cvarEnableButtonWatch; diff --git a/src/cfgparser.h b/src/cfgparser.h index baee9275..118db05e 100644 --- a/src/cfgparser.h +++ b/src/cfgparser.h @@ -19,7 +19,7 @@ #pragma once -#include "convar.h" +#include "tier0/convar.h" #include class CCfgParser diff --git a/src/commands.cpp b/src/commands.cpp index 6210eb35..7be7388d 100644 --- a/src/commands.cpp +++ b/src/commands.cpp @@ -21,11 +21,10 @@ #include "adminsystem.h" #include "common.h" #include "ctimer.h" -#include "detours.h" #include "discord.h" -#include "engine/igameeventsystem.h" +#include "engine2/igameeventsystem.h" +#include "engine2/ivengineserver2.h" #include "entity/cbaseentity.h" -#include "entity/cbasemodelentity.h" #include "entity/ccsplayercontroller.h" #include "entity/ccsplayerpawn.h" #include "entity/ccsweaponbase.h" @@ -40,7 +39,6 @@ #include "tier0/vprof.h" #include "usermessages.pb.h" #include "utils/entity.h" -#include "utlstring.h" #include "zombiereborn.h" #undef snprintf #include "vendor/nlohmann/json.hpp" @@ -173,9 +171,8 @@ void ParseWeaponCommand(const CCommand& args, CCSPlayerController* player) CUtlVector* weaponPurchases = pPawn->m_pActionTrackingServices->m_weaponPurchasesThisRound().m_weaponPurchases; bool found = false; - FOR_EACH_VEC(*weaponPurchases, i) + for (WeaponPurchaseCount_t& purchase : *weaponPurchases) { - WeaponPurchaseCount_t& purchase = (*weaponPurchases)[i]; if (purchase.m_nItemDefIndex == pWeaponInfo->m_iItemDefinitionIndex) { // Note ammo_grenade_limit_total is not followed here, only for checking inventory space @@ -200,9 +197,9 @@ void ParseWeaponCommand(const CCommand& args, CCSPlayerController* player) { CUtlVector>* weapons = pWeaponServices->m_hMyWeapons(); - FOR_EACH_VEC(*weapons, i) + for (const auto& hWeapon : *weapons) { - CBasePlayerWeapon* weapon = (*weapons)[i].Get(); + CBasePlayerWeapon* weapon = hWeapon.Get(); if (!weapon) continue; @@ -625,7 +622,7 @@ CON_COMMAND_CHAT(spec, "[name] - Spectate another player or join spectators") int iCommandPlayer = player ? player->GetPlayerSlot() : -1; int iNumClients = 0; - int pSlot[MAXPLAYERS]; + int pSlot[MAX_PLAYERS]; if (!g_playerManager->CanTargetPlayers(player, args[1], iNumClients, pSlot, NO_MULTIPLE | NO_SELF | NO_DEAD | NO_SPECTATOR | NO_IMMUNITY)) return; @@ -683,7 +680,7 @@ CON_COMMAND_CHAT(info, " - Get a player's information") } int iNumClients = 0; - int pSlots[MAXPLAYERS]; + int pSlots[MAX_PLAYERS]; ETargetType nType; if (!g_playerManager->CanTargetPlayers(player, args[1], iNumClients, pSlots, NO_BOT | NO_IMMUNITY, nType)) @@ -721,7 +718,7 @@ CON_COMMAND_CHAT(showteam, " - Get a player's current team") } int iNumClients = 0; - int pSlots[MAXPLAYERS]; + int pSlots[MAX_PLAYERS]; if (!g_playerManager->CanTargetPlayers(player, args[1], iNumClients, pSlots, NO_MULTIPLE | NO_IMMUNITY)) return; @@ -975,7 +972,7 @@ CON_COMMAND_CHAT(test_target, " [blocked flag] [...] - Test string targett iBlockedFlags |= NO_IMMUNITY; int iNumClients = 0; - int pSlots[MAXPLAYERS]; + int pSlots[MAX_PLAYERS]; if (!g_playerManager->CanTargetPlayers(player, args[1], iNumClients, pSlots, iBlockedFlags)) return; @@ -1093,7 +1090,7 @@ CON_COMMAND_CHAT(setkills, "- Set your kills") CON_COMMAND_CHAT(setcollisiongroup, " - Set a player's collision group") { int iNumClients = 0; - int pSlots[MAXPLAYERS]; + int pSlots[MAX_PLAYERS]; if (!g_playerManager->CanTargetPlayers(player, args[1], iNumClients, pSlots, NO_TARGET_BLOCKS)) return; @@ -1115,7 +1112,7 @@ CON_COMMAND_CHAT(setcollisiongroup, " - Set a player's collision group") CON_COMMAND_CHAT(setsolidtype, " - Set a player's solid type") { int iNumClients = 0; - int pSlots[MAXPLAYERS]; + int pSlots[MAX_PLAYERS]; if (!g_playerManager->CanTargetPlayers(player, args[1], iNumClients, pSlots, NO_TARGET_BLOCKS)) return; @@ -1137,7 +1134,7 @@ CON_COMMAND_CHAT(setsolidtype, " - Set a player's solid type") CON_COMMAND_CHAT(setinteraction, " - Set a player's interaction flags") { int iNumClients = 0; - int pSlots[MAXPLAYERS]; + int pSlots[MAX_PLAYERS]; if (!g_playerManager->CanTargetPlayers(player, args[1], iNumClients, pSlots, NO_TARGET_BLOCKS)) return; diff --git a/src/commands.h b/src/commands.h index d8ce7975..52488caa 100644 --- a/src/commands.h +++ b/src/commands.h @@ -19,9 +19,9 @@ #pragma once #include "adminsystem.h" -#include "convar.h" #include "entity/ccsplayercontroller.h" #include "leader.h" +#include "tier0/convar.h" #include class CChatCommand; diff --git a/src/common.h b/src/common.h index 1e428a42..f208d4bc 100644 --- a/src/common.h +++ b/src/common.h @@ -20,22 +20,11 @@ #pragma once #include "platform.h" +#include "shareddefs.h" #include "utils.h" #define VPROF_LEVEL 1 -#define CS_TEAM_NONE 0 -#define CS_TEAM_SPECTATOR 1 -#define CS_TEAM_T 2 -#define CS_TEAM_CT 3 - -#define HUD_PRINTNOTIFY 1 -#define HUD_PRINTCONSOLE 2 -#define HUD_PRINTTALK 3 -#define HUD_PRINTCENTER 4 - -#define MAXPLAYERS 64 - #ifdef _WIN32 #define ROOTBIN "/bin/win64/" #define GAMEBIN "/csgo/bin/win64/" diff --git a/src/cs2_sdk/cchecktransmitinfo.h b/src/cs2_sdk/cchecktransmitinfo.h deleted file mode 100644 index 1a3f472d..00000000 --- a/src/cs2_sdk/cchecktransmitinfo.h +++ /dev/null @@ -1,30 +0,0 @@ -#pragma once - -#include "bitvec.h" -#include "eiface.h" -#include "playerslot.h" -#include "utlvector.h" - -// https://github.com/Wend4r/sourcesdk/blob/main/public/iservernetworkable.h - -struct vis_info_t_extended -{ - uint32 m_uVisBitsBufSize; - SpawnGroupHandle_t m_SpawnGroupHandle; - CBitVec<4096> m_VisBits; -}; -COMPILE_TIME_ASSERT(sizeof(vis_info_t_extended) == 520); - -class CCheckTransmitInfoExtended -{ -public: - CBitVec* m_pTransmitEntity; // entities visible/sent to client - CBitVec* m_pTransmitNonPlayers; // non-player entities needing deletion deltas - CBitVec* m_pTransmitOutOfPVS; // entities that left PVS but still need delta update - CBitVec* m_pTransmitAlways; // entity n is always sent even if not in PVS (HLTV and Replay only) - CUtlVector m_vecTargetSlots; - vis_info_t_extended m_VisInfo; - CPlayerSlot m_nPlayerSlot; - bool m_bFullUpdate = false; -}; -COMPILE_TIME_ASSERT(sizeof(CCheckTransmitInfoExtended) == 584); \ No newline at end of file diff --git a/src/cs2_sdk/clientframe.h b/src/cs2_sdk/clientframe.h deleted file mode 100644 index 3a7df38f..00000000 --- a/src/cs2_sdk/clientframe.h +++ /dev/null @@ -1,55 +0,0 @@ -//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -//=============================================================================// - -#ifndef CLIENTFRAME_H -#define CLIENTFRAME_H -#ifdef _WIN32 - #pragma once -#endif - -#include -#include -#include - -class CFrameSnapshot; - -class CClientFrame -{ -public: - virtual ~CClientFrame(); - -public: - // State of entities this frame from the POV of the client. - int tick_count; // server tick of this snapshot - int last_entity; // highest entity index - CClientFrame* m_pNext; - - // Index of snapshot entry that stores the entities that were active and the serial numbers - // for the frame number this packed entity corresponds to - // m_pSnapshot MUST be private to force using SetSnapshot(), see reference counters - CFrameSnapshot* m_pSnapshot; - - // Used by server to indicate if the entity was in the player's pvs - CBitVec transmit_entity; // if bit n is set, entity n will be send to client - CBitVec unkBitVec2080; - CBitVec unkBitVec4128; - CBitVec unkBitVec6176; - CBitVec* transmit_always; // if bit is set, don't do PVS checks before sending (HLTV only) -}; // sizeof 8232 - -// TODO substitute CClientFrameManager with an intelligent structure (Tree, hash, cache, etc) -class CClientFrameManager -{ -public: - virtual ~CClientFrameManager(void) = default; - -public: - char pad120[120]; - CUtlMemoryPool m_ClientFramePool; - CClientFrame* m_Frames; // updates can be delta'ed from here -}; // sizeof 288 - -#endif // CLIENTFRAME_H \ No newline at end of file diff --git a/src/cs2_sdk/entity/cbaseentity.h b/src/cs2_sdk/entity/cbaseentity.h index 765bd168..7fda0b3e 100644 --- a/src/cs2_sdk/entity/cbaseentity.h +++ b/src/cs2_sdk/entity/cbaseentity.h @@ -28,7 +28,7 @@ #include "globaltypes.h" #include "mathlib/vector.h" #include "schema.h" -#include "tier1/utlstringtoken.h" +#include "tier0/utlstringtoken.h" class CGameUI; class CEnvHudHint; @@ -261,7 +261,7 @@ class CBaseEntity : public CEntityInstance void Remove() { - addresses::UTIL_Remove(this); + (this->*addresses::UTIL_Remove)(); } void SetMoveType(MoveType_t nMoveType) diff --git a/src/cs2_sdk/entity/cbaseplayerpawn.h b/src/cs2_sdk/entity/cbaseplayerpawn.h index 555537ab..cf008c9a 100644 --- a/src/cs2_sdk/entity/cbaseplayerpawn.h +++ b/src/cs2_sdk/entity/cbaseplayerpawn.h @@ -47,9 +47,9 @@ class CBasePlayerPawn : public CBaseModelEntity CUtlVector>* weapons = m_pWeaponServices()->m_hMyWeapons(); std::vector vecWeaponsToDrop; - FOR_EACH_VEC(*weapons, i) + for (const auto& hWeapon : *weapons) { - CBasePlayerWeapon* pWeapon = (*weapons)[i].Get(); + CBasePlayerWeapon* pWeapon = hWeapon.Get(); if (!pWeapon) continue; diff --git a/src/cs2_sdk/entity/ccsplayercontroller.h b/src/cs2_sdk/entity/ccsplayercontroller.h index e2f3378a..9464c0e8 100644 --- a/src/cs2_sdk/entity/ccsplayercontroller.h +++ b/src/cs2_sdk/entity/ccsplayercontroller.h @@ -20,8 +20,8 @@ #pragma once #include "../playermanager.h" -#include "../serversideclient.h" #include "cbaseplayercontroller.h" +#include "engine2/serversideclient.h" #include "services.h" class CCSPlayerController : public CBasePlayerController diff --git a/src/cs2_sdk/entity/ctakedamageinfo.h b/src/cs2_sdk/entity/ctakedamageinfo.h index 644d6d65..b327b7db 100644 --- a/src/cs2_sdk/entity/ctakedamageinfo.h +++ b/src/cs2_sdk/entity/ctakedamageinfo.h @@ -20,55 +20,9 @@ #pragma once #include "ehandle.h" #include "gametrace.h" +#include "shareddefs.h" #include -enum DamageTypes_t : uint32_t -{ - DMG_GENERIC = 0, // 0x0 - DMG_CRUSH = 1 << 0, // 0x1 - DMG_BULLET = 1 << 1, // 0x2 - DMG_SLASH = 1 << 2, // 0x4 - DMG_BURN = 1 << 3, // 0x8 - DMG_VEHICLE = 1 << 4, // 0x10 - DMG_FALL = 1 << 5, // 0x20 - DMG_BLAST = 1 << 6, // 0x40 - DMG_CLUB = 1 << 7, // 0x80 - DMG_SHOCK = 1 << 8, // 0x100 - DMG_SONIC = 1 << 9, // 0x200 - DMG_ENERGYBEAM = 1 << 10, // 0x400 - DMG_BUCKSHOT = 1 << 11, // 0x800 - DMG_DROWN = 1 << 14, // 0x4000 - DMG_POISON = 1 << 15, // 0x8000 - DMG_RADIATION = 1 << 16, // 0x10000 - DMG_DROWNRECOVER = 1 << 17, // 0x20000 - DMG_ACID = 1 << 18, // 0x40000 - DMG_PHYSGUN = 1 << 20, // 0x100000 - DMG_DISSOLVE = 1 << 21, // 0x200000 - DMG_BLAST_SURFACE = 1 << 22, // 0x400000 - DMG_HEADSHOT = 1 << 23, // 0x800000 -}; - -enum TakeDamageFlags_t : uint64_t -{ - DFLAG_NONE = 0, // 0x0 - DFLAG_SUPPRESS_HEALTH_CHANGES = 1 << 0, // 0x1 - DFLAG_SUPPRESS_PHYSICS_FORCE = 1 << 1, // 0x2 - DFLAG_SUPPRESS_EFFECTS = 1 << 2, // 0x4 - DFLAG_PREVENT_DEATH = 1 << 3, // 0x8 - DFLAG_FORCE_DEATH = 1 << 4, // 0x10 - DFLAG_ALWAYS_GIB = 1 << 5, // 0x20 - DFLAG_NEVER_GIB = 1 << 6, // 0x40 - DFLAG_REMOVE_NO_RAGDOLL = 1 << 7, // 0x80 - DFLAG_SUPPRESS_DAMAGE_MODIFICATION = 1 << 8, // 0x100 - DFLAG_ALWAYS_FIRE_DAMAGE_EVENTS = 1 << 9, // 0x200 - DFLAG_RADIUS_DMG = 1 << 10, // 0x400 - DFLAG_FORCEREDUCEARMOR_DMG = 1 << 11, // 0x800 - DFLAG_SUPPRESS_INTERRUPT_FLINCH = 1 << 12, // 0x1000 - DFLAG_IGNORE_DESTRUCTIBLE_PARTS = 1 << 13, // 0x2000 - DFLAG_IGNORE_ARMOR = 1 << 14, // 0x4000 - DFLAG_SUPPRESS_UTILREMOVE = 1 << 15, // 0x8000 -}; - struct AttackerInfo_t { bool m_bNeedInit; diff --git a/src/cs2_sdk/entity/customhudlayout.h b/src/cs2_sdk/entity/customhudlayout.h index 6559a068..0c2b3f5e 100644 --- a/src/cs2_sdk/entity/customhudlayout.h +++ b/src/cs2_sdk/entity/customhudlayout.h @@ -20,7 +20,6 @@ #pragma once #include "ccsplayercontroller.h" -#include "cstrike15_usermessages.pb.h" class CCSCustomHudLayout; diff --git a/src/cs2_sdk/entity/globaltypes.h b/src/cs2_sdk/entity/globaltypes.h index 285bb478..bbd4fa79 100644 --- a/src/cs2_sdk/entity/globaltypes.h +++ b/src/cs2_sdk/entity/globaltypes.h @@ -18,7 +18,9 @@ */ #pragma once +#include "networktransmitcomponent.h" #include "schema.h" +#include "shareddefs.h" #include "soundflags.h" #include @@ -57,17 +59,6 @@ enum ParticleAttachment_t : uint32_t MAX_PATTACH_TYPES = 0x10, }; -enum ObserverMode_t : uint8_t -{ - OBS_MODE_NONE = 0x0, - OBS_MODE_FIXED = 0x1, - OBS_MODE_IN_EYE = 0x2, - OBS_MODE_CHASE = 0x3, - OBS_MODE_ROAMING = 0x4, - OBS_MODE_DIRECTED = 0x5, - NUM_OBSERVER_MODES = 0x6, -}; - typedef uint32 SoundEventGuid_t; struct SndOpEventGuid_t { @@ -85,67 +76,6 @@ struct StartSoundEventInfo #pragma pack(pop) static_assert(sizeof(StartSoundEventInfo) == 20); // Ensure alignment change works -// used with EmitSound_t -enum gender_t : uint8 -{ - GENDER_NONE = 0x0, - GENDER_MALE = 0x1, - GENDER_FEMALE = 0x2, - GENDER_NAMVET = 0x3, - GENDER_TEENGIRL = 0x4, - GENDER_BIKER = 0x5, - GENDER_MANAGER = 0x6, - GENDER_GAMBLER = 0x7, - GENDER_PRODUCER = 0x8, - GENDER_COACH = 0x9, - GENDER_MECHANIC = 0xA, - GENDER_CEDA = 0xB, - GENDER_CRAWLER = 0xC, - GENDER_UNDISTRACTABLE = 0xD, - GENDER_FALLEN = 0xE, - GENDER_RIOT_CONTROL = 0xF, - GENDER_CLOWN = 0x10, - GENDER_JIMMY = 0x11, - GENDER_HOSPITAL_PATIENT = 0x12, - GENDER_BRIDE = 0x13, - GENDER_LAST = 0x14, -}; - -struct EmitSound_t -{ - EmitSound_t() : - m_pSoundName(0), - m_vecSoundOrigin(), - m_flVolume(VOL_NORM), - m_flSoundTime(0.0f), - m_nForceGuid(0), - m_nPitch(PITCH_NORM), - m_nFlags(0) - { - } - const char* m_pSoundName; // 0x0 - Vector m_vecSoundOrigin; // 0x8 - float m_flVolume; // 0x14 - float m_flSoundTime; // 0x18 -private: - uint8_t pad_1c[0x4]; - -public: - uint32_t m_nForceGuid; // 0x20 -private: - uint8_t pad_24[0x4]; - -public: - int16_t m_nPitch; // 0x28 - uint8_t m_nFlags; // 0x2a -}; // Size: 0x2b - -class CNetworkTransmitComponent -{ -public: - DECLARE_SCHEMA_CLASS_INLINE(CNetworkTransmitComponent) -}; - class CNetworkVelocityVector { public: diff --git a/src/cs2_sdk/entity/services.h b/src/cs2_sdk/entity/services.h index 8f52b483..b4a16806 100644 --- a/src/cs2_sdk/entity/services.h +++ b/src/cs2_sdk/entity/services.h @@ -23,7 +23,6 @@ #include #include -#include extern bool g_bAwsChangingTeam; @@ -61,7 +60,7 @@ class CPlayerControllerComponent SCHEMA_FIELD(CNetworkVarChainer, __m_pChainEntity) - CCSPlayerController* GetController() { return reinterpret_cast(__m_pChainEntity().m_pEntity); } + CCSPlayerController* GetController() { return reinterpret_cast(__m_pChainEntity().GetObject()); } }; class CPlayerPawnComponent @@ -95,7 +94,7 @@ class CPlayerPawnComponent SCHEMA_FIELD(CNetworkVarChainer, __m_pChainEntity) - CCSPlayerPawn* GetPawn() { return reinterpret_cast(__m_pChainEntity().m_pEntity); } + CCSPlayerPawn* GetPawn() { return reinterpret_cast(__m_pChainEntity().GetObject()); } }; class CPlayer_MovementServices : public CPlayerPawnComponent @@ -303,7 +302,7 @@ class CPlayer_ObserverServices : public CPlayerPawnComponent public: DECLARE_SCHEMA_CLASS(CPlayer_ObserverServices) - SCHEMA_FIELD(ObserverMode_t, m_iObserverMode) + SCHEMA_FIELD(uint8, m_iObserverMode) SCHEMA_FIELD(CHandle, m_hObserverTarget) SCHEMA_FIELD(ObserverMode_t, m_iObserverLastMode) SCHEMA_FIELD(bool, m_bForcedObserverMode) diff --git a/src/cs2_sdk/entityio.h b/src/cs2_sdk/entityio.h index 6ae7189a..4bc8cbf5 100644 --- a/src/cs2_sdk/entityio.h +++ b/src/cs2_sdk/entityio.h @@ -19,47 +19,11 @@ #pragma once -// Bandaid needed for #include "string_t.h" to compile... -#ifndef NULL - #define NULL 0 -#endif +#include +#include +#include -#include -#include -#include -#include - -struct EntityIOConnectionDesc_t -{ - string_t m_targetDesc; - string_t m_targetInput; - string_t m_valueOverride; - CEntityHandle m_hTarget; - EntityIOTargetType_t m_nTargetType; - int32 m_nTimesToFire; - float m_flDelay; -}; - -struct EntityIOConnection_t : EntityIOConnectionDesc_t -{ - bool m_bMarkedForRemoval; - EntityIOConnection_t* m_pNext; -}; - -struct EntityIOOutputDesc_t -{ - const char* m_pName; - uint32 m_nFlags; - uint32 m_nOutputOffset; -}; - -class CEntityIOOutput -{ -public: - void* vtable; - EntityIOConnection_t* m_pConnections; - EntityIOOutputDesc_t* m_pDesc; -}; +class CBaseEntity; class InputData_t { diff --git a/src/cs2_sdk/map.h b/src/cs2_sdk/map.h index 74bbe3e8..929f2162 100644 --- a/src/cs2_sdk/map.h +++ b/src/cs2_sdk/map.h @@ -19,7 +19,7 @@ #pragma once -#include "utlstring.h" +#include "tier0/utlstring.h" class CSingleWorldRep { diff --git a/src/cs2_sdk/netmessages.h b/src/cs2_sdk/netmessages.h deleted file mode 100644 index 061a0b2c..00000000 --- a/src/cs2_sdk/netmessages.h +++ /dev/null @@ -1,83 +0,0 @@ -#ifndef NETMESSAGES_H -#define NETMESSAGES_H - -#ifdef _WIN32 - #pragma once -#endif - -#include -#include -#include -#include -#undef min -#undef max - -class CNETMsg_Tick_t : public CNetMessagePB -{ -}; - -class CNETMsg_StringCmd_t : public CNetMessagePB -{ -}; - -class CNETMsg_SpawnGroup_LoadCompleted_t : public CNetMessagePB -{ -}; - -class CCLCMsg_ClientInfo_t : public CNetMessagePB -{ -}; - -class CCLCMsg_BaselineAck_t : public CNetMessagePB -{ -}; - -class CCLCMsg_LoadingProgress_t : public CNetMessagePB -{ -}; - -class CCLCMsg_SplitPlayerConnect_t : public CNetMessagePB -{ -}; - -class CCLCMsg_SplitPlayerDisconnect_t : public CNetMessagePB -{ -}; - -class CCLCMsg_CmdKeyValues_t : public CNetMessagePB -{ -}; - -class CCLCMsg_Move_t : public CNetMessagePB -{ -}; - -class CCLCMsg_VoiceData_t : public CNetMessagePB -{ -}; - -class CCLCMsg_RespondCvarValue_t : public CNetMessagePB -{ -}; - -class NetMessageSplitscreenUserChanged_t : public CNetMessagePB -{ -}; - -class NetMessagePacketStart_t : public CNetMessagePB -{ -}; - -class NetMessagePacketEnd_t : public CNetMessagePB -{ -}; - -class NetMessageConnectionClosed_t : public CNetMessagePB -{ -}; - -class NetMessageConnectionCrashed_t : public CNetMessagePB -{ -}; - -#endif // NETMESSAGES_H diff --git a/src/cs2_sdk/schema.cpp b/src/cs2_sdk/schema.cpp index bab07e43..1ebb504f 100644 --- a/src/cs2_sdk/schema.cpp +++ b/src/cs2_sdk/schema.cpp @@ -181,7 +181,7 @@ void EntityNetworkStateChanged(uintptr_t pEntity, uint nOffset) void ChainNetworkStateChanged(uintptr_t pNetworkVarChainer, uint nLocalOffset) { - CEntityInstance* pEntity = reinterpret_cast(pNetworkVarChainer)->m_pEntity; + CEntityInstance* pEntity = reinterpret_cast(pNetworkVarChainer)->GetObject(); if (pEntity) pEntity->NetworkStateChanged(NetworkStateChangedData(nLocalOffset, -1, reinterpret_cast(pNetworkVarChainer)->m_PathIndex)); diff --git a/src/cs2_sdk/schema.h b/src/cs2_sdk/schema.h index a25035a7..d95dbe2f 100644 --- a/src/cs2_sdk/schema.h +++ b/src/cs2_sdk/schema.h @@ -32,6 +32,8 @@ #include "../addresses.h" #include "const.h" +#include "networksystem/networkvar.h" +#include "schemasystem/schemasystem.h" #include "stdint.h" #include "tier0/dbg.h" #include "virtual.h" @@ -44,21 +46,6 @@ struct SchemaKey SchemaCollectionManipulatorFn_t manipulator = nullptr; }; -class CNetworkVarChainer -{ -public: - CEntityInstance* m_pEntity; - -private: - uint8 pad_0000[24]; - -public: - ChangeAccessorFieldPathIndex_t m_PathIndex; - -private: - uint8 pad_0024[4]; -}; - void EntityNetworkStateChanged(uintptr_t pEntity, uint nOffset); void ChainNetworkStateChanged(uintptr_t pNetworkVarChainer, uint nOffset); void NetworkVarStateChanged(uintptr_t pNetworkVar, uint32_t nOffset, uint32 nNetworkStateChangedOffset); diff --git a/src/cs2_sdk/serversideclient.h b/src/cs2_sdk/serversideclient.h deleted file mode 100644 index be76fee0..00000000 --- a/src/cs2_sdk/serversideclient.h +++ /dev/null @@ -1,451 +0,0 @@ -#ifndef SERVERSIDECLIENT_H -#define SERVERSIDECLIENT_H - -#if COMPILER_MSVC - #pragma once -#endif - -#include "clientframe.h" -#include "netmessages.h" - -#include -#include -// #include // @Wend4r: use instead. -#include "circularbuffer.h" -#include "networksystem/inetworksystem.h" -#include "threadtools.h" -#include "tier1/netadr.h" -#include -#include -#include -#include - -#include -#include -#undef min -#undef max - -class CHLTVServer; -class INetMessage; -class CNetworkGameServerBase; -class CNetworkGameServer; -class CUtlSlot; - -struct HltvReplayStats_t -{ - enum FailEnum_t - { - FAILURE_ALREADY_IN_REPLAY, - FAILURE_TOO_FREQUENT, - FAILURE_NO_FRAME, - FAILURE_NO_FRAME2, - FAILURE_CANNOT_MATCH_DELAY, - FAILURE_FRAME_NOT_READY, - NUM_FAILURES - }; - - uint nClients; - uint nStartRequests; - uint nSuccessfulStarts; - uint nStopRequests; - uint nAbortStopRequests; - uint nUserCancels; - uint nFullReplays; - uint nNetAbortReplays; - uint nFailedReplays[NUM_FAILURES]; -}; // sizeof 56 - -struct Spike_t -{ -public: - CUtlString m_szDesc; - int m_nBits; -}; // sizeof 16 - -class CNetworkStatTrace -{ -public: - CUtlVector m_Records; - int m_nMinWarningBytes; - int m_nStartBit; - int m_nCurBit; -}; // sizeof 40 - -enum CopiedLockState_t : int32 -{ - CLS_NOCOPY = 0, - CLS_UNLOCKED = 1, - CLS_LOCKED_BY_COPYING_THREAD = 2, -}; - -template -class CCopyableLock : public MUTEX -{ - typedef MUTEX BaseClass; - -public: - // ... -}; - -class CUtlSignaller_Base -{ -public: - using Delegate_t = CUtlDelegate; - - CUtlSignaller_Base(const Delegate_t& other) : - m_SlotDeletionDelegate(other) {} - CUtlSignaller_Base(Delegate_t&& other) : - m_SlotDeletionDelegate(Move(other)) {} - -private: - Delegate_t m_SlotDeletionDelegate; -}; - -class CUtlSlot -{ -public: - using MTElement_t = CUtlSignaller_Base*; - - CUtlSlot() : - m_ConnectedSignallers(0, 1) {} - -private: - CCopyableLock m_Mutex; - CUtlVector m_ConnectedSignallers; -}; - -class CServerSideClientBase : public CUtlSlot, public INetworkChannelNotify, public INetworkMessageProcessingPreFilter -{ -public: - virtual ~CServerSideClientBase() = 0; - -public: - CPlayerSlot GetPlayerSlot() const { return m_nClientSlot; } - CPlayerUserId GetUserID() const { return m_UserID; } - CEntityIndex GetEntityIndex() const { return m_nEntityIndex; } - CSteamID GetClientSteamID() const { return m_SteamID; } - const char* GetClientName() const { return m_Name; } - INetChannel* GetNetChannel() const { return m_NetChannel; } - const netadr_t* GetRemoteAddress() const { return &m_nAddr.GetAddress(); } - CNetworkGameServerBase* GetServer() const { return m_Server; } - - virtual void Connect(int socket, const char* pszName, int nUserID, INetChannel* pNetChannel, bool bFakePlayer, bool bSplitClient, int iClientPlatform) = 0; - virtual void Inactivate() = 0; - virtual void Reactivate(CPlayerSlot nSlot) = 0; - virtual void SetServer(CNetworkGameServer* pNetServer) = 0; - virtual void Reconnect() = 0; - virtual void Disconnect(ENetworkDisconnectionReason reason) = 0; - virtual bool CheckConnect() = 0; - -private: - virtual void unk_10() = 0; - -public: - virtual void SetRate(int nRate) = 0; - virtual void SetUpdateRate(float fUpdateRate) = 0; - virtual int GetRate() = 0; - - virtual void Clear() = 0; - - virtual bool ExecuteStringCommand(const CNETMsg_StringCmd_t& msg) = 0; // "false" trigger an anti spam counter to kick a client. - virtual void SendNetMessage(const CNetMessage* pData, NetChannelBufType_t bufType) = 0; - -#ifdef LINUX -private: - virtual void unk_17() = 0; -#endif - -public: - virtual void ClientPrintf(PRINTF_FORMAT_STRING const char*, ...) = 0; - - bool IsConnected() const { return m_nSignonState >= SIGNONSTATE_CONNECTED; } - bool IsInGame() const { return m_nSignonState == SIGNONSTATE_FULL; } - bool IsSpawned() const { return m_nSignonState >= SIGNONSTATE_NEW; } - bool IsActive() const { return m_nSignonState == SIGNONSTATE_FULL; } - virtual bool IsFakeClient() const { return m_bFakePlayer; } - virtual bool IsHLTV() = 0; - - // Is an actual human player or splitscreen player (not a bot and not a HLTV slot) - virtual bool IsHumanPlayer() const { return false; } - virtual bool IsHearingClient(CPlayerSlot nSlot) const { return false; } - virtual bool IsLowViolenceClient() const { return m_bLowViolence; } - - virtual bool IsSplitScreenUser() const { return m_bSplitScreenUser; } - -public: // Message Handlers - virtual bool ProcessTick(const CNETMsg_Tick_t& msg) = 0; - virtual bool ProcessStringCmd(const CNETMsg_StringCmd_t& msg) = 0; - -private: - virtual bool unk_27() = 0; - virtual bool unk_28() = 0; - -public: - virtual bool ProcessSpawnGroup_LoadCompleted(const CNETMsg_SpawnGroup_LoadCompleted_t& msg) = 0; - virtual bool ProcessClientInfo(const CCLCMsg_ClientInfo_t& msg) = 0; - virtual bool ProcessBaselineAck(const CCLCMsg_BaselineAck_t& msg) = 0; - virtual bool ProcessLoadingProgress(const CCLCMsg_LoadingProgress_t& msg) = 0; - virtual bool ProcessSplitPlayerConnect(const CCLCMsg_SplitPlayerConnect_t& msg) = 0; - virtual bool ProcessSplitPlayerDisconnect(const CCLCMsg_SplitPlayerDisconnect_t& msg) = 0; - virtual bool ProcessCmdKeyValues(const CCLCMsg_CmdKeyValues_t& msg) = 0; - -private: - virtual bool unk_36() = 0; - virtual bool unk_37() = 0; - -public: - virtual bool ProcessMove(const CCLCMsg_Move_t& msg) = 0; - virtual bool ProcessVoiceData(const CCLCMsg_VoiceData_t& msg) = 0; - virtual bool ProcessRespondCvarValue(const CCLCMsg_RespondCvarValue_t& msg) = 0; - - virtual bool ProcessPacketStart(const NetMessagePacketStart_t& msg) = 0; - virtual bool ProcessPacketEnd(const NetMessagePacketEnd_t& msg) = 0; - virtual bool ProcessConnectionClosed(const NetMessageConnectionClosed_t& msg) = 0; - virtual bool ProcessConnectionCrashed(const NetMessageConnectionCrashed_t& msg) = 0; - -public: - virtual bool ProcessChangeSplitscreenUser(const NetMessageSplitscreenUserChanged_t& msg) = 0; - -private: - virtual bool unk_47() = 0; - virtual bool unk_48() = 0; - virtual bool unk_49() = 0; - -public: - virtual void ConnectionStart(INetChannel* pNetChannel) = 0; - -private: // SpawnGroup something. - virtual void unk_51() = 0; - virtual void unk_52() = 0; - -public: - virtual void ExecuteDelayedCall(void*) = 0; - - virtual bool UpdateAcknowledgedFramecount(int tick) = 0; - void ForceFullUpdate() - { - // This seems to be wrong and crashes linux, plus I can't be bothered to check the vtable - // UpdateAcknowledgedFramecount(-1); - m_nDeltaTick = -1; - } - - virtual bool ShouldSendMessages() = 0; - virtual void UpdateSendState() = 0; - - virtual const CMsgPlayerInfo& GetPlayerInfo() const { return m_playerInfo; } - - virtual void UpdateUserSettings() = 0; - virtual void ResetUserSettings() = 0; - -private: - virtual void unk_60() = 0; - -public: - virtual void SendSignonData() = 0; - virtual void SpawnPlayer() = 0; - virtual void ActivatePlayer() = 0; - - virtual void SetName(const char* name) = 0; - virtual void SetUserCVar(const char* cvar, const char* value) = 0; - - SignonState_t GetSignonState() const { return m_nSignonState; } - - virtual void FreeBaselines() = 0; - - bool IsFullyAuthenticated(void) { return m_bFullyAuthenticated; } - void SetFullyAuthenticated(void) { m_bFullyAuthenticated = true; } - - virtual CServerSideClientBase* GetSplitScreenOwner() { return m_pAttachedTo; } - - virtual int GetNumPlayers() = 0; - - virtual void ShouldReceiveStringTableUserData() = 0; - -private: - virtual void unk_70(CPlayerSlot nSlot) = 0; - virtual void unk_71() = 0; - virtual void unk_72() = 0; - -public: - virtual int GetHltvLastSendTick() = 0; - -private: - virtual void unk_74() = 0; - virtual void unk_75() = 0; - virtual void unk_76() = 0; - -public: - virtual void Await() = 0; - - virtual void MarkToKick() = 0; - virtual void UnmarkToKick() = 0; - - virtual bool ProcessSignonStateMsg(int state) = 0; - virtual void PerformDisconnection(ENetworkDisconnectionReason reason) = 0; - -public: // INetworkMessageProcessingPreFilter - virtual bool FilterMessage(const CNetMessage* pData, INetChannel* pChannel) = 0; // "Client %d(%s) tried to send a RebroadcastSourceId msg.\n" - -public: - CUtlString m_UserIDString; // 72 - CUtlString m_Name; // 80 - CPlayerSlot m_nClientSlot; // 88 - CEntityIndex m_nEntityIndex; // 92 - CNetworkGameServerBase* m_Server; // 96 - INetChannel* m_NetChannel; // 104 - uint16 m_nConnectionTypeFlags; // 112 - bool m_bMarkedToKick; // 113 - SignonState_t m_nSignonState; // 116 - bool m_bSplitScreenUser; // 120 - bool m_bSplitAllowFastDisconnect; // 121 - int m_nSplitScreenPlayerSlot; // 124 - CServerSideClientBase* m_SplitScreenUsers[4]; // 128 - CServerSideClientBase* m_pAttachedTo; // 160 - bool m_bSplitPlayerDisconnecting; // 168 - int m_UnkVariable172; // 172 - bool m_bFakePlayer; // 176 - bool m_bSendingSnapshot; // 177 - [[maybe_unused]] char pad6[0x5]; - CPlayerUserId m_UserID = -1; // 184 - bool m_bReceivedPacket; // true, if client received a packet after the last send packet - CSteamID m_SteamID; // 187 - CSteamID m_UnkSteamID; // 195 - CSteamID m_UnkSteamID2; // 203 from auth ticket - CSteamID m_nFriendsID; // 211 - ns_address m_nAddr; // 220 - ns_address m_nAddr2; // 252 - KeyValues* m_ConVars; // 288 - bool m_bUnk0; - -private: - [[maybe_unused]] char pad273[0x28]; - -public: - bool m_bConVarsChanged; // 296 - bool m_bIsHLTV; // 298 - -private: - [[maybe_unused]] char pad29[0xB]; - -public: - uint32 m_nSendtableCRC; // 312 - uint32 m_uChallengeNumber; - int m_nSignonTick; // 320 - int m_nDeltaTick; // 324 - int m_UnkVariable3; // 328 - int m_nStringTableAckTick; // 332 - int m_UnkVariable4; // 336 - CFrameSnapshot* m_pLastSnapshot; // last send snapshot - CUtlVector m_vecLoadedSpawnGroups; // 352 - CMsgPlayerInfo m_playerInfo; // 376 - CFrameSnapshot* m_pBaseline; // 432 - int m_nBaselineUpdateTick; // 440 - CBitVec m_BaselinesSent; // 444 - int m_nBaselineUsed; // 0/1 toggling flag, singaling client what baseline to use - int m_nLoadingProgress; // 0..100 progress, only valid during loading - - // This is used when we send out a nodelta packet to put the client in a state where we wait - // until we get an ack from them on this packet. - // This is for 3 reasons: - // 1. A client requesting a nodelta packet means they're screwed so no point in deluging them with data. - // Better to send the uncompressed data at a slow rate until we hear back from them (if at all). - // 2. Since the nodelta packet deletes all client entities, we can't ever delta from a packet previous to it. - // 3. It can eat up a lot of CPU on the server to keep building nodelta packets while waiting for - // a client to get back on its feet. - int m_nForceWaitForTick = -1; - - CCircularBuffer m_UnkBuffer = {1024}; // 2504 (24 bytes) - bool m_bLowViolence = false; // true if client is in low-violence mode (L4D server needs to know) - bool m_bSomethingWithAddressType = true; // 2529 - bool m_bFullyAuthenticated = false; // 2530 - bool m_bUnk1 = false; // 2531 - int m_nUnk; - - // The datagram is written to after every frame, but only cleared - // when it is sent out to the client. overflow is tolerated. - - // Time when we should send next world state update ( datagram ) - float m_fNextMessageTime = 0.0f; - float m_fAuthenticatedTime = -1.0f; - - // Default time to wait for next message - float m_fSnapshotInterval = 0.0f; - -private: - // CSVCMsg_PacketEntities_t m_packetmsg; // 2552 - [[maybe_unused]] char pad2552[0x138]; // 2552 - -public: - CNetworkStatTrace m_Trace; // 2864 - int m_spamCommandsCount = 0; // 2904 if the value is greater than 16, the player will be kicked with reason 39 - int m_unknown = 0; // 2908 - double m_lastExecutedCommand = 0.0; // 2912 if command executed more than once per second, ++m_spamCommandCount - -private: - [[maybe_unused]] char pad2920[0x20]; // 2920 -}; - -class CServerSideClient : public CServerSideClientBase -{ -public: - virtual ~CServerSideClient() = 0; - -public: - CPlayerBitVec m_VoiceStreams; // 2952 - CPlayerBitVec m_VoiceProximity; // 2960 - CCheckTransmitInfo m_PackInfo; // 2968 - CClientFrameManager m_FrameManager; // 3568 - -private: - [[maybe_unused]] char pad3856[8]; // 3856 - -public: - float m_flLastClientCommandQuotaStart = 0.0f; // 3864 - float m_flTimeClientBecameFullyConnected = -1.0f; // 3868 - bool m_bVoiceLoopback = false; // 3872 - bool m_bUnk10 = false; // 3873 - int m_nHltvReplayDelay = 0; // 3876 - CHLTVServer* m_pHltvReplayServer; // 3880 - int m_nHltvReplayStopAt; // 3888 - int m_nHltvReplayStartAt; // 3892 - int m_nHltvReplaySlowdownBeginAt; // 3896 - int m_nHltvReplaySlowdownEndAt; // 3900 - float m_flHltvReplaySlowdownRate; // 3904 - int m_nHltvLastSendTick; // 3908 - float m_flHltvLastReplayRequestTime; // 3912 - CUtlVector m_HltvQueuedMessages; // 3920 - HltvReplayStats_t m_HltvReplayStats; // 3944 - void* m_pLastJob; // 4000 - -private: - [[maybe_unused]] char pad3984[8]; // 4008 -}; - -// not full class reversed -class CHLTVClient : public CServerSideClientBase -{ -public: - virtual ~CHLTVClient() = 0; - -public: - CNetworkGameServerBase* m_pHLTV; // 2960 - CUtlString m_szPassword; // 2968 - CUtlString m_szChatGroup; // 2976 // "all" or "group%d" - double m_fLastSendTime = 0.0; // 2984 - double m_flLastChatTime = 0.0; // 2992 - int m_nLastSendTick = 0; // 2996 - int m_unknown2 = 0; // 3000 - int m_nFullFrameTime = 0; // 3008 - int m_unknown3 = 0; // 3012 - -public: - bool m_bNoChat = false; // 3016 - bool m_bUnkBool = false; // 3017 - bool m_bUnkBool2 = false; // 3018 - bool m_bUnkBool3 = false; // 3019 - -private: - [[maybe_unused]] char pad3976[0x24]; // 3020 -}; - -#endif // SERVERSIDECLIENT_H diff --git a/src/cs2fixes.cpp b/src/cs2fixes.cpp index 8e3290d2..31f14648 100644 --- a/src/cs2fixes.cpp +++ b/src/cs2fixes.cpp @@ -18,10 +18,12 @@ */ #include "cs2fixes.h" -#include "iserver.h" +#include "engine2/inetworkgameserver.h" +#include "engine2/inetworkserverservice.h" +#include "engine2/ivengineserver2.h" +#include "engine2/networkgameserverbase.h" #include "adminsystem.h" -#include "appframework/IAppSystem.h" #include "cfgparser.h" #include "commands.h" #include "common.h" @@ -38,7 +40,6 @@ #include "gameconfig.h" #include "gamesystem.h" #include "hud_manager.h" -#include "icvar.h" #include "idlemanager.h" #include "khook_helpers.h" #include "map_votes.h" @@ -48,6 +49,7 @@ #include "patches.h" #include "playermanager.h" #include "schemasystem/schemasystem.h" +#include "tier0/icvar.h" #include "user_preferences.h" #include "virtual_hooks.h" #include "votemanager.h" @@ -68,12 +70,6 @@ float g_flLastTickedTime = 0.0f; bool g_bHasTicked = false; bool g_bRequiredInitLoaded = true; -CGameEntitySystem* GameEntitySystem() -{ - static int offset = g_GameConfig->GetOffset("GameEntitySystem"); - return *reinterpret_cast((uintptr_t)(g_pGameResourceServiceServer) + offset); -} - // Will return null between map end & new map startup, null check if necessary! INetworkGameServer* GetNetworkGameServer() { diff --git a/src/cs2fixes.h b/src/cs2fixes.h index e34860e1..c39e2df5 100644 --- a/src/cs2fixes.h +++ b/src/cs2fixes.h @@ -19,16 +19,17 @@ #pragma once -#include "cs2_sdk/netmessages.h" -#include "engine/igameeventsystem.h" +#include "engine2/igameeventsystem.h" +#include "engine2/isource2engine.h" #include "entity/cgamerules.h" -#include "gamesystems/spawngroup_manager.h" #include "igameevents.h" +#include "netmessages.pb.h" +#include "networksystem/inetworkmessages.h" #include "networksystem/inetworkserializer.h" #include "public/ics2fixes.h" #include "steam/isteamhttp.h" #include -#include +#include #ifdef AMBUILD #include "version_gen.h" diff --git a/src/ctimer.h b/src/ctimer.h index e152550b..d44f3465 100644 --- a/src/ctimer.h +++ b/src/ctimer.h @@ -40,6 +40,7 @@ class CTimerBase void SetLastExecute(float flLastExecute) { m_flLastExecute = flLastExecute; } public: + virtual ~CTimerBase() = default; virtual bool Execute(bool bAutomaticExecute = false) = 0; virtual void Cancel() = 0; diff --git a/src/customio.h b/src/customio.h index d6515eb6..72136474 100644 --- a/src/customio.h +++ b/src/customio.h @@ -19,14 +19,14 @@ #pragma once -#include "convar.h" -#include "utlstring.h" +#include "shareddefs.h" +#include "tier0/convar.h" +#include "tier0/utlstring.h" class CEntityIdentity; class CEntityInstance; class CBaseEntity; class CCSPlayerPawn; -enum DamageTypes_t : unsigned int; extern CConVar g_cvarBurnParticle; @@ -40,4 +40,4 @@ bool IgnitePawn(CCSPlayerPawn* pEntity, CBaseEntity* pInflictor = nullptr, CBaseEntity* pAttacker = nullptr, CBaseEntity* pAbility = nullptr, - DamageTypes_t nDamageType = DamageTypes_t(8)); // DMG_BURN + DamageTypes_t nDamageType = DMG_BURN); diff --git a/src/cvars.cpp b/src/cvars.cpp index 89863117..718d0087 100644 --- a/src/cvars.cpp +++ b/src/cvars.cpp @@ -18,7 +18,7 @@ */ #include "common.h" -#include "icvar.h" +#include "tier0/icvar.h" #include "tier0/memdbgon.h" diff --git a/src/cvarwhitelist.h b/src/cvarwhitelist.h index ecb77a70..8310cc56 100644 --- a/src/cvarwhitelist.h +++ b/src/cvarwhitelist.h @@ -19,7 +19,7 @@ #pragma once -#include "convar.h" +#include "tier0/convar.h" #undef snprintf #include "vendor/nlohmann/json_fwd.hpp" diff --git a/src/detours.cpp b/src/detours.cpp index 32410ab6..1b292335 100644 --- a/src/detours.cpp +++ b/src/detours.cpp @@ -26,10 +26,10 @@ #include "buttonwatch.h" #include "commands.h" #include "common.h" -#include "ctimer.h" #include "customio.h" #include "cvarwhitelist.h" #include "detours.h" +#include "engine2/serversideclient.h" #include "entities.h" #include "entity/cbasemodelentity.h" #include "entity/cbeam.h" @@ -44,16 +44,13 @@ #include "entity/ctriggerpush.h" #include "entity/services.h" #include "entwatch.h" -#include "gameconfig.h" #include "igameevents.h" #include "irecipientfilter.h" #include "khook_helpers.h" #include "map_votes.h" #include "mapmigrations.h" -#include "module.h" -#include "networksystem/inetworkserializer.h" #include "playermanager.h" -#include "serversideclient.h" +#include "tier0/splitstring.h" #include "tier0/vprof.h" #include "votemanager.h" #include "zombiereborn.h" @@ -454,10 +451,12 @@ KHook::Return Detour_CEntityIdentity_AcceptInput(CEntityIdentity* pThis, C // Handle KeyValue(s) if (!V_strnicmp(pInputName->String(), "KeyValue", 8)) { - if ((value->m_type == FIELD_CSTRING || value->m_type == FIELD_STRING) && value->m_pszString) + const char* pszValue = value->ToString(); + + if ((value->GetType() == FIELD_CSTRING || value->GetType() == FIELD_STRING) && pszValue && *pszValue) { // always const char*, even if it's FIELD_STRING (that is bug string from lua 'EntFire') - return {KHook::Action::Supersede, CustomIO_HandleInput(pThis->m_pInstance, value->m_pszString, pActivator, pCaller)}; + return {KHook::Action::Supersede, CustomIO_HandleInput(pThis->m_pInstance, pszValue, pActivator, pCaller)}; } Message("Invalid value type for input %s\n", pInputName->String()); return {KHook::Action::Supersede, false}; @@ -466,11 +465,12 @@ KHook::Return Detour_CEntityIdentity_AcceptInput(CEntityIdentity* pThis, C if (!V_strnicmp(pInputName->String(), "IgniteL", 7)) // Override IgniteLifetime { float flDuration = 0.f; + const char* pszValue = value->ToString(); - if ((value->m_type == FIELD_CSTRING || value->m_type == FIELD_STRING) && value->m_pszString) - flDuration = V_StringToFloat32(value->m_pszString, 0.f); + if ((value->GetType() == FIELD_CSTRING || value->GetType() == FIELD_STRING) && pszValue && *pszValue) + flDuration = V_StringToFloat32(pszValue, 0.f); else - flDuration = value->m_float32; + flDuration = value->Get(); CCSPlayerPawn* pPawn = reinterpret_cast(pThis->m_pInstance); @@ -480,11 +480,12 @@ KHook::Return Detour_CEntityIdentity_AcceptInput(CEntityIdentity* pThis, C else if (!V_strnicmp(pInputName->String(), "AddScore", 8)) { int iScore = 0; + const char* pszValue = value->ToString(); - if ((value->m_type == FIELD_CSTRING || value->m_type == FIELD_STRING) && value->m_pszString) - iScore = V_StringToInt32(value->m_pszString, 0); + if ((value->GetType() == FIELD_CSTRING || value->GetType() == FIELD_STRING) && pszValue && *pszValue) + iScore = V_StringToInt32(pszValue, 0); else - iScore = value->m_int32; + iScore = value->Get(); CCSPlayerPawn* pPawn = reinterpret_cast(pThis->m_pInstance); @@ -498,8 +499,10 @@ KHook::Return Detour_CEntityIdentity_AcceptInput(CEntityIdentity* pThis, C { if (const auto pHudHint = reinterpret_cast(pThis->m_pInstance)->AsHudHint()) { - if ((value->m_type == FIELD_CSTRING || value->m_type == FIELD_STRING) && value->m_pszString) - pHudHint->m_iszMessage(GameEntitySystem()->AllocPooledString(value->m_pszString)); + const char* pszValue = value->ToString(); + + if ((value->GetType() == FIELD_CSTRING || value->GetType() == FIELD_STRING) && pszValue && *pszValue) + pHudHint->m_iszMessage(GameEntitySystem()->AllocPooledString(pszValue)); return {KHook::Action::Supersede, true}; } } @@ -507,8 +510,10 @@ KHook::Return Detour_CEntityIdentity_AcceptInput(CEntityIdentity* pThis, C { if (const auto pModelEntity = reinterpret_cast(pThis->m_pInstance)->AsBaseModelEntity()) { - if ((value->m_type == FIELD_CSTRING || value->m_type == FIELD_STRING) && value->m_pszString && PrepareMapSetModel(pModelEntity)) - pModelEntity->SetModel(value->m_pszString); + const char* pszValue = value->ToString(); + + if ((value->GetType() == FIELD_CSTRING || value->GetType() == FIELD_STRING) && pszValue && *pszValue && PrepareMapSetModel(pModelEntity)) + pModelEntity->SetModel(pszValue); return {KHook::Action::Supersede, true}; } @@ -689,10 +694,8 @@ KHook::Return Detour_GetFreeClient(int64_t unk1, const __m12 return {KHook::Action::Ignore}; // Phantom client fix - for (int i = 0; i < GetClientList()->Count(); i++) + for (CServerSideClient* pClient : *GetClientList()) { - CServerSideClient* pClient = (*GetClientList())[i]; - if (pClient && pClient->GetSignonState() < SIGNONSTATE_CONNECTED) return {KHook::Action::Supersede, pClient}; } @@ -937,9 +940,8 @@ KHook::Return Detour_CWorldRendererMgr_CreateWorld_Internal_Po auto pWorld = singleWorld->m_pCWorld; auto vecLumpData = (CUtlVector*)((uint8_t*)pWorld + 0x298); - FOR_EACH_VEC(*vecLumpData, i) + for (auto& lump : *vecLumpData) { - auto& lump = (*vecLumpData)[i]; auto lumpData = *(LumpData**)lump; auto vecEntityKeyValues = (CUtlVector*)((uint8_t*)lumpData + 0x1220); diff --git a/src/detours.h b/src/detours.h index 9a1d22e4..dda7d4a3 100644 --- a/src/detours.h +++ b/src/detours.h @@ -21,7 +21,7 @@ #include "cs2_sdk/entityio.h" #include "khook.hpp" #include "map.h" -#include +#include class CCheckTransmitInfo; class IRecipientFilter; @@ -55,6 +55,8 @@ class QAngle; class CEconItemView; class CCSGameRules; class CBeam; +class IWorldRendererMgr; +struct CPulseArgumentPack; struct CTakeDamageResult; enum class AcquireMethod diff --git a/src/discord.cpp b/src/discord.cpp index cad81a75..c5b2f3f7 100644 --- a/src/discord.cpp +++ b/src/discord.cpp @@ -18,11 +18,10 @@ */ #include "discord.h" -#include "KeyValues.h" #include "common.h" #include "httpmanager.h" #include "interfaces/interfaces.h" -#include "utlstring.h" +#include "tier0/keyvalues.h" #include #include "vendor/nlohmann/json.hpp" diff --git a/src/entities.cpp b/src/entities.cpp index 3770f604..e23385bf 100644 --- a/src/entities.cpp +++ b/src/entities.cpp @@ -21,7 +21,6 @@ #include "ctimer.h" #include "entity.h" -#include "entity/cbaseplayercontroller.h" #include "entity/ccsplayercontroller.h" #include "entity/ccsplayerpawn.h" #include "entity/cgameplayerequip.h" @@ -67,9 +66,9 @@ static void StripPlayer(CCSPlayerPawn* pPawn, const std::unordered_set CUtlVector>* weapons = pWeaponService->m_hMyWeapons(); std::vector vecWeaponsToRemove; - FOR_EACH_VEC(*weapons, i) + for (const auto& hWeapon : *weapons) { - CBasePlayerWeapon* weapon = (*weapons)[i].Get(); + CBasePlayerWeapon* weapon = hWeapon.Get(); if (!weapon) continue; @@ -216,7 +215,7 @@ namespace CGamePlayerEquipHandler bool TriggerForActivatedPlayer(CGamePlayerEquip* pEntity, CBaseEntity* pActivator, variant_t* value) { - const auto pszWeapon = ((value->m_type == FIELD_CSTRING || value->m_type == FIELD_STRING) && value->m_pszString) ? value->m_pszString : nullptr; + const auto pszWeapon = (value->GetType() == FIELD_CSTRING || value->GetType() == FIELD_STRING) ? value->ToString() : nullptr; if (!pActivator || !pActivator->IsPawn()) return true; @@ -241,7 +240,7 @@ namespace CGamePlayerEquipHandler if (!pItemServices) return true; - if (pszWeapon && V_strcmp(pszWeapon, "(null)")) + if (pszWeapon && *pszWeapon && V_strcmp(pszWeapon, "(null)")) { pItemServices->GiveNamedItemAws(pszWeapon); // Don't execute game function (we fixed string param) diff --git a/src/entities.h b/src/entities.h index d18b4f6a..a878e7a3 100644 --- a/src/entities.h +++ b/src/entities.h @@ -19,8 +19,8 @@ #pragma once +#include "entity2/variant.h" #include -#include "variant.h" class InputData_t; class CGamePlayerEquip; diff --git a/src/entitylistener.cpp b/src/entitylistener.cpp index ab5d84a0..60696fc1 100644 --- a/src/entitylistener.cpp +++ b/src/entitylistener.cpp @@ -26,8 +26,6 @@ #include "entity/cgamerules.h" #include "entityclass.h" #include "entwatch.h" -#include "gameconfig.h" -#include "plat.h" CEntityListener* g_pEntityListener = nullptr; diff --git a/src/entitylistener.h b/src/entitylistener.h index bcab8be9..106a5101 100644 --- a/src/entitylistener.h +++ b/src/entitylistener.h @@ -18,9 +18,9 @@ */ #pragma once -#include "entitysystem.h" +#include "gameentitysystem.h" -class CEntityListener : public IEntityListener +class CEntityListener final : public IEntityListener { void OnEntitySpawned(CEntityInstance* pEntity) override; void OnEntityCreated(CEntityInstance* pEntity) override; diff --git a/src/entwatch.cpp b/src/entwatch.cpp index 3c77ee84..916b3710 100644 --- a/src/entwatch.cpp +++ b/src/entwatch.cpp @@ -21,33 +21,22 @@ #include "commands.h" #include "cs2fixes.h" #include "ctimer.h" -#include "customio.h" #include "detours.h" -#include "engine/igameeventsystem.h" #include "entity/cbasebutton.h" #include "entity/ccsplayercontroller.h" #include "entity/ccsplayerpawn.h" -#include "entity/cgamerules.h" #include "entity/cmathcounter.h" #include "entity/cpointworldtext.h" -#include "entity/cteam.h" #include "entity/services.h" #include "eventlistener.h" -#include "gameevents.pb.h" #include "leader.h" #include "map_votes.h" -#include "networksystem/inetworkmessages.h" #include "playermanager.h" -#include "recipientfilters.h" -#include "serversideclient.h" -#include "tier0/vprof.h" #include "user_preferences.h" -#include "usermessages.pb.h" #include "utils/entity.h" #include "vendor/nlohmann/json.hpp" #include "zombiereborn.h" #include -#include #include "tier0/memdbgon.h" @@ -1696,9 +1685,9 @@ void CEWHandler::Transfer(CCSPlayerController* pCaller, int iItemInstance, CHand } CUtlVector>* weapons = pOwnerPawn->m_pWeaponServices()->m_hMyWeapons(); - FOR_EACH_VEC(*weapons, i) + for (const auto& hWeapon : *weapons) { - CBasePlayerWeapon* pWeapon = (*weapons)[i].Get(); + CBasePlayerWeapon* pWeapon = hWeapon.Get(); if (!pWeapon) continue; @@ -1713,9 +1702,9 @@ void CEWHandler::Transfer(CCSPlayerController* pCaller, int iItemInstance, CHand // Make receiver drop the weapon in the item slot CUtlVector>* weapons = pReceiverPawn->m_pWeaponServices()->m_hMyWeapons(); - FOR_EACH_VEC(*weapons, i) + for (const auto& hWeapon : *weapons) { - CBasePlayerWeapon* pWeapon = (*weapons)[i].Get(); + CBasePlayerWeapon* pWeapon = hWeapon.Get(); if (!pWeapon) continue; @@ -2365,7 +2354,7 @@ CON_COMMAND_CHAT_FLAGS(etransfer, " - Transfer an En } int iNumClients = 0; - int pSlots[MAXPLAYERS]; + int pSlots[MAX_PLAYERS]; // Find receiver if (!g_playerManager->CanTargetPlayers(player, args[2], iNumClients, pSlots, NO_MULTIPLE | NO_SPECTATOR | NO_DEAD)) diff --git a/src/eventlistener.h b/src/eventlistener.h index 0c482b8d..f5cc1cd4 100644 --- a/src/eventlistener.h +++ b/src/eventlistener.h @@ -20,7 +20,6 @@ #pragma once #include "common.h" #include "igameevents.h" -#include "utlstring.h" class CGameEventListener; diff --git a/src/events.cpp b/src/events.cpp index a945929c..e64cec2c 100644 --- a/src/events.cpp +++ b/src/events.cpp @@ -17,12 +17,11 @@ * this program. If not, see . */ -#include "KeyValues.h" #include "commands.h" #include "common.h" #include "ctimer.h" +#include "engine2/ivengineserver2.h" #include "entities.h" -#include "entity/cbaseplayercontroller.h" #include "entity/cgamerules.h" #include "entwatch.h" #include "eventlistener.h" @@ -32,7 +31,6 @@ #include "map_votes.h" #include "mapmigrations.h" #include "panoramavote.h" -#include "recipientfilters.h" #include "topdefender.h" #include "votemanager.h" #include "zombiereborn.h" diff --git a/src/gamesystem.cpp b/src/gamesystem.cpp index ed00ec15..1214f0cd 100644 --- a/src/gamesystem.cpp +++ b/src/gamesystem.cpp @@ -19,7 +19,6 @@ #include "gamesystem.h" #include "addresses.h" -#include "adminsystem.h" #include "common.h" #include "customio.h" #include "entities.h" @@ -201,13 +200,11 @@ GS_EVENT_MEMBER(CGameSystem, PostSpawnGroupLoad) // Ensure clients have no leaked spawngroups every time a new one loads // Due to a timing problem for leaked spawngroups with this callback, clients may have one lingering, this is fine since it'll still be taken care of next time a spawngroup loads - FOR_EACH_VEC(*pClients, i) + for (auto pClient : *pClients) { - auto pClient = (*pClients)[i]; - - if (!pClient || pClient->m_vecLoadedSpawnGroups.Count() == vecActualSpawnGroups.Count()) + if (!pClient || pClient->m_LoadedSpawnGroups.Count() == vecActualSpawnGroups.Count()) continue; - pClient->m_vecLoadedSpawnGroups = vecActualSpawnGroups; + pClient->m_LoadedSpawnGroups = vecActualSpawnGroups; } } \ No newline at end of file diff --git a/src/gamesystem.h b/src/gamesystem.h index 2d2d7352..e59b5064 100644 --- a/src/gamesystem.h +++ b/src/gamesystem.h @@ -32,7 +32,7 @@ bool InitGameSystems(); bool UnregisterGameSystem(); template -class CGameSystemStaticCustomFactory : public CGameSystemStaticFactory +class CGameSystemStaticCustomFactory final : public CGameSystemStaticFactory { public: CGameSystemStaticCustomFactory(const char* pName, T* pActualGlobal, U** ppGlobalPointer = nullptr) : @@ -52,7 +52,7 @@ class CGameSystemStaticCustomFactory : public CGameSystemStaticFactory *CBaseGameSystemFactory::sm_pFirst = pFactoryCurrent->m_pNext; else pFactoryPrevious->m_pNext = pFactoryCurrent->m_pNext; - delete pFactoryCurrent; + delete this; return; } pFactoryPrevious = pFactoryCurrent; @@ -93,24 +93,6 @@ class CGameSystem : public CBaseGameSystem extern CGameSystem g_GameSystem; -// Quick and dirty definition -// MSVC for whatever reason flips overload ordering, and this has three of them -// So this is based on the linux bin which is correct, and MSVC will flip it to match the windows bin, fun -class IEntityResourceManifest -{ -public: - virtual void AddResource(const char*) = 0; - virtual void AddResource(const char*, void*) = 0; - virtual void AddResource(const char*, void*, void*, void*) = 0; - virtual void unk_04() = 0; - virtual void unk_05() = 0; - virtual void unk_06() = 0; - virtual void unk_07() = 0; - virtual void unk_08() = 0; - virtual void unk_09() = 0; - virtual void unk_10() = 0; -}; - abstract_class IGameSystemEventDispatcher{ public : virtual ~IGameSystemEventDispatcher(){} diff --git a/src/idlemanager.cpp b/src/idlemanager.cpp index f1b2c3da..6601003b 100644 --- a/src/idlemanager.cpp +++ b/src/idlemanager.cpp @@ -20,6 +20,7 @@ #include "idlemanager.h" #include "commands.h" #include "cs2fixes.h" +#include "engine2/ivengineserver2.h" #include CIdleSystem* g_pIdleSystem = nullptr; diff --git a/src/idlemanager.h b/src/idlemanager.h index 167f0c29..eff00a1d 100644 --- a/src/idlemanager.h +++ b/src/idlemanager.h @@ -18,7 +18,7 @@ */ #pragma once -#include "convar.h" +#include "tier0/convar.h" extern CConVar g_cvarIdleKickTime; diff --git a/src/leader.cpp b/src/leader.cpp index d0b84b37..d370223a 100644 --- a/src/leader.cpp +++ b/src/leader.cpp @@ -534,7 +534,7 @@ CON_COMMAND_CHAT_LEADER(glow, "[name] [color] - Toggle glow highlight on a playe std::string strCommandPlayerName = player ? player->GetPlayerName() : CONSOLE_NAME; int iNumClients = 0; - int pSlots[MAXPLAYERS]; + int pSlots[MAX_PLAYERS]; ETargetType nType; uint64 iTargetFlags = NO_DEAD; if (!bIsAdmin) @@ -638,7 +638,7 @@ CON_COMMAND_CHAT(vl, " - Vote for a player to become a leader") } int iNumClients = 0; - int pSlots[MAXPLAYERS]; + int pSlots[MAX_PLAYERS]; if (!g_playerManager->CanTargetPlayers(player, args[1], iNumClients, pSlots, NO_MULTIPLE | NO_SELF | NO_BOT | NO_IMMUNITY)) return; @@ -689,7 +689,7 @@ CON_COMMAND_CHAT_LEADER(defend, "[name|duration] [duration] - Place a defend mar std::string strCommandPlayerName = player ? player->GetPlayerName() : CONSOLE_NAME; int iNumClients = 0; - int pSlots[MAXPLAYERS]; + int pSlots[MAX_PLAYERS]; ETargetType nType; const char* pszTarget = "@me"; if ((args.ArgC() > 2 || (args.ArgC() == 2 && iDuration == -1)) && (bIsAdmin || g_cvarLeaderCanTargetPlayers.Get())) @@ -720,7 +720,7 @@ CON_COMMAND_CHAT_LEADER(tracer, "[name] [color] - Toggle projectile tracers on a std::string strCommandPlayerName = player ? player->GetPlayerName() : CONSOLE_NAME; int iNumClients = 0; - int pSlots[MAXPLAYERS]; + int pSlots[MAX_PLAYERS]; ETargetType nType; const char* pszTarget = "@me"; if (args.ArgC() >= 2 && (bIsAdmin || g_cvarLeaderCanTargetPlayers.Get())) @@ -776,7 +776,7 @@ CON_COMMAND_CHAT_LEADER(beacon, "[name] [color] - Toggle beacon on a player") std::string strCommandPlayerName = player ? player->GetPlayerName() : CONSOLE_NAME; int iNumClients = 0; - int pSlots[MAXPLAYERS]; + int pSlots[MAX_PLAYERS]; ETargetType nType; uint64 iTargetFlags = NO_DEAD; if (!bIsAdmin) @@ -964,7 +964,7 @@ CON_COMMAND_CHAT_LEADER(leader, "[name] [color] - Force leader status on a playe std::string strCommandPlayerName = player ? player->GetPlayerName() : CONSOLE_NAME; int iNumClients = 0; - int pSlots[MAXPLAYERS]; + int pSlots[MAX_PLAYERS]; ETargetType nType; const char* pszTarget = "@me"; if (args.ArgC() >= 2) @@ -998,7 +998,7 @@ CON_COMMAND_CHAT_FLAGS(removeleader, "[name] - Remove leader status from a playe std::string strCommandPlayerName = player ? player->GetPlayerName() : CONSOLE_NAME; int iNumClients = 0; - int pSlots[MAXPLAYERS]; + int pSlots[MAX_PLAYERS]; ETargetType nType; if (!g_playerManager->CanTargetPlayers(player, args[1], iNumClients, pSlots, NO_MULTIPLE | NO_BOT, nType)) diff --git a/src/map_votes.cpp b/src/map_votes.cpp index 67d990b7..7e4d8696 100644 --- a/src/map_votes.cpp +++ b/src/map_votes.cpp @@ -21,15 +21,15 @@ #include "commands.h" #include "common.h" #include "ctimer.h" +#include "engine2/inetworkgameserver.h" +#include "engine2/ivengineserver2.h" #include "entity/cgamerules.h" #include "eventlistener.h" -#include "iserver.h" #include "mapmigrations.h" #include "playermanager.h" #include "steam/steam_gameserver.h" -#include "strtools.h" -#include "utlstring.h" -#include "utlvector.h" +#include "tier0/tier0_strtools.h" +#include "tier0/utlvector.h" #undef snprintf #include "vendor/nlohmann/json.hpp" #include "votemanager.h" @@ -225,7 +225,7 @@ void CMapVoteSystem::OnLevelInit(const char* pszMapName) m_bIntermissionStarted = false; m_pForcedNextMap = nullptr; - for (int i = 0; i < MAXPLAYERS; i++) + for (int i = 0; i < MAX_PLAYERS; i++) ClearPlayerInfo(i); // Delay one tick to override any .cfg's @@ -295,7 +295,7 @@ void CMapVoteSystem::StartVote() } // Reset the player vote counts as the vote just started - for (int i = 0; i < MAXPLAYERS; i++) + for (int i = 0; i < MAX_PLAYERS; i++) m_arrPlayerVotes[i] = -1; // Print all available maps out to console @@ -1104,14 +1104,10 @@ bool CMapVoteSystem::IsIntermissionAllowed(bool bCheckOnly) return true; } -CUtlStringList CMapVoteSystem::CreateWorkshopMapGroup() +void CMapVoteSystem::CreateWorkshopMapGroup(CUtlStringList& mapList) { - CUtlStringList mapList; - for (auto pMap : m_vecMapList) mapList.CopyAndAddToTail(pMap->GetDisplayName()); - - return mapList; } bool CMapVoteSystem::WriteMapCooldownsToFile() @@ -1297,7 +1293,7 @@ void CMapVoteSystem::PutMapOnCooldown(const char* pszMapName, float fCooldown) // Add randomness if applicable if (g_cvarVoteMapsCooldown.Get() != 0.0f) { - float flRandomValue = ((float)rand() / RAND_MAX) * g_cvarVoteMapsCooldownRng.Get(); + float flRandomValue = ((float)rand() / (float)RAND_MAX) * g_cvarVoteMapsCooldownRng.Get(); if (rand() % 2) fCooldown += flRandomValue; diff --git a/src/map_votes.h b/src/map_votes.h index e6990288..90db95ad 100644 --- a/src/map_votes.h +++ b/src/map_votes.h @@ -17,11 +17,11 @@ * this program. If not, see . */ -#include "KeyValues.h" #include "common.h" #include "entity/ccsplayercontroller.h" #include "steam/isteamugc.h" #include "steam/steam_api_common.h" +#include "tier0/utlstringlist.h" #undef snprintf #include "vendor/nlohmann/json_fwd.hpp" #include @@ -168,7 +168,7 @@ class CMapVoteSystem CMapVoteSystem() { // Initialize the nomination / vote arrays to -1 - for (int i = 0; i < MAXPLAYERS; i++) + for (int i = 0; i < MAX_PLAYERS; i++) { m_arrPlayerNominations[i] = -1; m_arrPlayerVotes[i] = -1; @@ -200,7 +200,7 @@ class CMapVoteSystem bool IsVoteOngoing() { return m_bIsVoteOngoing; } bool IsIntermissionAllowed(bool bCheckOnly = true); bool IsMapListLoaded() { return m_bMapListLoaded; } - CUtlStringList CreateWorkshopMapGroup(); + void CreateWorkshopMapGroup(CUtlStringList& mapList); void QueueMapDownload(PublishedFileId_t iWorkshopId); void StartMapDownload(float flDelay = 0.0f); void PrintDownloadProgress(); @@ -234,10 +234,10 @@ class CMapVoteSystem std::vector> m_vecMapList; std::vector> m_vecGroups; std::vector> m_vecCooldowns; - int m_arrPlayerNominations[MAXPLAYERS]; + int m_arrPlayerNominations[MAX_PLAYERS]; std::shared_ptr m_pForcedNextMap; int m_iRandomWinnerShift = 0; - int m_arrPlayerVotes[MAXPLAYERS]; + int m_arrPlayerVotes[MAX_PLAYERS]; bool m_bIsVoteOngoing = false; bool m_bMapListLoaded = false; bool m_bIntermissionStarted = false; diff --git a/src/mapmigrations.cpp b/src/mapmigrations.cpp index 8e57a8eb..f7f8ec96 100644 --- a/src/mapmigrations.cpp +++ b/src/mapmigrations.cpp @@ -86,10 +86,8 @@ void CMapMigrations::RunMigrations(CUtlVector* pVecEntityKeyV void CMapMigrations::Migrations_Rendermode(CUtlVector* pVecEntityKeyValues) { - FOR_EACH_VEC(*pVecEntityKeyValues, i) + for (auto pKeyValues : *pVecEntityKeyValues) { - auto pKeyValues = (*pVecEntityKeyValues)[i]; - if (!pKeyValues->HasValue("rendermode")) continue; @@ -111,10 +109,8 @@ void CMapMigrations::Migrations_Rendermode(CUtlVector* pVecEn void CMapMigrations::Migrations_20260121(CUtlVector* pVecEntityKeyValues) { - FOR_EACH_VEC(*pVecEntityKeyValues, i) + for (auto pKeyValues : *pVecEntityKeyValues) { - auto pKeyValues = (*pVecEntityKeyValues)[i]; - if (!V_strcasecmp(pKeyValues->GetString("classname"), "func_door_rotating") && pKeyValues->HasValue("spawnflags")) { uint32 spawnFlags = pKeyValues->GetUint("spawnflags"); @@ -170,10 +166,10 @@ void CMapMigrations::Migrations_20260420(CBasePlayerWeapon* pWeapon) bool CMapMigrations::Migrations_20260922(CEntityIdentity* pThis, CUtlSymbolLarge* pInputName, CEntityInstance* pActivator, CEntityInstance* pCaller, variant_t* value) { // Fix stringified Pulse argument packs formatting float decimals breaking logic_case matching post 2026-09-22 CS2 update - if (value->m_type == FIELD_FLOAT32 && !V_strcasecmp(pInputName->String(), "InValue") && !V_strcasecmp(pThis->GetClassname(), "logic_case")) + if (value->GetType() == FIELD_FLOAT32 && !V_strcasecmp(pInputName->String(), "InValue") && !V_strcasecmp(pThis->GetClassname(), "logic_case")) { char szValue[32]; - V_snprintf(szValue, sizeof(szValue), "%g", value->m_float32); + V_snprintf(szValue, sizeof(szValue), "%g", value->Get()); // Back up through CEntityInstance_AcceptInput so we can just worry about variant_t ((CBaseEntity*)pThis->m_pInstance)->AcceptInput(pInputName->String(), szValue, pActivator, pCaller); diff --git a/src/mapmigrations.h b/src/mapmigrations.h index 9c57da3a..ec824c18 100644 --- a/src/mapmigrations.h +++ b/src/mapmigrations.h @@ -19,12 +19,10 @@ #pragma once -#include "KeyValues.h" -#include "convar.h" #include "cs2_sdk/entity/ccsweaponbase.h" #include "ehandle.h" +#include "tier0/convar.h" #include -#undef max extern CConVar g_cvarMapMigrations20260121; diff --git a/src/mempatch.cpp b/src/mempatch.cpp index 2dcd025e..d12008c3 100644 --- a/src/mempatch.cpp +++ b/src/mempatch.cpp @@ -19,9 +19,8 @@ #include "mempatch.h" #include "common.h" -#include "khook.hpp" #include "tier0/dbg.h" -#include "tier1/strtools.h" +#include "tier0/tier0_strtools.h" #include "utils/module.h" #include "tier0/memdbgon.h" diff --git a/src/panoramavote.cpp b/src/panoramavote.cpp index bd7117fd..8f406225 100644 --- a/src/panoramavote.cpp +++ b/src/panoramavote.cpp @@ -23,13 +23,12 @@ #include "common.h" #include "cs2fixes.h" #include "ctimer.h" -#include "engine/igameeventsystem.h" +#include "engine2/igameeventsystem.h" #include "entity/cvotecontroller.h" #include "networksystem/inetworkmessages.h" #include "panoramavote.h" #include "recipientfilters.h" #include "utils/entity.h" -#include "utlstring.h" #include "tier0/memdbgon.h" @@ -97,7 +96,7 @@ bool CPanoramaVoteHandler::IsPlayerInVotePool(int iSlot) if (!m_bIsVoteInProgress) return false; - if (iSlot < 0 || iSlot > MAXPLAYERS) + if (iSlot < 0 || iSlot > MAX_PLAYERS) return false; for (int i = 0; i < m_iVoterCount; i++) @@ -228,7 +227,7 @@ void CPanoramaVoteHandler::InitVoters(CRecipientFilter* pFilter) { // Clear any old info m_iVoterCount = 0; - for (int i = 0; i < MAXPLAYERS; i++) + for (int i = 0; i < MAX_PLAYERS; i++) { m_iVoters[i] = -1; hVoteController->m_nVotesCast[i] = VOTE_UNCAST; @@ -240,7 +239,7 @@ void CPanoramaVoteHandler::InitVoters(CRecipientFilter* pFilter) m_iVoterCount = pFilter->GetRecipientCount(); const uint64 x = *reinterpret_cast(&pFilter->GetRecipients()); - for (int i = 0, j = 0; i < MAXPLAYERS; i++) + for (int i = 0, j = 0; i < MAX_PLAYERS; i++) if (x & (static_cast(1u) << i)) m_iVoters[j] = i; } @@ -309,7 +308,7 @@ void CPanoramaVoteHandler::EndVote(YesNoVoteEndReason reason) info.no_votes = hVoteController->m_nVoteOptionCount[VOTE_OPTION2]; info.num_votes = info.yes_votes + info.no_votes; - for (int i = 0; i < MAXPLAYERS; i++) + for (int i = 0; i < MAX_PLAYERS; i++) { if (i < m_iVoterCount) { diff --git a/src/panoramavote.h b/src/panoramavote.h index 883414b3..1029b527 100644 --- a/src/panoramavote.h +++ b/src/panoramavote.h @@ -56,12 +56,12 @@ enum YesNoVoteAction #define VOTEINFO_CLIENT_ITEM 1 struct YesNoVoteInfo { - int num_votes; // Number of votes tallied in total - int yes_votes; // Number of votes for yes - int no_votes; // Number of votes for no - int num_clients; // Number of clients who could vote - int clientInfo[MAXPLAYERS][2]; // Client voting info, user VOTEINFO_CLIENT_ defines - // Anything >= [num_clients] is VOTE_NOTINCLUDED, VOTE_UNCAST = client didn't vote + int num_votes; // Number of votes tallied in total + int yes_votes; // Number of votes for yes + int no_votes; // Number of votes for no + int num_clients; // Number of clients who could vote + int clientInfo[MAX_PLAYERS][2]; // Client voting info, user VOTEINFO_CLIENT_ defines + // Anything >= [num_clients] is VOTE_NOTINCLUDED, VOTE_UNCAST = client didn't vote }; // Used to handle events relating to the vote menu @@ -135,7 +135,7 @@ class CPanoramaVoteHandler YesNoVoteHandler m_VoteHandler; YesNoVoteResult m_VoteResult; int m_iVoterCount; - int m_iVoters[MAXPLAYERS]; + int m_iVoters[MAX_PLAYERS]; int m_iCurrentVoteCaller; char m_szCurrentVoteTitle[256]; diff --git a/src/patches.cpp b/src/patches.cpp index 55df3bac..712291e1 100644 --- a/src/patches.cpp +++ b/src/patches.cpp @@ -18,13 +18,7 @@ */ #include "patches.h" -#include "addresses.h" -#include "common.h" -#include "entity/cbasemodelentity.h" -#include "entity/ccsplayercontroller.h" -#include "entity/ccsplayerpawn.h" -#include "icvar.h" -#include "irecipientfilter.h" +#include "tier0/convar.h" #include "tier0/memdbgon.h" diff --git a/src/patches.h b/src/patches.h index 7edf2478..2d454bc9 100644 --- a/src/patches.h +++ b/src/patches.h @@ -1,6 +1,5 @@ #pragma once -#include "gameconfig.h" #include "mempatch.h" extern CMemPatch g_CommonPatches[]; diff --git a/src/playermanager.cpp b/src/playermanager.cpp index 6f932105..4262fd85 100644 --- a/src/playermanager.cpp +++ b/src/playermanager.cpp @@ -22,7 +22,9 @@ #include "commands.h" #include "ctime" #include "ctimer.h" -#include "engine/igameeventsystem.h" +#include "engine2/igameeventsystem.h" +#include "engine2/ivengineserver2.h" +#include "engine2/serversideclient.h" #include "entity/ccsplayercontroller.h" #include "entwatch.h" #include "leader.h" @@ -30,11 +32,10 @@ #include "networksystem/inetworkmessages.h" #include "panoramavote.h" #include "recipientfilters.h" -#include "serversideclient.h" +#include "tier0/utlstring.h" #include "tier0/vprof.h" #include "user_preferences.h" #include "utils/entity.h" -#include "utlstring.h" #include "votemanager.h" #include "zombiereborn.h" #include <../cs2fixes.h> @@ -363,7 +364,7 @@ void ZEPlayer::StartBeacon(Color color, ZEPlayerHandle hGiver /* = 0*/) if (pPlayer->m_iTeamNum < CS_TEAM_T || !pPlayer->m_hPlayerPawn->IsAlive() || pPlayer->m_iTeamNum != iTeamNum) { - addresses::UTIL_Remove(pParticle); + pParticle->Remove(); return -1.0f; } @@ -389,7 +390,7 @@ void ZEPlayer::StartBeacon(Color color, ZEPlayerHandle hGiver /* = 0*/) // Remove beacon granted by leader if his leader was stripped if (!pBeaconGiver->IsLeader()) { - addresses::UTIL_Remove(pParticle); + pParticle->Remove(); return -1.0f; } @@ -404,7 +405,7 @@ void ZEPlayer::EndBeacon() CParticleSystem* pParticle = m_hBeaconParticle.Get(); if (pParticle) - addresses::UTIL_Remove(pParticle); + pParticle->Remove(); } // Kills off currently active mark (if exists) and makes a new one. @@ -519,7 +520,7 @@ void ZEPlayer::StartGlow(Color color, int duration) CBaseModelEntity* pModelParent = (CBaseModelEntity*)pParentSceneNode->m_pOwner(); if (pModelParent) - addresses::UTIL_Remove(pModelParent); + pModelParent->Remove(); return -1.0f; } @@ -545,7 +546,7 @@ void ZEPlayer::StartGlow(Color color, int duration) CBaseModelEntity* pModelParent = (CBaseModelEntity*)pParentSceneNode->m_pOwner(); if (pModelParent) - addresses::UTIL_Remove(pModelParent); + pModelParent->Remove(); return -1.0f; }); @@ -568,7 +569,7 @@ void ZEPlayer::EndGlow() CBaseModelEntity* pModelParent = (CBaseModelEntity*)pParentSceneNode->m_pOwner(); if (pModelParent) - addresses::UTIL_Remove(pModelParent); + pModelParent->Remove(); } void ZEPlayer::CycleButtonWatch() @@ -951,8 +952,8 @@ void CPlayerManager::OnClientPutInServer(CPlayerSlot slot) CServerSideClient* pClient = GetClientBySlot(slot); - if (pClient && pClient->m_vecLoadedSpawnGroups.Count() != vecActualSpawnGroups.Count()) - pClient->m_vecLoadedSpawnGroups = vecActualSpawnGroups; + if (pClient && pClient->m_LoadedSpawnGroups.Count() != vecActualSpawnGroups.Count()) + pClient->m_LoadedSpawnGroups = vecActualSpawnGroups; } void CPlayerManager::OnLateLoad() @@ -1226,9 +1227,9 @@ void CPlayerManager::SetupInfiniteAmmo() CUtlVector>* weapons = pWeaponServices->m_hMyWeapons(); - FOR_EACH_VEC(*weapons, i) + for (const auto& hWeapon : *weapons) { - CBasePlayerWeapon* weapon = (*weapons)[i].Get(); + CBasePlayerWeapon* weapon = hWeapon.Get(); if (!weapon) continue; @@ -1821,7 +1822,7 @@ bool CPlayerManager::CanTargetPlayers(CCSPlayerController* pPlayer, const char* ZEPlayer* CPlayerManager::GetPlayer(CPlayerSlot slot) { - if (slot.Get() < 0 || slot.Get() >= MAXPLAYERS) + if (slot.Get() < 0 || slot.Get() >= MAX_PLAYERS) return nullptr; return m_vecPlayers[slot.Get()]; @@ -1837,7 +1838,7 @@ ZEPlayer* CPlayerManager::GetPlayerFromUserId(uint16 userid) { uint8 index = userid & 0xFF; - if (index >= MAXPLAYERS) + if (index >= MAX_PLAYERS) return nullptr; return m_vecPlayers[index]; @@ -1980,10 +1981,8 @@ int CPlayerManager::GetOnlinePlayerCount(bool bCountBots) if (GetGlobals()) flLastUpdateTime = GetGlobals()->curtime; - for (int i = 0; i < GetClientList()->Count(); i++) + for (CServerSideClient* pClient : *GetClientList()) { - CServerSideClient* pClient = (*GetClientList())[i]; - if (pClient && pClient->GetSignonState() >= SIGNONSTATE_CONNECTED && (bCountBots || !pClient->IsFakeClient())) iOnlinePlayers++; } @@ -1998,6 +1997,6 @@ void CPlayerManager::FullUpdateAllClients() if (!pClients) return; - FOR_EACH_VEC(*pClients, i) - (*pClients)[i]->ForceFullUpdate(); + for (auto pClient : *pClients) + pClient->m_nDeltaTick = -1; } \ No newline at end of file diff --git a/src/playermanager.h b/src/playermanager.h index ee7eac18..9753fec7 100644 --- a/src/playermanager.h +++ b/src/playermanager.h @@ -18,7 +18,6 @@ */ #pragma once -#include "bitvec.h" #include "common.h" #include "entity/cparticlesystem.h" #include "entity/cpointorient.h" @@ -30,7 +29,8 @@ #include "steam/isteamuser.h" #include "steam/steam_api_common.h" #include "steam/steamclientpublic.h" -#include "utlvector.h" +#include "tier0/bitvec.h" +#include "tier0/utlvector.h" #include extern CConVar g_cvarFlashLightTransmitOthers; @@ -369,7 +369,7 @@ class ZEPlayer uint64 m_iAdminFlags; int m_iAdminImmunity; int m_iHideDistance; - CBitVec m_shouldTransmit; + CBitVec m_shouldTransmit; int m_iTotalDamage; int m_iTotalHits; int m_iTotalHeadshots; @@ -484,7 +484,7 @@ class CPlayerManager STEAM_GAMESERVER_CALLBACK_MANUAL(CPlayerManager, OnValidateAuthTicket, ValidateAuthTicketResponse_t, m_CallbackValidateAuthTicketResponse); private: - ZEPlayer* m_vecPlayers[MAXPLAYERS]; + ZEPlayer* m_vecPlayers[MAX_PLAYERS]; uint64 m_nUsingStopSound; uint64 m_nUsingSilenceSound; diff --git a/src/recipientfilters.h b/src/recipientfilters.h index 15500e67..06a3dd4e 100644 --- a/src/recipientfilters.h +++ b/src/recipientfilters.h @@ -49,7 +49,7 @@ class CRecipientFilter : public IRecipientFilter { m_Recipients.ClearAll(); - for (int i = 0; i < MAXPLAYERS; i++) + for (int i = 0; i < MAX_PLAYERS; i++) { if (!g_playerManager->GetPlayer(i)) continue; diff --git a/src/topdefender.cpp b/src/topdefender.cpp index 92fc5000..c08ad3af 100644 --- a/src/topdefender.cpp +++ b/src/topdefender.cpp @@ -21,7 +21,6 @@ #include "commands.h" #include "common.h" #include "ctimer.h" -#include "detours.h" #include "entity/ccsplayercontroller.h" #include "idlemanager.h" #include "playermanager.h" @@ -323,7 +322,7 @@ void TopDefenderSearch(CCSPlayerController* player, const CCommand& args) if (iRank <= 0 || iRank > sortedPlayers.size()) { int iNumClients = 0; - int pSlots[MAXPLAYERS]; + int pSlots[MAX_PLAYERS]; if (!g_playerManager->CanTargetPlayers(player, args[1], iNumClients, pSlots, NO_MULTIPLE)) return; diff --git a/src/user_preferences.cpp b/src/user_preferences.cpp index 27f41e47..bb694e16 100644 --- a/src/user_preferences.cpp +++ b/src/user_preferences.cpp @@ -23,7 +23,7 @@ #include "entwatch.h" #include "httpmanager.h" #include "playermanager.h" -#include "strtools.h" +#include "tier0/tier0_strtools.h" #include "zombiereborn.h" #include #undef snprintf diff --git a/src/user_preferences.h b/src/user_preferences.h index 5064c129..eff18b21 100644 --- a/src/user_preferences.h +++ b/src/user_preferences.h @@ -19,7 +19,6 @@ #pragma once #include "common.h" -#include "utlstring.h" #include #undef snprintf #include "vendor/nlohmann/json_fwd.hpp" @@ -56,6 +55,7 @@ class CPreferenceValue class CUserPreferencesStorage { public: + virtual ~CUserPreferencesStorage() = default; virtual void LoadPreferences(uint64 iSteamId, StorageCallback_t cb) = 0; virtual void StorePreferences(uint64 iSteamId, UserPrefsMap_t& preferences, StorageCallback_t cb) = 0; }; @@ -75,7 +75,7 @@ class CUserPreferencesSystem public: CUserPreferencesSystem() { - for (int i = 0; i < MAXPLAYERS; i++) + for (int i = 0; i < MAX_PLAYERS; i++) { m_mUserSteamIds[i] = 0; m_mPreferencesLoaded[i] = false; @@ -96,9 +96,9 @@ class CUserPreferencesSystem void PushPreferences(int iSlot); private: - UserPrefsMap_t m_mPreferencesMaps[MAXPLAYERS]; - uint64 m_mUserSteamIds[MAXPLAYERS]; - bool m_mPreferencesLoaded[MAXPLAYERS]; + UserPrefsMap_t m_mPreferencesMaps[MAX_PLAYERS]; + uint64 m_mUserSteamIds[MAX_PLAYERS]; + bool m_mPreferencesLoaded[MAX_PLAYERS]; }; extern CUserPreferencesSystem* g_pUserPreferencesSystem; \ No newline at end of file diff --git a/src/utils/entity.h b/src/utils/entity.h index 06ffbaa0..fad7d4fa 100644 --- a/src/utils/entity.h +++ b/src/utils/entity.h @@ -20,10 +20,8 @@ #pragma once #include "../addresses.h" -#include "datamap.h" +#include "entity2/variant.h" #include "platform.h" -#include "string_t.h" -#include "variant.h" class CEntityInstance; class CBaseEntity; diff --git a/src/utils/hud_manager.cpp b/src/utils/hud_manager.cpp index 58dde4ce..24e0f87c 100644 --- a/src/utils/hud_manager.cpp +++ b/src/utils/hud_manager.cpp @@ -21,7 +21,7 @@ #include "../cs2fixes.h" #include "../ctimer.h" #include "../recipientfilters.h" -#include "engine/igameeventsystem.h" +#include "engine2/igameeventsystem.h" #include "entity/cgamerules.h" #include "gameevents.pb.h" #include "networksystem/inetworkmessages.h" diff --git a/src/utils/khook_helpers.h b/src/utils/khook_helpers.h index fd004856..3725dde0 100644 --- a/src/utils/khook_helpers.h +++ b/src/utils/khook_helpers.h @@ -23,6 +23,7 @@ class CKHookBase { public: + virtual ~CKHookBase() = default; virtual void Configure() = 0; }; diff --git a/src/utils/module.h b/src/utils/module.h index 543af18d..4db6bd95 100644 --- a/src/utils/module.h +++ b/src/utils/module.h @@ -22,7 +22,7 @@ #include "dbg.h" #include "interface.h" #include "plat.h" -#include "strtools.h" +#include "tier0/tier0_strtools.h" #include #include diff --git a/src/utils/plat_unix.cpp b/src/utils/plat_unix.cpp index 7bcab072..56e798da 100644 --- a/src/utils/plat_unix.cpp +++ b/src/utils/plat_unix.cpp @@ -25,16 +25,17 @@ #include "module.h" #include "plat.h" #include "sys/mman.h" + #include #include #include #include - #include #include - #include #include + #include #include #include #include + #include #include "tier0/memdbgon.h" diff --git a/src/utils/utils.cpp b/src/utils/utils.cpp index b2114219..c6e640b3 100644 --- a/src/utils/utils.cpp +++ b/src/utils/utils.cpp @@ -20,6 +20,7 @@ #include "utils.h" #include "../cs2fixes.h" #include "../gameconfig.h" +#include "engine2/ivengineserver2.h" void Message(const char* msg, ...) { diff --git a/src/utils/utils.h b/src/utils/utils.h index 24d16c66..04ad3fa7 100644 --- a/src/utils/utils.h +++ b/src/utils/utils.h @@ -21,7 +21,7 @@ #include "playerslot.h" #include "steam/isteamugc.h" -#include "utlvector.h" +#include "tier0/utlvector.h" #include class CServerSideClient; diff --git a/src/utils/vscript_function.cpp b/src/utils/vscript_function.cpp index 5519b81a..32b97b0d 100644 --- a/src/utils/vscript_function.cpp +++ b/src/utils/vscript_function.cpp @@ -34,9 +34,8 @@ void* GetVScriptFunction(ScriptClassDesc_t* pScriptDesc, const char* pszFuncName }; const auto& functionBindings = *reinterpret_cast*>(&pScriptDesc->m_FunctionBindings); - FOR_EACH_VEC(functionBindings, i) + for (auto& functionBinding : functionBindings) { - auto& functionBinding = functionBindings.Element(i); if (V_strcmp(functionBinding.m_desc.m_pszScriptName, pszFuncName) != 0) continue; diff --git a/src/virtual_hooks.cpp b/src/virtual_hooks.cpp index 617744b4..7f8076eb 100644 --- a/src/virtual_hooks.cpp +++ b/src/virtual_hooks.cpp @@ -19,7 +19,6 @@ #include "virtual_hooks.h" #include "adminsystem.h" -#include "cchecktransmitinfo.h" #include "cfgparser.h" #include "commands.h" #include "common.h" @@ -27,7 +26,10 @@ #include "cs_gameevents.pb.h" #include "cstrike15_usermessages.pb.h" #include "ctimer.h" -#include "engine/IEngineService.h" +#include "engine2/iengineservicemgr.h" +#include "engine2/inetworkgameserver.h" +#include "engine2/ivengineserver2.h" +#include "engine2/serversideclient.h" #include "entities.h" #include "entity/ccsplayercontroller.h" #include "entity/customhudlayout.h" @@ -38,9 +40,7 @@ #include "eventlistener.h" #include "gameconfig.h" #include "gameevents.pb.h" -#include "icvar.h" #include "idlemanager.h" -#include "iserver.h" #include "khook_helpers.h" #include "leader.h" #include "map_votes.h" @@ -49,7 +49,7 @@ #include "networkstringtabledefs.h" #include "panoramavote.h" #include "playermanager.h" -#include "serversideclient.h" +#include "tier0/icvar.h" #include "tier0/vprof.h" #include "usermessages.pb.h" #include "votemanager.h" @@ -79,7 +79,7 @@ KHOOK_VIRTUAL(SwitchToLoop, &IEngineServiceMgr::SwitchToLoop, g_pEngineServiceMg KHook::Virtual createWorkshopMapGroupHook(0U, Hook_CreateWorkshopMapGroup, nullptr); KHook::Virtual loadEventsFromFileHook(&IGameEventManager2::LoadEventsFromFile, Hook_LoadEventsFromFile, nullptr); -KHook::Virtual processVoiceDataHook(&CServerSideClient::ProcessVoiceData, Hook_ProcessVoiceData, nullptr); +KHook::Virtual&> processVoiceDataHook(&CServerSideClient::ProcessVoiceData, Hook_ProcessVoiceData, nullptr); KHook::Virtual setGameSpawnGroupMgrHook(&INetworkGameServer::SetGameSpawnGroupMgr, Hook_SetGameSpawnGroupMgr, nullptr); KHook::Virtual*, bool> getTouchingListHook(0U, nullptr, Hook_GetTouchingList_Post); KHook::Virtual checkMovingGroundHook(0U, Hook_CheckMovingGround, nullptr); @@ -556,7 +556,7 @@ KHook::Return Hook_CheckTransmit_Post(ISource2GameEntities* pThis, CCheckT for (int i = 0; i < infoCount; i++) { - auto& pInfo = (CCheckTransmitInfoExtended*&)(ppInfoList[i]); + CCheckTransmitInfo* pInfo = ppInfoList[i]; CCSPlayerController* pSelfController = CCSPlayerController::FromSlot(pInfo->m_nPlayerSlot); if (!pSelfController || !pSelfController->IsConnected()) @@ -603,7 +603,7 @@ KHook::Return Hook_CheckTransmit_Post(ISource2GameEntities* pThis, CCheckT if (pSelfZEPlayer->ShouldBlockTransmit(j) && pOtherZEPlayer && !pOtherZEPlayer->IsLeader() && g_pEWHandler->FindItemInstanceByOwner(j, false, 0) == -1) { pInfo->m_pTransmitEntity->Clear(pPawn->entindex()); - pInfo->m_pTransmitNonPlayers->Set(pPawn->entindex()); + pInfo->m_pNonTransmitEntity->Set(pPawn->entindex()); } } @@ -733,7 +733,11 @@ KHook::Return Hook_SwitchToLoop(IEngineServiceMgr* pThis, const char* pszL KHook::Return Hook_CreateWorkshopMapGroup(IGameTypes* pThis, const char* name, const CUtlStringList& mapList) { if (g_cvarVoteManagerEnable.Get() && g_pMapVoteSystem->IsMapListLoaded()) - return KHook::Recall(nullptr, {KHook::Action::Ignore}, pThis, name, g_pMapVoteSystem->CreateWorkshopMapGroup()); + { + CUtlStringList workshopMapList; + g_pMapVoteSystem->CreateWorkshopMapGroup(workshopMapList); + return KHook::Recall(nullptr, {KHook::Action::Ignore}, pThis, name, workshopMapList); + } return {KHook::Action::Ignore}; } @@ -745,7 +749,7 @@ KHook::Return Hook_LoadEventsFromFile(IGameEventManager2* pThis, const char return {KHook::Action::Ignore}; } -KHook::Return Hook_ProcessVoiceData(CServerSideClient* pClient, const CCLCMsg_VoiceData_t& msg) +KHook::Return Hook_ProcessVoiceData(CServerSideClient* pClient, const CNetMessagePB& msg) { ZEPlayer* pPlayer = g_playerManager->GetPlayer(pClient->GetPlayerSlot()); @@ -813,9 +817,8 @@ KHook::Return Hook_GetTouchingList_Post(CVPhys2World* pThis, CUtlVector touchingLinks; std::vector unTouchLinks; - FOR_EACH_VEC(*pList, i) + for (const auto& link : *pList) { - const auto& link = pList->Element(i); if (link.IsUnTouching()) unTouchLinks.push_back(link); else @@ -855,7 +858,7 @@ KHook::Return Hook_CheckMovingGround(CCSPlayer_MovementServices* pThis, do int iSlot = pController->GetPlayerSlot(); - static int aPlayerTicks[MAXPLAYERS] = {0}; + static int aPlayerTicks[MAX_PLAYERS] = {0}; // The point of doing this is to avoid running the function (and applying/resetting basevelocity) multiple times per tick // This can happen when the client or server lags diff --git a/src/virtual_hooks.h b/src/virtual_hooks.h index 46b12042..f1ba5e90 100644 --- a/src/virtual_hooks.h +++ b/src/virtual_hooks.h @@ -19,12 +19,16 @@ #pragma once -#include "cs2_sdk/netmessages.h" -#include "engine/igameeventsystem.h" +#include "engine2/igameeventsystem.h" +#include "engine2/inetworkgameserver.h" +#include "engine2/inetworkserverservice.h" +#include "engine2/isource2server.h" #include "entity/cgamerules.h" #include "igameevents.h" -#include "iserver.h" #include "khook.hpp" +#include "netmessages.pb.h" +#include "networksystem/inetworkmessages.h" +#include "tier0/utlstringlist.h" class CCSPlayer_MovementServices; class CServerSideClient; @@ -61,7 +65,7 @@ KHook::Return Hook_DispatchConCommand(ICvar* pThis, ConCommandRef cmd, con KHook::Return Hook_SwitchToLoop(IEngineServiceMgr* pThis, const char* pszLoopModeName, KeyValues* pKV, uint32 nId, const char* pszAddonName, bool bUnk); KHook::Return Hook_CreateWorkshopMapGroup(IGameTypes* pThis, const char* name, const CUtlStringList& mapList); KHook::Return Hook_LoadEventsFromFile(IGameEventManager2* pThis, const char* filename, bool bSearchAll); -KHook::Return Hook_ProcessVoiceData(CServerSideClient* pClient, const CCLCMsg_VoiceData_t& msg); +KHook::Return Hook_ProcessVoiceData(CServerSideClient* pClient, const CNetMessagePB& msg); KHook::Return Hook_SetGameSpawnGroupMgr(INetworkGameServer* pThis, IGameSpawnGroupMgr* pSpawnGroupMgr); KHook::Return Hook_GetTouchingList_Post(CVPhys2World* pThis, CUtlVector* pList, bool unknown); KHook::Return Hook_CheckMovingGround(CCSPlayer_MovementServices* pThis, double frametime); diff --git a/src/votemanager.cpp b/src/votemanager.cpp index 786d699d..e9c681e3 100644 --- a/src/votemanager.cpp +++ b/src/votemanager.cpp @@ -21,8 +21,8 @@ #include "commands.h" #include "ctimer.h" #include "entity/cgamerules.h" -#include "icvar.h" #include "playermanager.h" +#include "tier0/convar.h" #include "tier0/memdbgon.h" @@ -563,7 +563,7 @@ void CVoteManager::ExtendMap(int iMinutes, bool bIncrementiExtends, bool bAllowE { m_iExtends++; - for (int i = 0; i < MAXPLAYERS; i++) + for (int i = 0; i < MAX_PLAYERS; i++) { ZEPlayer* pPlayer = g_playerManager->GetPlayer(i); if (pPlayer) diff --git a/src/zombiereborn.cpp b/src/zombiereborn.cpp index f7e5e5d3..a180a260 100644 --- a/src/zombiereborn.cpp +++ b/src/zombiereborn.cpp @@ -22,9 +22,10 @@ #include "commands.h" #include "ctimer.h" #include "customio.h" -#include "engine/igameeventsystem.h" +#include "engine2/igameeventsystem.h" +#include "engine2/ivengineserver2.h" +#include "engine2/serversideclient.h" #include "entity/cgamerules.h" -#include "entity/cparticlesystem.h" #include "entity/cteam.h" #include "entity/services.h" #include "eventlistener.h" @@ -33,8 +34,6 @@ #include "networksystem/inetworkmessages.h" #include "playermanager.h" #include "recipientfilters.h" -#include "serversideclient.h" -#include "tier0/vprof.h" #include "user_preferences.h" #include "utils/entity.h" #include "vendor/nlohmann/json.hpp" @@ -1082,9 +1081,9 @@ void ZR_StripAndGiveKnife(CCSPlayerPawn* pPawn) CUtlVector>* weapons = pWeaponServices->m_hMyWeapons(); - FOR_EACH_VEC(*weapons, i) + for (const auto& hWeapon : *weapons) { - CBasePlayerWeapon* pWeapon = (*weapons)[i].Get(); + CBasePlayerWeapon* pWeapon = hWeapon.Get(); if (pWeapon && pWeapon->GetWeaponVData()->m_GearSlot() == GEAR_SLOT_KNIFE) { @@ -1164,17 +1163,17 @@ std::vector ZR_GetSpawns() auto ctSpawns = g_pGameRules->m_CTSpawnPoints(); auto tSpawns = g_pGameRules->m_TerroristSpawnPoints(); - FOR_EACH_VEC(*ctSpawns, i) + for (const auto& hSpawn : *ctSpawns) { - SpawnPoint* pSpawn = (*ctSpawns)[i].Get(); + SpawnPoint* pSpawn = hSpawn.Get(); if (pSpawn) spawns.push_back(pSpawn); } - FOR_EACH_VEC(*tSpawns, i) + for (const auto& hSpawn : *tSpawns) { - SpawnPoint* pSpawn = (*tSpawns)[i].Get(); + SpawnPoint* pSpawn = hSpawn.Get(); if (pSpawn) spawns.push_back(pSpawn); @@ -1295,7 +1294,7 @@ void ZR_InitialInfection() // the num of mz to infect int iMZToInfect = vecCandidateControllers.size() / g_cvarInfectSpawnMZRatio.Get(); iMZToInfect = g_cvarInfectSpawnMinCount.Get() > iMZToInfect ? g_cvarInfectSpawnMinCount.Get() : iMZToInfect; - bool vecIsMZ[MAXPLAYERS] = {false}; + bool vecIsMZ[MAX_PLAYERS] = {false}; if (vecCandidateControllers.size() < g_cvarInfectSpawnMinCountReq.Get()) iMZToInfect = 0; @@ -2013,7 +2012,7 @@ CON_COMMAND_CHAT_FLAGS(infect, "- Infect a player", ADMFLAG_GENERIC) } int iNumClients = 0; - int pSlots[MAXPLAYERS]; + int pSlots[MAX_PLAYERS]; ETargetType nType; if (!g_playerManager->CanTargetPlayers(player, args[1], iNumClients, pSlots, NO_TERRORIST | NO_DEAD, nType)) @@ -2073,7 +2072,7 @@ CON_COMMAND_CHAT_FLAGS(revive, "- Revive a player", ADMFLAG_GENERIC) } int iNumClients = 0; - int pSlots[MAXPLAYERS]; + int pSlots[MAX_PLAYERS]; ETargetType nType; if (!g_playerManager->CanTargetPlayers(player, args[1], iNumClients, pSlots, NO_DEAD | NO_COUNTER_TERRORIST, nType)) diff --git a/src/zombiereborn.h b/src/zombiereborn.h index 84b6005f..12825f70 100644 --- a/src/zombiereborn.h +++ b/src/zombiereborn.h @@ -231,7 +231,7 @@ class CZRPlayerClassManager // These exist so we can iterate the class maps in insertion order std::vector m_ZombieClassKeys; std::vector m_HumanClassKeys; - std::weak_ptr m_vecRegenTimers[MAXPLAYERS]; + std::weak_ptr m_vecRegenTimers[MAX_PLAYERS]; }; extern CZRPlayerClassManager* g_pZRPlayerClassManager; From e92a2f54fa9dad405d6632a81c55770eeab1956d Mon Sep 17 00:00:00 2001 From: Vauff Date: Thu, 15 Oct 2026 03:06:57 -0400 Subject: [PATCH 5/7] Fix score changes not being networked --- src/cs2_sdk/entity/ccsplayercontroller.h | 2 +- src/leader.cpp | 4 ++-- src/topdefender.cpp | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/cs2_sdk/entity/ccsplayercontroller.h b/src/cs2_sdk/entity/ccsplayercontroller.h index 9464c0e8..fae1ace1 100644 --- a/src/cs2_sdk/entity/ccsplayercontroller.h +++ b/src/cs2_sdk/entity/ccsplayercontroller.h @@ -144,7 +144,7 @@ class CCSPlayerController : public CBasePlayerController void AddScore(int iScore) { - m_iScore() = m_iScore() + iScore; + m_iScore = m_iScore() + iScore; } void SetClanTag(const char* pszClanTag) diff --git a/src/leader.cpp b/src/leader.cpp index d370223a..251e87b3 100644 --- a/src/leader.cpp +++ b/src/leader.cpp @@ -195,7 +195,7 @@ static bool Leader_SetNewLeader(ZEPlayer* zpLeader, std::string strColor = "") if (zpLeader->IsLeader()) return false; - pLeader->m_iScore() = pLeader->m_iScore() + g_cvarLeaderExtraScore.Get(); + pLeader->m_iScore = pLeader->m_iScore() + g_cvarLeaderExtraScore.Get(); zpLeader->SetLeader(true); Color color = Color(0, 0, 0, 0); @@ -295,7 +295,7 @@ static void RemoveLeader(CCSPlayerController* ccsLeader) if (!zpLeader || !zpLeader->IsLeader()) return; - ccsLeader->m_iScore() = ccsLeader->m_iScore() - g_cvarLeaderExtraScore.Get(); + ccsLeader->m_iScore = ccsLeader->m_iScore() - g_cvarLeaderExtraScore.Get(); zpLeader->SetLeader(false); zpLeader->SetLeaderColor(Color(0, 0, 0, 0)); zpLeader->SetTracerColor(Color(0, 0, 0, 0)); diff --git a/src/topdefender.cpp b/src/topdefender.cpp index c08ad3af..262d9c4c 100644 --- a/src/topdefender.cpp +++ b/src/topdefender.cpp @@ -135,7 +135,7 @@ void TD_OnRoundStart(IGameEvent* pEvent) // If player is top defender, we set their score and clan tag if (g_cvarTopDefenderScore.Get() > 0 && pPlayer->GetTopDefenderStatus()) { - pController->m_iScore() = pController->m_iScore() + g_cvarTopDefenderScore.Get(); + pController->m_iScore = pController->m_iScore() + g_cvarTopDefenderScore.Get(); pController->SetClanTag(g_cvarTopDefenderClanTag.Get().String()); } } @@ -210,7 +210,7 @@ void TD_OnRoundEnd(IGameEvent* pEvent) if (pController) { pPlayer->SetTopDefenderStatus(false); - pController->m_iScore() = pController->m_iScore() - g_cvarTopDefenderScore.Get(); + pController->m_iScore = pController->m_iScore() - g_cvarTopDefenderScore.Get(); pController->ResetClanTag(); } } From c355d83829e24e2569b3ecf5c6570de078462ef1 Mon Sep 17 00:00:00 2001 From: Vauff Date: Thu, 15 Oct 2026 03:15:46 -0400 Subject: [PATCH 6/7] Fix some loop errors in panorama votes --- src/panoramavote.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/panoramavote.cpp b/src/panoramavote.cpp index 8f406225..4fe5faf3 100644 --- a/src/panoramavote.cpp +++ b/src/panoramavote.cpp @@ -96,7 +96,7 @@ bool CPanoramaVoteHandler::IsPlayerInVotePool(int iSlot) if (!m_bIsVoteInProgress) return false; - if (iSlot < 0 || iSlot > MAX_PLAYERS) + if (iSlot < 0 || iSlot >= MAX_PLAYERS) return false; for (int i = 0; i < m_iVoterCount; i++) @@ -241,7 +241,7 @@ void CPanoramaVoteHandler::InitVoters(CRecipientFilter* pFilter) const uint64 x = *reinterpret_cast(&pFilter->GetRecipients()); for (int i = 0, j = 0; i < MAX_PLAYERS; i++) if (x & (static_cast(1u) << i)) - m_iVoters[j] = i; + m_iVoters[j++] = i; } void CPanoramaVoteHandler::CheckForEarlyVoteClose() From 68504a135fae431060992f32c58249b8b1840ce5 Mon Sep 17 00:00:00 2001 From: Vauff Date: Thu, 15 Oct 2026 21:04:25 -0400 Subject: [PATCH 7/7] Rework cvar whitelist for 2026-10-14 CS2 update compatibility --- configs/cvar_whitelist.jsonc.example | 47 ++++++++++++++++++++++---- gamedata/cs2fixes.jsonc | 8 ++--- src/addresses.cpp | 47 ++++++++++++++++---------- src/addresses.h | 5 ++- src/cs2fixes.cpp | 1 + src/cvarwhitelist.cpp | 49 +++++++++++++++++++--------- src/cvarwhitelist.h | 10 +++++- src/detours.cpp | 12 ------- src/detours.h | 1 - src/gamesystem.cpp | 47 ++++---------------------- src/playermanager.cpp | 2 -- src/virtual_hooks.cpp | 2 -- 12 files changed, 127 insertions(+), 104 deletions(-) diff --git a/configs/cvar_whitelist.jsonc.example b/configs/cvar_whitelist.jsonc.example index e2efb939..7d9c477b 100644 --- a/configs/cvar_whitelist.jsonc.example +++ b/configs/cvar_whitelist.jsonc.example @@ -106,18 +106,22 @@ "cl_crosshair_sniper_show_normal_inaccuracy": true, "cl_crosshair_sniper_width": true, "cl_crosshair_t": true, - "cl_crosshairalpha": true, - "cl_crosshaircolor": true, "cl_crosshaircolor_b": true, "cl_crosshaircolor_g": true, "cl_crosshaircolor_r": true, + "cl_crosshaircolor_a": true, + "cl_crosshairoutline_b": true, + "cl_crosshairoutline_g": true, + "cl_crosshairoutline_r": true, + "cl_crosshairoutline_a": true, "cl_crosshairdot": true, - "cl_crosshairgap": true, - "cl_crosshairgap_useweaponvalue": true, - "cl_crosshairsize": true, + "cl_crosshair_gap": true, + "cl_crosshair_length": true, + "cl_crosshair_thickness": true, + "cl_crosshair_dynamic_spread_limit": true, "cl_crosshairstyle": true, - "cl_crosshairthickness": true, - "cl_crosshairusealpha": true, + "cl_ironsight_usecrosshaircolor": true, + "cl_ironsight_dot_scale": true, "cl_draw_only_deathnotices": true, "cl_drawhud": true, "cl_drawhud_force_deathnotices": true, @@ -528,6 +532,35 @@ "radio1": true, "radio2": true, "radio3": true, + "coverme": true, + "takepoint": true, + "holdpos": true, + "regroup": true, + "followme": true, + "takingfire": true, + "go": true, + "fallback": true, + "sticktog": true, + "cheer": true, + "thanks": true, + "compliment": true, + "getinpos": true, + "stormfront": true, + "report": true, + "roger": true, + "enemyspot": true, + "needbackup": true, + "sectorclear": true, + "inposition": true, + "reportingin": true, + "getout": true, + "negative": true, + "enemydown": true, + "throwsmokes": true, + "throwgrenades": true, + "throwfire": true, + "go_to_bombsite_a": true, + "go_to_bombsite_b": true, "player_ping": true, "mp_teamlogo_1": true, "mp_teamlogo_2": true, diff --git a/gamedata/cs2fixes.jsonc b/gamedata/cs2fixes.jsonc index 8e6877ce..d3e74c63 100644 --- a/gamedata/cs2fixes.jsonc +++ b/gamedata/cs2fixes.jsonc @@ -347,12 +347,12 @@ "windows": "48 8B C4 48 89 58 ? 57 48 81 EC ? ? ? ? 0F 29 70 ? 48 8B FA 0F 29 78 ? 48 8B D9", "linux": "55 48 89 E5 41 57 41 56 41 55 41 54 49 89 F4 53 48 89 FB 48 81 EC ? ? ? ? 66 0F 1F 44 00" }, - // Only called in an if statement by function with "DISALLOWED WORKSHOP CONVAR: %s" string - "IsCommandWhitelisted": + // CUtlSymbolTable filled from "whitelist_cvars", passed to CUtlSymbolTable::Find in function with "DISALLOWED WORKSHOP CONVAR: %s" string + "CCSAddonManager__CommandWhitelist": { "library": "server", - "windows": "48 83 EC ? 4C 8B C2 48 8D 0D ? ? ? ? 48 8D 54 24 ? FF", - "linux": "55 48 89 F2 48 8D 35 ? ? ? ? 48 89 E5 48 83 EC" + "windows": "48 8D 0D ? ? ? ? FF 15 ? ? ? ? B9 ? ? ? ? 66 39 08 0F 85", + "linux": "48 8D 35 ? ? ? ? 48 89 DF E8 ? ? ? ? 66 83 BD" }, // "CWorldRendererMgr::CreateWorld_Internal( %s ): Blocking load because marked for deletion during load" "CWorldRendererMgr_CreateWorld_Internal": diff --git a/src/addresses.cpp b/src/addresses.cpp index e49c4fcd..6b5b785c 100644 --- a/src/addresses.cpp +++ b/src/addresses.cpp @@ -82,33 +82,21 @@ bool addresses::Initialize() RESOLVE_SIG("CBasePlayerPawn_SnapViewAngles", addresses::CBasePlayerPawn_SnapViewAngles); RESOLVE_SIG("CBaseEntity_TakeDamageOld", addresses::CBaseEntity_TakeDamageOld); - return InitializeBanMap(); + return InitializeRipRelativeAddresses(); } -bool addresses::InitializeBanMap() +bool addresses::InitializeRipRelativeAddresses() { - // This signature directly points to the instruction referencing sm_mapGcBanInformation - uintptr_t pAddr = (uintptr_t)g_GameConfig->ResolveSignature("CCSGameRules__sm_mapGcBanInformation"); + addresses::sm_mapGcBanInformation = (decltype(addresses::sm_mapGcBanInformation))ResolveRipRelative("CCSGameRules__sm_mapGcBanInformation"); - if (!pAddr) + if (!addresses::sm_mapGcBanInformation) return false; - // the opcode is 3 bytes so we skip those - pAddr += 3; - - // Grab the offset as 4 bytes - uint32 offset = *(uint32*)pAddr; - - // Go to the next instruction, which is what the relative address is based off - pAddr += 4; - - // Get the real address - addresses::sm_mapGcBanInformation = (decltype(addresses::sm_mapGcBanInformation))(pAddr + offset); + addresses::CCSAddonManager_CommandWhitelist = (CUtlSymbolTable*)ResolveRipRelative("CCSAddonManager__CommandWhitelist"); - if (!addresses::sm_mapGcBanInformation) + if (!addresses::CCSAddonManager_CommandWhitelist) return false; - Message("Found %s at 0x%p\n", "CCSGameRules__sm_mapGcBanInformation", addresses::sm_mapGcBanInformation); return true; } @@ -133,3 +121,26 @@ bool addresses::InitializeVScriptFunctions() return true; } + +void* addresses::ResolveRipRelative(const char* pszName, int nOpcodeSize) +{ + uintptr_t pAddr = (uintptr_t)g_GameConfig->ResolveSignature(pszName); + + if (!pAddr) + return nullptr; + + // Skip the opcode, usually 3 bytes for 64-bit operands + pAddr += nOpcodeSize; + + // Grab the offset as 4 bytes + int32 offset = *(int32*)pAddr; + + // Go to the next instruction, which is what the relative address is based off + pAddr += 4; + + // Get the real address + void* pResult = (void*)(pAddr + offset); + + Message("Found %s at 0x%p\n", pszName, pResult); + return pResult; +} diff --git a/src/addresses.h b/src/addresses.h index 6bbce1e1..0ce51873 100644 --- a/src/addresses.h +++ b/src/addresses.h @@ -58,6 +58,7 @@ class CGameRules; class CEntityKeyValues; class IRecipientFilter; class CTakeDamageInfo; +class CUtlSymbolTable; class CCSPlayer_WeaponServices; class CBasePlayerWeapon; class CSpawnGroupMgrGameSystem; @@ -79,10 +80,12 @@ struct CGcBanInformation_t namespace addresses { bool Initialize(); - bool InitializeBanMap(); + bool InitializeRipRelativeAddresses(); bool InitializeVScriptFunctions(); + void* ResolveRipRelative(const char* pszName, int nOpcodeSize = 3); inline CUtlOrderedMap* sm_mapGcBanInformation; + inline CUtlSymbolTable* CCSAddonManager_CommandWhitelist; inline void(FASTCALL* SetGroundEntity)(CBaseEntity* ent, CBaseEntity* ground, CBaseEntity* unk3); inline void(FASTCALL* CCSPlayerController_SwitchTeam)(CCSPlayerController* pController, uint32 team); diff --git a/src/cs2fixes.cpp b/src/cs2fixes.cpp index 31f14648..ae84d71d 100644 --- a/src/cs2fixes.cpp +++ b/src/cs2fixes.cpp @@ -368,6 +368,7 @@ void CS2Fixes::OnLevelInit(char const* pMapName, g_playerManager->SetupInfiniteAmmo(); g_pMapVoteSystem->OnLevelInit(pMapName); + g_pConvarWhitelist->ApplyToGameTable(pMapName); if (g_cvarEnableZR.Get()) ZR_OnLevelInit(); diff --git a/src/cvarwhitelist.cpp b/src/cvarwhitelist.cpp index 3fe5a958..ee64d0a8 100644 --- a/src/cvarwhitelist.cpp +++ b/src/cvarwhitelist.cpp @@ -18,11 +18,13 @@ */ #include "cvarwhitelist.h" +#include "addresses.h" #include "commands.h" #include "utils.h" #undef snprintf #include "vendor/nlohmann/json.hpp" #include +#include CConVarWhitelist* g_pConvarWhitelist = nullptr; @@ -33,10 +35,15 @@ CON_COMMAND_CHAT_FLAGS(cvarwhitelist_reload, "- Reload the ConVar whitelist conf if (!g_cvarConVarWhitelistEnable.Get()) return; - if (g_pConvarWhitelist->LoadConfig()) + if (g_pConvarWhitelist->LoadConfig() && GetGlobals()) + { + g_pConvarWhitelist->ApplyToGameTable(GetGlobals()->mapname.ToCStr()); ClientPrint(player, HUD_PRINTTALK, CHAT_PREFIX "ConVar whitelist config reloaded!"); + } else + { ClientPrint(player, HUD_PRINTTALK, CHAT_PREFIX "Failed to reload ConVar whitelist config!"); + } } bool CConVarWhitelist::LoadConfig() @@ -98,25 +105,35 @@ bool CConVarWhitelist::LoadConfig() return true; } -bool CConVarWhitelist::IsWhitelisted(std::string strName) +void CConVarWhitelist::ApplyToGameTable(const char* pszMapName) { - auto globalIt = std::find_if(m_vecGlobalWhitelist.begin(), m_vecGlobalWhitelist.end(), [strName](const auto& wv) { - return wv.strConVar == StringToLower(strName); - }); + if (!g_cvarConVarWhitelistEnable.Get() || !IsConfigLoaded()) + return; - // Cannot load map overrides, only check global whitelist - if (!GetGlobals()) - return globalIt != m_vecGlobalWhitelist.end() && globalIt->bEnabled; + std::set setWhitelist; - auto mapVector = m_mapOverrides[GetGlobals()->mapname.ToCStr()]; - auto mapIt = std::find_if(mapVector.begin(), mapVector.end(), [strName](const auto& wv) { - return wv.strConVar == StringToLower(strName); - }); + for (const auto& wv : m_vecGlobalWhitelist) + if (wv.bEnabled) + setWhitelist.insert(wv.strConVar); + + auto it = m_mapOverrides.find(pszMapName); // If a map override is present, it takes priority - if (mapIt != mapVector.end()) - return mapIt->bEnabled; + if (it != m_mapOverrides.end()) + { + for (const auto& wv : it->second) + if (wv.bEnabled) + setWhitelist.insert(wv.strConVar); + else + setWhitelist.erase(wv.strConVar); + } + + CUtlSymbolTable* pWhitelistTable = addresses::CCSAddonManager_CommandWhitelist; + pWhitelistTable->RemoveAll(); + + // Modify the games table to be case-insensitive before we add our entries + static_cast(pWhitelistTable)->SetInsensitive(true); - // Or fall back to global whitelist - return globalIt != m_vecGlobalWhitelist.end() && globalIt->bEnabled; + for (const auto& strConVar : setWhitelist) + pWhitelistTable->AddString(strConVar.c_str()); } \ No newline at end of file diff --git a/src/cvarwhitelist.h b/src/cvarwhitelist.h index 8310cc56..514cabad 100644 --- a/src/cvarwhitelist.h +++ b/src/cvarwhitelist.h @@ -20,6 +20,7 @@ #pragma once #include "tier0/convar.h" +#include "tier0/utlsymboltable.h" #undef snprintf #include "vendor/nlohmann/json_fwd.hpp" @@ -33,6 +34,13 @@ struct WhitelistValue bool bEnabled; }; +// Workaround to access CUtlSymbolTable::m_bInsensitive, which is protected +class CUtlSymbolTableAccessor : public CUtlSymbolTable +{ +public: + void SetInsensitive(bool bInsensitive) { m_bInsensitive = bInsensitive; } +}; + class CConVarWhitelist { public: @@ -42,7 +50,7 @@ class CConVarWhitelist } bool LoadConfig(); - bool IsWhitelisted(std::string strName); + void ApplyToGameTable(const char* pszMapName); bool IsConfigLoaded() { return m_bConfigLoaded; }; private: diff --git a/src/detours.cpp b/src/detours.cpp index 1b292335..5f08d116 100644 --- a/src/detours.cpp +++ b/src/detours.cpp @@ -27,7 +27,6 @@ #include "commands.h" #include "common.h" #include "customio.h" -#include "cvarwhitelist.h" #include "detours.h" #include "engine2/serversideclient.h" #include "entities.h" @@ -87,7 +86,6 @@ KHOOK_MEMBER(CBaseModelEntity_SetModel, Detour_CBaseModelEntity_SetModel, nullpt KHOOK_MEMBER(CCSGameRules_GoToIntermission, Detour_CCSGameRules_GoToIntermission, nullptr); KHOOK_MEMBER(SetBeamOrigin, Detour_SetBeamOrigin, nullptr); KHOOK_MEMBER(SetBeamEndPos, Detour_SetBeamEndPos, nullptr); -KHOOK_FUNCTION(IsCommandWhitelisted, Detour_IsCommandWhitelisted, nullptr); KHOOK_MEMBER(CWorldRendererMgr_CreateWorld_Internal, nullptr, Detour_CWorldRendererMgr_CreateWorld_Internal_Post); std::vector& GetKHookList() @@ -695,10 +693,8 @@ KHook::Return Detour_GetFreeClient(int64_t unk1, const __m12 // Phantom client fix for (CServerSideClient* pClient : *GetClientList()) - { if (pClient && pClient->GetSignonState() < SIGNONSTATE_CONNECTED) return {KHook::Action::Supersede, pClient}; - } // Server is actually full for real return {KHook::Action::Supersede, nullptr}; @@ -923,14 +919,6 @@ KHook::Return Detour_SetBeamEndPos(CBeam* pThis, const Vector* pVecPositio return {KHook::Action::Supersede}; } -KHook::Return Detour_IsCommandWhitelisted(void* pAddonManager, const char* pszCommandName) -{ - if (!g_cvarConVarWhitelistEnable.Get() || !g_pConvarWhitelist->IsConfigLoaded()) - return {KHook::Action::Ignore}; - - return {KHook::Action::Supersede, g_pConvarWhitelist->IsWhitelisted(pszCommandName)}; -} - KHook::Return Detour_CWorldRendererMgr_CreateWorld_Internal_Post(IWorldRendererMgr* pThis, CSingleWorldRep* singleWorld) { // The world can fail to be created and the function will return nullptr. diff --git a/src/detours.h b/src/detours.h index dda7d4a3..b98b6eed 100644 --- a/src/detours.h +++ b/src/detours.h @@ -116,5 +116,4 @@ KHook::Return Detour_CBaseModelEntity_SetModel(CBaseModelEntity* pModel, c KHook::Return Detour_CCSGameRules_GoToIntermission(CCSGameRules* pThis, bool bAbortedMatch); KHook::Return Detour_SetBeamOrigin(CBeam* pThis, const Vector* pVecWorldPosition); KHook::Return Detour_SetBeamEndPos(CBeam* pThis, const Vector* pVecWorldPosition); -KHook::Return Detour_IsCommandWhitelisted(void* pAddonManager, const char* pszCommandName); KHook::Return Detour_CWorldRendererMgr_CreateWorld_Internal_Post(IWorldRendererMgr* pThis, CSingleWorldRep* pSingleWorld); diff --git a/src/gamesystem.cpp b/src/gamesystem.cpp index 1214f0cd..b79af782 100644 --- a/src/gamesystem.cpp +++ b/src/gamesystem.cpp @@ -23,7 +23,6 @@ #include "customio.h" #include "entities.h" #include "entity/cgamerules.h" -#include "gameconfig.h" #include "idlemanager.h" #include "leader.h" #include "playermanager.h" @@ -39,27 +38,14 @@ CGameSystemStaticCustomFactory* CGameSystem::sm_Factory = nullptr; // This mess is needed to get the pointer to sm_pFirst so we can insert game systems bool InitGameSystems() { - // This signature directly points to the instruction referencing sm_pFirst - uintptr_t pAddr = (uintptr_t)g_GameConfig->ResolveSignature("IGameSystem_InitAllSystems_pFirst"); + CBaseGameSystemFactory::sm_pFirst = (CBaseGameSystemFactory**)addresses::ResolveRipRelative("IGameSystem_InitAllSystems_pFirst"); - if (!pAddr) + if (!CBaseGameSystemFactory::sm_pFirst) { Panic("Failed to InitGameSystems, see warnings above.\n"); return false; } - // the opcode is 3 bytes so we skip those - pAddr += 3; - - // Grab the offset as 4 bytes - uint32 offset = *(uint32*)pAddr; - - // Go to the next instruction, which is the starting point of the relative jump - pAddr += 4; - - // Now grab our pointer - CBaseGameSystemFactory::sm_pFirst = (CBaseGameSystemFactory**)(pAddr + offset); - // And insert the game system(s) CGameSystem::sm_Factory = new CGameSystemStaticCustomFactory("CS2Fixes_GameSystem", &g_GameSystem); @@ -68,42 +54,23 @@ bool InitGameSystems() bool UnregisterGameSystem() { - // This signature directly points to the instruction referencing sm_pEventDispatcher - uintptr_t pAddr = (uintptr_t)g_GameConfig->ResolveSignature("IGameSystem_LoopPostInitAllSystems_pEventDispatcher"); + CGameSystemEventDispatcher** ppDispatchers = (CGameSystemEventDispatcher**)addresses::ResolveRipRelative("IGameSystem_LoopPostInitAllSystems_pEventDispatcher"); - if (!pAddr) + if (!ppDispatchers) { Panic("Failed to UnregisterGameSystem, see warnings above.\n"); return false; } - // the opcode is 3 bytes so we skip those - pAddr += 3; - - uint32 offset = *(uint32*)pAddr; - - // Go to the next instruction, which is the starting point of the relative jump - pAddr += 4; - - CGameSystemEventDispatcher** ppDispatchers = (CGameSystemEventDispatcher**)(pAddr + offset); - - pAddr = (uintptr_t)g_GameConfig->ResolveSignature("IGameSystem_LoopDestroyAllSystems_s_GameSystems"); + // Here the opcode is 2 bytes as it's moving a dword, not a qword, but that's the start of a vector object + CUtlVector* pGameSystems = (CUtlVector*)addresses::ResolveRipRelative("IGameSystem_LoopDestroyAllSystems_s_GameSystems", 2); - if (!pAddr) + if (!pGameSystems) { Panic("Failed to UnregisterGameSystem, see warnings above.\n"); return false; } - // Here the opcode is 2 bytes as it's moving a dword, not a qword, but that's the start of a vector object - pAddr += 2; - - offset = *(uint32*)pAddr; - - pAddr += 4; - - CUtlVector* pGameSystems = (CUtlVector*)(pAddr + offset); - auto* pDispatcher = *ppDispatchers; if (!pDispatcher || !pGameSystems) diff --git a/src/playermanager.cpp b/src/playermanager.cpp index 4262fd85..ee4eb752 100644 --- a/src/playermanager.cpp +++ b/src/playermanager.cpp @@ -1982,10 +1982,8 @@ int CPlayerManager::GetOnlinePlayerCount(bool bCountBots) flLastUpdateTime = GetGlobals()->curtime; for (CServerSideClient* pClient : *GetClientList()) - { if (pClient && pClient->GetSignonState() >= SIGNONSTATE_CONNECTED && (bCountBots || !pClient->IsFakeClient())) iOnlinePlayers++; - } return iOnlinePlayers; } diff --git a/src/virtual_hooks.cpp b/src/virtual_hooks.cpp index 7f8076eb..06f13727 100644 --- a/src/virtual_hooks.cpp +++ b/src/virtual_hooks.cpp @@ -818,12 +818,10 @@ KHook::Return Hook_GetTouchingList_Post(CVPhys2World* pThis, CUtlVector unTouchLinks; for (const auto& link : *pList) - { if (link.IsUnTouching()) unTouchLinks.push_back(link); else touchingLinks.push_back(link); - } if (touchingLinks.size() <= 1) return {KHook::Action::Ignore};