mirror of
https://github.com/rehlds/metamod-r.git
synced 2025-02-04 17:50:52 +03:00
Gracefully shutdown metamod and plugins when game is closing (for a proper reload using _restart command)
This commit is contained in:
parent
adc94141a4
commit
ec926a611f
@ -12,8 +12,11 @@ NEW_DLL_FUNCTIONS sNewFunctionTable;
|
||||
NEW_DLL_FUNCTIONS sNewFunctionTable_jit;
|
||||
NEW_DLL_FUNCTIONS *pHookedNewDllFunctions = &sNewFunctionTable;
|
||||
|
||||
void MM_PRE_HOOK EXT_FUNC mm_GameShutdown()
|
||||
// Unload game DLL and meta plugins
|
||||
void MM_POST_HOOK EXT_FUNC mm_GameShutdown()
|
||||
{
|
||||
g_metamod_active = false;
|
||||
if (g_plugins) g_plugins->unload_all();
|
||||
g_meta_extdll.unload();
|
||||
g_GameDLL.sys_module.unload();
|
||||
g_engine.sys_module.unload();
|
||||
@ -130,7 +133,7 @@ compile_data_t g_dllfunc_cdata[] =
|
||||
compile_data_t g_newdllfunc_cdata[] =
|
||||
{
|
||||
CDATA_NEWDLL(pfnOnFreeEntPrivateData), // Called right before the object's memory is freed. Calls its destructor.
|
||||
CDATA_NEWDLL_H(pfnGameShutdown, P_PRE, mm_GameShutdown), //
|
||||
CDATA_NEWDLL_H(pfnGameShutdown, P_POST, mm_GameShutdown), //
|
||||
CDATA_NEWDLL(pfnShouldCollide), //
|
||||
|
||||
CDATA_NEWDLL(pfnCvarValue), // (fz) Use mm_CvarValue2 instead
|
||||
|
@ -32,6 +32,8 @@ unsigned int g_CALL_API_count = 0;
|
||||
|
||||
int g_requestid_counter = 0;
|
||||
|
||||
bool g_metamod_active = false;
|
||||
|
||||
// Very first metamod function that's run.
|
||||
// Do startup operations...
|
||||
void metamod_startup()
|
||||
@ -61,6 +63,8 @@ void metamod_startup()
|
||||
Sys_Error("Failure to init game DLL; exiting...");
|
||||
}
|
||||
|
||||
g_metamod_active = true;
|
||||
|
||||
// Register various console commands and cvars.
|
||||
// Can I do these here, rather than waiting for GameDLLInit() ?
|
||||
// Looks like it works okay..
|
||||
@ -509,6 +513,8 @@ static void meta_apply_fix_data(std::vector<fixdata_t>& data)
|
||||
|
||||
void meta_rebuild_callbacks()
|
||||
{
|
||||
if (!g_metamod_active) return;
|
||||
|
||||
std::vector<fixdata_t> fixdata;
|
||||
if (g_metaGlobals.esp_save) {
|
||||
META_LOG("dll: Begin scan to collect callback fix data...");
|
||||
|
@ -74,6 +74,8 @@ extern unsigned int g_CALL_API_count;
|
||||
// stores previous requestid counter
|
||||
extern int g_requestid_counter;
|
||||
|
||||
extern bool g_metamod_active;
|
||||
|
||||
// (patch by BAILOPAN)
|
||||
// Holds cached player info, right now only things for querying cvars
|
||||
// Max players is always 32, small enough that we can use a static array
|
||||
|
@ -573,6 +573,15 @@ void MPluginList::unpause_all()
|
||||
}
|
||||
}
|
||||
|
||||
// Unload all plugins currently loaded
|
||||
void MPluginList::unload_all()
|
||||
{
|
||||
bool delayed;
|
||||
for (auto p : m_plugins) {
|
||||
p->unload(PT_ANYTIME, PNL_CMD_FORCED, delayed);
|
||||
}
|
||||
}
|
||||
|
||||
// Retry any pending actions on plugins, for instance load/unload delayed
|
||||
// until changelevel.
|
||||
void MPluginList::retry_all(PLUG_LOADTIME now)
|
||||
|
@ -35,6 +35,7 @@ public:
|
||||
bool load(); // load the list, at startup
|
||||
bool refresh(PLUG_LOADTIME now); // update from re-read inifile
|
||||
void unpause_all(); // unpause any paused plugins
|
||||
void unload_all(); // unload all plugins
|
||||
void retry_all(PLUG_LOADTIME now); // retry any pending plugin actions
|
||||
void show(int source_index = 0); // list plugins to console use dynamic alignment
|
||||
void show_static(int source_index = 0); // list plugins to console use static alignment
|
||||
|
@ -471,7 +471,7 @@ bool MPlugin::unload(PLUG_LOADTIME now, PL_UNLOAD_REASON reason, bool& delayed)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (m_action != PA_UNLOAD && m_action != PA_RELOAD) {
|
||||
if (m_action != PA_UNLOAD && m_action != PA_RELOAD && reason != PNL_CMD_FORCED) {
|
||||
META_WARNING("dll: Not unloading plugin '%s'; not marked for unload (action=%s)", m_desc, str_action());
|
||||
return false;
|
||||
}
|
||||
|
@ -64,17 +64,21 @@ MRegCmd* MRegCmdList::add(const char* addname, REG_CMD_FN cmd_handler, MPlugin*
|
||||
|
||||
void MRegCmdList::remove(char* cmd_name)
|
||||
{
|
||||
for (auto it = m_list.begin(), end = m_list.end(); it != end; ++it) {
|
||||
for (auto it = m_list.begin(); it != m_list.end(); ) {
|
||||
auto reg = *it;
|
||||
|
||||
if (!Q_stricmp(reg->m_name, cmd_name)) {
|
||||
if (g_RehldsFuncs) {
|
||||
g_RehldsFuncs->Cmd_RemoveCmd(cmd_name);
|
||||
m_list.erase(it);
|
||||
delete reg;
|
||||
it = m_list.erase(it);
|
||||
}
|
||||
else {
|
||||
reg->disable();
|
||||
it++;
|
||||
}
|
||||
} else {
|
||||
it++;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -82,17 +86,22 @@ void MRegCmdList::remove(char* cmd_name)
|
||||
// Disable any functions belonging to the given plugin (by index id).
|
||||
void MRegCmdList::remove(int owner_plugin_id)
|
||||
{
|
||||
for (auto it = m_list.begin(), end = m_list.end(); it != end; ++it) {
|
||||
for (auto it = m_list.begin(); it != m_list.end(); ) {
|
||||
auto reg = *it;
|
||||
|
||||
if (reg->m_plugid == owner_plugin_id) {
|
||||
if (reg->m_plugid != owner_plugin_id) {
|
||||
it++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (g_RehldsFuncs) {
|
||||
g_RehldsFuncs->Cmd_RemoveCmd(reg->m_name);
|
||||
m_list.erase(it);
|
||||
delete reg;
|
||||
it = m_list.erase(it);
|
||||
}
|
||||
else {
|
||||
reg->disable();
|
||||
}
|
||||
it++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -68,6 +68,7 @@ module_handle_t CSysModule::load(const char *filepath)
|
||||
{
|
||||
if (!m_handle) {
|
||||
m_handle = LoadLibrary(filepath);
|
||||
if (m_handle) m_free = true;
|
||||
|
||||
MODULEINFO module_info;
|
||||
if (GetModuleInformation(GetCurrentProcess(), m_handle, &module_info, sizeof(module_info))) {
|
||||
@ -157,6 +158,7 @@ module_handle_t CSysModule::load(const char *filepath)
|
||||
{
|
||||
if (!m_handle) {
|
||||
m_handle = dlopen(filepath, RTLD_NOW | RTLD_LOCAL | RTLD_DEEPBIND);
|
||||
if (m_handle) m_free = true;
|
||||
|
||||
char buf[1024], dummy[1024], path[260];
|
||||
Q_sprintf(buf, "/proc/%i/maps", getpid());
|
||||
|
Loading…
x
Reference in New Issue
Block a user