mirror of
https://github.com/rehlds/metamod-r.git
synced 2024-12-27 07:05:34 +03:00
Refactoring of mplugin and mlist
This commit is contained in:
parent
d1d2a9b755
commit
f7c115e736
@ -186,5 +186,4 @@ inline void UTIL_TraceLine(const Vector &vecStart, const Vector &vecEnd, IGNORE_
|
|||||||
TRACE_LINE(vecStart, vecEnd, (igmon == ignore_monsters), pentIgnore, ptr);
|
TRACE_LINE(vecStart, vecEnd, (igmon == ignore_monsters), pentIgnore, ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern char *UTIL_VarArgs(char *format, ...);
|
|
||||||
extern void UTIL_LogPrintf(const char *fmt, ...);
|
extern void UTIL_LogPrintf(const char *fmt, ...);
|
||||||
|
@ -197,7 +197,6 @@
|
|||||||
<ClCompile Include="..\src\linkgame.cpp" />
|
<ClCompile Include="..\src\linkgame.cpp" />
|
||||||
<ClCompile Include="..\src\log_meta.cpp" />
|
<ClCompile Include="..\src\log_meta.cpp" />
|
||||||
<ClCompile Include="..\src\metamod_rehlds_api.cpp" />
|
<ClCompile Include="..\src\metamod_rehlds_api.cpp" />
|
||||||
<ClCompile Include="..\src\meta_eiface.cpp" />
|
|
||||||
<ClCompile Include="..\src\metamod.cpp" />
|
<ClCompile Include="..\src\metamod.cpp" />
|
||||||
<ClCompile Include="..\src\mlist.cpp" />
|
<ClCompile Include="..\src\mlist.cpp" />
|
||||||
<ClCompile Include="..\src\mplayer.cpp" />
|
<ClCompile Include="..\src\mplayer.cpp" />
|
||||||
@ -213,7 +212,6 @@
|
|||||||
<ClCompile Include="..\src\reg_support.cpp" />
|
<ClCompile Include="..\src\reg_support.cpp" />
|
||||||
<ClCompile Include="..\src\sdk_util.cpp" />
|
<ClCompile Include="..\src\sdk_util.cpp" />
|
||||||
<ClCompile Include="..\src\studioapi.cpp" />
|
<ClCompile Include="..\src\studioapi.cpp" />
|
||||||
<ClCompile Include="..\src\support_meta.cpp" />
|
|
||||||
<ClCompile Include="..\src\utils.cpp" />
|
<ClCompile Include="..\src\utils.cpp" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
@ -232,7 +230,6 @@
|
|||||||
<ClInclude Include="..\src\log_meta.h" />
|
<ClInclude Include="..\src\log_meta.h" />
|
||||||
<ClInclude Include="..\src\metamod_rehlds_api.h" />
|
<ClInclude Include="..\src\metamod_rehlds_api.h" />
|
||||||
<ClInclude Include="..\src\meta_api.h" />
|
<ClInclude Include="..\src\meta_api.h" />
|
||||||
<ClInclude Include="..\src\meta_eiface.h" />
|
|
||||||
<ClInclude Include="..\src\metamod.h" />
|
<ClInclude Include="..\src\metamod.h" />
|
||||||
<ClInclude Include="..\src\mlist.h" />
|
<ClInclude Include="..\src\mlist.h" />
|
||||||
<ClInclude Include="..\src\mplayer.h" />
|
<ClInclude Include="..\src\mplayer.h" />
|
||||||
@ -245,7 +242,6 @@
|
|||||||
<ClInclude Include="..\src\reg_support.h" />
|
<ClInclude Include="..\src\reg_support.h" />
|
||||||
<ClInclude Include="..\src\sdk_util.h" />
|
<ClInclude Include="..\src\sdk_util.h" />
|
||||||
<ClInclude Include="..\src\studioapi.h" />
|
<ClInclude Include="..\src\studioapi.h" />
|
||||||
<ClInclude Include="..\src\support_meta.h" />
|
|
||||||
<ClInclude Include="..\src\utils.h" />
|
<ClInclude Include="..\src\utils.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
@ -41,9 +41,6 @@
|
|||||||
<ClCompile Include="..\src\log_meta.cpp">
|
<ClCompile Include="..\src\log_meta.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="..\src\meta_eiface.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\src\metamod.cpp">
|
<ClCompile Include="..\src\metamod.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
@ -77,9 +74,6 @@
|
|||||||
<ClCompile Include="..\src\studioapi.cpp">
|
<ClCompile Include="..\src\studioapi.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="..\src\support_meta.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\src\utils.cpp">
|
<ClCompile Include="..\src\utils.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
@ -130,9 +124,6 @@
|
|||||||
<ClInclude Include="..\src\meta_api.h">
|
<ClInclude Include="..\src\meta_api.h">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="..\src\meta_eiface.h">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\src\metamod.h">
|
<ClInclude Include="..\src\metamod.h">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
@ -169,9 +160,6 @@
|
|||||||
<ClInclude Include="..\src\studioapi.h">
|
<ClInclude Include="..\src\studioapi.h">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="..\src\support_meta.h">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\src\utils.h">
|
<ClInclude Include="..\src\utils.h">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
@ -128,7 +128,7 @@ void CForwardCallbackJIT::naked_main()
|
|||||||
for (int i = 0, hookid = 0; i < m_jitdata->plugins_count; i++) {
|
for (int i = 0, hookid = 0; i < m_jitdata->plugins_count; i++) {
|
||||||
auto plug = &m_jitdata->plugins[i];
|
auto plug = &m_jitdata->plugins[i];
|
||||||
|
|
||||||
if (plug->m_status < PL_RUNNING) // allow only running and paused
|
if (plug->status() < PL_RUNNING) // allow only running and paused
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
size_t fn_table = *(size_t *)(size_t(plug) + m_jitdata->table_offset);
|
size_t fn_table = *(size_t *)(size_t(plug) + m_jitdata->table_offset);
|
||||||
@ -141,7 +141,7 @@ void CForwardCallbackJIT::naked_main()
|
|||||||
|
|
||||||
// check status and handler set
|
// check status and handler set
|
||||||
mov(ecx, dword_ptr[fn_table + m_jitdata->pfn_offset]);
|
mov(ecx, dword_ptr[fn_table + m_jitdata->pfn_offset]);
|
||||||
cmp(byte_ptr[size_t(&plug->m_status)], PL_RUNNING);
|
cmp(byte_ptr[plug->status_ptr()], PL_RUNNING);
|
||||||
jecxz(go_next_plugin);
|
jecxz(go_next_plugin);
|
||||||
jnz(go_next_plugin);
|
jnz(go_next_plugin);
|
||||||
|
|
||||||
@ -209,7 +209,7 @@ void CForwardCallbackJIT::naked_main()
|
|||||||
for (int i = 0, hookid = 0; i < m_jitdata->plugins_count; i++) {
|
for (int i = 0, hookid = 0; i < m_jitdata->plugins_count; i++) {
|
||||||
auto plug = &m_jitdata->plugins[i];
|
auto plug = &m_jitdata->plugins[i];
|
||||||
|
|
||||||
if (plug->m_status < PL_RUNNING) // allow only running and paused
|
if (plug->status() < PL_RUNNING) // allow only running and paused
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
size_t fn_table = *(size_t *)(size_t(plug) + m_jitdata->post_table_offset);
|
size_t fn_table = *(size_t *)(size_t(plug) + m_jitdata->post_table_offset);
|
||||||
@ -222,7 +222,7 @@ void CForwardCallbackJIT::naked_main()
|
|||||||
|
|
||||||
// check status and handler set
|
// check status and handler set
|
||||||
mov(ecx, dword_ptr[fn_table + m_jitdata->pfn_offset]);
|
mov(ecx, dword_ptr[fn_table + m_jitdata->pfn_offset]);
|
||||||
cmp(byte_ptr[size_t(&plug->m_status)], PL_RUNNING);
|
cmp(byte_ptr[plug->status_ptr()], PL_RUNNING);
|
||||||
jecxz(go_next_plugin);
|
jecxz(go_next_plugin);
|
||||||
jnz(go_next_plugin);
|
jnz(go_next_plugin);
|
||||||
|
|
||||||
|
@ -335,7 +335,7 @@ void cmd_doplug(PLUG_CMD pcmd)
|
|||||||
// Otherwise, print error and exit.
|
// Otherwise, print error and exit.
|
||||||
if (pcmd == PC_REQUIRE)
|
if (pcmd == PC_REQUIRE)
|
||||||
{
|
{
|
||||||
if (findp && findp->m_status >= PL_RUNNING && unique)
|
if (findp && findp->status() >= PL_RUNNING && unique)
|
||||||
{
|
{
|
||||||
META_DEBUG(3, "Required plugin '%s' found loaded and running.", arg);
|
META_DEBUG(3, "Required plugin '%s' found loaded and running.", arg);
|
||||||
return;
|
return;
|
||||||
@ -375,69 +375,69 @@ void cmd_doplug(PLUG_CMD pcmd)
|
|||||||
{
|
{
|
||||||
case PC_PAUSE:
|
case PC_PAUSE:
|
||||||
if (findp->pause())
|
if (findp->pause())
|
||||||
META_CONS("Paused plugin '%s'", findp->m_desc);
|
META_CONS("Paused plugin '%s'", findp->description());
|
||||||
else
|
else
|
||||||
META_CONS("Pause failed for plugin '%s'", findp->m_desc);
|
META_CONS("Pause failed for plugin '%s'", findp->description());
|
||||||
break;
|
break;
|
||||||
case PC_UNPAUSE:
|
case PC_UNPAUSE:
|
||||||
if (findp->unpause())
|
if (findp->unpause())
|
||||||
META_CONS("Unpaused plugin '%s'", findp->m_desc);
|
META_CONS("Unpaused plugin '%s'", findp->description());
|
||||||
else
|
else
|
||||||
META_CONS("Unpause failed for plugin '%s'", findp->m_desc);
|
META_CONS("Unpause failed for plugin '%s'", findp->description());
|
||||||
break;
|
break;
|
||||||
case PC_UNLOAD:
|
case PC_UNLOAD:
|
||||||
{
|
{
|
||||||
findp->m_action = PA_UNLOAD;
|
findp->set_action(PA_UNLOAD);
|
||||||
if (findp->unload(PT_ANYTIME, PNL_COMMAND, PNL_COMMAND))
|
if (findp->unload(PT_ANYTIME, PNL_COMMAND))
|
||||||
{
|
{
|
||||||
META_CONS("Unloaded plugin '%s'", findp->m_desc);
|
META_CONS("Unloaded plugin '%s'", findp->description());
|
||||||
g_plugins->show();
|
g_plugins->show();
|
||||||
}
|
}
|
||||||
else if (false /*meta_errno == ME_DELAYED*/) // TODO
|
else if (false /*meta_errno == ME_DELAYED*/) // TODO
|
||||||
META_CONS("Unload delayed for plugin '%s'", findp->m_desc);
|
META_CONS("Unload delayed for plugin '%s'", findp->description());
|
||||||
else
|
else
|
||||||
META_CONS("Unload failed for plugin '%s'", findp->m_desc);
|
META_CONS("Unload failed for plugin '%s'", findp->description());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case PC_FORCE_UNLOAD:
|
case PC_FORCE_UNLOAD:
|
||||||
{
|
{
|
||||||
findp->m_action = PA_UNLOAD;
|
findp->set_action(PA_UNLOAD);
|
||||||
if (findp->unload(PT_ANYTIME, PNL_CMD_FORCED, PNL_CMD_FORCED))
|
if (findp->unload(PT_ANYTIME, PNL_CMD_FORCED))
|
||||||
{
|
{
|
||||||
META_CONS("Forced unload plugin '%s'", findp->m_desc);
|
META_CONS("Forced unload plugin '%s'", findp->description());
|
||||||
g_plugins->show();
|
g_plugins->show();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
META_CONS("Forced unload failed for plugin '%s'", findp->m_desc);
|
META_CONS("Forced unload failed for plugin '%s'", findp->description());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case PC_RELOAD:
|
case PC_RELOAD:
|
||||||
{
|
{
|
||||||
findp->m_action = PA_RELOAD;
|
findp->set_action(PA_RELOAD);
|
||||||
if (findp->reload(PT_ANYTIME, PNL_COMMAND))
|
if (findp->reload(PT_ANYTIME, PNL_COMMAND))
|
||||||
META_CONS("Reloaded plugin '%s'", findp->m_desc);
|
META_CONS("Reloaded plugin '%s'", findp->description());
|
||||||
else if (0/*meta_errno == ME_DELAYED*/) // TODO
|
else if (0/*meta_errno == ME_DELAYED*/) // TODO
|
||||||
META_CONS("Reload delayed for plugin '%s'", findp->m_desc);
|
META_CONS("Reload delayed for plugin '%s'", findp->description());
|
||||||
else if (0/*meta_errno == ME_NOTALLOWED*/)
|
else if (0/*meta_errno == ME_NOTALLOWED*/)
|
||||||
META_CONS("Reload not allowed for plugin '%s' now, only allowed %s", findp->m_desc, findp->str_loadable(SL_ALLOWED));
|
META_CONS("Reload not allowed for plugin '%s' now, only allowed %s", findp->description(), findp->str_loadable(SL_ALLOWED));
|
||||||
else
|
else
|
||||||
META_CONS("Reload failed for plugin '%s'", findp->m_desc);
|
META_CONS("Reload failed for plugin '%s'", findp->description());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case PC_RETRY:
|
case PC_RETRY:
|
||||||
if (findp->retry(PT_ANYTIME, PNL_COMMAND))
|
if (findp->retry(PT_ANYTIME, PNL_COMMAND))
|
||||||
META_CONS("Retry succeeded for plugin '%s'", findp->m_desc);
|
META_CONS("Retry succeeded for plugin '%s'", findp->description());
|
||||||
else
|
else
|
||||||
META_CONS("Retry failed for plugin '%s'", findp->m_desc);
|
META_CONS("Retry failed for plugin '%s'", findp->description());
|
||||||
break;
|
break;
|
||||||
case PC_CLEAR:
|
case PC_CLEAR:
|
||||||
if (!findp->clear())
|
if (!findp->clear())
|
||||||
{
|
{
|
||||||
META_CONS("Clear failed for plugin '%s'", findp->m_desc);
|
META_CONS("Clear failed for plugin '%s'", findp->description());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
META_CONS("Cleared failed plugin '%s' from list", findp->m_desc);
|
META_CONS("Cleared failed plugin '%s' from list", findp->description());
|
||||||
g_plugins->show();
|
g_plugins->show();
|
||||||
break;
|
break;
|
||||||
case PC_INFO:
|
case PC_INFO:
|
||||||
|
@ -193,7 +193,7 @@ void MConfig::set_directory()
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
NormalizePath(m_directory);
|
normalize_path(m_directory);
|
||||||
|
|
||||||
// get directory
|
// get directory
|
||||||
char *dir = Q_strrchr(m_directory, '/');
|
char *dir = Q_strrchr(m_directory, '/');
|
||||||
|
@ -3,8 +3,8 @@
|
|||||||
#define CDATA_ENG_H(x, p, h) CDATA_ENTRY(enginefuncs_t, x, p, size_t(h))
|
#define CDATA_ENG_H(x, p, h) CDATA_ENTRY(enginefuncs_t, x, p, size_t(h))
|
||||||
#define CDATA_ENG(x) CDATA_ENTRY(enginefuncs_t, x, P_PRE, 0u)
|
#define CDATA_ENG(x) CDATA_ENTRY(enginefuncs_t, x, P_PRE, 0u)
|
||||||
|
|
||||||
meta_enginefuncs_t g_meta_engfuncs; // static trampolines to dynamic callbacks (for gamedll)
|
enginefuncs_t g_meta_engfuncs; // static trampolines to dynamic callbacks (for gamedll)
|
||||||
meta_enginefuncs_t g_meta_engfuncs_jit; // dynamic jit callbacks
|
enginefuncs_t g_meta_engfuncs_jit; // dynamic jit callbacks
|
||||||
|
|
||||||
void MM_PRE_HOOK mm_QueryClientCvarValue(const edict_t* pEdict, const char* cvarName)
|
void MM_PRE_HOOK mm_QueryClientCvarValue(const edict_t* pEdict, const char* cvarName)
|
||||||
{
|
{
|
||||||
|
@ -12,8 +12,7 @@ typedef int (*GET_ENGINE_FUNCTIONS_FN)(enginefuncs_s *pengfuncsFromEngine, int *
|
|||||||
// Protect against other projects which use this include file but use the
|
// Protect against other projects which use this include file but use the
|
||||||
// normal enginefuncs_t type for their meta_engfuncs.
|
// normal enginefuncs_t type for their meta_engfuncs.
|
||||||
#ifdef METAMOD_CORE
|
#ifdef METAMOD_CORE
|
||||||
#include "meta_eiface.h" // meta_enginefuncs_t
|
extern enginefuncs_t g_meta_engfuncs;
|
||||||
extern meta_enginefuncs_t g_meta_engfuncs;
|
|
||||||
|
|
||||||
void compile_engine_callbacks();
|
void compile_engine_callbacks();
|
||||||
#else
|
#else
|
||||||
|
@ -10,14 +10,6 @@
|
|||||||
// "hack" our way around that by using a flag METAMOD_CORE which is set
|
// "hack" our way around that by using a flag METAMOD_CORE which is set
|
||||||
// when compiling Metamod proper.
|
// when compiling Metamod proper.
|
||||||
|
|
||||||
#ifdef METAMOD_CORE
|
|
||||||
#include "meta_eiface.h" // HL_enginefuncs_t
|
|
||||||
|
|
||||||
// Use a #define to bend the enginefuncs_t type to our HL_enginefuncs_t
|
|
||||||
// type instead as we now use that for the global object g_engfuncs.
|
|
||||||
#define enginefuncs_t HL_enginefuncs_t
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <enginecallback.h> // ALERT, etc
|
#include <enginecallback.h> // ALERT, etc
|
||||||
|
|
||||||
#ifdef METAMOD_CORE
|
#ifdef METAMOD_CORE
|
||||||
|
@ -116,7 +116,7 @@ bool setup_gamedll(gamedll_t *gamedll)
|
|||||||
|
|
||||||
// If the path is relative, the gamedll file will be missing and
|
// If the path is relative, the gamedll file will be missing and
|
||||||
// it might be found in the cache file.
|
// it might be found in the cache file.
|
||||||
if (!IsAbsolutePath(gamedll->pathname))
|
if (!is_abs_path(gamedll->pathname))
|
||||||
{
|
{
|
||||||
char szInstallPath[MAX_PATH];
|
char szInstallPath[MAX_PATH];
|
||||||
Q_snprintf(szInstallPath, sizeof(szInstallPath), "%s/%s", gamedll->gamedir, gamedll->pathname);
|
Q_snprintf(szInstallPath, sizeof(szInstallPath), "%s/%s", gamedll->gamedir, gamedll->pathname);
|
||||||
|
@ -34,7 +34,7 @@ void _fini()
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
//! Holds engine functionality callbacks
|
//! Holds engine functionality callbacks
|
||||||
HL_enginefuncs_t g_engfuncs;
|
enginefuncs_t g_engfuncs;
|
||||||
globalvars_t* gpGlobals;
|
globalvars_t* gpGlobals;
|
||||||
engine_t g_engine;
|
engine_t g_engine;
|
||||||
|
|
||||||
@ -49,7 +49,8 @@ void WINAPI GiveFnptrsToDll(enginefuncs_t *pengfuncsFromEngine, globalvars_t *pG
|
|||||||
g_engine.funcs = &g_engfuncs;
|
g_engine.funcs = &g_engfuncs;
|
||||||
g_engine.globals = pGlobals;
|
g_engine.globals = pGlobals;
|
||||||
|
|
||||||
g_engfuncs.initialise_interface(pengfuncsFromEngine);
|
g_engfuncs = *pengfuncsFromEngine;
|
||||||
|
flush_ALERT_buffer();
|
||||||
// NOTE! Have to call logging function _after_ initialising g_engfuncs, so
|
// NOTE! Have to call logging function _after_ initialising g_engfuncs, so
|
||||||
// that g_engfuncs.pfnAlertMessage() can be resolved properly, heh. :)
|
// that g_engfuncs.pfnAlertMessage() can be resolved properly, heh. :)
|
||||||
META_DEV("called: GiveFnptrsToDll");
|
META_DEV("called: GiveFnptrsToDll");
|
||||||
|
@ -1,20 +0,0 @@
|
|||||||
#include "precompiled.h"
|
|
||||||
|
|
||||||
void meta_new_dll_functions_t::set_from(NEW_DLL_FUNCTIONS* _pFuncs)
|
|
||||||
{
|
|
||||||
Q_memcpy(this, _pFuncs, sizeof(NEW_DLL_FUNCTIONS));
|
|
||||||
}
|
|
||||||
|
|
||||||
void meta_enginefuncs_t::set_from(enginefuncs_t* _pFuncs)
|
|
||||||
{
|
|
||||||
Q_memcpy(this, _pFuncs, sizeof(enginefuncs_t));
|
|
||||||
}
|
|
||||||
|
|
||||||
void HL_enginefuncs_t::initialise_interface(enginefuncs_t* _pFuncs)
|
|
||||||
{
|
|
||||||
set_from(_pFuncs);
|
|
||||||
|
|
||||||
// Now the pfnAlertMessage is available and we trust it to be a valid
|
|
||||||
// pointer, so flush the message buffer.
|
|
||||||
flush_ALERT_buffer();
|
|
||||||
}
|
|
@ -1,45 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
// We use our own versions of the engine/dll interface structs. We add a
|
|
||||||
// few dummy entries to the end and set them to 0. That way we are
|
|
||||||
// protected from updates to the HL SDK adding new functions which would
|
|
||||||
// cause a) the game dll copying arbitrary values from us and b) the game
|
|
||||||
// dll overwriting our memory when using an old Metamod with a new game
|
|
||||||
// dll.
|
|
||||||
|
|
||||||
// meta_new_dll_functions_t
|
|
||||||
struct meta_new_dll_functions_t: public NEW_DLL_FUNCTIONS
|
|
||||||
{
|
|
||||||
// Fill this object with pointers copied from a NEW_DLL_FUNCTIONS struct.
|
|
||||||
void set_from(NEW_DLL_FUNCTIONS* pFuncs);
|
|
||||||
};
|
|
||||||
|
|
||||||
// meta_enginefuncs_t
|
|
||||||
struct meta_enginefuncs_t : public enginefuncs_t
|
|
||||||
{
|
|
||||||
// Fill this object with pointers copied from an enginefuncs_t struct.
|
|
||||||
void set_from(enginefuncs_t* pFuncs);
|
|
||||||
};
|
|
||||||
|
|
||||||
// This is a specialisation of the meta_enginefuncs_t struct which is only
|
|
||||||
// used for the initial copy of the engine functions, i.e. those we get
|
|
||||||
// passed from the HL engine right at the beginning.
|
|
||||||
// Since there is only one master copy of engine functions this could be
|
|
||||||
// implemented as a singleton. This is left as an option for later.
|
|
||||||
struct HL_enginefuncs_t: public meta_enginefuncs_t
|
|
||||||
{
|
|
||||||
HL_enginefuncs_t() {};
|
|
||||||
|
|
||||||
// Fill this object with pointers copied from an enginefuncs_t struct
|
|
||||||
// and fixup the interface.
|
|
||||||
// For this class this happens in the GiveFptrsToDll() function
|
|
||||||
// with the pointers passed from the HL engine.
|
|
||||||
void initialise_interface(enginefuncs_t* pFuncs);
|
|
||||||
|
|
||||||
private:
|
|
||||||
// Moving copy_to() and set_from() to the private space.
|
|
||||||
void set_from(enginefuncs_t* pFuncs)
|
|
||||||
{
|
|
||||||
meta_enginefuncs_t::set_from(pFuncs);
|
|
||||||
}
|
|
||||||
};
|
|
@ -20,7 +20,7 @@ gamedll_t g_GameDLL;
|
|||||||
ALIGN16
|
ALIGN16
|
||||||
meta_globals_t g_metaGlobals;
|
meta_globals_t g_metaGlobals;
|
||||||
|
|
||||||
meta_enginefuncs_t g_plugin_engfuncs;
|
enginefuncs_t g_plugin_engfuncs;
|
||||||
|
|
||||||
MPluginList *g_plugins;
|
MPluginList *g_plugins;
|
||||||
MRegCmdList *g_regCmds;
|
MRegCmdList *g_regCmds;
|
||||||
@ -84,7 +84,7 @@ void metamod_startup()
|
|||||||
{
|
{
|
||||||
META_LOG("Configfile specified via localinfo: %s", cp);
|
META_LOG("Configfile specified via localinfo: %s", cp);
|
||||||
|
|
||||||
if (FileExistsInGameDir(cp))
|
if (is_file_exists_in_gamedir(cp))
|
||||||
{
|
{
|
||||||
Q_strncpy(configFile, cp, sizeof configFile - 1);
|
Q_strncpy(configFile, cp, sizeof configFile - 1);
|
||||||
configFile[sizeof configFile - 1] = '\0';
|
configFile[sizeof configFile - 1] = '\0';
|
||||||
@ -93,7 +93,7 @@ void metamod_startup()
|
|||||||
META_ERROR("Empty/missing config.ini file: %s; falling back to %s", cp, configFile);
|
META_ERROR("Empty/missing config.ini file: %s; falling back to %s", cp, configFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!FileExistsInGameDir(configFile))
|
if (!is_file_exists_in_gamedir(configFile))
|
||||||
{
|
{
|
||||||
Q_strncpy(configFile, g_config->directory(), sizeof configFile - 1);
|
Q_strncpy(configFile, g_config->directory(), sizeof configFile - 1);
|
||||||
configFile[sizeof configFile - 1] = '\0';
|
configFile[sizeof configFile - 1] = '\0';
|
||||||
@ -105,14 +105,14 @@ void metamod_startup()
|
|||||||
}
|
}
|
||||||
|
|
||||||
Q_strcat(configFile, "/" CONFIG_INI);
|
Q_strcat(configFile, "/" CONFIG_INI);
|
||||||
if (!FileExistsInGameDir(configFile))
|
if (!is_file_exists_in_gamedir(configFile))
|
||||||
{
|
{
|
||||||
META_DEBUG(2, "No config.ini file found: %s", CONFIG_INI);
|
META_DEBUG(2, "No config.ini file found: %s", CONFIG_INI);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load config file
|
// Load config file
|
||||||
if (FileExistsInGameDir(configFile))
|
if (is_file_exists_in_gamedir(configFile))
|
||||||
g_config->load(configFile);
|
g_config->load(configFile);
|
||||||
|
|
||||||
// Now, override config options with localinfo commandline options.
|
// Now, override config options with localinfo commandline options.
|
||||||
@ -163,7 +163,7 @@ void metamod_startup()
|
|||||||
// Copy, and store pointer in g_engine struct. Yes, we could just store
|
// Copy, and store pointer in g_engine struct. Yes, we could just store
|
||||||
// the actual engine_t struct in g_engine, but then it wouldn't be a
|
// the actual engine_t struct in g_engine, but then it wouldn't be a
|
||||||
// pointer to match the other g_engfuncs.
|
// pointer to match the other g_engfuncs.
|
||||||
g_plugin_engfuncs.set_from(g_engine.funcs);
|
g_plugin_engfuncs = *g_engine.funcs;
|
||||||
g_engine.pl_funcs = &g_plugin_engfuncs;
|
g_engine.pl_funcs = &g_plugin_engfuncs;
|
||||||
// substitute our special versions of various commands
|
// substitute our special versions of various commands
|
||||||
g_engine.pl_funcs->pfnAddServerCommand = meta_AddServerCommand;
|
g_engine.pl_funcs->pfnAddServerCommand = meta_AddServerCommand;
|
||||||
@ -197,7 +197,7 @@ void metamod_startup()
|
|||||||
// In fact, we need gamedir even earlier, so moved up above.
|
// In fact, we need gamedir even earlier, so moved up above.
|
||||||
|
|
||||||
// Load plugins file
|
// Load plugins file
|
||||||
if (!FileExistsInGameDir(pluginFile))
|
if (!is_file_exists_in_gamedir(pluginFile))
|
||||||
{
|
{
|
||||||
Q_strncpy(pluginFile, g_config->directory(), sizeof pluginFile - 1);
|
Q_strncpy(pluginFile, g_config->directory(), sizeof pluginFile - 1);
|
||||||
pluginFile[sizeof pluginFile - 1] = '\0';
|
pluginFile[sizeof pluginFile - 1] = '\0';
|
||||||
@ -209,7 +209,7 @@ void metamod_startup()
|
|||||||
}
|
}
|
||||||
|
|
||||||
Q_strcat(pluginFile, "/" PLUGINS_INI);
|
Q_strcat(pluginFile, "/" PLUGINS_INI);
|
||||||
if (!FileExistsInGameDir(pluginFile))
|
if (!is_file_exists_in_gamedir(pluginFile))
|
||||||
{
|
{
|
||||||
META_DEBUG(2, "No plugins.ini file found: %s", PLUGINS_INI);
|
META_DEBUG(2, "No plugins.ini file found: %s", PLUGINS_INI);
|
||||||
}
|
}
|
||||||
@ -243,7 +243,7 @@ void metamod_startup()
|
|||||||
execFile[sizeof execFile - 1] = '\0';
|
execFile[sizeof execFile - 1] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (FileExistsInGameDir(execFile))
|
if (is_file_exists_in_gamedir(execFile))
|
||||||
{
|
{
|
||||||
if (execFile[0] == '/')
|
if (execFile[0] == '/')
|
||||||
META_ERROR("Cannot exec absolute pathnames: %s", execFile);
|
META_ERROR("Cannot exec absolute pathnames: %s", execFile);
|
||||||
@ -268,7 +268,7 @@ bool meta_init_gamedll()
|
|||||||
Q_memset(&g_GameDLL, 0, sizeof g_GameDLL);
|
Q_memset(&g_GameDLL, 0, sizeof g_GameDLL);
|
||||||
|
|
||||||
GET_GAME_DIR(gamedir);
|
GET_GAME_DIR(gamedir);
|
||||||
NormalizePath(gamedir);
|
normalize_path(gamedir);
|
||||||
|
|
||||||
// As of 1.1.1.1, the engine routine GET_GAME_DIR no longer returns a
|
// As of 1.1.1.1, the engine routine GET_GAME_DIR no longer returns a
|
||||||
// full-pathname, but rather just the path specified as the argument to
|
// full-pathname, but rather just the path specified as the argument to
|
||||||
@ -280,7 +280,7 @@ bool meta_init_gamedll()
|
|||||||
// Note: the code has always assumed the server op wouldn't do:
|
// Note: the code has always assumed the server op wouldn't do:
|
||||||
// hlds -game other/firearms
|
// hlds -game other/firearms
|
||||||
//
|
//
|
||||||
if (IsAbsolutePath(gamedir))
|
if (is_abs_path(gamedir))
|
||||||
{
|
{
|
||||||
// Old style; GET_GAME_DIR returned full pathname. Copy this into
|
// Old style; GET_GAME_DIR returned full pathname. Copy this into
|
||||||
// our gamedir, and truncate to get the game name.
|
// our gamedir, and truncate to get the game name.
|
||||||
|
@ -6,7 +6,6 @@
|
|||||||
#include "conf_meta.h" // MConfig
|
#include "conf_meta.h" // MConfig
|
||||||
#include "osdep.h" // NAME_MAX, etc
|
#include "osdep.h" // NAME_MAX, etc
|
||||||
#include "mplayer.h" // MPlayerList
|
#include "mplayer.h" // MPlayerList
|
||||||
#include "meta_eiface.h" // HL_enginefuncs_t, meta_enginefuncs_t
|
|
||||||
#include "engine_t.h" // engine_t, Engine
|
#include "engine_t.h" // engine_t, Engine
|
||||||
|
|
||||||
#define PLUGINS_INI "plugins.ini" // file that lists plugins to load at startup
|
#define PLUGINS_INI "plugins.ini" // file that lists plugins to load at startup
|
||||||
@ -32,11 +31,11 @@ struct gamedll_t
|
|||||||
extern gamedll_t g_GameDLL;
|
extern gamedll_t g_GameDLL;
|
||||||
|
|
||||||
// SDK variables for storing engine funcs and globals.
|
// SDK variables for storing engine funcs and globals.
|
||||||
extern HL_enginefuncs_t g_engfuncs;
|
extern enginefuncs_t g_engfuncs;
|
||||||
extern globalvars_t *gpGlobals;
|
extern globalvars_t *gpGlobals;
|
||||||
|
|
||||||
// Our modified version of the engine funcs, to give to plugins.
|
// Our modified version of the engine funcs, to give to plugins.
|
||||||
extern meta_enginefuncs_t g_plugin_engfuncs;
|
extern enginefuncs_t g_plugin_engfuncs;
|
||||||
|
|
||||||
// g_config structure.
|
// g_config structure.
|
||||||
extern MConfig *g_config;
|
extern MConfig *g_config;
|
||||||
|
@ -11,7 +11,7 @@ MPluginList::MPluginList(const char* ifile) : m_max_loaded_count(0)
|
|||||||
Q_memset(m_plist, 0, sizeof m_plist);
|
Q_memset(m_plist, 0, sizeof m_plist);
|
||||||
for (int i = 0; i < MAX_PLUGINS; i++)
|
for (int i = 0; i < MAX_PLUGINS; i++)
|
||||||
{
|
{
|
||||||
m_plist[i].m_index = i + 1; // 1-based
|
new(m_plist + i) MPlugin(i + 1); // 1-based
|
||||||
}
|
}
|
||||||
|
|
||||||
m_max_loaded_count = 0;
|
m_max_loaded_count = 0;
|
||||||
@ -67,7 +67,6 @@ MPlugin *MPluginList::find(plid_t id)
|
|||||||
{
|
{
|
||||||
if (m_plist[i].m_status < PL_VALID)
|
if (m_plist[i].m_status < PL_VALID)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (m_plist[i].m_info == id)
|
if (m_plist[i].m_info == id)
|
||||||
return &m_plist[i];
|
return &m_plist[i];
|
||||||
}
|
}
|
||||||
@ -131,10 +130,10 @@ MPlugin *MPluginList::find_match(const char *prefix, bool& unique)
|
|||||||
if (plug->m_status < PL_VALID)
|
if (plug->m_status < PL_VALID)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (plug->m_info && !Q_strnicmp(plug->m_info->name, prefix, len)
|
if (plug->info() && !Q_strnicmp(plug->info()->name, prefix, len)
|
||||||
|| !Q_strnicmp(plug->m_desc, prefix, len)
|
|| !Q_strnicmp(plug->m_desc, prefix, len)
|
||||||
|| !Q_strnicmp(plug->m_file, prefix, len)
|
|| !Q_strnicmp(plug->m_file, prefix, len)
|
||||||
|| plug->m_info && !Q_strnicmp(plug->m_info->logtag, prefix, len))
|
|| plug->info() && !Q_strnicmp(plug->info()->logtag, prefix, len))
|
||||||
{
|
{
|
||||||
if (pfound) {
|
if (pfound) {
|
||||||
unique = false;
|
unique = false;
|
||||||
@ -182,7 +181,7 @@ MPlugin* MPluginList::plugin_addload(plid_t plid, const char* fname, PLUG_LOADTI
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pl_temp.resolve() != true) {
|
if (!pl_temp.resolve()) {
|
||||||
META_DEBUG(1, "Couldn't resolve given path into a file: %s", pl_temp.m_file);
|
META_DEBUG(1, "Couldn't resolve given path into a file: %s", pl_temp.m_file);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@ -215,7 +214,6 @@ MPlugin* MPluginList::plugin_addload(plid_t plid, const char* fname, PLUG_LOADTI
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
meta_rebuild_callbacks();
|
|
||||||
META_DEBUG(1, "Loaded plugin '%s' successfully", pl_added->m_desc);
|
META_DEBUG(1, "Loaded plugin '%s' successfully", pl_added->m_desc);
|
||||||
|
|
||||||
return pl_added;
|
return pl_added;
|
||||||
@ -263,7 +261,7 @@ MPlugin* MPluginList::add(MPlugin* padd)
|
|||||||
// copy pathname
|
// copy pathname
|
||||||
Q_strncpy(iplug->m_pathname, padd->m_pathname, sizeof iplug->m_pathname - 1);
|
Q_strncpy(iplug->m_pathname, padd->m_pathname, sizeof iplug->m_pathname - 1);
|
||||||
iplug->m_pathname[sizeof iplug->m_pathname - 1] = '\0';
|
iplug->m_pathname[sizeof iplug->m_pathname - 1] = '\0';
|
||||||
NormalizePath(iplug->m_pathname);
|
normalize_path(iplug->m_pathname);
|
||||||
|
|
||||||
iplug->m_source = padd->m_source;
|
iplug->m_source = padd->m_source;
|
||||||
iplug->m_status = padd->m_status;
|
iplug->m_status = padd->m_status;
|
||||||
@ -272,15 +270,13 @@ MPlugin* MPluginList::add(MPlugin* padd)
|
|||||||
return iplug;
|
return iplug;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Read plugins.ini at server startup.
|
// Read plugins.ini at server startup.
|
||||||
bool MPluginList::ini_startup()
|
bool MPluginList::ini_startup()
|
||||||
{
|
{
|
||||||
char line[MAX_STRBUF_LEN];
|
char line[MAX_STRBUF_LEN];
|
||||||
int n, ln;
|
int n, ln;
|
||||||
MPlugin *pmatch;
|
|
||||||
|
|
||||||
if (!FileExistsInGameDir(m_inifile))
|
if (!is_file_exists_in_gamedir(m_inifile))
|
||||||
{
|
{
|
||||||
META_ERROR("ini: Metamod plugins file empty or missing: %s", m_inifile);
|
META_ERROR("ini: Metamod plugins file empty or missing: %s", m_inifile);
|
||||||
return false;
|
return false;
|
||||||
@ -307,9 +303,7 @@ bool MPluginList::ini_startup()
|
|||||||
|
|
||||||
// Parse directly into next entry in array
|
// Parse directly into next entry in array
|
||||||
if (!m_plist[n].ini_parseline(line))
|
if (!m_plist[n].ini_parseline(line))
|
||||||
{
|
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
|
|
||||||
// Check for a duplicate - an existing entry with this pathname.
|
// Check for a duplicate - an existing entry with this pathname.
|
||||||
if (find(m_plist[n].m_pathname))
|
if (find(m_plist[n].m_pathname))
|
||||||
@ -321,18 +315,13 @@ bool MPluginList::ini_startup()
|
|||||||
|
|
||||||
// Check for a matching platform with different platform specifics
|
// Check for a matching platform with different platform specifics
|
||||||
// level.
|
// level.
|
||||||
if (nullptr != (pmatch = find_match(&m_plist[n])))
|
auto pmatch = find_match(&m_plist[n]);
|
||||||
|
if (pmatch)
|
||||||
{
|
{
|
||||||
if (pmatch->m_pfspecific >= m_plist[n].m_pfspecific)
|
META_DEBUG(1, "ini: Plugin in line %d overrides existing plugin", ln);
|
||||||
{
|
int index = pmatch->m_index;
|
||||||
META_DEBUG(1, "ini: Skipping plugin, line %d of %s: plugin with higher platform specific level already exists. (%d >= %d)", ln, m_inifile, pmatch->m_pfspecific, m_plist[n].m_pfspecific);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
META_DEBUG(1, "ini: Plugin in line %d overrides existing plugin with lower platform specific level %d, ours %d", ln, pmatch->m_pfspecific, m_plist[n].m_pfspecific);
|
|
||||||
int _index = pmatch->m_index;
|
|
||||||
Q_memset(pmatch, 0, sizeof(MPlugin));
|
Q_memset(pmatch, 0, sizeof(MPlugin));
|
||||||
pmatch->m_index = _index;
|
pmatch->m_index = index;
|
||||||
}
|
}
|
||||||
m_plist[n].m_action = PA_LOAD;
|
m_plist[n].m_action = PA_LOAD;
|
||||||
META_LOG("ini: Read plugin config for: %s", m_plist[n].m_desc);
|
META_LOG("ini: Read plugin config for: %s", m_plist[n].m_desc);
|
||||||
@ -340,12 +329,10 @@ bool MPluginList::ini_startup()
|
|||||||
m_max_loaded_count = n; // mark end of list
|
m_max_loaded_count = n; // mark end of list
|
||||||
}
|
}
|
||||||
META_LOG("ini: Finished reading plugins list: %s; Found %d plugins to load", m_inifile, n);
|
META_LOG("ini: Finished reading plugins list: %s; Found %d plugins to load", m_inifile, n);
|
||||||
|
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
|
|
||||||
if (!n)
|
if (!n)
|
||||||
{
|
META_LOG("ini: Warning; no plugins found to load?");
|
||||||
META_ERROR("ini: Warning; no plugins found to load?");
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -355,8 +342,6 @@ bool MPluginList::ini_refresh()
|
|||||||
{
|
{
|
||||||
char line[MAX_STRBUF_LEN];
|
char line[MAX_STRBUF_LEN];
|
||||||
int n, ln;
|
int n, ln;
|
||||||
MPlugin pl_temp;
|
|
||||||
MPlugin *pl_found, *pl_added;
|
|
||||||
|
|
||||||
FILE* fp = fopen(m_inifile, "r");
|
FILE* fp = fopen(m_inifile, "r");
|
||||||
if (!fp)
|
if (!fp)
|
||||||
@ -377,7 +362,7 @@ bool MPluginList::ini_refresh()
|
|||||||
*cp = '\0';
|
*cp = '\0';
|
||||||
|
|
||||||
// Parse into a temp plugin
|
// Parse into a temp plugin
|
||||||
Q_memset(&pl_temp, 0, sizeof pl_temp);
|
MPlugin pl_temp = {};
|
||||||
if (!pl_temp.ini_parseline(line))
|
if (!pl_temp.ini_parseline(line))
|
||||||
{
|
{
|
||||||
META_ERROR("ini: Skipping malformed line %d of %s",ln, m_inifile);
|
META_ERROR("ini: Skipping malformed line %d of %s",ln, m_inifile);
|
||||||
@ -385,32 +370,30 @@ bool MPluginList::ini_refresh()
|
|||||||
}
|
}
|
||||||
// Try to find plugin with this pathname in the current list of
|
// Try to find plugin with this pathname in the current list of
|
||||||
// plugins.
|
// plugins.
|
||||||
if (!(pl_found = find(pl_temp.m_pathname)))
|
auto pl_found = find(pl_temp.m_pathname);
|
||||||
|
if (!pl_found)
|
||||||
{
|
{
|
||||||
// Check for a matching platform with higher platform specifics
|
// Check for a matching platform with higher platform specifics
|
||||||
// level.
|
// level.
|
||||||
if (nullptr != (pl_found = find_match(&pl_temp)))
|
pl_found = find_match(&pl_temp);
|
||||||
|
if (pl_found)
|
||||||
{
|
{
|
||||||
if (pl_found->m_pfspecific >= pl_temp.m_pfspecific)
|
if (pl_found->m_action == PA_LOAD)
|
||||||
{
|
{
|
||||||
META_DEBUG(1, "ini: Skipping plugin, line %d of %s: plugin with higher platform specific level already exists. (%d >= %d)", ln, m_inifile, pl_found->m_pfspecific, pl_temp.m_pfspecific);
|
META_DEBUG(1, "ini: Plugin in line %d overrides loading of plugin", ln);
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (PA_LOAD == pl_found->m_action)
|
|
||||||
{
|
|
||||||
META_DEBUG(1, "ini: Plugin in line %d overrides loading of plugin with lower platform specific level %d, ours %d", ln, pl_found->m_pfspecific, pl_temp.m_pfspecific);
|
|
||||||
int _index = pl_found->m_index;
|
int _index = pl_found->m_index;
|
||||||
Q_memset(pl_found, 0, sizeof(MPlugin));
|
Q_memset(pl_found, 0, sizeof(MPlugin));
|
||||||
pl_found->m_index = _index;
|
pl_found->m_index = _index;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
META_DEBUG(1, "ini: Plugin in line %d should override existing plugin with lower platform specific level %d, ours %d. Unable to comply.", ln, pl_found->m_pfspecific, pl_temp.m_pfspecific);
|
META_DEBUG(1, "ini: Plugin in line %d should override existing plugin. Unable to comply.", ln);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// new plugin; add to list
|
// new plugin; add to list
|
||||||
if ((pl_added = add(&pl_temp)))
|
auto pl_added = add(&pl_temp);
|
||||||
|
if (pl_added)
|
||||||
{
|
{
|
||||||
// try to load this plugin at the next opportunity
|
// try to load this plugin at the next opportunity
|
||||||
pl_added->m_action = PA_LOAD;
|
pl_added->m_action = PA_LOAD;
|
||||||
@ -447,22 +430,17 @@ bool MPluginList::ini_refresh()
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (pl_found)
|
if (pl_found)
|
||||||
{
|
|
||||||
META_LOG("ini: Read plugin config for: %s", pl_found->m_desc);
|
META_LOG("ini: Read plugin config for: %s", pl_found->m_desc);
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
|
||||||
META_LOG("ini: Read plugin config for: %s", pl_temp.m_desc);
|
META_LOG("ini: Read plugin config for: %s", pl_temp.m_desc);
|
||||||
}
|
|
||||||
n++;
|
n++;
|
||||||
}
|
}
|
||||||
META_LOG("ini: Finished reading plugins list: %s; Found %d plugins", m_inifile, n);
|
META_LOG("ini: Finished reading plugins list: %s; Found %d plugins", m_inifile, n);
|
||||||
|
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
|
|
||||||
if (!n)
|
if (!n)
|
||||||
{
|
|
||||||
META_ERROR("ini: Warning; no plugins found to load?");
|
META_ERROR("ini: Warning; no plugins found to load?");
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -471,9 +449,7 @@ bool MPluginList::ini_refresh()
|
|||||||
bool MPluginList::cmd_addload(const char* args)
|
bool MPluginList::cmd_addload(const char* args)
|
||||||
{
|
{
|
||||||
MPlugin pl_temp = {};
|
MPlugin pl_temp = {};
|
||||||
MPlugin *pl_found, *pl_added;
|
if (!pl_temp.cmd_parseline(args))
|
||||||
|
|
||||||
if (pl_temp.cmd_parseline(args) != true)
|
|
||||||
{
|
{
|
||||||
META_CONS("Couldn't parse 'meta load' arguments: %s", args);
|
META_CONS("Couldn't parse 'meta load' arguments: %s", args);
|
||||||
return false;
|
return false;
|
||||||
@ -481,7 +457,7 @@ bool MPluginList::cmd_addload(const char* args)
|
|||||||
|
|
||||||
// resolve given path into a file; accepts various "shortcut"
|
// resolve given path into a file; accepts various "shortcut"
|
||||||
// pathnames.
|
// pathnames.
|
||||||
if (pl_temp.resolve() != true)
|
if (!pl_temp.resolve())
|
||||||
{
|
{
|
||||||
// Couldn't find a matching file on disk
|
// Couldn't find a matching file on disk
|
||||||
META_CONS("Couldn't resolve given path into a file: %s", pl_temp.m_file);
|
META_CONS("Couldn't resolve given path into a file: %s", pl_temp.m_file);
|
||||||
@ -490,14 +466,16 @@ bool MPluginList::cmd_addload(const char* args)
|
|||||||
|
|
||||||
// Try to find plugin with this pathname in the current list of
|
// Try to find plugin with this pathname in the current list of
|
||||||
// plugins.
|
// plugins.
|
||||||
if ((pl_found = find(pl_temp.m_pathname)))
|
auto pl_found = find(pl_temp.m_pathname);
|
||||||
|
if (pl_found)
|
||||||
{
|
{
|
||||||
// Already in list
|
// Already in list
|
||||||
META_CONS("Plugin '%s' already in current list; file=%s desc='%s'", pl_temp.m_file, pl_found->m_file, pl_found->m_desc);
|
META_CONS("Plugin '%s' already in current list; file=%s desc='%s'", pl_temp.m_file, pl_found->m_file, pl_found->m_desc);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// new plugin; add to list
|
// new plugin; add to list
|
||||||
if (!(pl_added = add(&pl_temp)))
|
auto pl_added = add(&pl_temp);
|
||||||
|
if (!pl_added)
|
||||||
{
|
{
|
||||||
META_CONS("Couldn't add plugin '%s' to list; see log", pl_temp.m_desc);
|
META_CONS("Couldn't add plugin '%s' to list; see log", pl_temp.m_desc);
|
||||||
return false;
|
return false;
|
||||||
@ -513,14 +491,13 @@ bool MPluginList::cmd_addload(const char* args)
|
|||||||
else
|
else
|
||||||
META_CONS("Couldn't load plugin '%s'; see log", pl_added->m_desc);
|
META_CONS("Couldn't load plugin '%s'; see log", pl_added->m_desc);
|
||||||
|
|
||||||
show(0);
|
show();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
META_CONS("Loaded plugin '%s' successfully", pl_added->m_desc);
|
META_CONS("Loaded plugin '%s' successfully", pl_added->m_desc);
|
||||||
|
show();
|
||||||
meta_rebuild_callbacks();
|
meta_rebuild_callbacks();
|
||||||
show(0);
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -540,16 +517,15 @@ bool MPluginList::load()
|
|||||||
if (m_plist[i].m_status < PL_VALID)
|
if (m_plist[i].m_status < PL_VALID)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (m_plist[i].load(PT_STARTUP) == true)
|
if (m_plist[i].load(PT_STARTUP))
|
||||||
n++;
|
n++;
|
||||||
else
|
else
|
||||||
// all plugins should be loadable at startup...
|
// all plugins should be loadable at startup...
|
||||||
META_ERROR("dll: Failed to load plugin '%s'", m_plist[i].m_file);
|
META_ERROR("dll: Failed to load plugin '%s'", m_plist[i].m_file);
|
||||||
}
|
}
|
||||||
|
|
||||||
meta_rebuild_callbacks();
|
|
||||||
|
|
||||||
META_LOG("dll: Finished loading %d plugins", n);
|
META_LOG("dll: Finished loading %d plugins", n);
|
||||||
|
meta_rebuild_callbacks();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -598,7 +574,7 @@ bool MPluginList::refresh(PLUG_LOADTIME now)
|
|||||||
{
|
{
|
||||||
META_DEBUG(1, "Unloading plugin '%s'", iplug->m_desc);
|
META_DEBUG(1, "Unloading plugin '%s'", iplug->m_desc);
|
||||||
iplug->m_action = PA_UNLOAD;
|
iplug->m_action = PA_UNLOAD;
|
||||||
if (iplug->unload(now, PNL_INI_DELETED, PNL_INI_DELETED))
|
if (iplug->unload(now, PNL_INI_DELETED))
|
||||||
nunloaded++;
|
nunloaded++;
|
||||||
/*else if (meta_errno == ME_DELAYED) TODO
|
/*else if (meta_errno == ME_DELAYED) TODO
|
||||||
ndelayed++;*/
|
ndelayed++;*/
|
||||||
@ -630,9 +606,8 @@ bool MPluginList::refresh(PLUG_LOADTIME now)
|
|||||||
ndone++;
|
ndone++;
|
||||||
}
|
}
|
||||||
|
|
||||||
meta_rebuild_callbacks();
|
|
||||||
|
|
||||||
META_LOG("dll: Finished updating %d plugins; kept %d, loaded %d, unloaded %d, reloaded %d, delayed %d", ndone, nkept, nloaded, nunloaded, nreloaded, ndelayed);
|
META_LOG("dll: Finished updating %d plugins; kept %d, loaded %d, unloaded %d, reloaded %d, delayed %d", ndone, nkept, nloaded, nunloaded, nreloaded, ndelayed);
|
||||||
|
meta_rebuild_callbacks();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -688,9 +663,9 @@ void MPluginList::show(int source_index)
|
|||||||
Q_strncpy(file, pl->m_file, sizeof file - 1);
|
Q_strncpy(file, pl->m_file, sizeof file - 1);
|
||||||
file[sizeof file - 1] = '\0';
|
file[sizeof file - 1] = '\0';
|
||||||
|
|
||||||
if (pl->m_info && pl->m_info->version)
|
if (pl->info() && pl->info()->version)
|
||||||
{
|
{
|
||||||
Q_strncpy(vers, pl->m_info->version, sizeof vers - 1);
|
Q_strncpy(vers, pl->info()->version, sizeof vers - 1);
|
||||||
vers[sizeof vers - 1] = '\0';
|
vers[sizeof vers - 1] = '\0';
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -724,16 +699,16 @@ void MPluginList::show_client(edict_t *pEntity)
|
|||||||
for (int i = 0; i < m_max_loaded_count; i++)
|
for (int i = 0; i < m_max_loaded_count; i++)
|
||||||
{
|
{
|
||||||
auto pl = &m_plist[i];
|
auto pl = &m_plist[i];
|
||||||
if (pl->m_status != PL_RUNNING || !pl->m_info)
|
if (pl->m_status != PL_RUNNING || !pl->info())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
n++;
|
n++;
|
||||||
META_CLIENT(pEntity, " [%3d] %s, v%s, %s, by %s, see %s", n,
|
META_CLIENT(pEntity, " [%3d] %s, v%s, %s, by %s, see %s", n,
|
||||||
pl->m_info->name ? pl->m_info->name : "<unknown>",
|
pl->info()->name ? pl->info()->name : "<unknown>",
|
||||||
pl->m_info->version ? pl->m_info->version : "<?>",
|
pl->info()->version ? pl->info()->version : "<?>",
|
||||||
pl->m_info->date ? pl->m_info->date : "<../../..>",
|
pl->info()->date ? pl->info()->date : "<../../..>",
|
||||||
pl->m_info->author ? pl->m_info->author : "<unknown>",
|
pl->info()->author ? pl->info()->author : "<unknown>",
|
||||||
pl->m_info->url ? pl->m_info->url : "<unknown>");
|
pl->info()->url ? pl->info()->url : "<unknown>");
|
||||||
}
|
}
|
||||||
|
|
||||||
META_CLIENT(pEntity, "%d plugins", n);
|
META_CLIENT(pEntity, "%d plugins", n);
|
||||||
|
@ -12,7 +12,8 @@
|
|||||||
#define WIDTH_MAX_PLUGINS 2
|
#define WIDTH_MAX_PLUGINS 2
|
||||||
|
|
||||||
// A list of plugins.
|
// A list of plugins.
|
||||||
class MPluginList {
|
class MPluginList
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
MPluginList(const char *ifile);
|
MPluginList(const char *ifile);
|
||||||
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -1,13 +1,12 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "api_info.h"
|
#include "utils.h"
|
||||||
#include "support_meta.h"
|
|
||||||
|
|
||||||
// Flags to indicate current "load" state of plugin.
|
// Flags to indicate current "load" state of plugin.
|
||||||
// NOTE: order is important, as greater/less comparisons are made.
|
// NOTE: order is important, as greater/less comparisons are made.
|
||||||
enum PLUG_STATUS : uint8
|
enum PLUG_STATUS : uint8
|
||||||
{
|
{
|
||||||
PL_EMPTY = 0, // empty slot
|
PL_EMPTY, // empty slot
|
||||||
PL_VALID, // has valid info in it
|
PL_VALID, // has valid info in it
|
||||||
PL_BADFILE, // nonexistent file (open failed), or not a valid plugin file (query failed)
|
PL_BADFILE, // nonexistent file (open failed), or not a valid plugin file (query failed)
|
||||||
PL_OPENED, // dlopened and queried
|
PL_OPENED, // dlopened and queried
|
||||||
@ -19,7 +18,7 @@ enum PLUG_STATUS : uint8
|
|||||||
// Action to take for plugin at next opportunity.
|
// Action to take for plugin at next opportunity.
|
||||||
enum PLUG_ACTION : uint8
|
enum PLUG_ACTION : uint8
|
||||||
{
|
{
|
||||||
PA_NULL = 0,
|
PA_NULL,
|
||||||
PA_NONE, // no action needed right now
|
PA_NONE, // no action needed right now
|
||||||
PA_KEEP, // keep, after ini refresh
|
PA_KEEP, // keep, after ini refresh
|
||||||
PA_LOAD, // load (dlopen, query) and try to attach
|
PA_LOAD, // load (dlopen, query) and try to attach
|
||||||
@ -31,7 +30,7 @@ enum PLUG_ACTION : uint8
|
|||||||
// Flags to indicate from where the plugin was loaded.
|
// Flags to indicate from where the plugin was loaded.
|
||||||
enum PLOAD_SOURCE : uint8
|
enum PLOAD_SOURCE : uint8
|
||||||
{
|
{
|
||||||
PS_INI = 0, // was loaded from the plugins.ini
|
PS_INI, // was loaded from the plugins.ini
|
||||||
PS_CMD, // was loaded via a server command
|
PS_CMD, // was loaded via a server command
|
||||||
PS_PLUGIN, // was loaded by other plugin
|
PS_PLUGIN, // was loaded by other plugin
|
||||||
};
|
};
|
||||||
@ -48,68 +47,50 @@ enum STR_LOADTIME : uint8
|
|||||||
// Flags for how to format description of status.
|
// Flags for how to format description of status.
|
||||||
enum STR_STATUS : uint8
|
enum STR_STATUS : uint8
|
||||||
{
|
{
|
||||||
ST_SIMPLE = 0, // single word
|
ST_SIMPLE, // single word
|
||||||
ST_SHOW, // for "show" output, 4 chars
|
ST_SHOW, // for "show" output, 4 chars
|
||||||
};
|
};
|
||||||
|
|
||||||
// Flags for how to format description of action.
|
// Flags for how to format description of action.
|
||||||
enum STR_ACTION : uint8
|
enum STR_ACTION : uint8
|
||||||
{
|
{
|
||||||
SA_SIMPLE = 0, // single word
|
SA_SIMPLE, // single word
|
||||||
SA_SHOW, // for "show" output, 4 chars
|
SA_SHOW, // for "show" output, 4 chars
|
||||||
};
|
};
|
||||||
|
|
||||||
// Flags for how to format description of source.
|
// Flags for how to format description of source.
|
||||||
enum STR_SOURCE : uint8
|
enum STR_SOURCE : uint8
|
||||||
{
|
{
|
||||||
SO_SIMPLE = 0, // two words
|
SO_SIMPLE, // two words
|
||||||
SO_SHOW, // for "list" output, 3 chars
|
SO_SHOW, // for "list" output, 3 chars
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum STR_PLATFORM : uint8
|
||||||
|
{
|
||||||
|
SP_WINDOWS,
|
||||||
|
SP_LINUX
|
||||||
|
};
|
||||||
|
|
||||||
// An individual plugin.
|
// An individual plugin.
|
||||||
class MPlugin {
|
class MPlugin
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
PLUG_STATUS m_status; // current status of plugin (loaded, etc)
|
MPlugin();
|
||||||
PLUG_ACTION m_action; // what to do with plugin (load, unload, etc)
|
MPlugin(int index);
|
||||||
PLOAD_SOURCE m_source; // source of the request to load the plugin
|
|
||||||
int m_index; // 1-based
|
|
||||||
plugin_info_t *m_info; // information plugin provides about itself
|
|
||||||
CSysModule m_sys_module;
|
|
||||||
time_t m_time_loaded; // when plugin was loaded
|
|
||||||
int m_source_plugin_index; // who loaded this plugin
|
|
||||||
int m_unloader_index;
|
|
||||||
bool m_is_unloader; // fix to prevent other plugins unload active unloader.
|
|
||||||
|
|
||||||
DLL_FUNCTIONS *m_dllapi_table;
|
bool ini_parseline(char *line); // parse line from .ini file
|
||||||
DLL_FUNCTIONS *m_dllapi_post_table;
|
bool cmd_parseline(const char *line); // parse from console command
|
||||||
NEW_DLL_FUNCTIONS *m_newapi_table;
|
|
||||||
NEW_DLL_FUNCTIONS *m_newapi_post_table;
|
|
||||||
enginefuncs_t *m_engine_table;
|
|
||||||
enginefuncs_t *m_engine_post_table;
|
|
||||||
|
|
||||||
gamedll_funcs_t m_gamedll_funcs;
|
|
||||||
mutil_funcs_t m_mutil_funcs;
|
|
||||||
|
|
||||||
char m_filename[PATH_MAX]; // ie "dlls/mm_test_i386.so", from inifile
|
|
||||||
char *m_file; // ie "mm_test_i386.so", ptr from filename
|
|
||||||
char m_desc[MAX_DESC_LEN]; // ie "Test metamod plugin", from inifile
|
|
||||||
char m_pathname[PATH_MAX]; // UNIQUE, ie "/home/willday/half-life/cstrike/dlls/mm_test_i386.so", built with GameDLL.gamedir
|
|
||||||
int m_pfspecific; // level of specific platform affinity, used during load time
|
|
||||||
|
|
||||||
bool ini_parseline(char *line); // parse line from inifile
|
|
||||||
bool cmd_parseline(const char *line); // parse from console command
|
|
||||||
bool plugin_parseline(const char *fname, int loader_index); // parse from plugin
|
bool plugin_parseline(const char *fname, int loader_index); // parse from plugin
|
||||||
bool check_input();
|
bool check_input(); // check filename, path, status
|
||||||
|
|
||||||
bool resolve(); // find a matching file on disk
|
bool resolve(); // find a matching file on disk
|
||||||
char *resolve_dirs(char *path) const;
|
char *resolve_dirs(const char *path, char *tempbuf, size_t bufsize) const; // try resolve filename in different dirs
|
||||||
char *resolve_prefix(char *path) const;
|
char *resolve_suffix(const char *path, char *tempbuf, size_t bufsize) const; // try resolve given filename with different suffixes
|
||||||
char *resolve_suffix(char *path) const;
|
|
||||||
|
|
||||||
bool platform_match(MPlugin* plugin) const;
|
bool platform_match(MPlugin* plugin) const; // check if a given plugin is the same but possibly for a different platform
|
||||||
|
|
||||||
bool load(PLUG_LOADTIME now);
|
bool load(PLUG_LOADTIME now); // load parsed plugin
|
||||||
bool unload(PLUG_LOADTIME now, PL_UNLOAD_REASON reason, PL_UNLOAD_REASON real_reason);
|
bool unload(PLUG_LOADTIME now, PL_UNLOAD_REASON reason);
|
||||||
bool reload(PLUG_LOADTIME now, PL_UNLOAD_REASON reason);
|
bool reload(PLUG_LOADTIME now, PL_UNLOAD_REASON reason);
|
||||||
bool pause();
|
bool pause();
|
||||||
bool unpause();
|
bool unpause();
|
||||||
@ -120,36 +101,66 @@ public:
|
|||||||
|
|
||||||
bool newer_file() const; // check for newer file on disk
|
bool newer_file() const; // check for newer file on disk
|
||||||
|
|
||||||
const char *str_status(STR_STATUS fmt) const;
|
const char *str_status(STR_STATUS fmt = ST_SIMPLE) const;
|
||||||
const char *str_action(STR_ACTION fmt) const;
|
const char *str_action(STR_ACTION fmt = SA_SIMPLE) const;
|
||||||
const char *str_source(STR_SOURCE fmt) const;
|
const char *str_source(STR_SOURCE fmt = SO_SIMPLE) const;
|
||||||
|
const char *str_reason(PL_UNLOAD_REASON reason) const;
|
||||||
const char *str_reason(PL_UNLOAD_REASON preason, PL_UNLOAD_REASON preal_reason) const;
|
|
||||||
static const char *str_loadtime(PLUG_LOADTIME pallow, STR_LOADTIME fmt);
|
static const char *str_loadtime(PLUG_LOADTIME pallow, STR_LOADTIME fmt);
|
||||||
|
|
||||||
const char *str_status() { return str_status(ST_SIMPLE); };
|
const char* str_loadable() const;
|
||||||
const char *str_action() { return str_action(SA_SIMPLE); };
|
const char* str_unloadable() const;
|
||||||
const char *str_source() { return str_source(SO_SIMPLE); };
|
const char* str_loadable(STR_LOADTIME fmt) const;
|
||||||
|
const char* str_unloadable(STR_LOADTIME fmt) const;
|
||||||
|
|
||||||
const char *str_loadable() {
|
PLUG_STATUS status() const;
|
||||||
if (m_info) return str_loadtime(m_info->loadable, SL_SIMPLE);
|
PLUG_ACTION action() const;
|
||||||
else return " -";
|
const char* description() const;
|
||||||
};
|
plugin_info_t* info() const;
|
||||||
const char *str_unloadable() {
|
int index() const;
|
||||||
if (m_info) return str_loadtime(m_info->unloadable, SL_SIMPLE);
|
int source_index() const;
|
||||||
else return " -";
|
const char* file() const;
|
||||||
};
|
const char* filename() const;
|
||||||
const char *str_loadable(STR_LOADTIME fmt) {
|
const char* pathname() const;
|
||||||
if (m_info) return str_loadtime(m_info->loadable, fmt);
|
const CSysModule& sys_module() const;
|
||||||
else return " -";
|
size_t status_ptr();
|
||||||
};
|
void set_action(PLUG_ACTION action);
|
||||||
const char *str_unloadable(STR_LOADTIME fmt) {
|
|
||||||
if (m_info) return str_loadtime(m_info->unloadable, fmt);
|
|
||||||
else return " -";
|
|
||||||
};
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool query();
|
bool query(); // check exports, call init, getfnptrs and query
|
||||||
bool attach(PLUG_LOADTIME now);
|
bool attach(PLUG_LOADTIME now); // call attach
|
||||||
bool detach(PLUG_LOADTIME now, PL_UNLOAD_REASON reason);
|
bool detach(PLUG_LOADTIME now, PL_UNLOAD_REASON reason); // call detach
|
||||||
|
|
||||||
|
PLUG_STATUS m_status; // current status of plugin (loaded, etc)
|
||||||
|
PLUG_ACTION m_action; // what to do with plugin (load, unload, etc)
|
||||||
|
PLOAD_SOURCE m_source; // source of the request to load the plugin
|
||||||
|
STR_PLATFORM m_platform; // plugin platform
|
||||||
|
int m_index; // 1-based
|
||||||
|
plugin_info_t *m_info; // information plugin provides about itself
|
||||||
|
CSysModule m_sys_module; // system module
|
||||||
|
time_t m_time_loaded; // when plugin was loaded
|
||||||
|
int m_source_plugin_index; // who loaded this plugin
|
||||||
|
int m_unloader_index; // index of unloader plugin
|
||||||
|
bool m_is_unloader; // fix to prevent other plugins unload active unloader.
|
||||||
|
|
||||||
|
public:
|
||||||
|
// pointers to tables inside plugins
|
||||||
|
DLL_FUNCTIONS *m_dllapi_table;
|
||||||
|
DLL_FUNCTIONS *m_dllapi_post_table;
|
||||||
|
NEW_DLL_FUNCTIONS *m_newapi_table;
|
||||||
|
NEW_DLL_FUNCTIONS *m_newapi_post_table;
|
||||||
|
enginefuncs_t *m_engine_table;
|
||||||
|
enginefuncs_t *m_engine_post_table;
|
||||||
|
|
||||||
|
private:
|
||||||
|
gamedll_funcs_t m_gamedll_funcs;
|
||||||
|
mutil_funcs_t m_mutil_funcs;
|
||||||
|
|
||||||
|
char m_filename[PATH_MAX]; // ie "dlls/mm_test_i386.so", from inifile
|
||||||
|
char *m_file; // ie "mm_test_i386.so", ptr from filename
|
||||||
|
char m_desc[MAX_DESC_LEN]; // ie "Test metamod plugin", from inifile
|
||||||
|
char m_pathname[PATH_MAX]; // UNIQUE, ie "/home/willday/half-life/cstrike/dlls/mm_test_i386.so", built with GameDLL.gamedir
|
||||||
|
|
||||||
|
static const char *s_rPrintLoadTime[][4];
|
||||||
|
|
||||||
|
friend class MPluginList;
|
||||||
};
|
};
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#include "precompiled.h"
|
#include "precompiled.h"
|
||||||
|
|
||||||
MRegCmd::MRegCmd(char* cmd_name, REG_CMD_FN cmd_handler, MPlugin* cmd_plugin) : m_pfunction(cmd_handler), m_plugid(cmd_plugin->m_index), m_status(RG_VALID)
|
MRegCmd::MRegCmd(char* cmd_name, REG_CMD_FN cmd_handler, MPlugin* cmd_plugin) : m_pfunction(cmd_handler), m_plugid(cmd_plugin->index()), m_status(RG_VALID)
|
||||||
{
|
{
|
||||||
m_name = Q_strdup(cmd_name);
|
m_name = Q_strdup(cmd_name);
|
||||||
}
|
}
|
||||||
@ -112,7 +112,7 @@ void MRegCmdList::show() const
|
|||||||
{
|
{
|
||||||
auto iplug = g_plugins->find(reg->m_plugid);
|
auto iplug = g_plugins->find(reg->m_plugid);
|
||||||
|
|
||||||
Q_strncpy(bplug, iplug ? iplug->m_desc : "(unknown)", sizeof bplug - 1);
|
Q_strncpy(bplug, iplug ? iplug->description() : "(unknown)", sizeof bplug - 1);
|
||||||
bplug[sizeof bplug - 1] = '\0';
|
bplug[sizeof bplug - 1] = '\0';
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -149,7 +149,7 @@ void MRegCmdList::show(int plugin_id) const
|
|||||||
META_CONS("%d commands", total_count);
|
META_CONS("%d commands", total_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
MRegCvar::MRegCvar(cvar_t* cv_ptr, MPlugin* cv_plugin) : m_cvar(cv_ptr), m_plugid(cv_plugin ? cv_plugin->m_index : 0), m_status(RG_VALID)
|
MRegCvar::MRegCvar(cvar_t* cv_ptr, MPlugin* cv_plugin) : m_cvar(cv_ptr), m_plugid(cv_plugin ? cv_plugin->index() : 0), m_status(RG_VALID)
|
||||||
{
|
{
|
||||||
m_cvar = new cvar_t;
|
m_cvar = new cvar_t;
|
||||||
m_cvar->name = Q_strdup(cv_ptr->name);
|
m_cvar->name = Q_strdup(cv_ptr->name);
|
||||||
@ -228,7 +228,7 @@ void MRegCvarList::show() const
|
|||||||
if (reg->m_status == RG_VALID)
|
if (reg->m_status == RG_VALID)
|
||||||
{
|
{
|
||||||
auto plug = g_plugins->find(reg->m_plugid);
|
auto plug = g_plugins->find(reg->m_plugid);
|
||||||
Q_strncpy(bplug, plug ? plug->m_desc : "(unknown)", sizeof bplug - 1);
|
Q_strncpy(bplug, plug ? plug->description() : "(unknown)", sizeof bplug - 1);
|
||||||
bplug[sizeof bplug - 1] = '\0';
|
bplug[sizeof bplug - 1] = '\0';
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -252,7 +252,7 @@ const char* EXT_FUNC mutil_GetPluginPath(plid_t plid)
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
Q_strncpy(buf, plug->m_pathname, sizeof buf - 1);
|
Q_strncpy(buf, plug->pathname(), sizeof buf - 1);
|
||||||
buf[sizeof buf - 1] = '\0';
|
buf[sizeof buf - 1] = '\0';
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
@ -301,7 +301,6 @@ int EXT_FUNC mutil_LoadMetaPlugin(plid_t plid, const char* fname, PLUG_LOADTIME
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto pl_loaded = g_plugins->plugin_addload(plid, fname, now);
|
auto pl_loaded = g_plugins->plugin_addload(plid, fname, now);
|
||||||
|
|
||||||
if (!pl_loaded)
|
if (!pl_loaded)
|
||||||
{
|
{
|
||||||
if (plugin_handle)
|
if (plugin_handle)
|
||||||
@ -309,13 +308,13 @@ int EXT_FUNC mutil_LoadMetaPlugin(plid_t plid, const char* fname, PLUG_LOADTIME
|
|||||||
|
|
||||||
return 1; // TODO: WTF
|
return 1; // TODO: WTF
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
if (plugin_handle)
|
|
||||||
*plugin_handle = (void *)pl_loaded->m_sys_module.gethandle();
|
|
||||||
|
|
||||||
return 0;
|
meta_rebuild_callbacks();
|
||||||
}
|
|
||||||
|
if (plugin_handle)
|
||||||
|
*plugin_handle = (void *)pl_loaded->sys_module().gethandle();
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int EXT_FUNC mutil_UnloadMetaPlugin(plid_t plid, const char *fname, PLUG_LOADTIME now, PL_UNLOAD_REASON reason)
|
int EXT_FUNC mutil_UnloadMetaPlugin(plid_t plid, const char *fname, PLUG_LOADTIME now, PL_UNLOAD_REASON reason)
|
||||||
@ -339,8 +338,10 @@ int EXT_FUNC mutil_UnloadMetaPlugin(plid_t plid, const char *fname, PLUG_LOADTIM
|
|||||||
if (!findp || !unique)
|
if (!findp || !unique)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
if (findp->plugin_unload(plid, now, reason))
|
if (findp->plugin_unload(plid, now, reason)) {
|
||||||
|
meta_rebuild_callbacks();
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -357,8 +358,10 @@ int EXT_FUNC mutil_UnloadMetaPluginByHandle(plid_t plid, void *plugin_handle, PL
|
|||||||
if (!findp)
|
if (!findp)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
if (findp->plugin_unload(plid, now, reason))
|
if (findp->plugin_unload(plid, now, reason)) {
|
||||||
|
meta_rebuild_callbacks();
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -7,12 +7,14 @@ CSysModule::CSysModule() : m_handle(0), m_base(0), m_size(0)
|
|||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
module_handle_t CSysModule::load(const char* filepath)
|
module_handle_t CSysModule::load(const char* filepath)
|
||||||
{
|
{
|
||||||
m_handle = LoadLibrary(filepath);
|
if (!m_handle) {
|
||||||
|
m_handle = LoadLibrary(filepath);
|
||||||
|
|
||||||
MODULEINFO module_info;
|
MODULEINFO module_info;
|
||||||
if (GetModuleInformation(GetCurrentProcess(), m_handle, &module_info, sizeof module_info)) {
|
if (GetModuleInformation(GetCurrentProcess(), m_handle, &module_info, sizeof module_info)) {
|
||||||
m_base = (uintptr_t)module_info.lpBaseOfDll;
|
m_base = (uintptr_t)module_info.lpBaseOfDll;
|
||||||
m_size = module_info.SizeOfImage;
|
m_size = module_info.SizeOfImage;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return m_handle;
|
return m_handle;
|
||||||
@ -20,7 +22,7 @@ module_handle_t CSysModule::load(const char* filepath)
|
|||||||
|
|
||||||
bool CSysModule::unload()
|
bool CSysModule::unload()
|
||||||
{
|
{
|
||||||
bool ret = false;
|
bool ret = true;
|
||||||
|
|
||||||
if (m_handle) {
|
if (m_handle) {
|
||||||
ret = FreeLibrary(m_handle) != ERROR;
|
ret = FreeLibrary(m_handle) != ERROR;
|
||||||
@ -34,7 +36,7 @@ bool CSysModule::unload()
|
|||||||
|
|
||||||
void* CSysModule::getsym(const char* name) const
|
void* CSysModule::getsym(const char* name) const
|
||||||
{
|
{
|
||||||
return GetProcAddress(m_handle, name);
|
return m_handle ? GetProcAddress(m_handle, name) : nullptr;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
static ElfW(Addr) dlsize(void* base)
|
static ElfW(Addr) dlsize(void* base)
|
||||||
@ -59,35 +61,38 @@ static ElfW(Addr) dlsize(void* base)
|
|||||||
|
|
||||||
module_handle_t CSysModule::load(const char* filepath)
|
module_handle_t CSysModule::load(const char* filepath)
|
||||||
{
|
{
|
||||||
m_handle = dlopen(filepath, RTLD_NOW);
|
if (!m_handle) {
|
||||||
|
m_handle = dlopen(filepath, RTLD_NOW);
|
||||||
|
|
||||||
char buf[1024], dummy[1024], path[260];
|
char buf[1024], dummy[1024], path[260];
|
||||||
sprintf(buf, "/proc/%i/maps", getpid());
|
sprintf(buf, "/proc/%i/maps", getpid());
|
||||||
|
|
||||||
FILE* fp = fopen(buf, "r");
|
FILE* fp = fopen(buf, "r");
|
||||||
|
|
||||||
while (fgets(buf, sizeof buf, fp)) {
|
while (fgets(buf, sizeof buf, fp)) {
|
||||||
uintptr_t start, end;
|
uintptr_t start, end;
|
||||||
|
|
||||||
int args = sscanf(buf, "%x-%x %128s %128s %128s %128s %255s", &start, &end, dummy, dummy, dummy, dummy, path);
|
int args = sscanf(buf, "%x-%x %128s %128s %128s %128s %255s", &start, &end, dummy, dummy, dummy, dummy, path);
|
||||||
if (args != 7) {
|
if (args != 7) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Q_stricmp(path, filepath)) {
|
||||||
|
m_base = start;
|
||||||
|
m_size = end - start;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Q_stricmp(path, filepath)) {
|
fclose(fp);
|
||||||
m_base = start;
|
|
||||||
m_size = end - start;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fclose(fp);
|
|
||||||
return m_handle;
|
return m_handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CSysModule::unload()
|
bool CSysModule::unload()
|
||||||
{
|
{
|
||||||
bool ret = false;
|
bool ret = true;
|
||||||
|
|
||||||
if (m_handle) {
|
if (m_handle) {
|
||||||
ret = dlclose(m_handle) != 0;
|
ret = dlclose(m_handle) != 0;
|
||||||
@ -101,7 +106,7 @@ bool CSysModule::unload()
|
|||||||
|
|
||||||
void* CSysModule::getsym(const char* name) const
|
void* CSysModule::getsym(const char* name) const
|
||||||
{
|
{
|
||||||
return dlsym(m_handle, name);
|
return m_handle ? dlsym(m_handle, name) : nullptr;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -130,7 +135,7 @@ const char* CSysModule::getloaderror()
|
|||||||
// http://msdn.microsoft.com/library/en-us/debug/errors_0sdh.asp
|
// http://msdn.microsoft.com/library/en-us/debug/errors_0sdh.asp
|
||||||
// except without FORMAT_MESSAGE_ALLOCATE_BUFFER, since we use a local
|
// except without FORMAT_MESSAGE_ALLOCATE_BUFFER, since we use a local
|
||||||
// static buffer.
|
// static buffer.
|
||||||
const char *str_GetLastError()
|
static const char *str_GetLastError()
|
||||||
{
|
{
|
||||||
static char buf[MAX_STRBUF_LEN];
|
static char buf[MAX_STRBUF_LEN];
|
||||||
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, nullptr, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&buf, MAX_STRBUF_LEN - 1, nullptr);
|
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, nullptr, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&buf, MAX_STRBUF_LEN - 1, nullptr);
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
// NOTE: order is crucial, as greater/less comparisons are made.
|
// NOTE: order is crucial, as greater/less comparisons are made.
|
||||||
enum PLUG_LOADTIME
|
enum PLUG_LOADTIME
|
||||||
{
|
{
|
||||||
PT_NEVER = 0,
|
PT_NEVER,
|
||||||
PT_STARTUP, // should only be loaded/unloaded at initial hlds execution
|
PT_STARTUP, // should only be loaded/unloaded at initial hlds execution
|
||||||
PT_CHANGELEVEL, // can be loaded/unloaded between maps
|
PT_CHANGELEVEL, // can be loaded/unloaded between maps
|
||||||
PT_ANYTIME, // can be loaded/unloaded at any time
|
PT_ANYTIME, // can be loaded/unloaded at any time
|
||||||
@ -14,7 +14,7 @@ enum PLUG_LOADTIME
|
|||||||
// Flags to indicate why the plugin is being unloaded.
|
// Flags to indicate why the plugin is being unloaded.
|
||||||
enum PL_UNLOAD_REASON
|
enum PL_UNLOAD_REASON
|
||||||
{
|
{
|
||||||
PNL_NULL = 0,
|
PNL_NULL,
|
||||||
PNL_INI_DELETED, // was deleted from plugins.ini
|
PNL_INI_DELETED, // was deleted from plugins.ini
|
||||||
PNL_FILE_NEWER, // file on disk is newer than last load
|
PNL_FILE_NEWER, // file on disk is newer than last load
|
||||||
PNL_COMMAND, // requested by server/console command
|
PNL_COMMAND, // requested by server/console command
|
||||||
|
@ -31,11 +31,9 @@
|
|||||||
#include "metamod.h"
|
#include "metamod.h"
|
||||||
#include "log_meta.h"
|
#include "log_meta.h"
|
||||||
#include "conf_meta.h"
|
#include "conf_meta.h"
|
||||||
#include "support_meta.h"
|
|
||||||
#include "dllapi.h"
|
#include "dllapi.h"
|
||||||
#include "engine_api.h"
|
#include "engine_api.h"
|
||||||
#include "game_support.h"
|
#include "game_support.h"
|
||||||
#include "meta_eiface.h"
|
|
||||||
#include "mreg.h"
|
#include "mreg.h"
|
||||||
#include "meta_api.h"
|
#include "meta_api.h"
|
||||||
#include "mutil.h"
|
#include "mutil.h"
|
||||||
|
@ -30,7 +30,7 @@ void EXT_FUNC meta_AddServerCommand(char *cmd_name, void (*function)())
|
|||||||
{
|
{
|
||||||
MPlugin *plug = g_plugins->find_memloc(function);
|
MPlugin *plug = g_plugins->find_memloc(function);
|
||||||
|
|
||||||
META_DEBUG(4, "called: meta_AddServerCommand; cmd_name=%s, function=%d, plugin=%s", cmd_name, function, plug ? plug->m_file : "unknown");
|
META_DEBUG(4, "called: meta_AddServerCommand; cmd_name=%s, function=%d, plugin=%s", cmd_name, function, plug ? plug->file() : "unknown");
|
||||||
|
|
||||||
if (!plug) {
|
if (!plug) {
|
||||||
META_ERROR("Failed to find memloc for regcmd '%s'", cmd_name);
|
META_ERROR("Failed to find memloc for regcmd '%s'", cmd_name);
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#include "precompiled.h"
|
#include "precompiled.h"
|
||||||
|
|
||||||
char *UTIL_VarArgs(char *format, ...)
|
char *UTIL_VarArgs(const char *format, ...)
|
||||||
{
|
{
|
||||||
va_list argptr;
|
va_list argptr;
|
||||||
static char string[1024];
|
static char string[1024];
|
||||||
|
@ -13,4 +13,5 @@
|
|||||||
#include "enginecallbacks.h"
|
#include "enginecallbacks.h"
|
||||||
#include <util.h>
|
#include <util.h>
|
||||||
|
|
||||||
|
char *UTIL_VarArgs(const char *format, ...);
|
||||||
void UTIL_HudMessage(edict_t *pEntity, const hudtextparms_t &textparms, const char *pMessage);
|
void UTIL_HudMessage(edict_t *pEntity, const hudtextparms_t &textparms, const char *pMessage);
|
||||||
|
@ -1,91 +0,0 @@
|
|||||||
#include "precompiled.h"
|
|
||||||
|
|
||||||
void __declspec(noreturn) do_exit(int exitval)
|
|
||||||
{
|
|
||||||
//Allahu Akbar!!
|
|
||||||
*((int *)nullptr) = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Checks for a non-empty file, relative to the gamedir if necessary.
|
|
||||||
// Formerly used LOAD_FILE_FOR_ME, which provided a simple way to check for
|
|
||||||
// a file under the gamedir, but which would _also_ look in the sibling
|
|
||||||
// "valve" directory, thus sometimes finding files that weren't desired.
|
|
||||||
// Also, formerly named just "valid_file".
|
|
||||||
//
|
|
||||||
// Special-case-recognize "/dev/null" as a valid file.
|
|
||||||
bool FileExistsInGameDir(const char *path)
|
|
||||||
{
|
|
||||||
struct stat st;
|
|
||||||
char buf[PATH_MAX];
|
|
||||||
|
|
||||||
if (!path)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (!Q_strcmp(path, "/dev/null"))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
if (IsAbsolutePath(path))
|
|
||||||
{
|
|
||||||
Q_strncpy(buf, path, sizeof buf);
|
|
||||||
buf[sizeof buf - 1] = '\0';
|
|
||||||
}
|
|
||||||
else
|
|
||||||
snprintf(buf, sizeof buf, "%s/%s", g_GameDLL.gamedir, path);
|
|
||||||
|
|
||||||
int ret = stat(buf, &st);
|
|
||||||
if (ret != 0)
|
|
||||||
{
|
|
||||||
META_DEBUG(5, "Unable to stat '%s': %s", buf, strerror(errno));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
int reg = S_ISREG(st.st_mode);
|
|
||||||
if (!reg)
|
|
||||||
{
|
|
||||||
META_DEBUG(5, "Not a regular file: %s", buf);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!st.st_size)
|
|
||||||
{
|
|
||||||
META_DEBUG(5, "Empty file: %s", buf);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ret == 0 && reg)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Turns path into a full path:
|
|
||||||
// - if not absolute, prepends gamedir
|
|
||||||
// - calls realpath() to collapse ".." and such
|
|
||||||
// - calls NormalizePath() to fix backslashes, etc
|
|
||||||
//
|
|
||||||
// Much like realpath, buffer pointed to by fullpath is assumed to be
|
|
||||||
// able to store a string of PATH_MAX length.
|
|
||||||
char* full_gamedir_path(const char* path, char* fullpath)
|
|
||||||
{
|
|
||||||
char buf[PATH_MAX];
|
|
||||||
|
|
||||||
// Build pathname from filename, plus gamedir if relative path.
|
|
||||||
if (IsAbsolutePath(path))
|
|
||||||
{
|
|
||||||
Q_strncpy(buf, path, sizeof buf - 1);
|
|
||||||
buf[sizeof buf - 1] = '\0';
|
|
||||||
}
|
|
||||||
else snprintf(buf, sizeof buf, "%s/%s", g_GameDLL.gamedir, path);
|
|
||||||
|
|
||||||
// Remove relative path components, if possible.
|
|
||||||
if (!realpath(buf, fullpath))
|
|
||||||
{
|
|
||||||
META_DEBUG(4, "Unable to get realpath for '%s': %s", buf, str_os_error());
|
|
||||||
Q_strncpy(fullpath, path, sizeof fullpath - 1);
|
|
||||||
fullpath[sizeof fullpath - 1] = '\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
// Replace backslashes, etc.
|
|
||||||
NormalizePath(fullpath);
|
|
||||||
return fullpath;
|
|
||||||
}
|
|
@ -1,23 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <sys/types.h> // stat
|
|
||||||
#include <sys/stat.h> // stat
|
|
||||||
|
|
||||||
#include "osdep.h" // _stricmp, S_ISREG,
|
|
||||||
|
|
||||||
void __declspec(noreturn) do_exit(int exitval);
|
|
||||||
|
|
||||||
bool FileExistsInGameDir(const char *path);
|
|
||||||
char *full_gamedir_path(const char *path, char *fullpath);
|
|
||||||
|
|
||||||
// Turn a variable/function name into the corresponding string, optionally
|
|
||||||
// stripping off the leading "len" characters. Useful for things like
|
|
||||||
// turning 'pfnClientCommand' into "ClientCommand" so we don't have to
|
|
||||||
// specify strings used for all the debugging/log messages.
|
|
||||||
#define STRINGIZE(name, len) #name+len
|
|
||||||
|
|
||||||
// Max description length for plugins.ini and other places.
|
|
||||||
#define MAX_DESC_LEN 256
|
|
||||||
|
|
||||||
// For various character string buffers.
|
|
||||||
#define MAX_STRBUF_LEN 1024
|
|
@ -1,5 +1,13 @@
|
|||||||
#include "precompiled.h"
|
#include "precompiled.h"
|
||||||
|
|
||||||
|
const char* g_platform_postfixes[4] =
|
||||||
|
{
|
||||||
|
"_i386.so",
|
||||||
|
"_i486.so",
|
||||||
|
"_i586.so",
|
||||||
|
"_i686.so",
|
||||||
|
};
|
||||||
|
|
||||||
bool is_yes(const char* str)
|
bool is_yes(const char* str)
|
||||||
{
|
{
|
||||||
return !Q_strcmp(str, "true") || !Q_strcmp(str, "yes") || !Q_strcmp(str, "1");
|
return !Q_strcmp(str, "true") || !Q_strcmp(str, "yes") || !Q_strcmp(str, "1");
|
||||||
@ -119,7 +127,7 @@ char *trimbuf(char *str)
|
|||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
void NormalizePath(char *path)
|
void normalize_path(char *path)
|
||||||
{
|
{
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
for (char* cp = path; *cp; cp++)
|
for (char* cp = path; *cp; cp++)
|
||||||
@ -133,7 +141,7 @@ void NormalizePath(char *path)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsAbsolutePath(const char *path)
|
bool is_abs_path(const char *path)
|
||||||
{
|
{
|
||||||
if (path[0] == '/') return true;
|
if (path[0] == '/') return true;
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
@ -143,6 +151,23 @@ bool IsAbsolutePath(const char *path)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool is_valid_path(const char *path)
|
||||||
|
{
|
||||||
|
struct stat st;
|
||||||
|
return !stat(path, &st) && S_ISREG(st.st_mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool is_platform_postfix(const char* pf)
|
||||||
|
{
|
||||||
|
if (pf) {
|
||||||
|
for (size_t i = 0; i < arraysize(g_platform_postfixes); i++) {
|
||||||
|
if (!Q_strcmp(pf, g_platform_postfixes[i]))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
char *realpath(const char *file_name, char *resolved_name)
|
char *realpath(const char *file_name, char *resolved_name)
|
||||||
{
|
{
|
||||||
@ -162,10 +187,94 @@ char *realpath(const char *file_name, char *resolved_name)
|
|||||||
}
|
}
|
||||||
|
|
||||||
FindClose(handle);
|
FindClose(handle);
|
||||||
NormalizePath(resolved_name);
|
normalize_path(resolved_name);
|
||||||
return resolved_name;
|
return resolved_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
#endif // _WIN32
|
#endif // _WIN32
|
||||||
|
|
||||||
|
void __declspec(noreturn) do_exit(int exitval)
|
||||||
|
{
|
||||||
|
//Allahu Akbar!!
|
||||||
|
*((int *)nullptr) = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Checks for a non-empty file, relative to the gamedir if necessary.
|
||||||
|
// Formerly used LOAD_FILE_FOR_ME, which provided a simple way to check for
|
||||||
|
// a file under the gamedir, but which would _also_ look in the sibling
|
||||||
|
// "valve" directory, thus sometimes finding files that weren't desired.
|
||||||
|
// Also, formerly named just "valid_file".
|
||||||
|
//
|
||||||
|
// Special-case-recognize "/dev/null" as a valid file.
|
||||||
|
bool is_file_exists_in_gamedir(const char *path)
|
||||||
|
{
|
||||||
|
char buf[PATH_MAX];
|
||||||
|
|
||||||
|
if (!path)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!Q_strcmp(path, "/dev/null"))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (is_abs_path(path)) {
|
||||||
|
Q_strncpy(buf, path, sizeof buf);
|
||||||
|
buf[sizeof buf - 1] = '\0';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
snprintf(buf, sizeof buf, "%s/%s", g_GameDLL.gamedir, path);
|
||||||
|
|
||||||
|
struct stat st;
|
||||||
|
int ret = stat(buf, &st);
|
||||||
|
if (ret != 0) {
|
||||||
|
META_DEBUG(5, "Unable to stat '%s': %s", buf, strerror(errno));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int reg = S_ISREG(st.st_mode);
|
||||||
|
if (!reg) {
|
||||||
|
META_DEBUG(5, "Not a regular file: %s", buf);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!st.st_size) {
|
||||||
|
META_DEBUG(5, "Empty file: %s", buf);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ret == 0 && reg)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Turns path into a full path:
|
||||||
|
// - if not absolute, prepends gamedir
|
||||||
|
// - calls realpath() to collapse ".." and such
|
||||||
|
// - calls NormalizePath() to fix backslashes, etc
|
||||||
|
//
|
||||||
|
// Much like realpath, buffer pointed to by fullpath is assumed to be
|
||||||
|
// able to store a string of PATH_MAX length.
|
||||||
|
char* full_gamedir_path(const char* path, char* fullpath)
|
||||||
|
{
|
||||||
|
char buf[PATH_MAX];
|
||||||
|
|
||||||
|
// Build pathname from filename, plus gamedir if relative path.
|
||||||
|
if (is_abs_path(path)) {
|
||||||
|
Q_strncpy(buf, path, sizeof buf - 1);
|
||||||
|
buf[sizeof buf - 1] = '\0';
|
||||||
|
}
|
||||||
|
else snprintf(buf, sizeof buf, "%s/%s", g_GameDLL.gamedir, path);
|
||||||
|
|
||||||
|
// Remove relative path components, if possible.
|
||||||
|
if (!realpath(buf, fullpath)) {
|
||||||
|
META_DEBUG(4, "Unable to get realpath for '%s': %s", buf, str_os_error());
|
||||||
|
Q_strncpy(fullpath, path, sizeof fullpath - 1);
|
||||||
|
fullpath[sizeof fullpath - 1] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Replace backslashes, etc.
|
||||||
|
normalize_path(fullpath);
|
||||||
|
return fullpath;
|
||||||
|
}
|
||||||
|
@ -1,5 +1,17 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
// Turn a variable/function name into the corresponding string, optionally
|
||||||
|
// stripping off the leading "len" characters. Useful for things like
|
||||||
|
// turning 'pfnClientCommand' into "ClientCommand" so we don't have to
|
||||||
|
// specify strings used for all the debugging/log messages.
|
||||||
|
#define STRINGIZE(name, len) #name+len
|
||||||
|
|
||||||
|
// Max description length for plugins.ini and other places.
|
||||||
|
#define MAX_DESC_LEN 256
|
||||||
|
|
||||||
|
// For various character string buffers.
|
||||||
|
#define MAX_STRBUF_LEN 1024
|
||||||
|
|
||||||
template <typename T, size_t N>
|
template <typename T, size_t N>
|
||||||
char(&ArraySizeHelper(T(&array)[N]))[N];
|
char(&ArraySizeHelper(T(&array)[N]))[N];
|
||||||
#define arraysize(array) (sizeof(ArraySizeHelper(array)))
|
#define arraysize(array) (sizeof(ArraySizeHelper(array)))
|
||||||
@ -54,5 +66,14 @@ char *realpath(const char *file_name, char *resolved_name);
|
|||||||
#endif // _WIN32
|
#endif // _WIN32
|
||||||
|
|
||||||
char* trimbuf(char *str);
|
char* trimbuf(char *str);
|
||||||
void NormalizePath(char *path);
|
void normalize_path(char *path);
|
||||||
bool IsAbsolutePath(const char *path);
|
bool is_abs_path(const char *path);
|
||||||
|
bool is_valid_path(const char *path);
|
||||||
|
bool is_platform_postfix(const char *pf);
|
||||||
|
|
||||||
|
void __declspec(noreturn) do_exit(int exitval);
|
||||||
|
|
||||||
|
bool is_file_exists_in_gamedir(const char *path);
|
||||||
|
char *full_gamedir_path(const char *path, char *fullpath);
|
||||||
|
|
||||||
|
extern const char* g_platform_postfixes[4];
|
||||||
|
Loading…
Reference in New Issue
Block a user