diff --git a/core/provider/provider_ep2.cpp b/core/provider/provider_ep2.cpp index 80cb575..1f6b9c7 100644 --- a/core/provider/provider_ep2.cpp +++ b/core/provider/provider_ep2.cpp @@ -43,6 +43,14 @@ #include #endif +#if SOURCE_ENGINE == SE_SOURCE2 +SH_DECL_HOOK1(ISource2ServerConfig, AllowDedicatedServers, const, 0, bool, EUniverse); +bool BaseProvider::AllowDedicatedServers(EUniverse universe) const +{ + RETURN_META_VALUE(MRES_SUPERCEDE, true); +} +#endif + /* Types */ typedef void (*CONPRINTF_FUNC)(const char *, ...); struct UsrMsgInfo @@ -187,6 +195,10 @@ void BaseProvider::Notify_DLLInit_Pre(CreateInterfaceFn engineFactory, { SH_ADD_HOOK_STATICFUNC(IServerGameClients, ClientCommand, gameclients, ClientCommand, false); } + +#if SOURCE_ENGINE == SE_SOURCE2 + SH_ADD_VPHOOK(ISource2ServerConfig, AllowDedicatedServers, serverconfig, SH_MEMBER(this, &BaseProvider::AllowDedicatedServers), false); +#endif } void BaseProvider::Notify_DLLShutdown_Pre() diff --git a/loader/gamedll.cpp b/loader/gamedll.cpp index 1aa5a59..1216b68 100644 --- a/loader/gamedll.cpp +++ b/loader/gamedll.cpp @@ -52,6 +52,7 @@ static ISource2ServerConfig *config_iface = NULL; static QueryValveInterface gamedll_qvi = NULL; static int gamedll_version = 0; static int isgd_shutdown_index = -1; +static int is2sc_allowdedi_index = 20; static char mm_path[PLATFORM_MAX_PATH]; static bool g_is_source2 = false; @@ -228,11 +229,15 @@ mm_PatchDllInit(bool patch); static void mm_PatchDllShutdown(); +static void +mm_PatchAllowDedicated(bool patch); + static void mm_PatchConnect(bool patch); static void *isgd_orig_init = NULL; static void *isgd_orig_shutdown = NULL; +static void *is2sc_orig_allowdedi = NULL; static void *is2sc_orig_connect = NULL; class VEmptyClass @@ -242,8 +247,9 @@ class VEmptyClass gamedll_bridge_info g_bridge_info; // Source2 - Rough start order -// CreateInterfaceFn (IS2SC) - hook Connect +// CreateInterfaceFn (IS2SC) - hook Connect and AllowDedicatedServer // IS2SC::Connect - save factory pointer. return orig. remove hook. +// IS2SC::AllowDedicatedServer - return true. remove hook. // CreateInterfaceFn (IS2S) - hook Init and Shutdown // IS2S::Init - do same as old ISGD::DLLInit, including core load. return orig. remove hook. // IS2S::Shutdown - <-- this @@ -293,6 +299,11 @@ public: return result; } + virtual bool AllowDedicatedServers(int universe) const + { + mm_PatchAllowDedicated(false); + return true; + } }; class ISource2Server @@ -650,6 +661,40 @@ mm_PatchDllShutdown() vtable_dest[isgd_shutdown_index] = vtable_src[mfp.vtblindex]; } +static void +mm_PatchAllowDedicated(bool patch) +{ + void **vtable_src; + void **vtable_dest; + SourceHook::MemFuncInfo mfp; + + SourceHook::GetFuncInfo(&ISource2ServerConfig::AllowDedicatedServers, mfp); + + assert(mfp.isVirtual); + assert(mfp.thisptroffs == 0); + assert(mfp.vtbloffs == 0); + + vtable_src = (void **) *(void **) &is2sc_thunk; + vtable_dest = (void **) *(void **) config_iface; + + SourceHook::SetMemAccess(&vtable_dest[is2sc_allowdedi_index], + sizeof(void*), + SH_MEM_READ | SH_MEM_WRITE | SH_MEM_EXEC); + + if (patch) + { + assert(is2sc_orig_allowdedi == NULL); + is2sc_orig_allowdedi = vtable_dest[is2sc_allowdedi_index]; + vtable_dest[is2sc_allowdedi_index] = vtable_src[mfp.vtblindex]; + } + else + { + assert(is2sc_orig_allowdedi != NULL); + vtable_dest[is2sc_allowdedi_index] = is2sc_orig_allowdedi; + is2sc_orig_allowdedi = NULL; + } +} + static void mm_PatchConnect(bool patch) { @@ -731,6 +776,7 @@ mm_GameDllRequest(const char *name, int *ret) gamedll_qvi = qvi; mm_PatchConnect(true); + mm_PatchAllowDedicated(true); if (ret != NULL) *ret = 0;