Fixed copy-paste error in 116256b519b5.
3 * =============================================================================
5 * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
6 * =============================================================================
8 * This program is free software; you can redistribute it and/or modify it under
9 * the terms of the GNU General Public License, version 3.0, as published by the
10 * Free Software Foundation.
12 * This program is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
17 * You should have received a copy of the GNU General Public License along with
18 * this program. If not, see <http://www.gnu.org/licenses/>.
20 * As a special exception, AlliedModders LLC gives you permission to link the
21 * code of this program (as well as its derivative works) to "Half-Life 2," the
22 * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
23 * by the Valve Corporation. You must obey the GNU General Public License in
24 * all respects for all other code used. Additionally, AlliedModders LLC grants
25 * this exception to all derivative works. AlliedModders LLC defines further
26 * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
27 * or <http://www.sourcemod.net/license.php>.
32 #include "sm_globals.h"
35 #include "concmd_cleaner.h"
36 #include "sm_stringutil.h"
37 #include "sourcemm_api.h"
38 #include "compat_wrappers.h"
40 #if SOURCE_ENGINE >= SE_ORANGEBOX
41 SH_DECL_HOOK1_void(ICvar, UnregisterConCommand, SH_NOATTRIB, 0, ConCommandBase *);
42 SH_DECL_HOOK1_void(ICvar, RegisterConCommand, SH_NOATTRIB, 0, ConCommandBase *);
44 SH_DECL_HOOK1_void(ICvar, RegisterConCommandBase, SH_NOATTRIB, 0, ConCommandBase *);
47 using namespace SourceHook;
51 ConCommandBase *pBase;
52 IConCommandTracker *cls;
56 List<ConCommandInfo *> tracked_bases;
57 IConCommandLinkListener *IConCommandLinkListener::head = NULL;
59 ConCommandBase *FindConCommandBase(const char *name);
61 class ConCommandCleaner : public SMGlobalClass
64 void OnSourceModAllInitialized()
66 #if SOURCE_ENGINE >= SE_ORANGEBOX
67 SH_ADD_HOOK(ICvar, UnregisterConCommand, icvar, SH_MEMBER(this, &ConCommandCleaner::UnlinkConCommandBase), false);
68 SH_ADD_HOOK(ICvar, RegisterConCommand, icvar, SH_MEMBER(this, &ConCommandCleaner::LinkConCommandBase), false);
70 SH_ADD_HOOK(ICvar, RegisterConCommandBase, icvar, SH_MEMBER(this, &ConCommandCleaner::LinkConCommandBase), false);
74 void OnSourceModShutdown()
76 #if SOURCE_ENGINE >= SE_ORANGEBOX
77 SH_REMOVE_HOOK(ICvar, UnregisterConCommand, icvar, SH_MEMBER(this, &ConCommandCleaner::UnlinkConCommandBase), false);
78 SH_REMOVE_HOOK(ICvar, RegisterConCommand, icvar, SH_MEMBER(this, &ConCommandCleaner::LinkConCommandBase), false);
80 SH_REMOVE_HOOK(ICvar, RegisterConCommandBase, icvar, SH_MEMBER(this, &ConCommandCleaner::LinkConCommandBase), false);
84 void LinkConCommandBase(ConCommandBase *pBase)
86 IConCommandLinkListener *listener = IConCommandLinkListener::head;
89 listener->OnLinkConCommand(pBase);
90 listener = listener->next;
94 void UnlinkConCommandBase(ConCommandBase *pBase)
96 ConCommandInfo *pInfo;
97 List<ConCommandInfo *>::iterator iter = tracked_bases.begin();
99 IConCommandLinkListener *listener = IConCommandLinkListener::head;
102 listener->OnUnlinkConCommand(pBase);
103 listener = listener->next;
108 while (iter != tracked_bases.end())
110 if ((*iter)->pBase == pBase)
113 iter = tracked_bases.erase(iter);
114 pInfo->cls->OnUnlinkConCommandBase(pBase, pBase->GetName(), true);
125 while (iter != tracked_bases.end())
127 /* This is just god-awful! */
128 if (FindCommandBase((*iter)->name) != (*iter)->pBase)
131 iter = tracked_bases.erase(iter);
132 pInfo->cls->OnUnlinkConCommandBase(pBase, pInfo->name, false);
143 void AddTarget(ConCommandBase *pBase, IConCommandTracker *cls)
145 ConCommandInfo *info = new ConCommandInfo;
149 strncopy(info->name, pBase->GetName(), sizeof(info->name));
151 tracked_bases.push_back(info);
154 void RemoveTarget(ConCommandBase *pBase, IConCommandTracker *cls)
156 List<ConCommandInfo *>::iterator iter;
157 ConCommandInfo *pInfo;
159 iter = tracked_bases.begin();
160 while (iter != tracked_bases.end())
163 if (pInfo->pBase == pBase && pInfo->cls == cls)
166 iter = tracked_bases.erase(iter);
176 void TrackConCommandBase(ConCommandBase *pBase, IConCommandTracker *me)
178 s_ConCmdTracker.AddTarget(pBase, me);
181 void UntrackConCommandBase(ConCommandBase *pBase, IConCommandTracker *me)
183 s_ConCmdTracker.RemoveTarget(pBase, me);
186 void Global_OnUnlinkConCommandBase(ConCommandBase *pBase)
188 s_ConCmdTracker.UnlinkConCommandBase(pBase);