fix: port to KHook for Metamod 2.0 build 1461+
Metamod 1461+ removed SourceHook (plugin API 17 -> 18), so the MM plugin was rejected and RayTraceImpl crashed on a null CRayTraceInterface002. Replace the two SourceHook hooks with KHook, build against Metamod's bundled KHook headers, include ray.h explicitly for the updated hl2sdk, and disambiguate TraceOptions/TraceResult from CounterStrikeSharp 1.0.375's new types of the same name.
This commit is contained in:
parent
616e169a2c
commit
971e91c711
8 changed files with 33 additions and 46 deletions
|
|
@ -41,11 +41,6 @@ list(APPEND SOURCE_FILES
|
||||||
${SOURCESDK_DIR}/entity2/entityidentity.cpp
|
${SOURCESDK_DIR}/entity2/entityidentity.cpp
|
||||||
${SOURCESDK_DIR}/entity2/entitysystem.cpp
|
${SOURCESDK_DIR}/entity2/entitysystem.cpp
|
||||||
${SOURCESDK_DIR}/entity2/entitykeyvalues.cpp
|
${SOURCESDK_DIR}/entity2/entitykeyvalues.cpp
|
||||||
${METAMOD_DIR}/core/sourcehook/sourcehook.cpp
|
|
||||||
${METAMOD_DIR}/core/sourcehook/sourcehook_impl_chookidman.cpp
|
|
||||||
${METAMOD_DIR}/core/sourcehook/sourcehook_impl_chookmaninfo.cpp
|
|
||||||
${METAMOD_DIR}/core/sourcehook/sourcehook_impl_cvfnptr.cpp
|
|
||||||
${METAMOD_DIR}/core/sourcehook/sourcehook_impl_cproto.cpp
|
|
||||||
vendor/dynlibutils/module.cpp
|
vendor/dynlibutils/module.cpp
|
||||||
vendor/dynlibutils/module.h
|
vendor/dynlibutils/module.h
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -59,8 +59,7 @@ include_directories(
|
||||||
${SOURCESDK}/public/game/server
|
${SOURCESDK}/public/game/server
|
||||||
${SOURCESDK}/public/schemasystem
|
${SOURCESDK}/public/schemasystem
|
||||||
${METAMOD_DIR}/core
|
${METAMOD_DIR}/core
|
||||||
${METAMOD_DIR}/core/sourcehook
|
${METAMOD_DIR}/third_party/khook/include
|
||||||
vendor/khook/include
|
|
||||||
vendor/spdlog/include
|
vendor/spdlog/include
|
||||||
vendor/nlohmann
|
vendor/nlohmann
|
||||||
vendor
|
vendor
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,8 @@ using CounterStrikeSharp.API.Modules.Memory;
|
||||||
using CounterStrikeSharp.API.Modules.Utils;
|
using CounterStrikeSharp.API.Modules.Utils;
|
||||||
using RayTraceAPI;
|
using RayTraceAPI;
|
||||||
using Vector = CounterStrikeSharp.API.Modules.Utils.Vector;
|
using Vector = CounterStrikeSharp.API.Modules.Utils.Vector;
|
||||||
|
using TraceOptions = RayTraceAPI.TraceOptions;
|
||||||
|
using TraceResult = RayTraceAPI.TraceResult;
|
||||||
|
|
||||||
namespace RayTraceImpl;
|
namespace RayTraceImpl;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
//
|
//
|
||||||
// Created by Michal Přikryl on 10.07.2025.
|
// Created by Michal Přikryl on 10.07.2025.
|
||||||
// Copyright (c) 2025 slynxcz. All rights reserved.
|
// Copyright (c) 2025 slynxcz. All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
@ -6,32 +6,45 @@
|
||||||
#include <raytrace.h>
|
#include <raytrace.h>
|
||||||
#include <shared.h>
|
#include <shared.h>
|
||||||
#include <dynlibutils/module.h>
|
#include <dynlibutils/module.h>
|
||||||
|
#include <khook.hpp>
|
||||||
|
|
||||||
class GameSessionConfiguration_t
|
class GameSessionConfiguration_t
|
||||||
{
|
{
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace RayTracePlugin::Listeners {
|
namespace RayTracePlugin::Listeners {
|
||||||
SourceHooks sourceHooks;
|
// Metamod 2.0 build 1461+ dropped SourceHook for KHook; these replace the old SH_DECL_HOOK*s.
|
||||||
|
static KHook::Return<void> Hook_StartupServer(INetworkServerService*, const GameSessionConfiguration_t&,
|
||||||
|
ISource2WorldSession*, const char*);
|
||||||
|
static KHook::Return<int> Hook_LoadEventsFromFile(IGameEventManager2* self, const char* filename, bool bSearchAll);
|
||||||
|
|
||||||
SH_DECL_HOOK3_void(INetworkServerService, StartupServer, SH_NOATTRIB, 0, const GameSessionConfiguration_t&, ISource2WorldSession*, const char*);
|
static KHook::Virtual<INetworkServerService, void, const GameSessionConfiguration_t&, ISource2WorldSession*, const char*>
|
||||||
SH_DECL_HOOK2(IGameEventManager2, LoadEventsFromFile, SH_NOATTRIB, 0, int, const char*, bool);
|
g_StartupServer(&INetworkServerService::StartupServer, nullptr, &Hook_StartupServer);
|
||||||
|
|
||||||
int g_iLoadEventsFromFileId = -1;
|
static KHook::Virtual<IGameEventManager2, int, const char*, bool>
|
||||||
|
g_LoadEventsFromFile(&IGameEventManager2::LoadEventsFromFile, &Hook_LoadEventsFromFile, nullptr);
|
||||||
|
|
||||||
|
// AddGlobal() reads the vtable from the first word of the "object" it is given, so hooking a raw
|
||||||
|
// vtable (the old SH_ADD_DVPHOOK) means passing a pointer to a slot that holds the vtable address.
|
||||||
|
static void* g_pGameEventManagerVTable = nullptr;
|
||||||
|
|
||||||
void InitListeners() {
|
void InitListeners() {
|
||||||
SH_ADD_HOOK(INetworkServerService, StartupServer, shared::g_pNetworkServerService, SH_MEMBER(&sourceHooks, &SourceHooks::Hook_StartupServer), true);
|
g_StartupServer.Add(shared::g_pNetworkServerService);
|
||||||
auto pCGameEventManagerVTable = DynLibUtils::CModule(shared::g_pServer).GetVirtualTableByName("CGameEventManager").RCast<IGameEventManager2*>();
|
|
||||||
g_iLoadEventsFromFileId = SH_ADD_DVPHOOK(IGameEventManager2, LoadEventsFromFile, pCGameEventManagerVTable, SH_MEMBER(&sourceHooks, &SourceHooks::Hook_LoadEventsFromFile), false);
|
g_pGameEventManagerVTable = DynLibUtils::CModule(shared::g_pServer).GetVirtualTableByName("CGameEventManager").RCast<void*>();
|
||||||
|
if (g_pGameEventManagerVTable)
|
||||||
|
g_LoadEventsFromFile.AddGlobal(reinterpret_cast<IGameEventManager2*>(&g_pGameEventManagerVTable));
|
||||||
}
|
}
|
||||||
|
|
||||||
void DestructListeners() {
|
void DestructListeners() {
|
||||||
SH_REMOVE_HOOK(INetworkServerService, StartupServer, shared::g_pNetworkServerService, SH_MEMBER(&sourceHooks, &SourceHooks::Hook_StartupServer), true);
|
g_StartupServer.Remove(shared::g_pNetworkServerService);
|
||||||
SH_REMOVE_HOOK_ID(g_iLoadEventsFromFileId);
|
|
||||||
|
if (g_pGameEventManagerVTable)
|
||||||
|
g_LoadEventsFromFile.RemoveGlobal(reinterpret_cast<IGameEventManager2*>(&g_pGameEventManagerVTable));
|
||||||
}
|
}
|
||||||
|
|
||||||
void SourceHooks::Hook_StartupServer(const GameSessionConfiguration_t& config,
|
static KHook::Return<void> Hook_StartupServer(INetworkServerService*, const GameSessionConfiguration_t&,
|
||||||
ISource2WorldSession*, const char*)
|
ISource2WorldSession*, const char*)
|
||||||
{
|
{
|
||||||
if (!shared::g_bDetoursLoaded)
|
if (!shared::g_bDetoursLoaded)
|
||||||
{
|
{
|
||||||
|
|
@ -39,11 +52,12 @@ namespace RayTracePlugin::Listeners {
|
||||||
RayTrace::g_CRayTrace.Initialize();
|
RayTrace::g_CRayTrace.Initialize();
|
||||||
shared::g_bDetoursLoaded = true;
|
shared::g_bDetoursLoaded = true;
|
||||||
}
|
}
|
||||||
|
return { KHook::Action::Ignore };
|
||||||
}
|
}
|
||||||
|
|
||||||
int SourceHooks::Hook_LoadEventsFromFile(const char* filename, bool bSearchAll)
|
static KHook::Return<int> Hook_LoadEventsFromFile(IGameEventManager2* self, const char* filename, bool bSearchAll)
|
||||||
{
|
{
|
||||||
ExecuteOnce(shared::g_pGameEventManager = META_IFACEPTR(IGameEventManager2));
|
ExecuteOnce(shared::g_pGameEventManager = self);
|
||||||
RETURN_META_VALUE(MRES_IGNORED, 0);
|
return { KHook::Action::Ignore, 0 };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,19 +4,10 @@
|
||||||
//
|
//
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <eiface.h>
|
#include <eiface.h>
|
||||||
#include <sourcehook.h>
|
|
||||||
#include <iserver.h>
|
#include <iserver.h>
|
||||||
|
|
||||||
namespace RayTracePlugin::Listeners {
|
namespace RayTracePlugin::Listeners {
|
||||||
void InitListeners();
|
void InitListeners();
|
||||||
|
|
||||||
void DestructListeners();
|
void DestructListeners();
|
||||||
|
|
||||||
class SourceHooks {
|
|
||||||
public:
|
|
||||||
void Hook_StartupServer(const GameSessionConfiguration_t& config, ISource2WorldSession*, const char*);
|
|
||||||
int Hook_LoadEventsFromFile(const char* filename, bool bSearchAll);
|
|
||||||
};
|
|
||||||
|
|
||||||
extern SourceHooks sourceHooks;
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <platform.h>
|
#include <platform.h>
|
||||||
#include "soundflags.h"
|
#include "soundflags.h"
|
||||||
|
#include <ray.h>
|
||||||
|
|
||||||
// struct TransmitInfo
|
// struct TransmitInfo
|
||||||
// {
|
// {
|
||||||
|
|
|
||||||
|
|
@ -6,8 +6,6 @@
|
||||||
#include <icvar.h>
|
#include <icvar.h>
|
||||||
#include <iserver.h>
|
#include <iserver.h>
|
||||||
#include <schemasystem.h>
|
#include <schemasystem.h>
|
||||||
#include <sourcehook/sourcehook.h>
|
|
||||||
#include <sourcehook/sourcehook_impl.h>
|
|
||||||
|
|
||||||
namespace RayTracePlugin::shared
|
namespace RayTracePlugin::shared
|
||||||
{
|
{
|
||||||
|
|
@ -27,11 +25,6 @@ namespace RayTracePlugin::shared
|
||||||
CGameResourceService *g_pGameResourceServiceServer = nullptr;
|
CGameResourceService *g_pGameResourceServiceServer = nullptr;
|
||||||
CGameConfig *g_pGameConfig = nullptr;
|
CGameConfig *g_pGameConfig = nullptr;
|
||||||
|
|
||||||
SourceHook::Impl::CSourceHookImpl source_hook_impl;
|
|
||||||
SourceHook::ISourceHook* source_hook = &source_hook_impl;
|
|
||||||
|
|
||||||
int source_hook_pluginid = 0;
|
|
||||||
|
|
||||||
CGlobalVars *getGlobalVars() {
|
CGlobalVars *getGlobalVars() {
|
||||||
INetworkGameServer *server = g_pNetworkServerService->GetIGameServer();
|
INetworkGameServer *server = g_pNetworkServerService->GetIGameServer();
|
||||||
if (!server) return nullptr;
|
if (!server) return nullptr;
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,6 @@
|
||||||
#include <gameconfig.h>
|
#include <gameconfig.h>
|
||||||
#include <igameeventsystem.h>
|
#include <igameeventsystem.h>
|
||||||
#include "schema/cgameresourceserviceserver.h"
|
#include "schema/cgameresourceserviceserver.h"
|
||||||
#include <sourcehook/sourcehook.h>
|
|
||||||
|
|
||||||
class CGameEntitySystem;
|
class CGameEntitySystem;
|
||||||
|
|
||||||
|
|
@ -33,15 +32,8 @@ namespace RayTracePlugin::shared
|
||||||
extern CGameResourceService* g_pGameResourceServiceServer;
|
extern CGameResourceService* g_pGameResourceServiceServer;
|
||||||
extern CGameConfig *g_pGameConfig;
|
extern CGameConfig *g_pGameConfig;
|
||||||
|
|
||||||
extern SourceHook::ISourceHook *source_hook;
|
|
||||||
extern int source_hook_pluginid;
|
|
||||||
|
|
||||||
CGlobalVars* getGlobalVars();
|
CGlobalVars* getGlobalVars();
|
||||||
|
|
||||||
extern bool g_bDetoursLoaded;
|
extern bool g_bDetoursLoaded;
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef SH_GLOB_SHPTR
|
|
||||||
#define SH_GLOB_SHPTR RayTracePlugin::shared::source_hook
|
|
||||||
#undef SH_GLOB_PLUGPTR
|
|
||||||
#define SH_GLOB_PLUGPTR RayTracePlugin::shared::source_hook_pluginid
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue