1
0
mirror of https://github.com/alliedmodders/metamod-source.git synced 2024-12-01 13:24:25 +01:00

Fixed a few bugs in console commands

Added hooking of shutdown commands
Warning - Crashes on SH_ADD_HOOK_STATICFUNC?

--HG--
extra : convert_revision : svn%3Ac2935e3e-5518-0410-8daf-afa5dab7d4e3/trunk%4013
This commit is contained in:
David Anderson 2005-04-17 03:37:50 +00:00
parent 1f37ba9f73
commit e2100056f4
6 changed files with 136 additions and 55 deletions

View File

@ -261,6 +261,9 @@ bool CPluginManager::_Pause(CPluginManager::CPlugin *pl, char *error, size_t max
if (pl->m_API->Pause(error, maxlen))
{
g_SourceHook.PausePlugin(pl->m_Id);
pl->m_Status = Pl_Paused;
return true;
}
}
@ -280,6 +283,9 @@ bool CPluginManager::_Unpause(CPluginManager::CPlugin *pl, char *error, size_t m
if (pl->m_API->Unpause(error, maxlen))
{
g_SourceHook.UnpausePlugin(pl->m_Id);
pl->m_Status = Pl_Running;
return true;
}
}

View File

@ -44,14 +44,14 @@ CON_COMMAND(meta, "Metamod:Source Menu")
Msg(" GameDLL/Plugins: David \"BAILOPAN\" Anderson\n");
Msg(" GameDLL: Scott \"Damaged Soul\" Ehlert\n");
Msg("For more information, see the official website\n");
Msg("http://www.sourcemm.net/\n");
Msg("http://www.sourcemm.net/\n\n");
return;
} else if (strcmp(command, "version") == 0) {
Msg("Metamod:Source version %s\n", SOURCEMM_VERSION);
Msg("Compiled on: %s\n", SOURCEMM_DATE);
Msg("Plugin interface version: %d/%d\n", PLAPI_VERSION, PLAPI_MIN_VERSION);
Msg("http://www.sourcemm.net/\n");
Msg("http://www.sourcemm.net/\n\n");
return;
} else if (strcmp(command, "game") == 0) {
@ -74,6 +74,9 @@ CON_COMMAND(meta, "Metamod:Source Menu")
SourceMM::CPluginManager::CPlugin *pl;
PluginIter i;
const char *status="";
const char *version=NULL;
const char *name=NULL;
const char *author=NULL;
Msg("-Id- %-16.15s %-8.7s %-12.11s %-8.7s\n", "Name", "Version", "Author", "Status");
for (i=g_PluginMngr._begin(); i!=g_PluginMngr._end(); i++)
@ -93,9 +96,31 @@ CON_COMMAND(meta, "Metamod:Source Menu")
} else if (pl->m_Status == Pl_NotFound) {
status = "NOFILE";
}
Msg("[%02d] %-16.15s %-8.7s %-12.11s %-8.7s\n", pl->m_Id, pl->m_API->GetName(), pl->m_API->GetVersion(), pl->m_API->GetAuthor(), status);
if (pl->m_API)
{
version = pl->m_API->GetVersion();
author = pl->m_API->GetAuthor();
name = pl->m_API->GetName();
} else {
version = "-";
author = "-";
name = "-";
}
if (!version)
version = "-";
if (!author)
author = "-";
if (!name)
name = pl->m_File.c_str();
Msg("[%02d] %-16.15s %-8.7s %-12.11s %-8.7s\n", pl->m_Id, name, version, author, status);
}
Msg("\n");
return;
} else if (strcmp(command, "info") == 0) {
if (args >= 3)
@ -125,7 +150,7 @@ CON_COMMAND(meta, "Metamod:Source Menu")
Msg("URL: %s\n", pl->m_API->GetURL());
Msg("Details: API %03d, Date: %s\n", pl->m_API->GetApiVersion(), pl->m_API->GetDate());
}
Msg("File: %s\n", pl->m_File.c_str());
Msg("File: %s\n\n", pl->m_File.c_str());
return;
} else {
@ -137,28 +162,16 @@ CON_COMMAND(meta, "Metamod:Source Menu")
if (args >= 3)
{
int id = atoi(e->Cmd_Argv(2));
SourceMM::CPluginManager::CPlugin *pl = g_PluginMngr.FindById(id);
if (!pl)
char error[255];
if (!g_PluginMngr.Pause(id, error, sizeof(error)-1))
{
Msg("Plugin %d not found.\n", id);
Msg("Pause failed: %s\n", error);
return;
}
if (pl->m_Status != Pl_Running)
{
Msg("Plugin %d is not pausable.\n", pl->m_Id);
return;
}
char error[255]={0};
if (!pl->m_API->Pause(error, sizeof(error)-1))
{
Msg("Plugin %d refused pause: %s\n", pl->m_Id, error);
return;
}
g_SourceHook.PausePlugin(pl->m_Id);
Msg("\"%s\" has been paused.\n", pl->m_API->GetName());
Msg("Plugin %d has been paused.\n", id);
return;
} else {
@ -170,28 +183,15 @@ CON_COMMAND(meta, "Metamod:Source Menu")
if (args >= 3)
{
int id = atoi(e->Cmd_Argv(2));
SourceMM::CPluginManager::CPlugin *pl = g_PluginMngr.FindById(id);
if (!pl)
char error[255];
if (!g_PluginMngr.Unpause(id, error, sizeof(error)-1))
{
Msg("Plugin %d not found.\n", id);
Msg("Unpause failed: %s\n", error);
return;
}
if (pl->m_Status != Pl_Paused)
{
Msg("Plugin %d is not unpausable.\n", pl->m_Id);
return;
}
char error[255]={0};
if (!pl->m_API->Pause(error, sizeof(error)-1))
{
Msg("Plugin %d refused unpause: %s\n", pl->m_Id, error);
return;
}
g_SourceHook.UnpausePlugin(pl->m_Id);
Msg("\"%s\" has been unpaused.\n", pl->m_API->GetName());
Msg("Plugin %d has been unpaused.\n", id);
return;
} else {
@ -211,10 +211,10 @@ CON_COMMAND(meta, "Metamod:Source Menu")
} else {
const char *ext = UTIL_GetExtension(file);
#if defined WIN32 || defined _WIN32
ext ? "" : ".dll";
ext = ext ? "" : ".dll";
snprintf(full_path, sizeof(full_path)-1, "%s\\%s%s", g_ModPath.c_str(), file, ext);
#else
ext ? "" : "_i486.so";
ext = ext ? "" : "_i486.so";
snprintf(full_path, sizeof(full_path)-1, "%s/%s%s", g_ModPath.c_str(), file, ext);
#endif
}
@ -301,6 +301,7 @@ CON_COMMAND(meta, "Metamod:Source Menu")
Msg("usage: meta <command> [arguments]\n");
Msg(" clear - Unload all plugins forcefully\n");
Msg(" credits - About Metamod:Source\n");
Msg(" force_unload - Forcefully unload a plugin\n");
Msg(" game - Information about GameDLL\n");
Msg(" info - Information about a plugin\n");
Msg(" list - List plugins\n");
@ -310,4 +311,5 @@ CON_COMMAND(meta, "Metamod:Source Menu")
Msg(" unload - Unload a loaded plugin\n");
Msg(" unpause - Unpause a paused plugin\n");
Msg(" version - Version information\n");
Msg("\n");
}

View File

@ -1,13 +1,28 @@
#include <oslink.h>
#include "SamplePlugin.h"
SamplePlugin g_SamplePlugin;
PLUGIN_EXPOSE(SamplePlugin, g_SamplePlugin);
//SH_DECL_HOOK6(IServerGameDLL, LevelInit, SH_NOATTRIB, 0, bool, char const *, char const *, char const *, char const *, bool, bool);
//bool LevelInit_handler( char const *pMapName, char const *pMapEntities, char const *pOldLevel, char const *pLandmarkName, bool loadGame, bool background );
bool SamplePlugin::Load(PluginId id, ISmmAPI *ismm, factories *list, char *error, size_t maxlen)
{
PLUGIN_SAVEVARS();
IServerGameDLL *isgd = (IServerGameDLL *)((ismm->serverFactory())(INTERFACEVERSION_SERVERGAMEDLL, NULL));
if (!isgd)
{
snprintf(error, maxlen, "Could not find interface %s", INTERFACEVERSION_SERVERGAMEDLL);
return false;
}
//SH_ADD_HOOK_STATICFUNC(IServerGameDLL, LevelInit, isgd, LevelInit_handler, false);
return true;
}
@ -15,3 +30,16 @@ bool SamplePlugin::Unload(char *error, size_t maxlen)
{
return true;
}
/*bool LevelInit_handler( char const *pMapName, char const *pMapEntities, char const *pOldLevel, char const *pLandmarkName, bool loadGame, bool background )
{
FILE *fp = fopen("c:\\dump.txt", "at");
if (!fp)
RETURN_META_VALUE(MRES_IGNORED, false);
fprintf(fp, "Map name: %s (old level: %s)\n", pMapName?pMapName:"", pOldLevel?pOldLevel:"");
fclose(fp);
RETURN_META_VALUE(MRES_IGNORED, false);
}*/

View File

@ -22,7 +22,7 @@
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;SAMPLE_MM_EXPORTS"
MinimalRebuild="TRUE"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
RuntimeLibrary="5"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="TRUE"
@ -31,6 +31,7 @@
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="tier0.lib"
OutputFile="$(OutDir)/sample_mm.dll"
LinkIncremental="2"
GenerateDebugInformation="TRUE"
@ -70,6 +71,7 @@
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;SAMPLE_MM_EXPORTS"
RuntimeLibrary="4"
UsePrecompiledHeader="0"
ExpandAttributedSource="TRUE"
WarningLevel="3"
Detect64BitPortabilityProblems="FALSE"
DebugInformationFormat="3"/>
@ -82,7 +84,7 @@
GenerateDebugInformation="TRUE"
SubSystem="2"
OptimizeReferences="2"
EnableCOMDATFolding="2"
EnableCOMDATFolding="1"
ImportLibrary="$(OutDir)/sample_mm.lib"
TargetMachine="1"/>
<Tool

View File

@ -31,13 +31,18 @@ CHLTVDirector *g_TempDirector = NULL;
GameDllInfo g_GameDll = {false, NULL, NULL};
EngineInfo g_Engine = {NULL, NULL, NULL, NULL};
SourceHook::CSourceHookImpl g_SourceHook;
SourceHook::ISourceHook *g_SHPtr;
std::string g_ModPath;
std::string g_BinPath;
PluginId g_PLID = Pl_Console; //Technically, SourceMM is the "Console" plugin... :p
///////////////////////////////////
// Main code for HL2 Interaction //
///////////////////////////////////
void DLLShutdown_handler(void);
SH_DECL_HOOK0_void(IServerGameDLL, DLLShutdown, SH_NOATTRIB, 0);
//This is where the magic happens
SMM_API void *CreateInterface(const char *name, int *ret)
{
@ -94,6 +99,9 @@ bool CServerGameDLL::DLLInit(CreateInterfaceFn engineFactory, CreateInterfaceFn
{
if (!g_GameDll.loaded)
{
//Initialize SourceHook
g_SHPtr = static_cast<SourceHook::ISourceHook *>(&g_SourceHook);
//The gamedll isn't loaded yet. We need to find out where it's hiding.
IVEngineServer *ive = (IVEngineServer *)((engineFactory)(INTERFACEVERSION_VENGINESERVER, NULL));
if (!ive)
@ -151,6 +159,8 @@ bool CServerGameDLL::DLLInit(CreateInterfaceFn engineFactory, CreateInterfaceFn
return false;
}
g_GameDll.serverGameDLL = serverDll;
//Set this information early in case our wrappers are called somehow
g_Engine.engineFactory = engineFactory;
g_Engine.icvar = (ICvar *)(g_Engine.engineFactory)(VENGINE_CVAR_INTERFACE_VERSION, NULL);
@ -240,6 +250,9 @@ bool CServerGameDLL::DLLInit(CreateInterfaceFn engineFactory, CreateInterfaceFn
//Everything's done.
g_GameDll.loaded = true;
//Initialize our shutdown hook
SH_ADD_HOOK_STATICFUNC(IServerGameDLL, DLLShutdown, serverDll, DLLShutdown_handler, false);
//Initialize our console hooks
ConCommandBaseMgr::OneTimeInit(static_cast<IConCommandBaseAccessor *>(&g_SMConVarAccessor));
@ -263,6 +276,29 @@ bool CServerGameDLL::DLLInit(CreateInterfaceFn engineFactory, CreateInterfaceFn
return false;
}
void DLLShutdown_handler(void)
{
//It's time for us to shut down too!
g_PluginMngr.UnloadAll();
//Call the DLL...
g_GameDll.serverGameDLL->DLLShutdown();
//Unload the DLL forcefully
dlclose(g_GameDll.lib);
memset(&g_GameDll, 0, sizeof(GameDllInfo));
//For now, I'm not gonna bother freeing the memory allocated above.
//Why?
// 1. We're exiting the application (I should hope!)
// 2. If we're not exiting, we just deallocated the gamedll, so we're about to crash out ANYWAY
// 3. We never saved the original vtable pointers, and we'd have to copy them back to get our destructors.
//Soooo... we'll just accept our fate here.
//DON'T CALL THE GAMEDLL! IT'S GONE! pinin' for the fjords
RETURN_META(MRES_SUPERCEDE);
}
int LoadPluginsFromFile(const char *file)
{
FILE *fp;

View File

@ -55,6 +55,7 @@ struct GameDllInfo
bool loaded;
HINSTANCE lib;
CreateInterfaceFn factory;
IServerGameDLL *serverGameDLL;
};
/** @brief Stores information about the HL2 Engine pointers */
@ -83,4 +84,10 @@ extern std::string g_ModPath;
/** @brief Path to server binary */
extern std::string g_BinPath;
/** @brief Global variable for SourceHook macros */
extern SourceHook::ISourceHook *g_SHPtr;
/** @brief We have our own internal plugin id... */
extern PluginId g_PLID;
#endif //_INCLUDE_SOURCEMM_H