mirror of
https://github.com/alliedmodders/metamod-source.git
synced 2025-12-07 10:28:30 +00:00
Working ConCommandBase replacement code
--HG-- extra : convert_revision : svn%3Ac2935e3e-5518-0410-8daf-afa5dab7d4e3/trunk%4068
This commit is contained in:
parent
a7da6651b9
commit
5155055435
@ -11,6 +11,7 @@
|
||||
#include "CPlugin.h"
|
||||
#include "CSmmAPI.h"
|
||||
#include "sourcemm.h"
|
||||
#include "concommands.h"
|
||||
|
||||
/**
|
||||
* @brief Implements functions from CPlugin.h
|
||||
@ -184,6 +185,23 @@ bool CPluginManager::Retry(PluginId id, char *error, size_t len)
|
||||
return false;
|
||||
}
|
||||
|
||||
CPluginManager::CPlugin *CPluginManager::FindByAPI(ISmmPlugin *api)
|
||||
{
|
||||
PluginIter i;
|
||||
|
||||
//don't find bad plugins!
|
||||
if (!api)
|
||||
return NULL;
|
||||
|
||||
for (i=m_Plugins.begin(); i!=m_Plugins.end(); i++)
|
||||
{
|
||||
if ( (*i)->m_API == api )
|
||||
return (*i);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
CPluginManager::CPlugin *CPluginManager::_Load(const char *file, PluginId source, char *error, size_t maxlen)
|
||||
{
|
||||
FILE *fp;
|
||||
@ -278,6 +296,8 @@ bool CPluginManager::_Unload(CPluginManager::CPlugin *pl, bool force, char *erro
|
||||
//Make sure to detach it from sourcehook!
|
||||
g_SourceHook.UnloadPlugin(pl->m_Id);
|
||||
|
||||
UnregAllConCmds(pl);
|
||||
|
||||
//Clean up the DLL
|
||||
dlclose(pl->m_Lib);
|
||||
pl->m_Lib = NULL;
|
||||
@ -374,6 +394,8 @@ bool CPluginManager::UnloadAll()
|
||||
if ( (*i)->m_API->Unload(NULL, 0) )
|
||||
status = false;
|
||||
|
||||
UnregAllConCmds( (*i) );
|
||||
|
||||
//Unlink from SourceHook
|
||||
g_SourceHook.UnloadPlugin( (*i)->m_Id );
|
||||
|
||||
@ -382,10 +404,10 @@ bool CPluginManager::UnloadAll()
|
||||
}
|
||||
delete (*i);
|
||||
}
|
||||
|
||||
i = m_Plugins.erase(i);
|
||||
}
|
||||
|
||||
m_Plugins.clear();
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
@ -413,3 +435,58 @@ PluginIter CPluginManager::_end()
|
||||
{
|
||||
return m_Plugins.end();
|
||||
}
|
||||
|
||||
void CPluginManager::AddPluginCvar(ISmmPlugin *api, ConCommandBase *pCvar)
|
||||
{
|
||||
CPlugin *pl = FindByAPI(api);
|
||||
|
||||
if (!pl)
|
||||
return;
|
||||
|
||||
pl->m_Cvars.push_back(pCvar);
|
||||
}
|
||||
|
||||
void CPluginManager::AddPluginCmd(ISmmPlugin *api, ConCommandBase *pCmd)
|
||||
{
|
||||
CPlugin *pl = FindByAPI(api);
|
||||
|
||||
if (!pl)
|
||||
return;
|
||||
|
||||
pl->m_Cmds.push_back(pCmd);
|
||||
}
|
||||
|
||||
void CPluginManager::RemovePluginCvar(ISmmPlugin *api, ConCommandBase *pCvar)
|
||||
{
|
||||
CPlugin *pl = FindByAPI(api);
|
||||
|
||||
if (!pl)
|
||||
return;
|
||||
|
||||
pl->m_Cvars.remove(pCvar);
|
||||
}
|
||||
|
||||
void CPluginManager::RemovePluginCmd(ISmmPlugin *api, ConCommandBase *pCmd)
|
||||
{
|
||||
CPlugin *pl = FindByAPI(api);
|
||||
|
||||
if (!pl)
|
||||
return;
|
||||
|
||||
pl->m_Cmds.remove(pCmd);
|
||||
}
|
||||
|
||||
void CPluginManager::UnregAllConCmds(CPlugin *pl)
|
||||
{
|
||||
std::list<ConCommandBase *>::iterator i;
|
||||
|
||||
for (i=pl->m_Cvars.begin(); i!=pl->m_Cvars.end(); i++)
|
||||
g_SMConVarAccessor.Unregister( (*i) );
|
||||
|
||||
pl->m_Cvars.clear();
|
||||
|
||||
for (i=pl->m_Cmds.begin(); i!=pl->m_Cmds.end(); i++)
|
||||
g_SMConVarAccessor.Unregister( (*i) );
|
||||
|
||||
pl->m_Cmds.clear();
|
||||
}
|
||||
|
||||
@ -18,6 +18,9 @@
|
||||
|
||||
#include <list>
|
||||
#include <string>
|
||||
#include <interface.h>
|
||||
#include <eiface.h>
|
||||
#include <convar.h>
|
||||
#include "IPluginManager.h"
|
||||
#include "oslink.h"
|
||||
|
||||
@ -55,6 +58,8 @@ namespace SourceMM
|
||||
ISmmPlugin *m_API;
|
||||
HINSTANCE m_Lib;
|
||||
factories fac_list;
|
||||
std::list<ConCommandBase *> m_Cvars;
|
||||
std::list<ConCommandBase *> m_Cmds;
|
||||
};
|
||||
public:
|
||||
CPluginManager();
|
||||
@ -69,6 +74,11 @@ namespace SourceMM
|
||||
public:
|
||||
bool Query(PluginId id, const char *&file, factories *&list, Pl_Status &status, PluginId &source);
|
||||
|
||||
void AddPluginCvar(ISmmPlugin *api, ConCommandBase *pCvar);
|
||||
void AddPluginCmd(ISmmPlugin *api, ConCommandBase *pCmd);
|
||||
void RemovePluginCvar(ISmmPlugin *api, ConCommandBase *pCvar);
|
||||
void RemovePluginCmd(ISmmPlugin *api, ConCommandBase *pCmd);
|
||||
|
||||
/**
|
||||
* @brief Finds a plugin by Id
|
||||
*
|
||||
@ -77,6 +87,8 @@ namespace SourceMM
|
||||
*/
|
||||
CPlugin *FindById(PluginId id);
|
||||
|
||||
CPlugin *FindByAPI(ISmmPlugin *api);
|
||||
|
||||
/**
|
||||
* @brief Attempts to reload a failed plugin
|
||||
*
|
||||
@ -96,6 +108,7 @@ namespace SourceMM
|
||||
bool _Unload(CPlugin *pl, bool force, char *error, size_t maxlen);
|
||||
bool _Pause(CPlugin *pl, char *error, size_t maxlen);
|
||||
bool _Unpause(CPlugin *pl, char *error, size_t maxlen);
|
||||
void UnregAllConCmds(CPlugin *pl);
|
||||
private:
|
||||
PluginId m_LastId;
|
||||
std::list<CPlugin *> m_Plugins;
|
||||
|
||||
@ -93,13 +93,27 @@ IConCommandBaseAccessor *CSmmAPI::GetCvarBaseAccessor()
|
||||
return static_cast<IConCommandBaseAccessor *>(&g_SMConVarAccessor);
|
||||
}
|
||||
|
||||
bool CSmmAPI::RegisterConCmdBase(ConCommandBase *pCommand)
|
||||
bool CSmmAPI::RegisterConCmdBase(ISmmPlugin *plugin, ConCommandBase *pCommand)
|
||||
{
|
||||
return g_SMConVarAccessor.RegisterConCommandBase(pCommand);
|
||||
if (pCommand->IsCommand())
|
||||
{
|
||||
g_PluginMngr.AddPluginCmd(plugin, pCommand);
|
||||
} else {
|
||||
g_PluginMngr.AddPluginCvar(plugin, pCommand);
|
||||
}
|
||||
|
||||
return g_SMConVarAccessor.Register(pCommand);
|
||||
}
|
||||
|
||||
void CSmmAPI::UnregisterConCmdBase(ConCommandBase *pCommand)
|
||||
void CSmmAPI::UnregisterConCmdBase(ISmmPlugin *plugin, ConCommandBase *pCommand)
|
||||
{
|
||||
if (pCommand->IsCommand())
|
||||
{
|
||||
g_PluginMngr.RemovePluginCmd(plugin, pCommand);
|
||||
} else {
|
||||
g_PluginMngr.RemovePluginCvar(plugin, pCommand);
|
||||
}
|
||||
|
||||
g_SMConVarAccessor.Unregister(pCommand);
|
||||
}
|
||||
|
||||
|
||||
@ -35,8 +35,8 @@ namespace SourceMM
|
||||
void SetLastMetaReturn(META_RES res);
|
||||
META_RES GetLastMetaReturn();
|
||||
IConCommandBaseAccessor *GetCvarBaseAccessor();
|
||||
bool RegisterConCmdBase(ConCommandBase *pCommand);
|
||||
void UnregisterConCmdBase(ConCommandBase *pCommand);
|
||||
bool RegisterConCmdBase(ISmmPlugin *plugin, ConCommandBase *pCommand);
|
||||
void UnregisterConCmdBase(ISmmPlugin *plugin, ConCommandBase *pCommand);
|
||||
private:
|
||||
META_RES m_Res;
|
||||
};
|
||||
|
||||
@ -42,8 +42,8 @@ public:
|
||||
public:
|
||||
//Added in 1.00-RC2 to solve concommand problems
|
||||
virtual IConCommandBaseAccessor *GetCvarBaseAccessor() =0;
|
||||
virtual bool RegisterConCmdBase(ConCommandBase *pCommand) =0;
|
||||
virtual void UnregisterConCmdBase(ConCommandBase *pCommand) =0;
|
||||
virtual bool RegisterConCmdBase(ISmmPlugin *plugin, ConCommandBase *pCommand) =0;
|
||||
virtual void UnregisterConCmdBase(ISmmPlugin *plugin, ConCommandBase *pCommand) =0;
|
||||
};
|
||||
|
||||
#endif //_INCLUDE_ISMM_API_H
|
||||
|
||||
@ -138,8 +138,13 @@ public:
|
||||
g_SMAPI->SetLastMetaReturn(mres); \
|
||||
return value;
|
||||
|
||||
#define META_LOG g_SMAPI->LogMsg
|
||||
#define META_LOG g_SMAPI->LogMsg
|
||||
#define META_REGCMD(name) g_SMAPI->RegisterConCmdBase(g_PLAPI, name##_command)
|
||||
#define META_REGCVAR(var) g_SMAPI->RegisterConCmdBase(g_PLAPI, var)
|
||||
#define META_UNREGCMD(name) g_SMAPI->UnregisterConCmdBase(g_PLAPI, name##_command)
|
||||
#define META_UNREGCVAR(var) g_SMAPI->UnregisterConCmdBase(g_PLAPI, var)
|
||||
|
||||
//probably should use this up above someday
|
||||
#define CONCMD_VARNAME(name) name##_command
|
||||
|
||||
#if !defined SMM_API
|
||||
|
||||
@ -8,6 +8,8 @@
|
||||
* ============================
|
||||
*/
|
||||
|
||||
#include <string>
|
||||
#include <ctype.h>
|
||||
#include "concommands.h"
|
||||
#include "CPlugin.h"
|
||||
|
||||
@ -16,6 +18,7 @@
|
||||
* @file concommands.cpp
|
||||
*/
|
||||
|
||||
CAlwaysRegisterableCommand g_EternalCommand;
|
||||
SMConVarAccessor g_SMConVarAccessor;
|
||||
|
||||
bool SMConVarAccessor::RegisterConCommandBase(ConCommandBase *pCommand)
|
||||
@ -34,6 +37,15 @@ bool SMConVarAccessor::RegisterConCommandBase(ConCommandBase *pCommand)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SMConVarAccessor::Register(ConCommandBase *pCommand)
|
||||
{
|
||||
//simple, don't mark as part of sourcemm!
|
||||
pCommand->SetNext( NULL );
|
||||
g_Engine.icvar->RegisterConCommandBase(pCommand);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void SMConVarAccessor::MarkCommandsAsGameDLL()
|
||||
{
|
||||
for (std::list<ConCommandBase*>::iterator iter = m_RegisteredCommands.begin();
|
||||
@ -43,37 +55,34 @@ void SMConVarAccessor::MarkCommandsAsGameDLL()
|
||||
}
|
||||
}
|
||||
|
||||
void SMConVarAccessor::Unregister(ConCommandBase *pCvar)
|
||||
void SMConVarAccessor::Unregister(ConCommandBase *pCommand)
|
||||
{
|
||||
ICvar *cv = g_Engine.icvar;
|
||||
|
||||
ConCommandBase *ptr = cv->GetCommands();
|
||||
|
||||
if (ptr == pCvar && ptr->GetNext())
|
||||
if (ptr == pCommand)
|
||||
{
|
||||
//we're at the beginning of the list
|
||||
*ptr = *(ptr->GetNext());
|
||||
return;
|
||||
//first in list
|
||||
g_EternalCommand.BringToFront();
|
||||
g_EternalCommand.SetNext(const_cast<ConCommandBase *>(pCommand->GetNext()));
|
||||
} else {
|
||||
//find us and unregister us
|
||||
ConCommandBase *pPrev = NULL;
|
||||
while (ptr)
|
||||
{
|
||||
if (ptr == pCommand)
|
||||
break;
|
||||
pPrev = ptr;
|
||||
ptr = const_cast<ConCommandBase *>(ptr->GetNext());
|
||||
}
|
||||
if (pPrev && ptr == pCommand)
|
||||
{
|
||||
pPrev->SetNext(const_cast<ConCommandBase *>(pCommand->GetNext()));
|
||||
}
|
||||
}
|
||||
|
||||
while (ptr)
|
||||
{
|
||||
ConCommandBase *pNext = const_cast<ConCommandBase *>(ptr->GetNext());
|
||||
if (pNext == pCvar)
|
||||
break;
|
||||
ptr = pNext;
|
||||
}
|
||||
|
||||
if (ptr)
|
||||
{
|
||||
ptr->SetNext(const_cast<ConCommandBase *>(pCvar->GetNext()));
|
||||
pCvar->SetNext(NULL);
|
||||
}
|
||||
|
||||
m_RegisteredCommands.remove(pCvar);
|
||||
}
|
||||
|
||||
ConVar metamod_version("metamod_version", SOURCEMM_VERSION, FCVAR_REPLICATED | FCVAR_SPONLY, "Metamod:Source Version");
|
||||
ConVar metamod_version("metamod_version", SOURCEMM_VERSION, FCVAR_REPLICATED | FCVAR_SPONLY | FCVAR_NOTIFY, "Metamod:Source Version");
|
||||
|
||||
CON_COMMAND(meta, "Metamod:Source Menu")
|
||||
{
|
||||
@ -111,9 +120,9 @@ CON_COMMAND(meta, "Metamod:Source Menu")
|
||||
} else if (strcmp(command, "refresh") == 0) {
|
||||
char full_path[255];
|
||||
#if defined WIN32 || defined _WIN32
|
||||
snprintf(full_path, sizeof(full_path)-1, "%s\\%s", g_ModPath.c_str(), "metaplugins.ini");
|
||||
snprintf(full_path, sizeof(full_path)-1, "%s\\addons\\metamod\\%s", g_ModPath.c_str(), "metaplugins.ini");
|
||||
#else
|
||||
snprintf(full_path, sizeof(full_path)-1, "%s/%s", g_ModPath.c_str(), "metaplugins.ini");
|
||||
snprintf(full_path, sizeof(full_path)-1, "%s/addons/metamod/%s", g_ModPath.c_str(), "metaplugins.ini");
|
||||
#endif
|
||||
LoadPluginsFromFile(full_path);
|
||||
|
||||
@ -169,6 +178,68 @@ CON_COMMAND(meta, "Metamod:Source Menu")
|
||||
|
||||
Msg("\n");
|
||||
|
||||
return;
|
||||
} else if (strcmp(command, "cmds") == 0) {
|
||||
if (args >= 3)
|
||||
{
|
||||
int id = atoi(e->Cmd_Argv(2));
|
||||
SourceMM::CPluginManager::CPlugin *pl = g_PluginMngr.FindById(id);
|
||||
|
||||
if (!pl)
|
||||
{
|
||||
Msg("Plugin %d not found.\n", id);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!pl->m_API)
|
||||
{
|
||||
Msg("Plugin %d is not loaded.\n", id);
|
||||
} else {
|
||||
Msg("Console commands for %s:\n", pl->m_API->GetName());
|
||||
std::list<ConCommandBase *>::iterator ci;
|
||||
size_t count = 0;
|
||||
|
||||
for (ci=pl->m_Cmds.begin(); ci!=pl->m_Cmds.end(); ci++)
|
||||
{
|
||||
count++;
|
||||
Msg(" [%5d] %-s\n", count, (*ci)->GetName());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Msg("Usage: meta cmds <id>\n");
|
||||
}
|
||||
|
||||
return;
|
||||
} else if (strcmp(command, "cvars") == 0) {
|
||||
if (args >= 3)
|
||||
{
|
||||
int id = atoi(e->Cmd_Argv(2));
|
||||
SourceMM::CPluginManager::CPlugin *pl = g_PluginMngr.FindById(id);
|
||||
|
||||
if (!pl)
|
||||
{
|
||||
Msg("Plugin %d not found.\n", id);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!pl->m_API)
|
||||
{
|
||||
Msg("Plugin %d is not loaded.\n", id);
|
||||
} else {
|
||||
Msg("Registered cvars for %s:\n", pl->m_API->GetName());
|
||||
std::list<ConCommandBase *>::iterator ci;
|
||||
size_t count = 0;
|
||||
|
||||
for (ci=pl->m_Cvars.begin(); ci!=pl->m_Cvars.end(); ci++)
|
||||
{
|
||||
count++;
|
||||
Msg(" [%5d] %-s\n", count, (*ci)->GetName());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Msg("Usage: meta cvars <id>\n");
|
||||
}
|
||||
|
||||
return;
|
||||
} else if (strcmp(command, "info") == 0) {
|
||||
if (args >= 3)
|
||||
@ -368,6 +439,8 @@ CON_COMMAND(meta, "Metamod:Source Menu")
|
||||
Msg("Metamod:Source Menu\n");
|
||||
Msg("usage: meta <command> [arguments]\n");
|
||||
Msg(" clear - Unload all plugins forcefully\n");
|
||||
Msg(" cmds - Show plugin commands\n");
|
||||
Msg(" cvars - Show plugin cvars\n");
|
||||
Msg(" credits - About Metamod:Source\n");
|
||||
Msg(" force_unload - Forcefully unload a plugin\n");
|
||||
Msg(" game - Information about GameDLL\n");
|
||||
@ -382,3 +455,65 @@ CON_COMMAND(meta, "Metamod:Source Menu")
|
||||
Msg(" version - Version information\n");
|
||||
Msg("\n");
|
||||
}
|
||||
|
||||
int UTIL_CmpNocase(const std::string &s1, const std::string &s2)
|
||||
{
|
||||
std::string::const_iterator p1 = s1.begin();
|
||||
std::string::const_iterator p2 = s2.begin();
|
||||
|
||||
while (p1 != s1.end() && p2 != s2.end())
|
||||
{
|
||||
if(toupper(*p1) != toupper(*p2))
|
||||
return (toupper(*p1)<toupper(*p2)) ? -1 : 1;
|
||||
++p1;
|
||||
++p2;
|
||||
}
|
||||
|
||||
return (s2.size() == s1.size()) ? 0 : (s1.size() < s2.size()) ? -1 : 1; // size is unsigned
|
||||
}
|
||||
|
||||
CAlwaysRegisterableCommand::CAlwaysRegisterableCommand()
|
||||
{
|
||||
Create("", NULL, FCVAR_UNREGISTERED|FCVAR_GAMEDLL);
|
||||
m_pICvar = NULL;
|
||||
}
|
||||
|
||||
bool CAlwaysRegisterableCommand::IsRegistered( void ) const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void CAlwaysRegisterableCommand::BringToFront()
|
||||
{
|
||||
if (!m_pICvar)
|
||||
m_pICvar = g_Engine.icvar;
|
||||
|
||||
// First, let's try to find us!
|
||||
ConCommandBase *pPtr = m_pICvar->GetCommands();
|
||||
|
||||
if (pPtr == this)
|
||||
{
|
||||
// We are already at the beginning; Nothing to do
|
||||
return;
|
||||
}
|
||||
|
||||
while (pPtr)
|
||||
{
|
||||
if (pPtr == this && pPtr->IsCommand() && UTIL_CmpNocase(GetName(), pPtr->GetName()) == 0)
|
||||
break;
|
||||
ConCommandBase *pPrev = NULL;
|
||||
while (pPtr)
|
||||
{
|
||||
if (pPtr == this)
|
||||
break;
|
||||
pPrev = pPtr;
|
||||
pPtr = const_cast<ConCommandBase*>(pPtr->GetNext());
|
||||
}
|
||||
if (pPrev && pPtr == this)
|
||||
{
|
||||
pPrev->SetNext(m_pNext); // Remove us from the list
|
||||
}
|
||||
// Now, register us
|
||||
m_pICvar->RegisterConCommandBase(this);
|
||||
}
|
||||
}
|
||||
|
||||
@ -27,8 +27,20 @@ class SMConVarAccessor : public IConCommandBaseAccessor
|
||||
std::list<ConCommandBase*> m_RegisteredCommands;
|
||||
public:
|
||||
virtual bool RegisterConCommandBase(ConCommandBase *pCommand);
|
||||
bool Register(ConCommandBase *pCommand);
|
||||
void MarkCommandsAsGameDLL();
|
||||
void Unregister(ConCommandBase *pCvar);
|
||||
void Unregister(ConCommandBase *pCommand);
|
||||
};
|
||||
|
||||
class CAlwaysRegisterableCommand : public ConCommandBase
|
||||
{
|
||||
ICvar *m_pICvar;
|
||||
public:
|
||||
CAlwaysRegisterableCommand();
|
||||
bool IsRegistered( void ) const;
|
||||
// If already registered, removes us
|
||||
// Then it registers us again
|
||||
void BringToFront();
|
||||
};
|
||||
|
||||
extern SMConVarAccessor g_SMConVarAccessor;
|
||||
|
||||
@ -87,6 +87,7 @@
|
||||
AdditionalDependencies="tier0.lib vstdlib.lib"
|
||||
OutputFile="$(OutDir)/server.dll"
|
||||
LinkIncremental="1"
|
||||
IgnoreDefaultLibraryNames=""
|
||||
GenerateDebugInformation="TRUE"
|
||||
SubSystem="2"
|
||||
OptimizeReferences="2"
|
||||
@ -175,6 +176,9 @@
|
||||
<File
|
||||
RelativePath=".\oslink.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\resource.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\sourcemm.h">
|
||||
</File>
|
||||
|
||||
@ -27,8 +27,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 1,0,0,2
|
||||
PRODUCTVERSION 1,0,0,2
|
||||
FILEVERSION 1,0,0,3
|
||||
PRODUCTVERSION 1,0,0,3
|
||||
FILEFLAGSMASK 0x17L
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
|
||||
Loading…
Reference in New Issue
Block a user