Skip to content
Draft
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
4 changes: 3 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,10 @@ jobs:
sm:
- label: "1.12"
branch: "1.12-dev"
mms_branch: "1.12-dev"
- label: "1.13"
branch: "master"
mms_branch: "1.12-dev"
target:
- os: ubuntu-latest
os_name: linux
Expand Down Expand Up @@ -91,7 +93,7 @@ jobs:
uses: actions/checkout@v7
with:
repository: alliedmodders/metamod-source
ref: 1.12-dev
ref: ${{ matrix.sm.mms_branch }}
path: mmsource
submodules: recursive

Expand Down
21 changes: 19 additions & 2 deletions AMBuildScript
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# vim: set ts=2 sw=2 tw=99 noet ft=python:
import os
import re
import platform

def ResolveEnvPath(env, folder):
Expand Down Expand Up @@ -400,10 +401,15 @@ class ExtensionConfig(object):
SetArchFlags(compiler)

compiler.cxxincludes += [
os.path.join(self.mms_root, 'core'),
os.path.join(self.mms_root, 'core', 'sourcehook'),
os.path.join(self.mms_root, 'core')
]

mms_major = int(self.get_mms_version()[0])
if mms_major >= 2:
compiler.cxxincludes += [os.path.join(self.mms_root, 'third_party', 'khook', 'include')]
else:
compiler.cxxincludes += [os.path.join(self.mms_root, 'core', 'sourcehook')]

for other_sdk in self.sdk_manifests:
compiler.defines += [f'SE_{other_sdk["define"]}={other_sdk["code"]}']

Expand Down Expand Up @@ -447,6 +453,17 @@ class ExtensionConfig(object):
else:
raise Exception("Could not find a suitable copy of spcomp in SourceMod binary root")

def get_mms_version(self):
mms_version_file = os.path.join(self.mms_root, "product.version")
if not os.path.isfile(mms_version_file):
raise Exception("Could not find product.version under Metamod:Source root")
with open(mms_version_file, "r") as f:
version = f.read().strip()
match = re.match(r'([0-9]+).([0-9]+).([0-9]+).*', version)
if match:
return match.groups()
raise Exception("Could not parse product.version from Metamod:Source")

Extension = ExtensionConfig()
Extension.detectSDKs()
Extension.find_spcomp()
Expand Down
23 changes: 18 additions & 5 deletions cssdm_events.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -144,39 +144,52 @@ void DM_SchedRespawn(int client)
player->respawn_timer = timersys->CreateTimer(&s_PlayerSpawner, DM_GetRespawnWait(), data, 0);
}

#if METAMOD_PLAPI_VERSION < 18
void OnClientCommand_Post(edict_t *edict, const CCommand &args)
#else
KHook::Return<void> OnClientCommand_Post(IServerGameClients *gameClients, edict_t *edict, const CCommand &args)
#endif
{
const char *cmd;

if (!g_IsRunning)
{
return;
goto end;
}

const char *cmd = args.Arg(0);
cmd = args.Arg(0);

if (strcmp(cmd, "joinclass") == 0)
{
int client = gamehelpers->IndexOfEdict(edict);
dm_player_t *player = DM_GetPlayer(client);
if (!player || !player->pEntity)
{
return;
goto end;
}

if (DM_IsPlayerAlive(client))
{
return;
goto end;
}

if (!player->will_respawn_on_class)
{
return;
goto end;
}

player->will_respawn_on_class = false;

/* Respawn! */
DM_SchedRespawn(client);
}

end:
#if METAMOD_PLAPI_VERSION < 18
RETURN_META(MRES_IGNORED);
#else
return { KHook::Action::Ignore };
#endif
}

#define IMPLEMENT_EVENT(name) \
Expand Down
4 changes: 4 additions & 0 deletions cssdm_events.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,11 @@ DECLARE_EVENT(round_end);
class CCommand;

void DM_ClearRagdollTimers();
#if METAMOD_PLAPI_VERSION < 18
void OnClientCommand_Post(edict_t *edict, const CCommand &args);
#else
KHook::Return<void> OnClientCommand_Post(IServerGameClients *gameClients, edict_t *edict, const CCommand &args);
#endif

