1.1 --- a/core/ConCmdManager.cpp Tue Mar 06 07:38:19 2007 +0000
1.2 +++ b/core/ConCmdManager.cpp Tue Mar 06 23:59:25 2007 +0000
1.3 @@ -741,15 +741,18 @@
1.4 return;
1.5 }
1.6
1.7 + const sm_plugininfo_t *plinfo = pPlugin->GetPublicInfo();
1.8 + const char *plname = IS_STR_FILLED(plinfo->name) ? plinfo->name : pPlugin->GetFilename();
1.9 +
1.10 CmdList *pList;
1.11 if (!pPlugin->GetProperty("CommandList", (void **)&pList))
1.12 {
1.13 - g_RootMenu.ConsolePrint("[SM] No commands found for %s", pPlugin->GetFilename());
1.14 + g_RootMenu.ConsolePrint("[SM] No commands found for: %s", plname);
1.15 return;
1.16 }
1.17 if (!pList->size())
1.18 {
1.19 - g_RootMenu.ConsolePrint("[SM] No commands found for %s", pPlugin->GetFilename());
1.20 + g_RootMenu.ConsolePrint("[SM] No commands found for: %s", plname);
1.21 return;
1.22 }
1.23
1.24 @@ -757,10 +760,11 @@
1.25 const char *type = NULL;
1.26 const char *name;
1.27 const char *help;
1.28 - g_RootMenu.ConsolePrint(" %-17.16s %-8.7s %s", "[Name]", "[Type]", "[Help]");
1.29 + g_RootMenu.ConsolePrint("[SM] Listing %d commands for: %s", pList->size(), plname);
1.30 + g_RootMenu.ConsolePrint(" %-17.16s %-8.7s %s", "[Name]", "[Type]", "[Help]");
1.31 for (iter=pList->begin();
1.32 iter!=pList->end();
1.33 - iter++)
1.34 + iter++, id++)
1.35 {
1.36 PlCmdInfo &cmd = (*iter);
1.37 if (cmd.type == Cmd_Server)
1.38 @@ -778,7 +782,7 @@
1.39 } else {
1.40 help = cmd.pInfo->pCmd->GetHelpText();
1.41 }
1.42 - g_RootMenu.ConsolePrint(" %-17.16s %-12.11s %s", name, type, help);
1.43 + g_RootMenu.ConsolePrint(" %-17.16s %-12.11s %s", name, type, help);
1.44 }
1.45
1.46 return;
2.1 --- a/core/ConVarManager.cpp Tue Mar 06 07:38:19 2007 +0000
2.2 +++ b/core/ConVarManager.cpp Tue Mar 06 23:59:25 2007 +0000
2.3 @@ -21,9 +21,12 @@
2.4
2.5 ConVarManager g_ConVarManager;
2.6
2.7 +const ParamType CONVARCHANGE_PARAMS[] = {Param_Cell, Param_String, Param_String};
2.8 +typedef List<const ConVar *> ConVarList;
2.9 +
2.10 ConVarManager::ConVarManager() : m_ConVarType(0)
2.11 {
2.12 - // Create a convar lookup trie
2.13 + /* Create a convar lookup trie */
2.14 m_ConVarCache = sm_trie_create();
2.15 }
2.16
2.17 @@ -31,10 +34,10 @@
2.18 {
2.19 List<ConVarInfo *>::iterator iter;
2.20
2.21 - // Destroy our convar lookup trie
2.22 + /* Destroy our convar lookup trie */
2.23 sm_trie_destroy(m_ConVarCache);
2.24
2.25 - // Destroy all the ConVarInfo structures
2.26 + /* Destroy all the ConVarInfo structures */
2.27 for (iter = m_ConVars.begin(); iter != m_ConVars.end(); iter++)
2.28 {
2.29 delete (*iter);
2.30 @@ -47,15 +50,15 @@
2.31 {
2.32 HandleAccess sec;
2.33
2.34 - // Set up access rights for the 'ConVar' handle type
2.35 + /* Set up access rights for the 'ConVar' handle type */
2.36 sec.access[HandleAccess_Read] = 0;
2.37 sec.access[HandleAccess_Delete] = HANDLE_RESTRICT_IDENTITY | HANDLE_RESTRICT_OWNER;
2.38 sec.access[HandleAccess_Clone] = HANDLE_RESTRICT_IDENTITY | HANDLE_RESTRICT_OWNER;
2.39
2.40 - // Create the 'ConVar' handle type
2.41 + /* Create the 'ConVar' handle type */
2.42 m_ConVarType = g_HandleSys.CreateType("ConVar", this, 0, NULL, &sec, g_pCoreIdent, NULL);
2.43
2.44 - // Add the 'cvars' option to the 'sm' console command
2.45 + /* Add the 'convars' option to the 'sm' console command */
2.46 g_RootMenu.AddRootConsoleCommand("convars", "View convars created by a plugin", this);
2.47 }
2.48
2.49 @@ -64,33 +67,33 @@
2.50 IChangeableForward *fwd;
2.51 List<ConVarInfo *>::iterator i;
2.52
2.53 - // Iterate list of ConVarInfo structures
2.54 + /* Iterate list of ConVarInfo structures */
2.55 for (i = m_ConVars.begin(); i != m_ConVars.end(); i++)
2.56 {
2.57 fwd = (*i)->changeForward;
2.58
2.59 - // Free any convar-change forwards that still exist
2.60 + /* Free any convar-change forwards that still exist */
2.61 if (fwd)
2.62 {
2.63 g_Forwards.ReleaseForward(fwd);
2.64 }
2.65 }
2.66
2.67 - // Remove the 'cvars' option from the 'sm' console command
2.68 + /* Remove the 'convars' option from the 'sm' console command */
2.69 g_RootMenu.RemoveRootConsoleCommand("convars", this);
2.70
2.71 - // Remove the 'ConVar' handle type
2.72 + /* Remove the 'ConVar' handle type */
2.73 g_HandleSys.RemoveType(m_ConVarType, g_pCoreIdent);
2.74 }
2.75
2.76 -void ConVarManager::OnPluginDestroyed(IPlugin *plugin)
2.77 +void ConVarManager::OnPluginUnloaded(IPlugin *plugin)
2.78 {
2.79 - CVector<ConVar *> *cvarList;
2.80 + ConVarList *pConVarList;
2.81
2.82 - // If plugin has a convar list, free its memory
2.83 - if (plugin->GetProperty("ConVarList", reinterpret_cast<void **>(&cvarList), true))
2.84 + /* If plugin has a convar list, free its memory */
2.85 + if (plugin->GetProperty("ConVarList", (void **)&pConVarList, true))
2.86 {
2.87 - delete cvarList;
2.88 + delete pConVarList;
2.89 }
2.90 }
2.91
2.92 @@ -99,18 +102,18 @@
2.93 ConVarInfo *info;
2.94 ConVar *pConVar = static_cast<ConVar *>(object);
2.95
2.96 - // Find convar in lookup trie
2.97 + /* Find convar in lookup trie */
2.98 sm_trie_retrieve(m_ConVarCache, pConVar->GetName(), reinterpret_cast<void **>(&info));
2.99
2.100 - // If convar was created by SourceMod plugin...
2.101 + /* If convar was created by SourceMod plugin... */
2.102 if (info->sourceMod)
2.103 {
2.104 - // Delete string allocations
2.105 + /* Delete string allocations */
2.106 delete [] pConVar->GetName();
2.107 delete [] pConVar->GetDefault();
2.108 delete [] pConVar->GetHelpText();
2.109
2.110 - // Then unlink it from SourceMM
2.111 + /* Then unlink it from SourceMM */
2.112 g_SMAPI->UnregisterConCmdBase(g_PLAPI, pConVar);
2.113 }
2.114 }
2.115 @@ -119,78 +122,80 @@
2.116 {
2.117 if (argcount >= 3)
2.118 {
2.119 - int id = 1;
2.120 -
2.121 - // Get plugin index that was passed
2.122 - int num = atoi(g_RootMenu.GetArgument(2));
2.123 + /* Get plugin index that was passed */
2.124 + int id = atoi(g_RootMenu.GetArgument(2));
2.125
2.126 - // If invalid plugin index...
2.127 - if (num < 1 || num > (int)g_PluginSys.GetPluginCount())
2.128 + /* Get plugin object */
2.129 + CPlugin *plugin = g_PluginSys.GetPluginByOrder(id);
2.130 +
2.131 + if (!plugin)
2.132 {
2.133 - g_RootMenu.ConsolePrint("[SM] Plugin index %d not found.", num);
2.134 + g_RootMenu.ConsolePrint("[SM] Plugin index %d not found.", id);
2.135 return;
2.136 }
2.137
2.138 - // Get plugin object
2.139 - CPlugin *pl = g_PluginSys.GetPluginByOrder(num);
2.140 -
2.141 - CVector<ConVar *> *cvarList = NULL;
2.142 + /* Get plugin name */
2.143 + const sm_plugininfo_t *plinfo = plugin->GetPublicInfo();
2.144 + const char *plname = IS_STR_FILLED(plinfo->name) ? plinfo->name : plugin->GetFilename();
2.145
2.146 - // Get convar list from 'ConVar' property
2.147 - pl->GetProperty("ConVar", reinterpret_cast<void **>(&cvarList));
2.148 + ConVarList *pConVarList;
2.149 + ConVarList::iterator iter;
2.150
2.151 - // If no cvar list...
2.152 - if (cvarList == NULL)
2.153 + /* If no convar list... */
2.154 + if (!plugin->GetProperty("ConVarList", (void **)&pConVarList))
2.155 {
2.156 - g_RootMenu.ConsolePrint("[SM] No convars for \"%s\"", pl->GetPublicInfo()->name);
2.157 + g_RootMenu.ConsolePrint("[SM] No convars found for: %s", plname);
2.158 return;
2.159 }
2.160
2.161 - g_RootMenu.ConsolePrint("[SM] Displaying convars for \"%s\"", pl->GetPublicInfo()->name);
2.162 + g_RootMenu.ConsolePrint("[SM] Listing %d convars for: %s", pConVarList->size(), plname);
2.163 + g_RootMenu.ConsolePrint(" %-32.31s %s", "[Name]", "[Value]");
2.164
2.165 - // Iterate convar list and display each one
2.166 - for (size_t i = 0; i < cvarList->size(); i++, id++)
2.167 + /* Iterate convar list and display each one */
2.168 + for (iter = pConVarList->begin(); iter != pConVarList->end(); iter++)
2.169 {
2.170 - ConVar *pConVar = (*cvarList)[i];
2.171 - g_RootMenu.ConsolePrint(" %02d \"%s\" = \"%s\"", id, pConVar->GetName(), pConVar->GetString());
2.172 + const ConVar *pConVar = (*iter);
2.173 + g_RootMenu.ConsolePrint(" %-32.31s %s", pConVar->GetName(), pConVar->GetString());
2.174 }
2.175
2.176 return;
2.177 }
2.178
2.179 - // Display usage of subcommand
2.180 + /* Display usage of subcommand */
2.181 g_RootMenu.ConsolePrint("[SM] Usage: sm convars <plugin #>");
2.182 }
2.183
2.184 -Handle_t ConVarManager::CreateConVar(IPluginContext *pContext, const char *name, const char *defaultVal, const char *helpText, int flags, bool hasMin, float min, bool hasMax, float max)
2.185 +Handle_t ConVarManager::CreateConVar(IPluginContext *pContext, const char *name, const char *defaultVal, const char *description, int flags, bool hasMin, float min, bool hasMax, float max)
2.186 {
2.187 ConVar *pConVar = NULL;
2.188 - ConVarInfo *info = NULL;
2.189 - CVector<ConVar *> *cvarList = NULL;
2.190 + ConVarInfo *pInfo = NULL;
2.191 + ConVarList *pConVarList = NULL;
2.192 Handle_t hndl = 0;
2.193
2.194 - // Find out if the convar exists already
2.195 + /* Find out if the convar exists already */
2.196 pConVar = icvar->FindVar(name);
2.197
2.198 - // If the convar already exists...
2.199 - if (pConVar != NULL)
2.200 + /* If the convar already exists... */
2.201 + if (pConVar)
2.202 {
2.203 - // First check if we already have a handle to it
2.204 - if (sm_trie_retrieve(m_ConVarCache, name, reinterpret_cast<void **>(&info)))
2.205 + /* First find out if we already have a handle to it */
2.206 + if (sm_trie_retrieve(m_ConVarCache, name, (void **)&pInfo))
2.207 {
2.208 - // If we do, then return that handle
2.209 - return info->handle;
2.210 + return pInfo->handle;
2.211 } else {
2.212 - // If we don't, then create a new handle from the convar
2.213 + /* If we don't, then create a new handle from the convar */
2.214 hndl = g_HandleSys.CreateHandle(m_ConVarType, pConVar, NULL, g_pCoreIdent, NULL);
2.215
2.216 - info = new ConVarInfo;
2.217 - info->handle = hndl;
2.218 - info->sourceMod = false;
2.219 - info->changeForward = NULL;
2.220 - info->origCallback = pConVar->GetCallback();
2.221 + /* Create and initialize ConVarInfo structure */
2.222 + pInfo = new ConVarInfo();
2.223 + pInfo->handle = hndl;
2.224 + pInfo->sourceMod = false;
2.225 + pInfo->changeForward = NULL;
2.226 + pInfo->origCallback = pConVar->GetCallback();
2.227
2.228 - m_ConVars.push_back(info);
2.229 + /* Insert struct into caches */
2.230 + m_ConVars.push_back(pInfo);
2.231 + sm_trie_insert(m_ConVarCache, name, pInfo);
2.232
2.233 return hndl;
2.234 }
2.235 @@ -201,47 +206,33 @@
2.236
2.237 while (pBase)
2.238 {
2.239 - if (strcmp(pBase->GetName(), name) == 0)
2.240 + if (pBase->IsCommand() && strcmp(pBase->GetName(), name) == 0)
2.241 {
2.242 - return pContext->ThrowNativeError("Convar \"%s\" was not created. A console command with the same name already exists.", name);
2.243 + return BAD_HANDLE;
2.244 }
2.245
2.246 pBase = const_cast<ConCommandBase *>(pBase->GetNext());
2.247 }
2.248
2.249 - // Since we didn't find an existing convar (or concmd with the same name), now we can finally create it!
2.250 - pConVar = new ConVar(sm_strdup(name), sm_strdup(defaultVal), flags, sm_strdup(helpText), hasMin, min, hasMax, max);
2.251 -
2.252 - // Find plugin creating convar
2.253 - IPlugin *pl = g_PluginSys.FindPluginByContext(pContext->GetContext());
2.254 -
2.255 - // Get convar list from 'ConVar' property of plugin
2.256 - pl->GetProperty("ConVarList", reinterpret_cast<void **>(&cvarList));
2.257 + /* Since an existing convar (or concmd with the same name) was not found , now we can finally create it */
2.258 + pConVar = new ConVar(sm_strdup(name), sm_strdup(defaultVal), flags, sm_strdup(description), hasMin, min, hasMax, max);
2.259
2.260 - // If 'ConVar' property doesn't exist...
2.261 - if (cvarList == NULL)
2.262 - {
2.263 - // Then create it
2.264 - cvarList = new CVector<ConVar *>;
2.265 - pl->SetProperty("ConVarList", cvarList);
2.266 - }
2.267 + /* Add convar to plugin's list */
2.268 + AddConVarToPluginList(pContext, pConVar);
2.269
2.270 - // Add new convar to plugin's list
2.271 - cvarList->push_back(pConVar);
2.272 -
2.273 - // Create a handle from the new convar
2.274 + /* Create a handle from the new convar */
2.275 hndl = g_HandleSys.CreateHandle(m_ConVarType, pConVar, NULL, g_pCoreIdent, NULL);
2.276
2.277 - info = new ConVarInfo;
2.278 - info->handle = hndl;
2.279 - info->sourceMod = true;
2.280 - info->changeForward = NULL;
2.281 - info->origCallback = NULL;
2.282 + /* Create and initialize ConVarInfo structure */
2.283 + pInfo = new ConVarInfo();
2.284 + pInfo->handle = hndl;
2.285 + pInfo->sourceMod = true;
2.286 + pInfo->changeForward = NULL;
2.287 + pInfo->origCallback = NULL;
2.288
2.289 - m_ConVars.push_back(info);
2.290 -
2.291 - // Insert the handle into our lookup trie
2.292 - sm_trie_insert(m_ConVarCache, name, info);
2.293 + /* Insert struct into caches */
2.294 + m_ConVars.push_back(pInfo);
2.295 + sm_trie_insert(m_ConVarCache, name, pInfo);
2.296
2.297 return hndl;
2.298 }
2.299 @@ -249,159 +240,165 @@
2.300 Handle_t ConVarManager::FindConVar(const char *name)
2.301 {
2.302 ConVar *pConVar = NULL;
2.303 - ConVarInfo *info = NULL;
2.304 - Handle_t hndl = 0;
2.305 + ConVarInfo *pInfo;
2.306 + Handle_t hndl;
2.307
2.308 - // Search for convar
2.309 + /* Search for convar */
2.310 pConVar = icvar->FindVar(name);
2.311
2.312 - // If it doesn't exist, then return an invalid handle
2.313 - if (pConVar == NULL)
2.314 + /* If it doesn't exist, then return an invalid handle */
2.315 + if (!pConVar)
2.316 {
2.317 return BAD_HANDLE;
2.318 }
2.319
2.320 - // At this point, convar exists, so find out if we already have a handle for it
2.321 - if (sm_trie_retrieve(m_ConVarCache, name, reinterpret_cast<void **>(&info)))
2.322 + /* At this point, the convar exists. So, find out if we already have a handle */
2.323 + if (sm_trie_retrieve(m_ConVarCache, name, (void **)&pInfo))
2.324 {
2.325 - // If we do, then return that handle
2.326 - return info->handle;
2.327 + return pInfo->handle;
2.328 }
2.329
2.330 - // If we don't, then create a new handle from the convar
2.331 + /* If we don't have a handle, then create a new one */
2.332 hndl = g_HandleSys.CreateHandle(m_ConVarType, pConVar, NULL, g_pCoreIdent, NULL);
2.333
2.334 - info = new ConVarInfo;
2.335 - info->handle = hndl;
2.336 - info->sourceMod = false;
2.337 - info->changeForward = NULL;
2.338 - info->origCallback = pConVar->GetCallback();
2.339 + /* Create and initilize ConVarInfo structure */
2.340 + pInfo = new ConVarInfo();
2.341 + pInfo->handle = hndl;
2.342 + pInfo->sourceMod = false;
2.343 + pInfo->changeForward = NULL;
2.344 + pInfo->origCallback = pConVar->GetCallback();
2.345
2.346 - m_ConVars.push_back(info);
2.347 -
2.348 - // Insert the handle into our cache
2.349 - sm_trie_insert(m_ConVarCache, name, info);
2.350 + /* Insert struct into our caches */
2.351 + m_ConVars.push_back(pInfo);
2.352 + sm_trie_insert(m_ConVarCache, name, pInfo);
2.353
2.354 return hndl;
2.355 }
2.356
2.357 -void ConVarManager::HookConVarChange(IPluginContext *pContext, ConVar *pConVar, funcid_t funcid)
2.358 +void ConVarManager::HookConVarChange(ConVar *pConVar, IPluginFunction *pFunction)
2.359 {
2.360 - IPluginFunction *func = pContext->GetFunctionById(funcid);
2.361 - IChangeableForward *fwd = NULL;
2.362 - char fwdName[64];
2.363 - ConVarInfo *info = NULL;
2.364 -
2.365 - // This shouldn't happen...
2.366 - if (func == NULL)
2.367 - {
2.368 - pContext->ThrowNativeError("Invalid function specified");
2.369 - return;
2.370 - }
2.371 -
2.372 - // Create a forward name
2.373 - UTIL_Format(fwdName, sizeof(fwdName), "ConVar.%s", pConVar->GetName());
2.374 + ConVarInfo *pInfo;
2.375 + IChangeableForward *pForward;
2.376
2.377 - // First find out if the forward already exists
2.378 - g_Forwards.FindForward(fwdName, &fwd);
2.379 -
2.380 - // If the forward doesn't exist...
2.381 - if (fwd == NULL)
2.382 + /* Find the convar in the lookup trie */
2.383 + if (sm_trie_retrieve(m_ConVarCache, pConVar->GetName(), (void **)&pInfo))
2.384 {
2.385 - // This is the forward's parameter type list
2.386 - ParamType p[] = {Param_Cell, Param_String, Param_String};
2.387 + /* Get the forward */
2.388 + pForward = pInfo->changeForward;
2.389
2.390 - // Create the forward
2.391 - fwd = g_Forwards.CreateForwardEx(fwdName, ET_Ignore, 3, p);
2.392 + /* If forward does not exist, create it */
2.393 + if (!pForward)
2.394 + {
2.395 + pForward = g_Forwards.CreateForwardEx(NULL, ET_Ignore, 3, CONVARCHANGE_PARAMS);
2.396 + pInfo->changeForward = pForward;
2.397
2.398 - // Find the convar in the lookup trie
2.399 - if (sm_trie_retrieve(m_ConVarCache, pConVar->GetName(), reinterpret_cast<void **>(&info)))
2.400 - {
2.401 - // Set the convar's forward to the newly created one
2.402 - info->changeForward = fwd;
2.403 -
2.404 - // Set the convar's callback to our static one
2.405 + /* Install our own callback */
2.406 pConVar->InstallChangeCallback(OnConVarChanged);
2.407 }
2.408 +
2.409 + /* Add function to forward's list */
2.410 + pForward->AddFunction(pFunction);
2.411 }
2.412 -
2.413 - // Add the function to the forward's list
2.414 - fwd->AddFunction(func);
2.415 }
2.416
2.417 -void ConVarManager::UnhookConVarChange(IPluginContext *pContext, ConVar *pConVar, funcid_t funcid)
2.418 +void ConVarManager::UnhookConVarChange(ConVar *pConVar, IPluginFunction *pFunction)
2.419 {
2.420 - IPluginFunction *func = pContext->GetFunctionById(funcid);
2.421 - IChangeableForward *fwd = NULL;
2.422 - ConVarInfo *info = NULL;
2.423 + ConVarInfo *pInfo;
2.424 + IChangeableForward *pForward;
2.425 + IPluginContext *pContext = pFunction->GetParentContext();
2.426
2.427 - // This shouldn't happen...
2.428 - if (func == NULL)
2.429 + /* Find the convar in the lookup trie */
2.430 + if (sm_trie_retrieve(m_ConVarCache, pConVar->GetName(), (void **)&pInfo))
2.431 {
2.432 - pContext->ThrowNativeError("Invalid function specified");
2.433 - return;
2.434 - }
2.435 + /* Get the forward */
2.436 + pForward = pInfo->changeForward;
2.437
2.438 - // Find the convar in the lookup trie
2.439 - if (sm_trie_retrieve(m_ConVarCache, pConVar->GetName(), reinterpret_cast<void **>(&info)))
2.440 - {
2.441 - // Get the forward
2.442 - fwd = info->changeForward;
2.443 -
2.444 - // If the forward doesn't exist, we can't unhook anything
2.445 - if (fwd == NULL)
2.446 + /* If the forward doesn't exist, we can't unhook anything */
2.447 + if (!pForward)
2.448 {
2.449 pContext->ThrowNativeError("Convar \"%s\" has no active hook", pConVar->GetName());
2.450 return;
2.451 }
2.452
2.453 - // Remove the function from the forward's list
2.454 - if (!fwd->RemoveFunction(func))
2.455 + /* Remove the function from the forward's list */
2.456 + if (!pForward->RemoveFunction(pFunction))
2.457 {
2.458 pContext->ThrowNativeError("Invalid hook callback specified for convar \"%s\"", pConVar->GetName());
2.459 return;
2.460 }
2.461
2.462 - // If the forward now has 0 functions in it...
2.463 - if (fwd->GetFunctionCount() == 0)
2.464 + /* If the forward now has 0 functions in it... */
2.465 + if (pForward->GetFunctionCount() == 0)
2.466 {
2.467 - // Free this forward
2.468 - g_Forwards.ReleaseForward(fwd);
2.469 - info->changeForward = NULL;
2.470 + /* Free this forward */
2.471 + g_Forwards.ReleaseForward(pForward);
2.472 + pInfo->changeForward = NULL;
2.473 +
2.474 + /* Put back the original convar callback */
2.475 + pConVar->InstallChangeCallback(pInfo->origCallback);
2.476 + }
2.477 + }
2.478 +}
2.479 +
2.480 +void ConVarManager::AddConVarToPluginList(IPluginContext *pContext, const ConVar *pConVar)
2.481 +{
2.482 + ConVarList *pConVarList;
2.483 + ConVarList::iterator iter;
2.484 + bool inserted = false;
2.485 + const char *orig = pConVar->GetName();
2.486 +
2.487 + IPlugin *plugin = g_PluginSys.FindPluginByContext(pContext->GetContext());
2.488
2.489 - // Put the back the original convar callback
2.490 - pConVar->InstallChangeCallback(info->origCallback);
2.491 + /* Check plugin for an existing convar list */
2.492 + if (!plugin->GetProperty("ConVarList", (void **)&pConVarList))
2.493 + {
2.494 + pConVarList = new ConVarList();
2.495 + plugin->SetProperty("ConVarList", pConVarList);
2.496 + }
2.497 +
2.498 + /* Insert convar into list which is sorted alphabetically */
2.499 + for (iter = pConVarList->begin(); iter != pConVarList->end(); iter++)
2.500 + {
2.501 + if (strcmp(orig, (*iter)->GetName()) < 0)
2.502 + {
2.503 + pConVarList->insert(iter, pConVar);
2.504 + inserted = true;
2.505 + break;
2.506 }
2.507 }
2.508 +
2.509 + if (!inserted)
2.510 + {
2.511 + pConVarList->push_back(pConVar);
2.512 + }
2.513 }
2.514
2.515 void ConVarManager::OnConVarChanged(ConVar *pConVar, const char *oldValue)
2.516 {
2.517 - // If the values are the same...
2.518 + /* If the values are the same, exit early in order to not trigger callbacks */
2.519 if (strcmp(pConVar->GetString(), oldValue) == 0)
2.520 {
2.521 - // Exit early in order to not trigger callbacks
2.522 return;
2.523 }
2.524
2.525 - Trie *cache = g_ConVarManager.GetConVarCache();
2.526 - ConVarInfo *info;
2.527 + Trie *pCache = g_ConVarManager.GetConVarCache();
2.528 + ConVarInfo *pInfo;
2.529
2.530 - // Find the convar in the lookup trie
2.531 - sm_trie_retrieve(cache, pConVar->GetName(), reinterpret_cast<void **>(&info));
2.532 + /* Find the convar in the lookup trie */
2.533 + sm_trie_retrieve(pCache, pConVar->GetName(), (void **)&pInfo);
2.534
2.535 - FnChangeCallback origCallback = info->origCallback;
2.536 - IChangeableForward *fwd = info->changeForward;
2.537 + FnChangeCallback origCallback = pInfo->origCallback;
2.538 + IChangeableForward *pForward = pInfo->changeForward;
2.539
2.540 - // If there was a change callback installed previously, call it
2.541 + /* If there was a change callback installed previously, call it */
2.542 if (origCallback)
2.543 {
2.544 origCallback(pConVar, oldValue);
2.545 }
2.546
2.547 - // Now call forwards in plugins that have hooked this
2.548 - fwd->PushCell(info->handle);
2.549 - fwd->PushString(pConVar->GetString());
2.550 - fwd->PushString(oldValue);
2.551 - fwd->Execute(NULL);
2.552 + /* Now call forwards in plugins that have hooked this */
2.553 + pForward->PushCell(pInfo->handle);
2.554 + pForward->PushString(oldValue);
2.555 + pForward->PushString(pConVar->GetString());
2.556 + pForward->Execute(NULL);
2.557 }
3.1 --- a/core/ConVarManager.h Tue Mar 06 07:38:19 2007 +0000
3.2 +++ b/core/ConVarManager.h Tue Mar 06 23:59:25 2007 +0000
3.3 @@ -51,7 +51,7 @@
3.4 public: // IHandleTypeDispatch
3.5 void OnHandleDestroy(HandleType_t type, void *object);
3.6 public: // IPluginsListener
3.7 - void OnPluginDestroyed(IPlugin *plugin);
3.8 + void OnPluginUnloaded(IPlugin *plugin);
3.9 public: //IRootConsoleCommand
3.10 void OnRootConsoleCommand(const char *command, unsigned int argcount);
3.11 public:
3.12 @@ -74,8 +74,8 @@
3.13 /**
3.14 * Create a convar and return a handle to it.
3.15 */
3.16 - Handle_t CreateConVar(IPluginContext *pContext, const char *name, const char *defaultVal, const char *helpText,
3.17 - int flags, bool hasMin, float min, bool hasMax, float max);
3.18 + Handle_t CreateConVar(IPluginContext *pContext, const char *name, const char *defaultVal,
3.19 + const char *description, int flags, bool hasMin, float min, bool hasMax, float max);
3.20
3.21 /**
3.22 * Searches for a convar and returns a handle to it
3.23 @@ -85,14 +85,19 @@
3.24 /**
3.25 * Add a function to call when the specified convar changes.
3.26 */
3.27 - void HookConVarChange(IPluginContext *pContext, ConVar *pConVar, funcid_t funcid);
3.28 + void HookConVarChange(ConVar *pConVar, IPluginFunction *pFunction);
3.29
3.30 /**
3.31 * Remove a function from the forward that will be called when the specified convar changes.
3.32 */
3.33 - void UnhookConVarChange(IPluginContext *pContext, ConVar *pConVar, funcid_t funcid);
3.34 + void UnhookConVarChange(ConVar *pConVar, IPluginFunction *pFunction);
3.35 private:
3.36 /**
3.37 + * Adds a convar to a plugin's list.
3.38 + */
3.39 + static void AddConVarToPluginList(IPluginContext *pContext, const ConVar *pConVar);
3.40 +
3.41 + /**
3.42 * Static callback that Valve's ConVar class executes when the convar's value changes.
3.43 */
3.44 static void OnConVarChanged(ConVar *pConVar, const char *oldValue);
4.1 --- a/core/EventManager.cpp Tue Mar 06 07:38:19 2007 +0000
4.2 +++ b/core/EventManager.cpp Tue Mar 06 23:59:25 2007 +0000
4.3 @@ -21,10 +21,9 @@
4.4
4.5 SH_DECL_HOOK2(IGameEventManager2, FireEvent, SH_NOATTRIB, 0, bool, IGameEvent *, bool);
4.6
4.7 +const ParamType GAMEEVENT_PARAMS[] = {Param_Cell, Param_String, Param_Cell};
4.8 typedef List<EventHook *> EventHookList;
4.9
4.10 -const ParamType GAMEEVENT_PARAMS[] = {Param_Cell, Param_String, Param_Cell};
4.11 -
4.12 EventManager::EventManager() : m_EventType(0), m_NotifyPlugins(true), m_EventCopy(NULL)
4.13 {
4.14 /* Create an event lookup trie */
4.15 @@ -93,12 +92,13 @@
4.16 void EventManager::OnPluginUnloaded(IPlugin *plugin)
4.17 {
4.18 EventHookList *pHookList;
4.19 + EventHookList::iterator iter;
4.20 EventHook *pHook;
4.21
4.22 // If plugin has an event hook list...
4.23 if (plugin->GetProperty("EventHooks", reinterpret_cast<void **>(&pHookList), true))
4.24 {
4.25 - for (EventHookList::iterator iter = pHookList->begin(); iter != pHookList->end(); iter++)
4.26 + for (iter = pHookList->begin(); iter != pHookList->end(); iter++)
4.27 {
4.28 pHook = (*iter);
4.29
5.1 --- a/core/EventManager.h Tue Mar 06 07:38:19 2007 +0000
5.2 +++ b/core/EventManager.h Tue Mar 06 23:59:25 2007 +0000
5.3 @@ -11,8 +11,8 @@
5.4 * Version: $Id$
5.5 */
5.6
5.7 -#ifndef _INCLUDE_SOURCEMOD_CGAMEEVENTMANAGER_H_
5.8 -#define _INCLUDE_SOURCEMOD_CGAMEEVENTMANAGER_H_
5.9 +#ifndef _INCLUDE_SOURCEMOD_EVENTMANAGER_H_
5.10 +#define _INCLUDE_SOURCEMOD_EVENTMANAGER_H_
5.11
5.12 #include "sm_globals.h"
5.13 #include "sourcemm_api.h"
5.14 @@ -109,4 +109,4 @@
5.15
5.16 extern EventManager g_EventManager;
5.17
5.18 -#endif // _INCLUDE_SOURCEMOD_CGAMEEVENTMANAGER_H_
5.19 +#endif // _INCLUDE_SOURCEMOD_EVENTMANAGER_H_
6.1 --- a/core/sm_stringutil.h Tue Mar 06 07:38:19 2007 +0000
6.2 +++ b/core/sm_stringutil.h Tue Mar 06 23:59:25 2007 +0000
6.3 @@ -22,6 +22,8 @@
6.4
6.5 #define LANG_SERVER 0
6.6
6.7 +#define IS_STR_FILLED(var) (var[0] != '\0')
6.8 +
6.9 size_t atcprintf(char *buffer, size_t maxlen, const char *format, IPluginContext *pCtx, const cell_t *params, int *param);
6.10 const char *stristr(const char *str, const char *substr);
6.11 unsigned int strncopy(char *dest, const char *src, size_t count);
7.1 --- a/core/smn_console.cpp Tue Mar 06 07:38:19 2007 +0000
7.2 +++ b/core/smn_console.cpp Tue Mar 06 23:59:25 2007 +0000
7.3 @@ -29,7 +29,7 @@
7.4 // While the engine seems to accept a blank convar name, it causes a crash upon server quit
7.5 if (name == NULL || strcmp(name, "") == 0)
7.6 {
7.7 - return pContext->ThrowNativeError("Null or blank convar name is not allowed");
7.8 + return pContext->ThrowNativeError("Convar with blank name is not permitted");
7.9 }
7.10
7.11 pContext->LocalToString(params[2], &defaultVal);
7.12 @@ -40,7 +40,14 @@
7.13 float min = sp_ctof(params[6]);
7.14 float max = sp_ctof(params[8]);
7.15
7.16 - return g_ConVarManager.CreateConVar(pContext, name, defaultVal, helpText, params[4], hasMin, min, hasMax, max);
7.17 + Handle_t hndl = g_ConVarManager.CreateConVar(pContext, name, defaultVal, helpText, params[4], hasMin, min, hasMax, max);
7.18 +
7.19 + if (hndl == BAD_HANDLE)
7.20 + {
7.21 + return pContext->ThrowNativeError("Convar \"%s\" was not created. A console command with the same name already exists.", name);
7.22 + }
7.23 +
7.24 + return hndl;
7.25 }
7.26
7.27 static cell_t sm_FindConVar(IPluginContext *pContext, const cell_t *params)
7.28 @@ -49,12 +56,6 @@
7.29
7.30 pContext->LocalToString(params[1], &name);
7.31
7.32 - // While the engine seems to accept a blank convar name, it causes a crash upon server quit
7.33 - if (name == NULL || strcmp(name, "") == 0)
7.34 - {
7.35 - return BAD_HANDLE;
7.36 - }
7.37 -
7.38 return g_ConVarManager.FindConVar(name);
7.39 }
7.40
7.41 @@ -70,7 +71,14 @@
7.42 return pContext->ThrowNativeError("Invalid convar handle %x (error %d)", hndl, err);
7.43 }
7.44
7.45 - g_ConVarManager.HookConVarChange(pContext, pConVar, static_cast<funcid_t>(params[2]));
7.46 + IPluginFunction *pFunction = pContext->GetFunctionById(params[2]);
7.47 +
7.48 + if (!pFunction)
7.49 + {
7.50 + return pContext->ThrowNativeError("Invalid function id (%X)", params[2]);
7.51 + }
7.52 +
7.53 + g_ConVarManager.HookConVarChange(pConVar, pFunction);
7.54
7.55 return 1;
7.56 }
7.57 @@ -87,7 +95,14 @@
7.58 return pContext->ThrowNativeError("Invalid convar handle %x (error %d)", hndl, err);
7.59 }
7.60
7.61 - g_ConVarManager.UnhookConVarChange(pContext, pConVar, static_cast<funcid_t>(params[2]));
7.62 + IPluginFunction *pFunction = pContext->GetFunctionById(params[2]);
7.63 +
7.64 + if (!pFunction)
7.65 + {
7.66 + return pContext->ThrowNativeError("Invalid function id (%X)", params[2]);
7.67 + }
7.68 +
7.69 + g_ConVarManager.UnhookConVarChange(pConVar, pFunction);
7.70
7.71 return 1;
7.72 }
8.1 --- a/core/systems/PluginSys.cpp Tue Mar 06 07:38:19 2007 +0000
8.2 +++ b/core/systems/PluginSys.cpp Tue Mar 06 23:59:25 2007 +0000
8.3 @@ -1415,7 +1415,6 @@
8.4 }
8.5 }
8.6
8.7 -#define IS_STR_FILLED(var) (var[0] != '\0')
8.8 void CPluginManager::OnRootConsoleCommand(const char *command, unsigned int argcount)
8.9 {
8.10 if (argcount >= 3)
8.11 @@ -1432,7 +1431,7 @@
8.12 g_RootMenu.ConsolePrint("[SM] No plugins loaded");
8.13 return;
8.14 } else {
8.15 - g_RootMenu.ConsolePrint("[SM] Displaying %d plugin%s:", GetPluginCount(), (plnum > 1) ? "s" : "");
8.16 + g_RootMenu.ConsolePrint("[SM] Listing %d plugin%s:", GetPluginCount(), (plnum > 1) ? "s" : "");
8.17 }
8.18
8.19 IPluginIterator *iter = GetPluginIterator();
9.1 --- a/plugins/include/console.inc Tue Mar 06 07:38:19 2007 +0000
9.2 +++ b/plugins/include/console.inc Tue Mar 06 23:59:25 2007 +0000
9.3 @@ -209,7 +209,7 @@
9.4 *
9.5 * @param name Name of new convar.
9.6 * @param defaultValue String containing the default value of new convar.
9.7 - * @param helpText Optional description of the convar.
9.8 + * @param description Optional description of the convar.
9.9 * @param flags Optional bitstring of flags determining how the convar should be handled. See FCVAR_* constants for more details.
9.10 * @param hasMin Optional boolean that determines if the convar has a minimum value.
9.11 * @param min Minimum floating point value that the convar can have if hasMin is true.
9.12 @@ -218,7 +218,7 @@
9.13 * @return A handle to the newly created convar. If the convar already exists, INVALID_HANDLE is returned.
9.14 * @error Convar name is blank or is the same as an existing console command.
9.15 */
9.16 -native Handle:CreateConVar(const String:name[], const String:defaultValue[], const String:helpText[]="", flags=0, bool:hasMin=false, Float:min=0.0, bool:hasMax=false, Float:max=0.0);
9.17 +native Handle:CreateConVar(const String:name[], const String:defaultValue[], const String:description[]="", flags=0, bool:hasMin=false, Float:min=0.0, bool:hasMax=false, Float:max=0.0);
9.18
9.19 /**
9.20 * Searches for a console variable.
9.21 @@ -236,7 +236,7 @@
9.22 * @param newValue String containing the new value of the convar.
9.23 * @noreturn
9.24 */
9.25 -functag OnConVarChanged public(Handle:convar, const String:oldValue[], const String:newValue[]);
9.26 +functag ConVarChanged public(Handle:convar, const String:oldValue[], const String:newValue[]);
9.27
9.28 /**
9.29 * Creates a hook for when a console variable's value is changed.
9.30 @@ -246,7 +246,7 @@
9.31 * @noreturn
9.32 * @error Invalid or corrupt Handle or invalid callback function.
9.33 */
9.34 -native HookConVarChange(Handle:convar, OnConVarChanged:callback);
9.35 +native HookConVarChange(Handle:convar, ConVarChanged:callback);
9.36
9.37 /**
9.38 * Removes a hook for when a console variable's value is changed.
9.39 @@ -256,7 +256,7 @@
9.40 * @noreturn
9.41 * @error Invalid or corrupt Handle, invalid callback function, or no active hook on convar.
9.42 */
9.43 -native UnhookConVarChange(Handle:convar, OnConVarChanged:callback);
9.44 +native UnhookConVarChange(Handle:convar, ConVarChanged:callback);
9.45
9.46 /**
9.47 * Returns the boolean value of a console variable.