Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add game system support and resource precaching #144

Merged
merged 4 commits into from
Dec 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions AMBuilder
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ for sdk_name in MMSPlugin.sdks:
'src/ctimer.cpp',
'src/playermanager.cpp',
'src/gameconfig.cpp',
'src/gamesystem.cpp',
'src/votemanager.cpp',
'src/httpmanager.cpp',
'src/discord.cpp',
Expand Down
2 changes: 2 additions & 0 deletions CS2Fixes.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,7 @@
<ClCompile Include="src\discord.cpp" />
<ClCompile Include="src\events.cpp" />
<ClCompile Include="src\gameconfig.cpp" />
<ClCompile Include="src\gamesystem.cpp" />
<ClCompile Include="src\httpmanager.cpp" />
<ClCompile Include="src\map_votes.cpp" />
<ClCompile Include="src\mempatch.cpp" />
Expand Down Expand Up @@ -212,6 +213,7 @@
<ClInclude Include="src\detours.h" />
<ClInclude Include="src\discord.h" />
<ClInclude Include="src\eventlistener.h" />
<ClInclude Include="src\gamesystem.h" />
<ClInclude Include="src\httpmanager.h" />
<ClInclude Include="src\mempatch.h" />
<ClInclude Include="src\addresses.h" />
Expand Down
6 changes: 6 additions & 0 deletions CS2Fixes.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,9 @@
<ClCompile Include="sdk\entity2\entityidentity.cpp">
<Filter>Source Files\sdk</Filter>
</ClCompile>
<ClCompile Include="src\gamesystem.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="src\mempatch.h">
Expand Down Expand Up @@ -199,5 +202,8 @@
<ClInclude Include="src\discord.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\gamesystem.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
</Project>
9 changes: 9 additions & 0 deletions gamedata/cs2fixes.games.txt
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,15 @@
"library" "server"
"windows" "\x40\x56\x57\x48\x83\xEC\x58\x48\x8B\x41\x10"
"linux" "\x55\x48\x89\xE5\x41\x57\x41\x56\x41\x55\x41\x54\x49\x89\xFC\x53\x48\x83\xEC\x38\x4C\x8D\x2D\x2A\x2A\x2A\x2A\x49\x8B\x7D\x00\x48\x85\xFF\x0F\x84\x2A\x2A\x2A\x2A"
}

// "Game System %s is defined twice!\n"
// Note that this signature points to the instruction with sm_pFirst which is the first qword referenced in the function.
"IGameSystem_InitAllSystems_pFirst"
{
"library" "server"
"windows" "\x48\x8B\x1D\x2A\x2A\x2A\x2A\x48\x85\xDB\x0F\x84\x2A\x2A\x2A\x2A\xBE\x2A\x2A\x2A\x2A\x0F\x1F\x00\x48\x8B\x7B\x10"
"linux" "\x4C\x8B\x35\x2A\x2A\x2A\x2A\x4D\x85\xF6\x75\x2D\xE9\x2A\x2A\x2A\x2A\x0F\x1F\x40\x00\x48\x8B\x05"
}
}
"Offsets"
Expand Down
4 changes: 4 additions & 0 deletions src/cs2fixes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
#include "plat.h"
#include "entitysystem.h"
#include "engine/igameeventsystem.h"
#include "gamesystem.h"
#include "ctimer.h"
#include "playermanager.h"
#include <entity.h>
Expand Down Expand Up @@ -207,6 +208,9 @@ bool CS2Fixes::Load(PluginId id, ISmmAPI *ismm, char *error, size_t maxlen, bool
bRequiredInitLoaded = false;
}

if (!InitGameSystems())
bRequiredInitLoaded = false;

if (!bRequiredInitLoaded)
{
snprintf(error, maxlen, "One or more address lookups, patches or detours failed, please refer to startup logs for more information");
Expand Down
68 changes: 68 additions & 0 deletions src/gamesystem.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/**
* =============================================================================
* CS2Fixes
* Copyright (C) 2023 Source2ZE
* =============================================================================
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, version 3.0, as published by the
* Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/

#include "common.h"
#include "gameconfig.h"
#include "addresses.h"
#include "gamesystem.h"

extern CGameConfig *g_GameConfig;

CBaseGameSystemFactory **CBaseGameSystemFactory::sm_pFirst = nullptr;

CResourcePrecacheSystem g_ResourcePrecacheSystem;
IGameSystemFactory *CResourcePrecacheSystem::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, and the opcode is 3 bytes so we skip those
uint8 *ptr = (uint8*)g_GameConfig->ResolveSignature("IGameSystem_InitAllSystems_pFirst") + 3;

if (!ptr)
{
Panic("Failed to InitGameSystems, see warnings above.\n");
return false;
}

// Grab the offset as 4 bytes
uint32 offset = *(uint32*)ptr;

// Go to the next instruction, which is the starting point of the relative jump
ptr += 4;

// Now grab our pointer
CBaseGameSystemFactory::sm_pFirst = (CBaseGameSystemFactory **)(ptr + offset);

// And insert the game system(s)
CResourcePrecacheSystem::sm_Factory = new CGameSystemStaticFactory<CResourcePrecacheSystem>("ResourcePrecacheSystem", &g_ResourcePrecacheSystem);

return true;
}

GS_EVENT_MEMBER(CResourcePrecacheSystem, BuildGameSessionManifest)
{
Message("CResourcePrecacheSystem::BuildGameSessionManifest\n");

IEntityResourceManifest *pResourceManifest = msg->m_pResourceManifest;

// This takes any resource type, model or not
// Any resource adding MUST be done here, the resource manifest is not long-lived
// pResourceManifest->AddResource("characters/models/my_character_model.vmdl");
}
67 changes: 67 additions & 0 deletions src/gamesystem.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/**
* =============================================================================
* CS2Fixes
* Copyright (C) 2023 Source2ZE
* =============================================================================
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, version 3.0, as published by the
* Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/

#include "common.h"
#include "entitysystem.h"
#include "igamesystemfactory.h"

bool InitGameSystems();

class CResourcePrecacheSystem : public CBaseGameSystem
{
public:
GS_EVENT(BuildGameSessionManifest);

void Shutdown() override
{
Message("CResourcePrecacheSystem::Shutdown\n");
delete sm_Factory;
}

void SetGameSystemGlobalPtrs(void *pValue) override
{
if (sm_Factory)
sm_Factory->SetGlobalPtr(pValue);
}

bool DoesGameSystemReallocate() override
{
return sm_Factory->ShouldAutoAdd();
}

static IGameSystemFactory *sm_Factory;
};

// 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;
};