class DMData
{
Expand Down
30 changes: 29 additions & 1 deletion cssdm_ffa.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,11 @@

// Don't patch anything on CSGO
#if SOURCE_ENGINE != SE_CSGO
SH_DECL_MANUALHOOK2(CGameRules_IPointsForKill, 62+EXTRA_VTBL_OFFSET, 0, 0, int, CBasePlayer *, CBasePlayer *);
#if METAMOD_PLAPI_VERSION < 18
SH_DECL_MANUALHOOK2(CGameRules_IPointsForKill, 80+EXTRA_VTBL_OFFSET, 0, 0, int, CBasePlayer *, CBasePlayer *);
#else
class CGameRules;
#endif

#if defined PLATFORM_64BITS
#define PLATFORM_ARCH_SUFFIX "64"
Expand Down Expand Up @@ -72,12 +76,24 @@ static void *g_domrev_addr = NULL;
static dmpatch_t g_domrev_patch;
static dmpatch_t g_domrev_restore;

#if METAMOD_PLAPI_VERSION < 18
int OnIPointsForKill(CBasePlayer *pl1, CBasePlayer *pl2)
#else
KHook::Return<int> OnIPointsForKill(CGameRules *gamerules, CBasePlayer *pl1, CBasePlayer *pl2)
#endif
{
/* If we're hooked, FFA is always on. */
#if METAMOD_PLAPI_VERSION < 18
RETURN_META_VALUE(MRES_SUPERCEDE, 1);
#else
return { KHook::Action::Supersede, 1 };
#endif
}

#if METAMOD_PLAPI_VERSION >= 18
KHook::Virtual<CGameRules, int, CBasePlayer *, CBasePlayer *> Hook_IPointsForKill(80 + EXTRA_VTBL_OFFSET, OnIPointsForKill, nullptr);
#endif

bool DM_FFA_LoadPatch(const char *name, dmpatch_t *patch, char *error, size_t maxlength)
{
char fullname[255];
Expand Down Expand Up @@ -168,7 +184,11 @@ bool DM_Prepare_FFA(char *error, size_t maxlength)
snprintf(error, maxlength, "Could not find IPointsForKills offset");
return false;
}
#if METAMOD_PLAPI_VERSION < 18
SH_MANUALHOOK_RECONFIGURE(CGameRules_IPointsForKill, offset, 0, 0);
#else
Hook_IPointsForKill.Configure(offset);
#endif

g_FFA_Prepared = true;

Expand Down Expand Up @@ -205,7 +225,11 @@ bool DM_Patch_FFA()
// needs a new gamerules address on every map load
if (!g_FFA_PointsHooked && LoadGameRulesAddress())
{
#if METAMOD_PLAPI_VERSION < 18
SH_ADD_MANUALHOOK_STATICFUNC(CGameRules_IPointsForKill, g_gamerules_addr, OnIPointsForKill, false);
#else
Hook_IPointsForKill.Add(reinterpret_cast<CGameRules *>(g_gamerules_addr));
#endif
g_FFA_PointsHooked = true;
}

Expand All @@ -224,7 +248,11 @@ bool DM_Unpatch_FFA()
// g_gamerules_addr won't be null if we're already hooked
if (!g_IsInGlobalShutdown && g_FFA_PointsHooked)
{
#if METAMOD_PLAPI_VERSION < 18
SH_REMOVE_MANUALHOOK_STATICFUNC(CGameRules_IPointsForKill, g_gamerules_addr, OnIPointsForKill, false);
#else
Hook_IPointsForKill.Remove(reinterpret_cast<CGameRules *>(g_gamerules_addr));
#endif
g_FFA_PointsHooked = false;
}

Expand Down
26 changes: 26 additions & 0 deletions cssdm_main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,10 @@
#include "cssdm_weapons.h"
#include "cssdm_version.h"

#if METAMOD_PLAPI_VERSION < 18
SH_DECL_HOOK0_void(IServerGameDLL, DLLShutdown, SH_NOATTRIB, false);
SH_DECL_HOOK2_void(IServerGameClients, ClientCommand, SH_NOATTRIB, false, edict_t *, const CCommand &);
#endif

Deathmatch g_DM;
IGameEventManager2 *gameevents = NULL;
Expand Down Expand Up @@ -122,12 +124,26 @@ bool Deathmatch::SDK_OnMetamodLoad(ISmmAPI *ismm, char *error, size_t maxlen, bo
return true;
}

#if METAMOD_PLAPI_VERSION < 18
void OnDLLShutdown()
#else
KHook::Return<void> OnDLLShutdown(IServerGameDLL *server)
#endif
{
g_IsInGlobalShutdown = true;
#if METAMOD_PLAPI_VERSION < 18
RETURN_META(MRES_IGNORED);
#else
return { KHook::Action::Ignore };
#endif
}

#if METAMOD_PLAPI_VERSION >= 18
KHook::Virtual<IServerGameDLL, void> Hook_DLLShutdown(&IServerGameDLL::DLLShutdown, OnDLLShutdown, nullptr);
KHook::Virtual<IServerGameClients, void, edict_t *, const CCommand &> Hook_ClientCommand(
&IServerGameClients::ClientCommand, nullptr, OnClientCommand_Post);
#endif

bool Startup(char *error, size_t maxlength)
{
playerhelpers->AddClientListener(&g_ClientListener);
Expand All @@ -141,8 +157,13 @@ bool Startup(char *error, size_t maxlength)

g_Startup = true;

#if METAMOD_PLAPI_VERSION < 18
SH_ADD_HOOK_STATICFUNC(IServerGameDLL, DLLShutdown, gamedll, OnDLLShutdown, false);
SH_ADD_HOOK_STATICFUNC(IServerGameClients, ClientCommand, gameclients, OnClientCommand_Post, true);
#else
Hook_DLLShutdown.Add(gamedll);
Hook_ClientCommand.Add(gameclients);
#endif

DM_InitCallbacks();

Expand Down Expand Up @@ -184,8 +205,13 @@ void Shutdown()
ShutdownUtils();

/* Unhook everything from SourceHook */
#if METAMOD_PLAPI_VERSION < 18
SH_REMOVE_HOOK_STATICFUNC(IServerGameClients, ClientCommand, gameclients, OnClientCommand_Post, true);
SH_REMOVE_HOOK_STATICFUNC(IServerGameDLL, DLLShutdown, gamedll, OnDLLShutdown, false);
#else
Hook_ClientCommand.Remove(gameclients);
Hook_DLLShutdown.Remove(gamedll);
#endif
}

void Deathmatch::SDK_OnAllLoaded()
Expand Down
12 changes: 9 additions & 3 deletions cssdm_utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,11 @@
#include "cssdm_players.h"
#include "cssdm_utils.h"
#include "cssdm_includesdk.h"
#if METAMOD_PLAPI_VERSION < 18
#include <sh_memory.h>
#else
#include <khook/memory.hpp>
#endif

std::list<ICallWrapper *> g_CallWrappers;
ICallWrapper *g_pRoundRespawn = NULL;
Expand All @@ -39,8 +43,6 @@ ICallWrapper *g_pGiveAmmo = NULL;
int g_RagdollOffset = 0;
int g_LifeStateOffset = 0;

void DM_ProtectMemory(void *addr, int length, int prot);

CBaseEntity *DM_GetBaseEntity(int index)
{
edict_t *pEdict = gamehelpers->EdictOfIndex(index);
Expand Down Expand Up @@ -221,7 +223,7 @@ void DM_ApplyPatch(void *address, int offset, const dmpatch_t *patch, dmpatch_t
{
unsigned char *addr = (unsigned char *)address + offset;

DM_SetMemPatchable(addr, 20);
DM_SetMemPatchable(addr, patch->bytes);

if (restore)
{
Expand All @@ -240,7 +242,11 @@ void DM_ApplyPatch(void *address, int offset, const dmpatch_t *patch, dmpatch_t

void DM_SetMemPatchable(void *address, size_t size)
{
#if METAMOD_PLAPI_VERSION < 18
SourceHook::SetMemAccess(address, size, SH_MEM_READ|SH_MEM_WRITE|SH_MEM_EXEC);
#else
KHook::Memory::SetAccess(address, size, KHook::Memory::Flags::READ | KHook::Memory::Flags::WRITE | KHook::Memory::EXECUTE);
#endif
}

#define GET_PROPERTY(cls, name, var) \
Expand Down
Loading