Skip to content

Commit 02e3490

Browse files
committed
Fixed ConVar/ServerCommand registration conflicts.
Fixed Client/Say/Server commands decorators from raising on unload when no callback was registered. Remove the public/private hack. Fixed server commands from potentially unregistering overrides rather than themselves. Added the ability to override convars as server commands and prevent their assignment from the console. Fixed memory leak for new convars allocated by the interpreter. Fixed execute_server_command, queue_server_command and insert_server_command being executed with an extra empty space.
1 parent ff7819a commit 02e3490

16 files changed

+209
-93
lines changed

Diff for: addons/source-python/packages/source-python/commands/command.py

+9-1
Original file line numberDiff line numberDiff line change
@@ -53,4 +53,12 @@ def __call__(self, callback):
5353

5454
def _unload_instance(self):
5555
"""Unregister the commands."""
56-
self._manager_class.unregister_commands(self.names, self.callback)
56+
# Get the registered callback
57+
callback = self.callback
58+
59+
# Was no callback registered?
60+
if callback is None:
61+
return
62+
63+
# Unregister the commands
64+
self._manager_class.unregister_commands(self.names, callback)

Diff for: src/core/modules/commands/commands.h

+1-29
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
// Includes.
3131
//-----------------------------------------------------------------------------
3232
#include "utilities/wrap_macros.h"
33-
#include "convar.h"
33+
#include "utilities/convar.h"
3434
#include "utilities/ipythongenerator.h"
3535
#include "boost/typeof/typeof.hpp"
3636

@@ -99,34 +99,6 @@ class CCommandExt
9999
};
100100

101101

102-
//-----------------------------------------------------------------------------
103-
// ConCommandBase extension class.
104-
//-----------------------------------------------------------------------------
105-
class ConCommandBaseExt
106-
{
107-
public:
108-
static int GetFlags(ConCommandBase* command)
109-
{
110-
return command->m_nFlags;
111-
}
112-
113-
static void SetFlags(ConCommandBase* command, int flags)
114-
{
115-
command->m_nFlags = flags;
116-
}
117-
118-
static void AddFlags(ConCommandBase* command, int flags)
119-
{
120-
command->m_nFlags |= flags;
121-
}
122-
123-
static void RemoveFlags(ConCommandBase* command, int flags)
124-
{
125-
command->m_nFlags &= ~flags;
126-
}
127-
};
128-
129-
130102
//-----------------------------------------------------------------------------
131103
// ConCommand extension class.
132104
//-----------------------------------------------------------------------------

Diff for: src/core/modules/commands/commands_client.cpp

+1-4
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,11 @@
2727
//-----------------------------------------------------------------------------
2828
// Includes
2929
//-----------------------------------------------------------------------------
30-
// This is required for accessing m_nFlags without patching convar.h
31-
#define private public
32-
3330
#include "boost/unordered_map.hpp"
3431
#include "commands_client.h"
3532
#include "commands.h"
3633
#include "edict.h"
37-
#include "convar.h"
34+
#include "utilities/convar.h"
3835
#include "engine/iserverplugin.h"
3936
#include "utilities/call_python.h"
4037
#include "boost/python/call.hpp"

Diff for: src/core/modules/commands/commands_client.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ class CClientCommandManager
5656

5757
const char* GetName();
5858

59-
private:
59+
public:
6060
CListenerManager m_vecCallables;
6161
const char* m_Name;
6262
};

Diff for: src/core/modules/commands/commands_client_wrap.cpp

-3
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,6 @@
2727
//-----------------------------------------------------------------------------
2828
// Includes.
2929
//-----------------------------------------------------------------------------
30-
// This is required for accessing m_nFlags without patching convar.h
31-
#define private public
32-
3330
#include "export_main.h"
3431
#include "utilities/wrap_macros.h"
3532
#include "modules/memory/memory_tools.h"

Diff for: src/core/modules/commands/commands_say.cpp

+4-7
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,6 @@
2727
//-----------------------------------------------------------------------------
2828
// Includes.
2929
//-----------------------------------------------------------------------------
30-
// This is required for accessing m_nFlags without patching convar.h
31-
#define private public
32-
3330
#include <iostream>
3431
#include <string>
3532
#include "utilities/call_python.h"
@@ -38,7 +35,7 @@
3835
#include "boost/unordered_map.hpp"
3936
#include "sp_main.h"
4037
#include "modules/listeners/listeners_manager.h"
41-
#include "convar.h"
38+
#include "utilities/convar.h"
4239

