mirror of
https://github.com/alliedmodders/metamod-source.git
synced 2024-11-29 11:24:19 +01:00
Added gamedll bridging to ep2/l4d provider (bug 3412).
This commit is contained in:
parent
18251be939
commit
105665bdaf
@ -19,7 +19,8 @@ OBJECTS = metamod.cpp \
|
|||||||
provider/console.cpp \
|
provider/console.cpp \
|
||||||
provider/provider_ep2.cpp \
|
provider/provider_ep2.cpp \
|
||||||
provider/vsp_listener.cpp \
|
provider/vsp_listener.cpp \
|
||||||
vsp_bridge.cpp
|
vsp_bridge.cpp \
|
||||||
|
gamedll_bridge.cpp
|
||||||
|
|
||||||
##############################################
|
##############################################
|
||||||
### CONFIGURE ANY OTHER FLAGS/OPTIONS HERE ###
|
### CONFIGURE ANY OTHER FLAGS/OPTIONS HERE ###
|
||||||
|
64
core/gamedll_bridge.cpp
Normal file
64
core/gamedll_bridge.cpp
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
#include <assert.h>
|
||||||
|
#include "metamod.h"
|
||||||
|
#include "metamod_plugins.h"
|
||||||
|
#include "metamod_util.h"
|
||||||
|
#include <loader_bridge.h>
|
||||||
|
#include "provider/provider_ep2.h"
|
||||||
|
|
||||||
|
using namespace SourceMM;
|
||||||
|
|
||||||
|
class GameDllBridge : public IGameDllBridge
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual bool DLLInit_Pre(const gamedll_bridge_info *info, char *buffer, size_t maxlength)
|
||||||
|
{
|
||||||
|
if (!mm_DetectGameInformation())
|
||||||
|
{
|
||||||
|
UTIL_Format(buffer, maxlength, "Metamod:Source failed to detect game paths; cannot load.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
server = (IServerGameDLL *)info->isgd;
|
||||||
|
g_Metamod.SetGameDLLInfo((CreateInterfaceFn)info->gsFactory,
|
||||||
|
info->dllVersion,
|
||||||
|
true);
|
||||||
|
mm_InitializeGlobals((CreateInterfaceFn)info->engineFactory,
|
||||||
|
(CreateInterfaceFn)info->physicsFactory,
|
||||||
|
(CreateInterfaceFn)info->fsFactory,
|
||||||
|
(CGlobalVars*)info->pGlobals);
|
||||||
|
mm_InitializeForLoad();
|
||||||
|
mm_StartupMetamod(false);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
virtual void DLLInit_Post(int *isgdUnload)
|
||||||
|
{
|
||||||
|
SourceHook::MemFuncInfo mfi;
|
||||||
|
|
||||||
|
mfi.isVirtual = false;
|
||||||
|
SourceHook::GetFuncInfo(&IServerGameDLL::DLLShutdown, mfi);
|
||||||
|
assert(mfi.isVirtual);
|
||||||
|
assert(mfi.vtbloffs == 0);
|
||||||
|
assert(mfi.thisptroffs == 0);
|
||||||
|
*isgdUnload = mfi.vtblindex;
|
||||||
|
|
||||||
|
g_PluginMngr.SetAllLoaded();
|
||||||
|
}
|
||||||
|
virtual void *QueryInterface(const char *iface, int *ret)
|
||||||
|
{
|
||||||
|
return g_Metamod.GetServerFactory(true)(iface, ret);
|
||||||
|
}
|
||||||
|
virtual void Unload()
|
||||||
|
{
|
||||||
|
mm_UnloadMetamod();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
GameDllBridge mm16_gamedll_bridge;
|
||||||
|
|
||||||
|
SMM_API IGameDllBridge *
|
||||||
|
GetGameDllBridge()
|
||||||
|
{
|
||||||
|
return &mm16_gamedll_bridge;
|
||||||
|
}
|
||||||
|
|
340
core/metamod.cpp
340
core/metamod.cpp
@ -45,26 +45,9 @@ using namespace SourceHook::Impl;
|
|||||||
* @file sourcemm.cpp
|
* @file sourcemm.cpp
|
||||||
*/
|
*/
|
||||||
|
|
||||||
SH_DECL_MANUALHOOK4(SGD_DLLInit, 0, 0, 0, bool, CreateInterfaceFn, CreateInterfaceFn, CreateInterfaceFn, CGlobalVars *);
|
|
||||||
SH_DECL_MANUALHOOK0(SGD_GameInit, 0, 0, 0, bool);
|
SH_DECL_MANUALHOOK0(SGD_GameInit, 0, 0, 0, bool);
|
||||||
SH_DECL_MANUALHOOK6(SGD_LevelInit, 0, 0, 0, bool, const char *, const char *, const char *, const char *, bool, bool);
|
SH_DECL_MANUALHOOK6(SGD_LevelInit, 0, 0, 0, bool, const char *, const char *, const char *, const char *, bool, bool);
|
||||||
SH_DECL_MANUALHOOK0_void(SGD_LevelShutdown, 0, 0, 0);
|
SH_DECL_MANUALHOOK0_void(SGD_LevelShutdown, 0, 0, 0);
|
||||||
SH_DECL_MANUALHOOK0_void(SGD_DLLShutdown, 0, 0, 0);
|
|
||||||
|
|
||||||
static bool
|
|
||||||
Handler_DLLInit(CreateInterfaceFn engineFactory,
|
|
||||||
CreateInterfaceFn physicsFactory,
|
|
||||||
CreateInterfaceFn filesystemFactory,
|
|
||||||
CGlobalVars *pGlobals);
|
|
||||||
|
|
||||||
static bool
|
|
||||||
Handler_DLLInit_Post(CreateInterfaceFn engineFactory,
|
|
||||||
CreateInterfaceFn physicsFactory,
|
|
||||||
CreateInterfaceFn filesystemFactory,
|
|
||||||
CGlobalVars *pGlobals);
|
|
||||||
|
|
||||||
static void
|
|
||||||
Handler_DLLShutdown();
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
Handler_LevelShutdown();
|
Handler_LevelShutdown();
|
||||||
@ -88,14 +71,12 @@ LookForVDFs(const char *dir);
|
|||||||
|
|
||||||
struct game_dll_t
|
struct game_dll_t
|
||||||
{
|
{
|
||||||
HINSTANCE lib;
|
|
||||||
CreateInterfaceFn factory;
|
CreateInterfaceFn factory;
|
||||||
};
|
};
|
||||||
|
|
||||||
static String mod_path;
|
static String mod_path;
|
||||||
static String metamod_path;
|
static String metamod_path;
|
||||||
static String full_bin_path;
|
static String full_bin_path;
|
||||||
static bool parsed_game_info = false;
|
|
||||||
static int vsp_version = 0;
|
static int vsp_version = 0;
|
||||||
static int gamedll_version = 0;
|
static int gamedll_version = 0;
|
||||||
static int engine_build = SOURCE_ENGINE_UNKNOWN;
|
static int engine_build = SOURCE_ENGINE_UNKNOWN;
|
||||||
@ -125,9 +106,6 @@ CSourceHookImpl g_SourceHook;
|
|||||||
ISourceHook *g_SHPtr = &g_SourceHook;
|
ISourceHook *g_SHPtr = &g_SourceHook;
|
||||||
SourceMM::ISmmAPI *g_pMetamod = &g_Metamod;
|
SourceMM::ISmmAPI *g_pMetamod = &g_Metamod;
|
||||||
|
|
||||||
static void
|
|
||||||
ClearGamedllList();
|
|
||||||
|
|
||||||
/* Helper Macro */
|
/* Helper Macro */
|
||||||
#define IFACE_MACRO(orig,nam) \
|
#define IFACE_MACRO(orig,nam) \
|
||||||
CPluginManager::CPlugin *pl; \
|
CPluginManager::CPlugin *pl; \
|
||||||
@ -182,14 +160,6 @@ mm_InitializeForLoad()
|
|||||||
|
|
||||||
SourceHook::MemFuncInfo info;
|
SourceHook::MemFuncInfo info;
|
||||||
|
|
||||||
if (!provider->GetHookInfo(ProvidedHook_DLLInit, &info))
|
|
||||||
{
|
|
||||||
provider->DisplayError("Metamod:Source could not find a valid hook for IServerGameDLL::DLLInit");
|
|
||||||
}
|
|
||||||
SH_MANUALHOOK_RECONFIGURE(SGD_DLLInit, info.vtblindex, info.vtbloffs, info.thisptroffs);
|
|
||||||
SH_ADD_MANUALHOOK_STATICFUNC(SGD_DLLInit, server, Handler_DLLInit, false);
|
|
||||||
SH_ADD_MANUALHOOK_STATICFUNC(SGD_DLLInit, server, Handler_DLLInit_Post, true);
|
|
||||||
|
|
||||||
if (!provider->GetHookInfo(ProvidedHook_GameInit, &info))
|
if (!provider->GetHookInfo(ProvidedHook_GameInit, &info))
|
||||||
{
|
{
|
||||||
provider->DisplayError("Metamod:Source could not find a valid hook for IServerGameDLL::GameInit");
|
provider->DisplayError("Metamod:Source could not find a valid hook for IServerGameDLL::GameInit");
|
||||||
@ -210,13 +180,6 @@ mm_InitializeForLoad()
|
|||||||
}
|
}
|
||||||
SH_MANUALHOOK_RECONFIGURE(SGD_LevelShutdown, info.vtblindex, info.vtbloffs, info.thisptroffs);
|
SH_MANUALHOOK_RECONFIGURE(SGD_LevelShutdown, info.vtblindex, info.vtbloffs, info.thisptroffs);
|
||||||
SH_ADD_MANUALHOOK_STATICFUNC(SGD_LevelShutdown, server, Handler_LevelShutdown, true);
|
SH_ADD_MANUALHOOK_STATICFUNC(SGD_LevelShutdown, server, Handler_LevelShutdown, true);
|
||||||
|
|
||||||
if (!provider->GetHookInfo(ProvidedHook_DLLShutdown, &info))
|
|
||||||
{
|
|
||||||
provider->DisplayError("Metamod:Source could not find a valid hook for IServerGameDLL::DLLShutdown");
|
|
||||||
}
|
|
||||||
SH_MANUALHOOK_RECONFIGURE(SGD_DLLShutdown, info.vtblindex, info.vtbloffs, info.thisptroffs);
|
|
||||||
SH_ADD_MANUALHOOK_STATICFUNC(SGD_DLLShutdown, server, Handler_DLLShutdown, false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
@ -245,266 +208,12 @@ mm_DetectGameInformation()
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This is where the magic happens */
|
void *
|
||||||
SMM_API void *
|
ServerFactory(const char *iface, int *ret)
|
||||||
CreateInterface(const char *iface, int *ret)
|
|
||||||
{
|
{
|
||||||
/* Prevent loading of self as a SourceMM plugin or Valve server plugin :x */
|
|
||||||
if (strcmp(iface, METAMOD_PLAPI_NAME) == 0)
|
|
||||||
{
|
|
||||||
provider->DisplayWarning("Do not try loading Metamod:Source as a plugin.\n");
|
|
||||||
|
|
||||||
if (ret)
|
|
||||||
{
|
|
||||||
*ret = IFACE_FAILED;
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!g_bIsVspBridged && strncmp(iface, "ISERVERPLUGINCALLBACKS", 22) == 0)
|
|
||||||
{
|
|
||||||
if (vsp_callbacks != NULL && atoi(&iface[22]) != vsp_version)
|
|
||||||
{
|
|
||||||
if (ret != NULL)
|
|
||||||
*ret = IFACE_FAILED;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
vsp_version = atoi(&iface[22]);
|
|
||||||
vsp_callbacks = provider->GetVSPCallbacks(vsp_version);
|
|
||||||
|
|
||||||
if (ret)
|
|
||||||
*ret = (vsp_callbacks != NULL) ? IFACE_OK : IFACE_FAILED;
|
|
||||||
|
|
||||||
if (vsp_callbacks == NULL)
|
|
||||||
vsp_version = 0;
|
|
||||||
|
|
||||||
return vsp_callbacks;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (g_bIsVspBridged)
|
|
||||||
{
|
|
||||||
IFACE_MACRO(gamedll_info.factory, GameDLL);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!parsed_game_info)
|
|
||||||
{
|
|
||||||
parsed_game_info = true;
|
|
||||||
|
|
||||||
if (!mm_DetectGameInformation())
|
|
||||||
{
|
|
||||||
provider->DisplayError("GetFileOfAddress() failed! Metamod cannot load.\n");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
char temp_path[PATH_SIZE];
|
|
||||||
|
|
||||||
/* Path to gameinfo.txt */
|
|
||||||
g_Metamod.PathFormat(temp_path, PATH_SIZE, "%s/%s", mod_path.c_str(), "gameinfo.txt");
|
|
||||||
|
|
||||||
FILE *fp = fopen(temp_path, "rt");
|
|
||||||
|
|
||||||
if (!fp)
|
|
||||||
{
|
|
||||||
provider->DisplayError("Unable to open gameinfo.txt! Metamod cannot load.\n");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
char buffer[255];
|
|
||||||
char key[128], val[128];
|
|
||||||
bool search = false;
|
|
||||||
bool gamebin = false;
|
|
||||||
char *ptr;
|
|
||||||
const char *lptr;
|
|
||||||
char cur_path[PATH_SIZE];
|
|
||||||
|
|
||||||
getcwd(cur_path, PATH_SIZE);
|
|
||||||
|
|
||||||
while (!feof(fp) && fgets(buffer, sizeof(buffer), fp) != NULL)
|
|
||||||
{
|
|
||||||
UTIL_TrimComments(buffer);
|
|
||||||
UTIL_TrimLeft(buffer);
|
|
||||||
UTIL_TrimRight(buffer);
|
|
||||||
|
|
||||||
if (stricmp(buffer, "SearchPaths") == 0)
|
|
||||||
{
|
|
||||||
search = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!search)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
UTIL_KeySplit(buffer, key, sizeof(key) - 1, val, sizeof(val) - 1);
|
|
||||||
if (stricmp(key, "Game") == 0 || stricmp(key, "GameBin") == 0)
|
|
||||||
{
|
|
||||||
if (stricmp(key, "Game") == 0)
|
|
||||||
{
|
|
||||||
gamebin = false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
gamebin = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (strncmp(val, "|gameinfo_path|", sizeof("|gameinfo_path|") - 1) == 0)
|
|
||||||
{
|
|
||||||
ptr = &(val[sizeof("|gameinfo_path|") - 1]);
|
|
||||||
if (ptr[0] == '.')
|
|
||||||
{
|
|
||||||
ptr++;
|
|
||||||
}
|
|
||||||
lptr = mod_path.c_str();
|
|
||||||
} else {
|
|
||||||
ptr = val;
|
|
||||||
lptr = cur_path;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t ptr_len = strlen(ptr);
|
|
||||||
if (ptr[ptr_len] == '/' || ptr[ptr_len] == '\\')
|
|
||||||
{
|
|
||||||
ptr[--ptr_len] = '\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
/* No need to append "bin" if key is GameBin */
|
|
||||||
if (gamebin)
|
|
||||||
{
|
|
||||||
g_Metamod.PathFormat(temp_path, PATH_SIZE, "%s/%s/%s", lptr, ptr, SERVER_DLL);
|
|
||||||
}
|
|
||||||
else if (!ptr[0])
|
|
||||||
{
|
|
||||||
g_Metamod.PathFormat(temp_path, PATH_SIZE, "%s/%s/%s", lptr, "bin", SERVER_DLL);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
g_Metamod.PathFormat(temp_path, PATH_SIZE, "%s/%s/%s/%s", lptr, ptr, "bin", SERVER_DLL);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If not path to SourceMM... */
|
|
||||||
if (!UTIL_PathCmp(metamod_path.c_str(), temp_path))
|
|
||||||
{
|
|
||||||
FILE *temp_fp = fopen(temp_path, "rb");
|
|
||||||
if (!temp_fp)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
fclose(temp_fp);
|
|
||||||
|
|
||||||
/* Search for a matching game dll */
|
|
||||||
List<game_dll_t *>::iterator iter;
|
|
||||||
game_dll_t *pCheck;
|
|
||||||
bool found = false;
|
|
||||||
for (iter = gamedll_list.begin(); iter != gamedll_list.end(); iter++)
|
|
||||||
{
|
|
||||||
pCheck = (*iter);
|
|
||||||
if (GetFileOfAddress((void *)pCheck->factory, buffer, sizeof(buffer)))
|
|
||||||
{
|
|
||||||
if (UTIL_PathCmp(temp_path, buffer))
|
|
||||||
{
|
|
||||||
found = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (found)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
HINSTANCE gamedll = dlmount(temp_path);
|
|
||||||
if (gamedll == NULL)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
CreateInterfaceFn fn = (CreateInterfaceFn)dlsym(gamedll, "CreateInterface");
|
|
||||||
if (fn == NULL)
|
|
||||||
{
|
|
||||||
dlclose(gamedll);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
game_dll_t *pInfo = new game_dll_t;
|
|
||||||
pInfo->factory = fn;
|
|
||||||
pInfo->lib = gamedll;
|
|
||||||
gamedll_list.push_back(pInfo);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fclose(fp);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!is_gamedll_loaded)
|
|
||||||
{
|
|
||||||
if (strncmp(iface, "ServerGameDLL", 13) == 0)
|
|
||||||
{
|
|
||||||
List<game_dll_t *>::iterator iter;
|
|
||||||
game_dll_t *pInfo;
|
|
||||||
for (iter=gamedll_list.begin(); iter!=gamedll_list.end(); iter++)
|
|
||||||
{
|
|
||||||
pInfo = (*iter);
|
|
||||||
if ((server = (IServerGameDLL *)((pInfo->factory)(iface, ret))) != NULL)
|
|
||||||
{
|
|
||||||
if ((gamedll_version = provider->TryServerGameDLL(iface)) != 0)
|
|
||||||
{
|
|
||||||
/* We have a match. Erase us from the list and save our info. */
|
|
||||||
gamedll_list.erase(iter);
|
|
||||||
gamedll_info = *pInfo;
|
|
||||||
delete pInfo;
|
|
||||||
is_gamedll_loaded = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
/* :TODO: error otherwise? */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (is_gamedll_loaded)
|
|
||||||
{
|
|
||||||
ClearGamedllList();
|
|
||||||
mm_InitializeForLoad();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (ret)
|
|
||||||
{
|
|
||||||
*ret = IFACE_FAILED;
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* wtf do we do... */
|
|
||||||
/* :TODO: .. something a bit more intelligent? */
|
|
||||||
provider->DisplayError("Engine requested unknown interface before GameDLL was known!\n");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If we got here, there's definitely a GameDLL */
|
|
||||||
IFACE_MACRO(gamedll_info.factory, GameDLL);
|
IFACE_MACRO(gamedll_info.factory, GameDLL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
ClearGamedllList()
|
|
||||||
{
|
|
||||||
List<game_dll_t *>::iterator iter;
|
|
||||||
|
|
||||||
game_dll_t *pInfo;
|
|
||||||
for (iter = gamedll_list.begin(); iter != gamedll_list.end(); iter++)
|
|
||||||
{
|
|
||||||
pInfo = (*iter);
|
|
||||||
dlclose(pInfo->lib);
|
|
||||||
delete pInfo;
|
|
||||||
}
|
|
||||||
|
|
||||||
gamedll_list.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
int
|
||||||
mm_LoadPluginsFromFile(const char *_file)
|
mm_LoadPluginsFromFile(const char *_file)
|
||||||
{
|
{
|
||||||
@ -813,18 +522,6 @@ mm_InitializeGlobals(CreateInterfaceFn engineFactory,
|
|||||||
provider->Notify_DLLInit_Pre(engineFactory, gamedll_info.factory);
|
provider->Notify_DLLInit_Pre(engineFactory, gamedll_info.factory);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
|
||||||
Handler_DLLInit(CreateInterfaceFn engineFactory,
|
|
||||||
CreateInterfaceFn physicsFactory,
|
|
||||||
CreateInterfaceFn filesystemFactory,
|
|
||||||
CGlobalVars *pGlobals)
|
|
||||||
{
|
|
||||||
mm_InitializeGlobals(engineFactory, physicsFactory, filesystemFactory, pGlobals);
|
|
||||||
mm_StartupMetamod(false);
|
|
||||||
|
|
||||||
RETURN_META_VALUE(MRES_IGNORED, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
Handler_GameInit()
|
Handler_GameInit()
|
||||||
{
|
{
|
||||||
@ -846,16 +543,6 @@ Handler_GameInit()
|
|||||||
RETURN_META_VALUE(MRES_IGNORED, true);
|
RETURN_META_VALUE(MRES_IGNORED, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
|
||||||
Handler_DLLInit_Post(CreateInterfaceFn engineFactory,
|
|
||||||
CreateInterfaceFn physicsFactory,
|
|
||||||
CreateInterfaceFn filesystemFactory,
|
|
||||||
CGlobalVars *pGlobals)
|
|
||||||
{
|
|
||||||
g_PluginMngr.SetAllLoaded();
|
|
||||||
RETURN_META_VALUE(MRES_IGNORED, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
mm_UnloadMetamod()
|
mm_UnloadMetamod()
|
||||||
{
|
{
|
||||||
@ -864,25 +551,7 @@ mm_UnloadMetamod()
|
|||||||
|
|
||||||
provider->Notify_DLLShutdown_Pre();
|
provider->Notify_DLLShutdown_Pre();
|
||||||
|
|
||||||
if (is_gamedll_loaded)
|
|
||||||
{
|
|
||||||
SH_CALL(server, &IServerGameDLL::DLLShutdown)();
|
|
||||||
}
|
|
||||||
|
|
||||||
g_SourceHook.CompleteShutdown();
|
g_SourceHook.CompleteShutdown();
|
||||||
|
|
||||||
if (is_gamedll_loaded && gamedll_info.lib)
|
|
||||||
{
|
|
||||||
dlclose(gamedll_info.lib);
|
|
||||||
is_gamedll_loaded = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
Handler_DLLShutdown()
|
|
||||||
{
|
|
||||||
mm_UnloadMetamod();
|
|
||||||
RETURN_META(MRES_SUPERCEDE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -973,7 +642,7 @@ CreateInterfaceFn MetamodSource::GetFileSystemFactory(bool syn/* =true */)
|
|||||||
CreateInterfaceFn MetamodSource::GetServerFactory(bool syn/* =true */)
|
CreateInterfaceFn MetamodSource::GetServerFactory(bool syn/* =true */)
|
||||||
{
|
{
|
||||||
if (syn)
|
if (syn)
|
||||||
return CreateInterface;
|
return ServerFactory;
|
||||||
return gamedll_info.factory;
|
return gamedll_info.factory;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1408,10 +1077,11 @@ bool MetamodSource::IsLoadedAsGameDLL()
|
|||||||
return is_gamedll_loaded;
|
return is_gamedll_loaded;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MetamodSource::SetGameDLLInfo(CreateInterfaceFn serverFactory, int version)
|
void MetamodSource::SetGameDLLInfo(CreateInterfaceFn serverFactory, int version, bool loaded)
|
||||||
{
|
{
|
||||||
gamedll_info.factory = serverFactory;
|
gamedll_info.factory = serverFactory;
|
||||||
gamedll_version = version;
|
gamedll_version = version;
|
||||||
|
is_gamedll_loaded = loaded;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -98,7 +98,7 @@ public:
|
|||||||
const char *GetPluginsFile();
|
const char *GetPluginsFile();
|
||||||
void UnregisterConCommandBase(PluginId id, ConCommandBase *pCommand);
|
void UnregisterConCommandBase(PluginId id, ConCommandBase *pCommand);
|
||||||
void NotifyVSPListening(IServerPluginCallbacks *callbacks);
|
void NotifyVSPListening(IServerPluginCallbacks *callbacks);
|
||||||
void SetGameDLLInfo(CreateInterfaceFn serverFactory, int version);
|
void SetGameDLLInfo(CreateInterfaceFn serverFactory, int version, bool loaded);
|
||||||
};
|
};
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
@ -41,8 +41,6 @@ namespace SourceMM
|
|||||||
{
|
{
|
||||||
ProvidedHook_LevelInit = 0, /**< IServerGameDLL::LevelInit */
|
ProvidedHook_LevelInit = 0, /**< IServerGameDLL::LevelInit */
|
||||||
ProvidedHook_LevelShutdown = 1, /**< IServerGameDLL::LevelShutdown */
|
ProvidedHook_LevelShutdown = 1, /**< IServerGameDLL::LevelShutdown */
|
||||||
ProvidedHook_DLLInit = 2, /**< IServerGameDLL::DLLInit */
|
|
||||||
ProvidedHook_DLLShutdown = 3, /**< IServerGameDLL::DLLShutdown */
|
|
||||||
ProvidedHook_GameInit = 4, /**< IServerGameDLL::GameInit */
|
ProvidedHook_GameInit = 4, /**< IServerGameDLL::GameInit */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -99,91 +99,6 @@ void UTIL_TrimRight(char *buffer)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* :TODO: this should skip string literals */
|
|
||||||
void UTIL_TrimComments(char *buffer)
|
|
||||||
{
|
|
||||||
int num_sc = 0;
|
|
||||||
size_t len = strlen(buffer);
|
|
||||||
if (buffer)
|
|
||||||
{
|
|
||||||
for (int i = len - 1; i >= 0; i--)
|
|
||||||
{
|
|
||||||
if (buffer[i] == '/')
|
|
||||||
{
|
|
||||||
if (++num_sc >= 2 && i==0)
|
|
||||||
{
|
|
||||||
buffer[i] = '\0';
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (num_sc >= 2)
|
|
||||||
{
|
|
||||||
buffer[i] = '\0';
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
num_sc = 0;
|
|
||||||
}
|
|
||||||
/* size_t won't go below 0, manually break out */
|
|
||||||
if (i == 0)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void UTIL_KeySplit(const char *str, char *buf1, size_t len1, char *buf2, size_t len2)
|
|
||||||
{
|
|
||||||
size_t start;
|
|
||||||
size_t len = strlen(str);
|
|
||||||
|
|
||||||
for (start = 0; start < len; start++)
|
|
||||||
{
|
|
||||||
if (!isspace(str[start]))
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t end;
|
|
||||||
for (end = start; end < len; end++)
|
|
||||||
{
|
|
||||||
if (isspace(str[end]))
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t i, c = 0;
|
|
||||||
for (i = start; i < end; i++, c++)
|
|
||||||
{
|
|
||||||
if (c >= len1)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
buf1[c] = str[i];
|
|
||||||
}
|
|
||||||
buf1[c] = '\0';
|
|
||||||
|
|
||||||
for (start = end; start < len; start++)
|
|
||||||
{
|
|
||||||
if (!isspace(str[start]))
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (c = 0; start < len; start++, c++)
|
|
||||||
{
|
|
||||||
if (c >= len2)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
buf2[c] = str[start];
|
|
||||||
}
|
|
||||||
buf2[c] = '\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
bool UTIL_PathCmp(const char *path1, const char *path2)
|
bool UTIL_PathCmp(const char *path1, const char *path2)
|
||||||
{
|
{
|
||||||
size_t pos1 = 0, pos2 = 0;
|
size_t pos1 = 0, pos2 = 0;
|
||||||
|
@ -45,11 +45,6 @@
|
|||||||
*/
|
*/
|
||||||
const char *UTIL_GetExtension(const char *file);
|
const char *UTIL_GetExtension(const char *file);
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Removes C-style comments from string.
|
|
||||||
*/
|
|
||||||
void UTIL_TrimComments(char *buffer);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Removes whitespace characters from left side of string.
|
* @brief Removes whitespace characters from left side of string.
|
||||||
*/
|
*/
|
||||||
@ -60,11 +55,6 @@ void UTIL_TrimLeft(char *buffer);
|
|||||||
*/
|
*/
|
||||||
void UTIL_TrimRight(char *buffer);
|
void UTIL_TrimRight(char *buffer);
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Breaks a string at the first space until it reaches a non-space.
|
|
||||||
*/
|
|
||||||
void UTIL_KeySplit(const char *str, char *buf1, size_t len1, char *buf2, size_t len2);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Compares two file paths.
|
* @brief Compares two file paths.
|
||||||
*/
|
*/
|
||||||
|
@ -414,6 +414,10 @@
|
|||||||
RelativePath="..\vsp_bridge.cpp"
|
RelativePath="..\vsp_bridge.cpp"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\gamedll_bridge.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
</Filter>
|
</Filter>
|
||||||
<Filter
|
<Filter
|
||||||
Name="Header Files"
|
Name="Header Files"
|
||||||
|
@ -258,14 +258,6 @@ bool BaseProvider::GetHookInfo(ProvidedHooks hook, SourceHook::MemFuncInfo *pInf
|
|||||||
{
|
{
|
||||||
SourceHook::GetFuncInfo(&IServerGameDLL::GameInit, mfi);
|
SourceHook::GetFuncInfo(&IServerGameDLL::GameInit, mfi);
|
||||||
}
|
}
|
||||||
else if (hook == ProvidedHook_DLLShutdown)
|
|
||||||
{
|
|
||||||
SourceHook::GetFuncInfo(&IServerGameDLL::DLLShutdown, mfi);
|
|
||||||
}
|
|
||||||
else if (hook == ProvidedHook_DLLInit)
|
|
||||||
{
|
|
||||||
SourceHook::GetFuncInfo(&IServerGameDLL::DLLInit, mfi);
|
|
||||||
}
|
|
||||||
|
|
||||||
*pInfo = mfi;
|
*pInfo = mfi;
|
||||||
|
|
||||||
|
@ -47,7 +47,7 @@ public:
|
|||||||
gamedll_iface[15] = '0' + i;
|
gamedll_iface[15] = '0' + i;
|
||||||
if ((server = (IServerGameDLL *)info->gsFactory(gamedll_iface, NULL)) != NULL)
|
if ((server = (IServerGameDLL *)info->gsFactory(gamedll_iface, NULL)) != NULL)
|
||||||
{
|
{
|
||||||
g_Metamod.SetGameDLLInfo((CreateInterfaceFn)info->gsFactory, i);
|
g_Metamod.SetGameDLLInfo((CreateInterfaceFn)info->gsFactory, i, false);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user