4340
#include "commands_say.h"
4441
#include "commands.h"
@@ -158,7 +155,7 @@ SayConCommand* SayConCommand::CreateCommand(const char* szName, const char* szHe
158155
{
159156
// Store the current command's help text and flags
160157
szHelpTextCopy = strdup(pConCommand->GetHelpText());
161-
iFlags = pConCommand->m_nFlags;
158+
iFlags = GetConCommandFlags(pConCommand);
162159

163160
// Unregister the old command
164161
g_pCVar->UnregisterConCommand(pConCommand);
@@ -192,8 +189,8 @@ SayConCommand::~SayConCommand()
192189
// Get the ConCommand instance
193190
ConCommand* pConCommand = g_pCVar->FindCommand(m_Name);
194191

195-
// Was the command overwritten as a ConVar or by another DLL?
196-
if (pConCommand && pConCommand->GetDLLIdentifier() == CVarDLLIdentifier())
192+
// Make sure we only unregister ourselves
193+
if (pConCommand == this)
197194
{
198195
// Unregister the ConCommand
199196
g_pCVar->UnregisterConCommand(pConCommand);

Diff for: src/core/modules/commands/commands_say.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ class SayConCommand: public ConCommand
5050
protected:
5151
void Dispatch( const CCommand& command );
5252

53-
private:
53+
public:
5454
SayConCommand(ConCommand* pConCommand, const char* szName, const char* szHelpText, int iFlags);
5555
const char* m_Name;
5656
ConCommand* m_pOldCommand;
@@ -86,7 +86,7 @@ class CSayCommandManager
8686

8787
const char* GetName();
8888

89-
private:
89+
public:
9090
const char* m_Name;
9191
CListenerManager m_vecCallables;
9292
};

Diff for: src/core/modules/commands/commands_say_wrap.cpp

-3
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,6 @@
2727
//-----------------------------------------------------------------------------
2828
// Includes.
2929
//-----------------------------------------------------------------------------
30-
// This is required for accessing m_nFlags without patching convar.h
31-
#define private public
32-
3330
#include "export_main.h"
3431
#include "utilities/wrap_macros.h"
3532
#include "modules/memory/memory_tools.h"

Diff for: src/core/modules/commands/commands_server.cpp

+20-12
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,6 @@
2727
//-----------------------------------------------------------------------------
2828
// Includes
2929
//-----------------------------------------------------------------------------
30-
// This is required for accessing m_nFlags without patching convar.h
31-
#define private public
32-
3330
#include "utilities/call_python.h"
3431

3532
#include "boost/unordered_map.hpp"
@@ -56,8 +53,12 @@ class CPluginConVarAccessor : public IConCommandBaseAccessor
5653
public:
5754
virtual bool RegisterConCommandBase(ConCommandBase* pCommand)
5855
{
59-
g_pCVar->RegisterConCommand(pCommand);
60-
return true;
56+
if (!g_pCVar->FindCommandBase(pCommand->GetName())) {
57+
g_pCVar->RegisterConCommand(pCommand);
58+
return true;
59+
}
60+
61+
return false;
6162
}
6263
};
6364

@@ -121,15 +122,17 @@ CServerCommandManager* CServerCommandManager::CreateCommand(const char* szName,
121122
char* szHelpTextCopy = NULL;
122123

123124
// FInd if the command already exists
124-
ConCommand* pConCommand = g_pCVar->FindCommand(szName);
125+
ConCommandBase* pConCommand = g_pCVar->FindCommandBase(szName);
125126
if( pConCommand )
126127
{
127128
// Store the current command's help text and flags
128129
szHelpTextCopy = strdup(pConCommand->GetHelpText());
129-
iFlags = pConCommand->m_nFlags;
130+
iFlags = GetConCommandFlags(pConCommand);
130131

131132
// Unregister the old command
132-
g_pCVar->UnregisterConCommand(pConCommand);
133+
if (pConCommand->IsRegistered()) {
134+
g_pCVar->UnregisterConCommand(pConCommand);
135+
}
133136
}
134137
else if( szHelpText != NULL )
135138
{
@@ -144,7 +147,7 @@ CServerCommandManager* CServerCommandManager::CreateCommand(const char* szName,
144147
//-----------------------------------------------------------------------------
145148
// CServerCommandManager constructor.
146149
//-----------------------------------------------------------------------------
147-
CServerCommandManager::CServerCommandManager(ConCommand* pConCommand,
150+
CServerCommandManager::CServerCommandManager(ConCommandBase* pConCommand,
148151
const char* szName, const char* szHelpText, int iFlags):
149152
ConCommand(szName, (FnCommandCallback_t)NULL, szHelpText, iFlags),
150153
m_pOldCommand(pConCommand)
@@ -163,8 +166,8 @@ CServerCommandManager::~CServerCommandManager()
163166
// Get the ConCommand instance
164167
ConCommand* pConCommand = g_pCVar->FindCommand(m_Name);
165168

166-
// Was the command overwritten as a ConVar or by another DLL?
167-
if (pConCommand && pConCommand->GetDLLIdentifier() == CVarDLLIdentifier())
169+
// Make sure we only unregister ourselves
170+
if (pConCommand == this)
168171
{
169172
// Unregister the ConCommand
170173
g_pCVar->UnregisterConCommand(pConCommand);
@@ -236,7 +239,12 @@ void CServerCommandManager::Dispatch( const CCommand& command )
236239
// Was the command previously registered?
237240
if(m_pOldCommand)
238241
{
239-
m_pOldCommand->Dispatch(command);
242+
if (m_pOldCommand->IsCommand()) {
243+
static_cast<ConCommand *>(m_pOldCommand)->Dispatch(command);
244+
}
245+
else {
246+
static_cast<ConVar *>(m_pOldCommand)->SetValue(command.ArgS());
247+
}
240248
}
241249

242250
// Post hook callbacks

Diff for: src/core/modules/commands/commands_server.h

+3-3
Original file line numberDiff line numberDiff line change
@@ -50,11 +50,11 @@ class CServerCommandManager : public ConCommand
5050
protected:
5151
void Dispatch( const CCommand& command);
5252

53-
private:
54-
CServerCommandManager(ConCommand* pConCommand, const char* szName, const char* szHelpString = 0, int iFlags = 0);
53+
public:
54+
CServerCommandManager(ConCommandBase* pConCommand, const char* szName, const char* szHelpString = 0, int iFlags = 0);
5555
std::map< HookType_t, CListenerManager* > m_vecCallables;
5656
const char* m_Name;
57-
ConCommand* m_pOldCommand;
57+
ConCommandBase* m_pOldCommand;
5858
};
5959

6060
#endif // _COMMANDS_SERVER_H

Diff for: src/core/modules/commands/commands_server_wrap.cpp

-3
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,6 @@
2727
//-----------------------------------------------------------------------------
2828
// Includes.
2929
//-----------------------------------------------------------------------------
30-
// This is required for accessing m_nFlags without patching convar.h
31-
#define private public
32-
3330
#include "boost/unordered_map.hpp"
3431
#include "utilities/wrap_macros.h"
3532
#include "commands_server.h"

Diff for: src/core/modules/commands/commands_wrap.cpp

+4-7
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,6 @@
2727
//-----------------------------------------------------------------------------
2828
// Includes.
2929
//-----------------------------------------------------------------------------
30-
// This is required for accessing m_nFlags without patching convar.h
31-
#define private public
32-
3330
#include "utilities/wrap_macros.h"
3431
#include "export_main.h"
3532
#include "modules/memory/memory_tools.h"
@@ -170,20 +167,20 @@ void export_concommandbase(scope _commands)
170167
)
171168

172169
.def("add_flags",
173-
&ConCommandBaseExt::AddFlags,
170+
&AddConCommandFlags,
174171
"Adds the given flags to the ConVar.",
175172
args("flag")
176173
)
177174

178175
.def("remove_flags",
179-
&ConCommandBaseExt::RemoveFlags,
176+
&RemoveConCommandFlags,
180177
"Removes the given flags from the ConVar.",
181178
args("flag")
182179
)
183180

184181
.add_property("flags",
185-
&ConCommandBaseExt::GetFlags,
186-
&ConCommandBaseExt::SetFlags,
182+
&GetConCommandFlags,
183+
&SetConCommandFlags,
187184
"Returns its flags."
188185
)
189186

Diff for: src/core/modules/cvars/cvars.h

+45-10
Original file line numberDiff line numberDiff line change
@@ -30,18 +30,37 @@
3030
//-----------------------------------------------------------------------------
3131
// Includes.
3232
//-----------------------------------------------------------------------------
33-
#include "convar.h"
33+
#include "icvar.h"
34+
#include "utilities/convar.h"
3435
#include "utilities/sp_util.h"
36+
#include "modules/commands/commands_server.h"
3537

3638

3739
//-----------------------------------------------------------------------------
38-
// Returns Source.Python's DLL identifier.
40+
// ICvar shared extension class.
3941
//-----------------------------------------------------------------------------
40-
inline CVarDLLIdentifier_t CVarDLLIdentifier()
42+
class ICVarSharedExt
4143
{
42-
static CVarDLLIdentifier_t s_nDLLIdentifier = ConCommandBase().GetDLLIdentifier();
43-
return s_nDLLIdentifier;
44-
}
44+
public:
45+
static ConVar *FindVar(ICvar *pCVar, const char *szName)
46+
{
47+
ConCommandBase *pBase = pCVar->FindCommandBase(szName);
48+
if (pBase)
49+
{
50+
if (pBase->IsCommand()) {
51+
CServerCommandManager *pManager = dynamic_cast<CServerCommandManager *>(pBase);
52+
if (pManager && pManager->m_pOldCommand && !pManager->m_pOldCommand->IsCommand()) {
53+
return static_cast<ConVar *>(pManager->m_pOldCommand);
54+
}
55+
}
56+
else {
57+
return static_cast<ConVar *>(pBase);
58+
}
59+
}
60+
61+
return NULL;
62+
};
63+
};
4564

4665

4766
//-----------------------------------------------------------------------------
@@ -73,18 +92,34 @@ class ConVarExt
7392
PyErr_Clear();
7493
}
7594

76-
ConVar *pConVar = g_pCVar->FindVar(name);
95+
ConVar *pConVar = ICVarSharedExt::FindVar(g_pCVar, name);
7796
if (!pConVar)
7897
{
7998
ConVar* pConVar = new ConVar(strdup(name), strdup(value), flags,
8099
strdup(description), !min_value.is_none(), fMin, !max_value.is_none(), fMax);
81100

82-
return boost::shared_ptr<ConVar>(pConVar, &NeverDeleteDeleter<ConVar *>);
101+
return boost::shared_ptr<ConVar>(pConVar, &Deleter);
83102
}
84103

85104
return boost::shared_ptr<ConVar>(pConVar, &NeverDeleteDeleter<ConVar *>);
86105
}
87106

107+
static void Deleter(ConVar *pConVar)
108+
{
109+
ConCommandBase *pBase = g_pCVar->FindCommandBase(pConVar->GetName());
110+
if (pBase) {
111+
CServerCommandManager *pManager = dynamic_cast<CServerCommandManager *>(pBase);
112+
if (pManager && pManager->m_pOldCommand == pConVar) {
113+
pManager->m_pOldCommand = NULL;
114+
}
115+
else if (pBase == pConVar) {
116+
g_pCVar->UnregisterConCommand(pConVar);
117+
}
118+
}
119+
120+
delete pConVar;
121+
}
122+
88123
static bool HasMin(ConVar* pConVar)
89124
{
90125
float fMin;
@@ -118,13 +153,13 @@ class ConVarExt
118153

119154
static void MakePublic(ConVar* pConVar)
120155
{
121-
pConVar->m_nFlags |= FCVAR_NOTIFY;
156+
AddConCommandFlags(pConVar, FCVAR_NOTIFY);
122157
g_pCVar->CallGlobalChangeCallbacks(pConVar, pConVar->GetString(), pConVar->GetFloat());
123158
}
124159

125160
static void RemovePublic(ConVar* pConVar)
126161
{
127-
pConVar->m_nFlags &= ~FCVAR_NOTIFY;
162+
RemoveConCommandFlags(pConVar, FCVAR_NOTIFY);
128163
g_pCVar->CallGlobalChangeCallbacks(pConVar, pConVar->GetString(), pConVar->GetFloat());
129164
}
130165
};

0 commit comments

Comments
 (0)