Move scared guts of core into logic (bug 5680, r=fyren).
authorDavid Anderson <dvander@alliedmods.net>
Fri Mar 29 11:37:29 2013 -0700 (2013-03-29)
changeset 38724c93f74cae51
parent 3871 4edce76aefe3
child 3873 a496ff7c2aad
Move scared guts of core into logic (bug 5680, r=fyren).
core/ADTFactory.cpp
core/AMBuilder
core/AdminCache.cpp
core/ConCmdManager.cpp
core/ConVarManager.cpp
core/ConsoleDetours.cpp
core/CoreConfig.cpp
core/Database.cpp
core/Database.h
core/EventManager.cpp
core/ExtensionSys.cpp
core/ExtensionSys.h
core/ForwardSys.cpp
core/HalfLife2.cpp
core/HandleSys.cpp
core/HandleSys.h
core/Logger.cpp
core/Logger.h
core/MenuManager.cpp
core/MenuStyle_Base.cpp
core/NativeInvoker.cpp
core/NativeInvoker.h
core/NativeOwner.cpp
core/NativeOwner.h
core/PlayerManager.cpp
core/PluginSys.cpp
core/PluginSys.h
core/ShareSys.cpp
core/ShareSys.h
core/TimerSys.cpp
core/TimerSys.h
core/UserMessages.cpp
core/UserMessages.h
core/frame_hooks.cpp
core/logic/AMBuilder
core/logic/AutoHandleRooter.h
core/logic/ExtensionSys.cpp
core/logic/ExtensionSys.h
core/logic/HandleSys.cpp
core/logic/HandleSys.h
core/logic/NativeInvoker.cpp
core/logic/NativeInvoker.h
core/logic/NativeOwner.cpp
core/logic/NativeOwner.h
core/logic/PluginSys.cpp
core/logic/PluginSys.h
core/logic/ShareSys.cpp
core/logic/ShareSys.h
core/logic/common_logic.cpp
core/logic/common_logic.h
core/logic/intercom.h
core/logic/msvc10/logic.vcxproj
core/logic/msvc10/logic.vcxproj.filters
core/logic/smn_fakenatives.cpp
core/logic/smn_players.cpp
core/logic_bridge.cpp
core/logic_bridge.h
core/msvc10/sourcemod_mm.vcxproj
core/msvc10/sourcemod_mm.vcxproj.filters
core/msvc11/sourcemod_mm.sln
core/msvc11/sourcemod_mm.vcxproj
core/sm_autonatives.cpp
core/sm_autonatives.h
core/sm_srvcmds.cpp
core/sm_srvcmds.h
core/sm_stringutil.cpp
core/smn_bitbuffer.cpp
core/smn_console.cpp
core/smn_core.cpp
core/smn_database.cpp
core/smn_events.cpp
core/smn_fakenatives.cpp
core/smn_halflife.cpp
core/smn_hudtext.cpp
core/smn_keyvalues.cpp
core/smn_menus.cpp
core/smn_protobuf.cpp
core/smn_usermsgs.cpp
core/sourcemm_api.cpp
core/sourcemod.cpp
public/AutoHandleRooter.h
public/IExtensionSys.h
public/IHandleSys.h
public/ILibrarySys.h
public/IShareSys.h
     1.1 --- a/core/ADTFactory.cpp	Fri Mar 29 12:28:02 2013 -0400
     1.2 +++ b/core/ADTFactory.cpp	Fri Mar 29 11:37:29 2013 -0700
     1.3 @@ -31,7 +31,7 @@
     1.4  
     1.5  #include "ADTFactory.h"
     1.6  #include "sm_globals.h"
     1.7 -#include "ShareSys.h"
     1.8 +#include "logic_bridge.h"
     1.9  
    1.10  ADTFactory g_AdtFactory;
    1.11  
    1.12 @@ -47,7 +47,7 @@
    1.13  
    1.14  void ADTFactory::OnSourceModAllInitialized()
    1.15  {
    1.16 -	g_ShareSys.AddInterface(NULL, this);
    1.17 +	sharesys->AddInterface(NULL, this);
    1.18  }
    1.19  
    1.20  IBasicTrie *ADTFactory::CreateBasicTrie()
     2.1 --- a/core/AMBuilder	Fri Mar 29 12:28:02 2013 -0400
     2.2 +++ b/core/AMBuilder	Fri Mar 29 11:37:29 2013 -0700
     2.3 @@ -50,7 +50,6 @@
     2.4  
     2.5  	files = [
     2.6  		'AdminCache.cpp',
     2.7 -		'ExtensionSys.cpp',
     2.8  		'MenuStyle_Valve.cpp',
     2.9  		'logic_bridge.cpp',
    2.10  		'smn_entities.cpp',
    2.11 @@ -63,19 +62,16 @@
    2.12  		'sm_trie.cpp',
    2.13  		'CDataPack.cpp',
    2.14  		'frame_hooks.cpp',
    2.15 -		'NativeInvoker.cpp',
    2.16  		'smn_fakenatives.cpp',
    2.17  		'smn_nextmap.cpp',
    2.18  		'sourcemm_api.cpp',
    2.19  		'ChatTriggers.cpp',
    2.20 -		'NativeOwner.cpp',
    2.21  		'smn_player.cpp',
    2.22  		'sourcemod.cpp',
    2.23  		'concmd_cleaner.cpp',
    2.24  		'HalfLife2.cpp',
    2.25  		'NextMap.cpp',
    2.26  		'ConCmdManager.cpp',
    2.27 -		'HandleSys.cpp',
    2.28  		'ConVarManager.cpp',
    2.29  		'LibrarySys.cpp',
    2.30  		'PlayerManager.cpp',
    2.31 @@ -83,7 +79,6 @@
    2.32  		'CoreConfig.cpp',
    2.33  		'Logger.cpp',
    2.34  		'smn_halflife.cpp',
    2.35 -		'PluginSys.cpp',
    2.36  		'smn_console.cpp',
    2.37  		'UserMessages.cpp',
    2.38  		'Database.cpp',
    2.39 @@ -92,7 +87,6 @@
    2.40  		'smn_hudtext.cpp',
    2.41  		'smn_usermsgs.cpp',
    2.42  		'MenuStyle_Base.cpp',
    2.43 -		'ShareSys.cpp',
    2.44  		'smn_database.cpp',
    2.45  		'smn_keyvalues.cpp',
    2.46  		'smn_vector.cpp',
     3.1 --- a/core/AdminCache.cpp	Fri Mar 29 12:28:02 2013 -0400
     3.2 +++ b/core/AdminCache.cpp	Fri Mar 29 11:37:29 2013 -0700
     3.3 @@ -33,7 +33,6 @@
     3.4  #include <assert.h>
     3.5  #include <ITextParsers.h>
     3.6  #include "AdminCache.h"
     3.7 -#include "ShareSys.h"
     3.8  #include "ForwardSys.h"
     3.9  #include "PlayerManager.h"
    3.10  #include "ConCmdManager.h"
    3.11 @@ -42,6 +41,7 @@
    3.12  #include "sm_stringutil.h"
    3.13  #include "sourcemm_api.h"
    3.14  #include "sm_srvcmds.h"
    3.15 +#include "logic_bridge.h"
    3.16  
    3.17  #define LEVEL_STATE_NONE		0
    3.18  #define LEVEL_STATE_LEVELS		1
    3.19 @@ -294,7 +294,7 @@
    3.20  void AdminCache::OnSourceModAllInitialized()
    3.21  {
    3.22  	m_pCacheFwd = g_Forwards.CreateForward("OnRebuildAdminCache", ET_Ignore, 1, NULL, Param_Cell);
    3.23 -	g_ShareSys.AddInterface(NULL, this);
    3.24 +	sharesys->AddInterface(NULL, this);
    3.25  }
    3.26  
    3.27  void AdminCache::OnSourceModLevelChange(const char *mapName)
     4.1 --- a/core/ConCmdManager.cpp	Fri Mar 29 12:28:02 2013 -0400
     4.2 +++ b/core/ConCmdManager.cpp	Fri Mar 29 11:37:29 2013 -0700
     4.3 @@ -73,13 +73,14 @@
     4.4  
     4.5  void ConCmdManager::OnSourceModAllInitialized()
     4.6  {
     4.7 -	g_PluginSys.AddPluginsListener(this);
     4.8 +	scripts->AddPluginsListener(this);
     4.9  	g_RootMenu.AddRootConsoleCommand("cmds", "List console commands", this);
    4.10  	SH_ADD_HOOK(IServerGameClients, SetCommandClient, serverClients, SH_MEMBER(this, &ConCmdManager::SetCommandClient), false);
    4.11  }
    4.12  
    4.13  void ConCmdManager::OnSourceModShutdown()
    4.14  {
    4.15 +	scripts->RemovePluginsListener(this);
    4.16  	/* All commands should already be removed by the time we're done */
    4.17  	SH_REMOVE_HOOK(IServerGameClients, SetCommandClient, serverClients, SH_MEMBER(this, &ConCmdManager::SetCommandClient), false);
    4.18  	g_RootMenu.RemoveRootConsoleCommand("cmds", this);
    4.19 @@ -109,7 +110,7 @@
    4.20  	{
    4.21  		CmdHook *pHook = (*iter);
    4.22  		IPluginContext *pContext = pHook->pf->GetParentContext();
    4.23 -		IPlugin *pPlugin = g_PluginSys.GetPluginByCtx(pContext->GetContext());
    4.24 +		IPlugin *pPlugin = scripts->FindPluginByContext(pContext->GetContext());
    4.25  		CmdList *pList = NULL;
    4.26  		
    4.27  		//gaben
    4.28 @@ -623,7 +624,7 @@
    4.29  
    4.30  	/* Now add to the plugin */
    4.31  	CmdList *pList;
    4.32 -	IPlugin *pPlugin = g_PluginSys.GetPluginByCtx(pFunction->GetParentContext()->GetContext());
    4.33 +	IPlugin *pPlugin = scripts->FindPluginByContext(pFunction->GetParentContext()->GetContext());
    4.34  	if (!pPlugin->GetProperty("CommandList", (void **)&pList))
    4.35  	{
    4.36  		pList = new CmdList();
    4.37 @@ -663,7 +664,7 @@
    4.38  
    4.39  	/* Add to the plugin */
    4.40  	CmdList *pList;
    4.41 -	IPlugin *pPlugin = g_PluginSys.GetPluginByCtx(pFunction->GetParentContext()->GetContext());
    4.42 +	IPlugin *pPlugin = scripts->FindPluginByContext(pFunction->GetParentContext()->GetContext());
    4.43  	if (!pPlugin->GetProperty("CommandList", (void **)&pList))
    4.44  	{
    4.45  		pList = new CmdList();
    4.46 @@ -915,7 +916,7 @@
    4.47  	{
    4.48  		const char *text = command.Arg(2);
    4.49  
    4.50 -		CPlugin *pPlugin = g_PluginSys.FindPluginByConsoleArg(text);
    4.51 +		IPlugin *pPlugin = scripts->FindPluginByConsoleArg(text);
    4.52  
    4.53  		if (!pPlugin)
    4.54  		{
     5.1 --- a/core/ConVarManager.cpp	Fri Mar 29 12:28:02 2013 -0400
     5.2 +++ b/core/ConVarManager.cpp	Fri Mar 29 11:37:29 2013 -0700
     5.3 @@ -29,13 +29,12 @@
     5.4  
     5.5  #include "ConVarManager.h"
     5.6  #include "HalfLife2.h"
     5.7 -#include "PluginSys.h"
     5.8  #include "ForwardSys.h"
     5.9 -#include "HandleSys.h"
    5.10  #include "sm_srvcmds.h"
    5.11  #include "sm_stringutil.h"
    5.12  #include <sh_vector.h>
    5.13  #include <sm_trie_tpl.h>
    5.14 +#include "logic_bridge.h"
    5.15  
    5.16  ConVarManager g_ConVarManager;
    5.17  
    5.18 @@ -106,7 +105,7 @@
    5.19  	sec.access[HandleAccess_Clone] = HANDLE_RESTRICT_IDENTITY | HANDLE_RESTRICT_OWNER;
    5.20  
    5.21  	/* Create the 'ConVar' handle type */
    5.22 -	m_ConVarType = g_HandleSys.CreateType("ConVar", this, 0, NULL, &sec, g_pCoreIdent, NULL);
    5.23 +	m_ConVarType = handlesys->CreateType("ConVar", this, 0, NULL, &sec, g_pCoreIdent, NULL);
    5.24  }
    5.25  
    5.26  void ConVarManager::OnSourceModAllInitialized()
    5.27 @@ -128,7 +127,7 @@
    5.28  	SH_ADD_HOOK(ICvar, CallGlobalChangeCallback, icvar, SH_STATIC(OnConVarChanged), false);
    5.29  #endif
    5.30  
    5.31 -	g_PluginSys.AddPluginsListener(this);
    5.32 +	scripts->AddPluginsListener(this);
    5.33  
    5.34  	/* Add the 'convars' option to the 'sm' console command */
    5.35  	g_RootMenu.AddRootConsoleCommand("cvars", "View convars created by a plugin", this);
    5.36 @@ -146,7 +145,7 @@
    5.37  
    5.38  		iter = m_ConVars.erase(iter);
    5.39  
    5.40 -		g_HandleSys.FreeHandle(pInfo->handle, &sec);
    5.41 +		handlesys->FreeHandle(pInfo->handle, &sec);
    5.42  		if (pInfo->pChangeForward != NULL)
    5.43  		{
    5.44  			g_Forwards.ReleaseForward(pInfo->pChangeForward);
    5.45 @@ -200,10 +199,10 @@
    5.46  	/* Remove the 'convars' option from the 'sm' console command */
    5.47  	g_RootMenu.RemoveRootConsoleCommand("cvars", this);
    5.48  
    5.49 -	g_PluginSys.RemovePluginsListener(this);
    5.50 +	scripts->RemovePluginsListener(this);
    5.51  
    5.52  	/* Remove the 'ConVar' handle type */
    5.53 -	g_HandleSys.RemoveType(m_ConVarType, g_pCoreIdent);
    5.54 +	handlesys->RemoveType(m_ConVarType, g_pCoreIdent);
    5.55  }
    5.56  
    5.57  /**
    5.58 @@ -269,7 +268,7 @@
    5.59  	convar_cache.remove(name);
    5.60  
    5.61  	/* Now make sure no plugins are referring to this pointer */
    5.62 -	IPluginIterator *pl_iter = g_PluginSys.GetPluginIterator();
    5.63 +	IPluginIterator *pl_iter = scripts->GetPluginIterator();
    5.64  	while (pl_iter->MorePlugins())
    5.65  	{
    5.66  		IPlugin *pl = pl_iter->GetPlugin();
    5.67 @@ -285,7 +284,7 @@
    5.68  	}
    5.69  
    5.70  	/* Free resources */
    5.71 -	g_HandleSys.FreeHandle(pInfo->handle, &sec);
    5.72 +	handlesys->FreeHandle(pInfo->handle, &sec);
    5.73  	delete pInfo;
    5.74  }
    5.75  
    5.76 @@ -337,7 +336,7 @@
    5.77  		}
    5.78  		
    5.79  		/* Get plugin object */
    5.80 -		CPlugin *plugin = g_PluginSys.FindPluginByConsoleArg(arg);
    5.81 +		IPlugin *plugin = scripts->FindPluginByConsoleArg(arg);
    5.82  
    5.83  		if (!plugin)
    5.84  		{
    5.85 @@ -418,7 +417,7 @@
    5.86  			pInfo->pVar = pConVar;
    5.87  
    5.88  			/* If we don't, then create a new handle from the convar */
    5.89 -			hndl = g_HandleSys.CreateHandle(m_ConVarType, pInfo, NULL, g_pCoreIdent, NULL);
    5.90 +			hndl = handlesys->CreateHandle(m_ConVarType, pInfo, NULL, g_pCoreIdent, NULL);
    5.91  			if (hndl == BAD_HANDLE)
    5.92  			{
    5.93  				delete pInfo;
    5.94 @@ -449,7 +448,7 @@
    5.95  	pInfo->pChangeForward = NULL;
    5.96  
    5.97  	/* Create a handle from the new convar */
    5.98 -	hndl = g_HandleSys.CreateHandle(m_ConVarType, pInfo, NULL, g_pCoreIdent, NULL);
    5.99 +	hndl = handlesys->CreateHandle(m_ConVarType, pInfo, NULL, g_pCoreIdent, NULL);
   5.100  	if (hndl == BAD_HANDLE)
   5.101  	{
   5.102  		delete pInfo;
   5.103 @@ -500,7 +499,7 @@
   5.104  	pInfo->pVar = pConVar;
   5.105  
   5.106  	/* If we don't have a handle, then create a new one */
   5.107 -	hndl = g_HandleSys.CreateHandle(m_ConVarType, pInfo, NULL, g_pCoreIdent, NULL);
   5.108 +	hndl = handlesys->CreateHandle(m_ConVarType, pInfo, NULL, g_pCoreIdent, NULL);
   5.109  	if (hndl == BAD_HANDLE)
   5.110  	{
   5.111  		delete pInfo;
   5.112 @@ -639,7 +638,7 @@
   5.113  	bool inserted = false;
   5.114  	const char *orig = pConVar->GetName();
   5.115  
   5.116 -	IPlugin *plugin = g_PluginSys.FindPluginByContext(pContext->GetContext());
   5.117 +	IPlugin *plugin = scripts->FindPluginByContext(pContext->GetContext());
   5.118  
   5.119  	/* Check plugin for an existing convar list */
   5.120  	if (!plugin->GetProperty("ConVarList", (void **)&pConVarList))
   5.121 @@ -772,7 +771,7 @@
   5.122  	ConVarInfo *pInfo;
   5.123  	HandleError error;
   5.124  	
   5.125 -	if ((error = g_HandleSys.ReadHandle(hndl, m_ConVarType, NULL, (void **)&pInfo)) != HandleError_None)
   5.126 +	if ((error = handlesys->ReadHandle(hndl, m_ConVarType, NULL, (void **)&pInfo)) != HandleError_None)
   5.127  	{
   5.128  		return error;
   5.129  	}
     6.1 --- a/core/ConsoleDetours.cpp	Fri Mar 29 12:28:02 2013 -0400
     6.2 +++ b/core/ConsoleDetours.cpp	Fri Mar 29 11:37:29 2013 -0700
     6.3 @@ -49,7 +49,7 @@
     6.4  #include "ConCmdManager.h"
     6.5  #include "HalfLife2.h"
     6.6  #include "ConCommandBaseIterator.h"
     6.7 -#include "ShareSys.h"
     6.8 +#include "logic_bridge.h"
     6.9  
    6.10  #if defined PLATFORM_POSIX
    6.11  # include <dlfcn.h>
    6.12 @@ -576,7 +576,7 @@
    6.13  {
    6.14  	m_pForward = g_Forwards.CreateForwardEx("OnAnyCommand", ET_Hook, 3, NULL, Param_Cell,
    6.15  	                                        Param_String, Param_Cell);
    6.16 -	g_ShareSys.AddCapabilityProvider(NULL, this, FEATURECAP_COMMANDLISTENER);
    6.17 +	sharesys->AddCapabilityProvider(NULL, this, FEATURECAP_COMMANDLISTENER);
    6.18  }
    6.19  
    6.20  void ConsoleDetours::OnSourceModShutdown()
     7.1 --- a/core/CoreConfig.cpp	Fri Mar 29 12:28:02 2013 -0400
     7.2 +++ b/core/CoreConfig.cpp	Fri Mar 29 11:37:29 2013 -0700
     7.3 @@ -38,9 +38,9 @@
     7.4  #include "sm_stringutil.h"
     7.5  #include "LibrarySys.h"
     7.6  #include "Logger.h"
     7.7 -#include "PluginSys.h"
     7.8  #include "ForwardSys.h"
     7.9  #include "frame_hooks.h"
    7.10 +#include "logic_bridge.h"
    7.11  
    7.12  #ifdef PLATFORM_WINDOWS
    7.13  ConVar sm_corecfgfile("sm_corecfgfile", "addons\\sourcemod\\configs\\core.cfg", 0, "SourceMod core configuration file");
    7.14 @@ -321,7 +321,7 @@
    7.15  #endif
    7.16  }
    7.17  
    7.18 -bool SM_ExecuteConfig(CPlugin *pl, AutoConfig *cfg, bool can_create)
    7.19 +bool SM_ExecuteConfig(IPlugin *pl, AutoConfig *cfg, bool can_create)
    7.20  {
    7.21  	bool will_create = false;
    7.22  	
    7.23 @@ -500,10 +500,10 @@
    7.24  
    7.25  void SM_ConfigsExecuted_Plugin(unsigned int serial)
    7.26  {
    7.27 -	IPluginIterator *iter = g_PluginSys.GetPluginIterator();
    7.28 +	IPluginIterator *iter = scripts->GetPluginIterator();
    7.29  	while (iter->MorePlugins())
    7.30  	{
    7.31 -		CPlugin *plugin = (CPlugin *)(iter->GetPlugin());
    7.32 +		IPlugin *plugin = iter->GetPlugin();
    7.33  		if (plugin->GetSerial() == serial)
    7.34  		{
    7.35  			SM_DoSingleExecFwds(plugin->GetBaseContext());
    7.36 @@ -516,7 +516,7 @@
    7.37  
    7.38  void SM_ExecuteForPlugin(IPluginContext *ctx)
    7.39  {
    7.40 -	CPlugin *plugin = (CPlugin *)g_PluginSys.GetPluginByCtx(ctx->GetContext());
    7.41 +	SMPlugin *plugin = scripts->FindPluginByContext(ctx->GetContext());
    7.42  
    7.43  	unsigned int num = plugin->GetConfigCount();
    7.44  	if (!num)
    7.45 @@ -545,19 +545,18 @@
    7.46  
    7.47  	engine->ServerCommand("exec sourcemod/sourcemod.cfg\n");
    7.48  
    7.49 -	IPluginIterator *iter = g_PluginSys.GetPluginIterator();
    7.50 -	while (iter->MorePlugins())
    7.51 +	CVector<SMPlugin *> plugins;
    7.52 +	scripts->ListPlugins(&plugins);
    7.53 +	for (size_t i = 0; i < plugins.size(); i++)
    7.54  	{
    7.55 -		CPlugin *plugin = (CPlugin *)(iter->GetPlugin());
    7.56 +		SMPlugin *plugin = plugins[i];
    7.57  		unsigned int num = plugin->GetConfigCount();
    7.58  		bool can_create = true;
    7.59  		for (unsigned int i=0; i<num; i++)
    7.60  		{
    7.61  			can_create = SM_ExecuteConfig(plugin, plugin->GetConfig(i), can_create);
    7.62  		}
    7.63 -		iter->NextPlugin();
    7.64  	}
    7.65 -	iter->Release();
    7.66  
    7.67  	g_bGotServerStart = true;
    7.68  	CheckAndFinalizeConfigs();
     8.1 --- a/core/Database.cpp	Fri Mar 29 12:28:02 2013 -0400
     8.2 +++ b/core/Database.cpp	Fri Mar 29 11:37:29 2013 -0700
     8.3 @@ -30,14 +30,12 @@
     8.4   */
     8.5  
     8.6  #include "Database.h"
     8.7 -#include "HandleSys.h"
     8.8 -#include "ShareSys.h"
     8.9  #include "sourcemod.h"
    8.10  #include "sm_stringutil.h"
    8.11  #include "Logger.h"
    8.12 -#include "ExtensionSys.h"
    8.13  #include <stdlib.h>
    8.14  #include <IThreader.h>
    8.15 +#include "logic_bridge.h"
    8.16  
    8.17  #define DBPARSE_LEVEL_NONE		0
    8.18  #define DBPARSE_LEVEL_MAIN		1
    8.19 @@ -55,14 +53,14 @@
    8.20  {
    8.21  	HandleAccess sec;
    8.22  
    8.23 -	g_HandleSys.InitAccessDefaults(NULL, &sec);
    8.24 +	handlesys->InitAccessDefaults(NULL, &sec);
    8.25  	sec.access[HandleAccess_Delete] |= HANDLE_RESTRICT_IDENTITY;
    8.26  	sec.access[HandleAccess_Clone] |= HANDLE_RESTRICT_IDENTITY;
    8.27  	
    8.28 -	m_DriverType = g_HandleSys.CreateType("IDriver", this, 0, NULL, &sec, g_pCoreIdent, NULL);
    8.29 -	m_DatabaseType = g_HandleSys.CreateType("IDatabase", this, 0, NULL, NULL, g_pCoreIdent, NULL);
    8.30 +	m_DriverType = handlesys->CreateType("IDriver", this, 0, NULL, &sec, g_pCoreIdent, NULL);
    8.31 +	m_DatabaseType = handlesys->CreateType("IDatabase", this, 0, NULL, NULL, g_pCoreIdent, NULL);
    8.32  
    8.33 -	g_ShareSys.AddInterface(NULL, this);
    8.34 +	sharesys->AddInterface(NULL, this);
    8.35  
    8.36  	g_SourceMod.BuildPath(Path_SM, m_Filename, sizeof(m_Filename), "configs/databases.cfg");
    8.37  
    8.38 @@ -70,7 +68,7 @@
    8.39  	m_pThinkLock = g_pThreader->MakeMutex();
    8.40  	m_pQueueLock = g_pThreader->MakeMutex();
    8.41  
    8.42 -	g_PluginSys.AddPluginsListener(this);
    8.43 +	scripts->AddPluginsListener(this);
    8.44  }
    8.45  
    8.46  void DBManager::OnSourceModLevelChange(const char *mapName)
    8.47 @@ -98,12 +96,12 @@
    8.48  void DBManager::OnSourceModShutdown()
    8.49  {
    8.50  	KillWorkerThread();
    8.51 -	g_PluginSys.RemovePluginsListener(this);
    8.52 +	scripts->RemovePluginsListener(this);
    8.53  	m_pConfigLock->DestroyThis();
    8.54  	m_pThinkLock->DestroyThis();
    8.55  	m_pQueueLock->DestroyThis();
    8.56 -	g_HandleSys.RemoveType(m_DatabaseType, g_pCoreIdent);
    8.57 -	g_HandleSys.RemoveType(m_DriverType, g_pCoreIdent);
    8.58 +	handlesys->RemoveType(m_DatabaseType, g_pCoreIdent);
    8.59 +	handlesys->RemoveType(m_DriverType, g_pCoreIdent);
    8.60  	ClearConfigs();
    8.61  }
    8.62  
    8.63 @@ -125,7 +123,7 @@
    8.64  		return;
    8.65  	}
    8.66  
    8.67 -	if (g_HandleSys.TypeCheck(type, m_DatabaseType))
    8.68 +	if (handlesys->TypeCheck(type, m_DatabaseType))
    8.69  	{
    8.70  		IDatabase *pdb = (IDatabase *)object;
    8.71  		pdb->Close();
    8.72 @@ -402,7 +400,7 @@
    8.73  		return BAD_HANDLE;
    8.74  	}
    8.75  
    8.76 -	return g_HandleSys.CreateHandle(type, ptr, pToken, g_pCoreIdent, NULL);
    8.77 +	return handlesys->CreateHandle(type, ptr, pToken, g_pCoreIdent, NULL);
    8.78  }
    8.79  
    8.80  HandleError DBManager::ReadHandle(Handle_t hndl, DBHandleType dtype, void **ptr)
    8.81 @@ -420,13 +418,13 @@
    8.82  
    8.83  	HandleSecurity sec(NULL, g_pCoreIdent);
    8.84  
    8.85 -	return g_HandleSys.ReadHandle(hndl, type, &sec, ptr);
    8.86 +	return handlesys->ReadHandle(hndl, type, &sec, ptr);
    8.87  }
    8.88  
    8.89  HandleError DBManager::ReleaseHandle(Handle_t hndl, DBHandleType type, IdentityToken_t *token)
    8.90  {
    8.91  	HandleSecurity sec(token, g_pCoreIdent);
    8.92 -	return g_HandleSys.FreeHandle(hndl, &sec);
    8.93 +	return handlesys->FreeHandle(hndl, &sec);
    8.94  }
    8.95  
    8.96  unsigned int DBManager::GetDriverCount()
    8.97 @@ -485,7 +483,7 @@
    8.98  	char filename[PLATFORM_MAX_PATH];
    8.99  	UTIL_Format(filename, sizeof(filename), "dbi.%s.ext", name);
   8.100  
   8.101 -	IExtension *pExt = g_Extensions.LoadAutoExtension(filename);
   8.102 +	IExtension *pExt = extsys->LoadAutoExtension(filename);
   8.103  	if (!pExt || !pExt->IsLoaded() || m_drivers.size() <= last_size)
   8.104  	{
   8.105  		return NULL;
   8.106 @@ -729,6 +727,6 @@
   8.107  
   8.108  void DBManager::AddDependency(IExtension *myself, IDBDriver *driver)
   8.109  {
   8.110 -	g_Extensions.AddRawDependency(myself, driver->GetIdentity(), driver);
   8.111 +	extsys->AddRawDependency(myself, driver->GetIdentity(), driver);
   8.112  }
   8.113  
     9.1 --- a/core/Database.h	Fri Mar 29 12:28:02 2013 -0400
     9.2 +++ b/core/Database.h	Fri Mar 29 11:37:29 2013 -0700
     9.3 @@ -40,8 +40,8 @@
     9.4  #include <ITextParsers.h>
     9.5  #include "sm_memtable.h"
     9.6  #include <IThreader.h>
     9.7 +#include <IPluginSys.h>
     9.8  #include "sm_simple_prioqueue.h"
     9.9 -#include "PluginSys.h"
    9.10  
    9.11  using namespace SourceHook;
    9.12  
    10.1 --- a/core/EventManager.cpp	Fri Mar 29 12:28:02 2013 -0400
    10.2 +++ b/core/EventManager.cpp	Fri Mar 29 11:37:29 2013 -0700
    10.3 @@ -31,9 +31,8 @@
    10.4  
    10.5  #include "EventManager.h"
    10.6  #include "ForwardSys.h"
    10.7 -#include "HandleSys.h"
    10.8 -#include "PluginSys.h"
    10.9  #include "sm_stringutil.h"
   10.10 +#include "logic_bridge.h"
   10.11  
   10.12  EventManager g_EventManager;
   10.13  
   10.14 @@ -90,7 +89,7 @@
   10.15  	sec.access[HandleAccess_Clone] = HANDLE_RESTRICT_IDENTITY | HANDLE_RESTRICT_OWNER;
   10.16  
   10.17  	/* Create the 'GameEvent' handle type */
   10.18 -	m_EventType = g_HandleSys.CreateType("GameEvent", this, 0, NULL, &sec, g_pCoreIdent, NULL);
   10.19 +	m_EventType = handlesys->CreateType("GameEvent", this, 0, NULL, &sec, g_pCoreIdent, NULL);
   10.20  }
   10.21  
   10.22  void EventManager::OnSourceModShutdown()
   10.23 @@ -100,7 +99,7 @@
   10.24  	SH_REMOVE_HOOK(IGameEventManager2, FireEvent, gameevents, SH_MEMBER(this, &EventManager::OnFireEvent_Post), true);
   10.25  
   10.26  	/* Remove the 'GameEvent' handle type */
   10.27 -	g_HandleSys.RemoveType(m_EventType, g_pCoreIdent);
   10.28 +	handlesys->RemoveType(m_EventType, g_pCoreIdent);
   10.29  
   10.30  	/* Remove ourselves as listener for events */
   10.31  	gameevents->RemoveListener(this);
   10.32 @@ -187,7 +186,7 @@
   10.33  	if (!sm_trie_retrieve(m_EventHooks, name, (void **)&pHook))
   10.34  	{
   10.35  		EventHookList *pHookList;
   10.36 -		IPlugin *plugin = g_PluginSys.GetPluginByCtx(pFunction->GetParentContext()->GetContext());
   10.37 +		IPlugin *plugin = scripts->FindPluginByContext(pFunction->GetParentContext()->GetContext());
   10.38  
   10.39  		/* Check plugin for an existing EventHook list */
   10.40  		if (!plugin->GetProperty("EventHooks", (void **)&pHookList))
   10.41 @@ -300,7 +299,7 @@
   10.42  		/* If reference count is now 0, free hook structure */
   10.43  
   10.44  		EventHookList *pHookList;
   10.45 -		IPlugin *plugin = g_PluginSys.GetPluginByCtx(pFunction->GetParentContext()->GetContext());
   10.46 +		IPlugin *plugin = scripts->FindPluginByContext(pFunction->GetParentContext()->GetContext());
   10.47  
   10.48  		/* Get plugin's event hook list */
   10.49  		if (!plugin->GetProperty("EventHooks", (void**)&pHookList))
   10.50 @@ -411,7 +410,7 @@
   10.51  		{
   10.52  			EventInfo info(pEvent, NULL);
   10.53  			HandleSecurity sec(NULL, g_pCoreIdent);
   10.54 -			Handle_t hndl = g_HandleSys.CreateHandle(m_EventType, &info, NULL, g_pCoreIdent, NULL);
   10.55 +			Handle_t hndl = handlesys->CreateHandle(m_EventType, &info, NULL, g_pCoreIdent, NULL);
   10.56  
   10.57  			info.bDontBroadcast = bDontBroadcast;
   10.58  
   10.59 @@ -424,7 +423,7 @@
   10.60  
   10.61  			broadcast = info.bDontBroadcast;
   10.62  
   10.63 -			g_HandleSys.FreeHandle(hndl, &sec);
   10.64 +			handlesys->FreeHandle(hndl, &sec);
   10.65  		}
   10.66  
   10.67  		if (pHook->postCopy)
   10.68 @@ -476,7 +475,7 @@
   10.69  				info.bDontBroadcast = bDontBroadcast;
   10.70  				info.pEvent = m_EventCopies.front();
   10.71  				info.pOwner = NULL;
   10.72 -				hndl = g_HandleSys.CreateHandle(m_EventType, &info, NULL, g_pCoreIdent, NULL);
   10.73 +				hndl = handlesys->CreateHandle(m_EventType, &info, NULL, g_pCoreIdent, NULL);
   10.74  
   10.75  				pForward->PushCell(hndl);
   10.76  			} else {
   10.77 @@ -491,7 +490,7 @@
   10.78  			{
   10.79  				/* Free handle */
   10.80  				HandleSecurity sec(NULL, g_pCoreIdent);
   10.81 -				g_HandleSys.FreeHandle(hndl, &sec);
   10.82 +				handlesys->FreeHandle(hndl, &sec);
   10.83  
   10.84  				/* Free event structure */
   10.85  				gameevents->FreeEvent(info.pEvent);
    11.1 --- a/core/ExtensionSys.cpp	Fri Mar 29 12:28:02 2013 -0400
    11.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.3 @@ -1,1487 +0,0 @@
    11.4 -/**
    11.5 - * vim: set ts=4 sw=4 tw=99 noet :
    11.6 - * =============================================================================
    11.7 - * SourceMod
    11.8 - * Copyright (C) 2004-2010 AlliedModders LLC.  All rights reserved.
    11.9 - * =============================================================================
   11.10 - *
   11.11 - * This program is free software; you can redistribute it and/or modify it under
   11.12 - * the terms of the GNU General Public License, version 3.0, as published by the
   11.13 - * Free Software Foundation.
   11.14 - * 
   11.15 - * This program is distributed in the hope that it will be useful, but WITHOUT
   11.16 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   11.17 - * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
   11.18 - * details.
   11.19 - *
   11.20 - * You should have received a copy of the GNU General Public License along with
   11.21 - * this program.  If not, see <http://www.gnu.org/licenses/>.
   11.22 - *
   11.23 - * As a special exception, AlliedModders LLC gives you permission to link the
   11.24 - * code of this program (as well as its derivative works) to "Half-Life 2," the
   11.25 - * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
   11.26 - * by the Valve Corporation.  You must obey the GNU General Public License in
   11.27 - * all respects for all other code used.  Additionally, AlliedModders LLC grants
   11.28 - * this exception to all derivative works.  AlliedModders LLC defines further
   11.29 - * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
   11.30 - * or <http://www.sourcemod.net/license.php>.
   11.31 - *
   11.32 - * Version: $Id$
   11.33 - */
   11.34 -
   11.35 -#include <stdlib.h>
   11.36 -#include "ExtensionSys.h"
   11.37 -#include "LibrarySys.h"
   11.38 -#include "ShareSys.h"
   11.39 -#include "Logger.h"
   11.40 -#include "sourcemm_api.h"
   11.41 -#include "sm_srvcmds.h"
   11.42 -#include "sm_stringutil.h"
   11.43 -#include "PlayerManager.h"
   11.44 -
   11.45 -CExtensionManager g_Extensions;
   11.46 -IdentityType_t g_ExtType;
   11.47 -
   11.48 -void CExtension::Initialize(const char *filename, const char *path)
   11.49 -{
   11.50 -	m_pAPI = NULL;
   11.51 -	m_pIdentToken = NULL;
   11.52 -	unload_code = 0;
   11.53 -	m_bFullyLoaded = false;
   11.54 -	m_File.assign(filename);
   11.55 -	m_Path.assign(path);
   11.56 -	char real_name[PLATFORM_MAX_PATH];
   11.57 -	g_LibSys.GetFileFromPath(real_name, sizeof(real_name), m_Path.c_str());
   11.58 -	m_RealFile.assign(real_name);
   11.59 -}
   11.60 -
   11.61 -CRemoteExtension::CRemoteExtension(IExtensionInterface *pAPI, const char *filename, const char *path)
   11.62 -{
   11.63 -	Initialize(filename, path);
   11.64 -	m_pAPI = pAPI;
   11.65 -}
   11.66 -
   11.67 -#if defined METAMOD_PLAPI_VERSION
   11.68 -#if SOURCE_ENGINE == SE_LEFT4DEAD
   11.69 -#define GAMEFIX "2.l4d"
   11.70 -#elif SOURCE_ENGINE == SE_LEFT4DEAD2
   11.71 -#define GAMEFIX "2.l4d2"
   11.72 -#elif SOURCE_ENGINE == SE_ALIENSWARM
   11.73 -#define GAMEFIX "2.swarm"
   11.74 -#elif SOURCE_ENGINE == SE_ORANGEBOX
   11.75 -#define GAMEFIX "2.ep2"
   11.76 -#elif SOURCE_ENGINE == SE_BLOODYGOODTIME
   11.77 -#define GAMEFIX "2.bgt"
   11.78 -#elif SOURCE_ENGINE == SE_EYE
   11.79 -#define GAMEFIX "2.eye"
   11.80 -#elif SOURCE_ENGINE == SE_CSS
   11.81 -#define GAMEFIX "2.css"
   11.82 -#elif SOURCE_ENGINE == SE_ORANGEBOXVALVE
   11.83 -#define GAMEFIX "2.ep2v"
   11.84 -#elif SOURCE_ENGINE == SE_DARKMESSIAH
   11.85 -#define GAMEFIX "2.darkm"
   11.86 -#elif SOURCE_ENGINE == SE_PORTAL2
   11.87 -#define GAMEFIX "2.portal2"
   11.88 -#elif SOURCE_ENGINE == SE_CSGO
   11.89 -#define GAMEFIX "2.csgo"
   11.90 -#elif SOURCE_ENGINE == SE_DOTA
   11.91 -#define GAMEFIX "2.dota"
   11.92 -#else
   11.93 -#define GAMEFIX "2.ep1"
   11.94 -#endif //(SOURCE_ENGINE == SE_LEFT4DEAD) || (SOURCE_ENGINE == SE_LEFT4DEAD2)
   11.95 -#else  //METAMOD_PLAPI_VERSION
   11.96 -#define GAMEFIX "1.ep1"
   11.97 -#endif //METAMOD_PLAPI_VERSION
   11.98 -
   11.99 -CLocalExtension::CLocalExtension(const char *filename)
  11.100 -{
  11.101 -	m_PlId = 0;
  11.102 -	m_pLib = NULL;
  11.103 -
  11.104 -	char path[PLATFORM_MAX_PATH];
  11.105 -
  11.106 -	/* Special case for new bintools binary */
  11.107 -	if (strcmp(filename, "bintools.ext") == 0)
  11.108 -	{
  11.109 -		goto normal;
  11.110 -	}
  11.111 -
  11.112 -	/* Zeroth, see if there is an engine specific build in the new place. */
  11.113 -	g_SourceMod.BuildPath(Path_SM,
  11.114 -		path,
  11.115 -		PLATFORM_MAX_PATH,
  11.116 -		"extensions/%s." GAMEFIX "." PLATFORM_LIB_EXT,
  11.117 -		filename);
  11.118 -
  11.119 -	if (g_LibSys.IsPathFile(path))
  11.120 -	{
  11.121 -		goto found;
  11.122 -	}
  11.123 -
  11.124 -	/* First see if there is an engine specific build! */
  11.125 -	g_SourceMod.BuildPath(Path_SM, 
  11.126 -		path, 
  11.127 -		PLATFORM_MAX_PATH,
  11.128 -		"extensions/auto." GAMEFIX "/%s." PLATFORM_LIB_EXT,
  11.129 -		filename);
  11.130 -
  11.131 -	/* Try the "normal" version */
  11.132 -	if (!g_LibSys.IsPathFile(path))
  11.133 -	{
  11.134 -		normal:
  11.135 -		g_SourceMod.BuildPath(Path_SM,
  11.136 -			path,
  11.137 -			PLATFORM_MAX_PATH,
  11.138 -			"extensions/%s." PLATFORM_LIB_EXT,
  11.139 -			filename);
  11.140 -	}
  11.141 -
  11.142 -found:
  11.143 -	Initialize(filename, path);
  11.144 -}
  11.145 -
  11.146 -bool CRemoteExtension::Load(char *error, size_t maxlength)
  11.147 -{
  11.148 -	if (!PerformAPICheck(error, maxlength))
  11.149 -	{
  11.150 -		m_pAPI = NULL;
  11.151 -		return false;
  11.152 -	}
  11.153 -
  11.154 -	if (!CExtension::Load(error, maxlength))
  11.155 -	{
  11.156 -		m_pAPI = NULL;
  11.157 -		return false;
  11.158 -	}
  11.159 -
  11.160 -	return true;
  11.161 -}
  11.162 -
  11.163 -bool CLocalExtension::Load(char *error, size_t maxlength)
  11.164 -{
  11.165 -	m_pLib = g_LibSys.OpenLibrary(m_Path.c_str(), error, maxlength);
  11.166 -
  11.167 -	if (m_pLib == NULL)
  11.168 -	{
  11.169 -		return false;
  11.170 -	}
  11.171 -
  11.172 -	typedef IExtensionInterface *(*GETAPI)();
  11.173 -	GETAPI pfnGetAPI = NULL;
  11.174 -
  11.175 -	if ((pfnGetAPI=(GETAPI)m_pLib->GetSymbolAddress("GetSMExtAPI")) == NULL)
  11.176 -	{
  11.177 -		m_pLib->CloseLibrary();
  11.178 -		m_pLib = NULL;
  11.179 -		snprintf(error, maxlength, "Unable to find extension entry point");
  11.180 -		return false;
  11.181 -	}
  11.182 -
  11.183 -	m_pAPI = pfnGetAPI();
  11.184 -
  11.185 -	/* Check pointer and version */
  11.186 -	if (!PerformAPICheck(error, maxlength))
  11.187 -	{
  11.188 -		m_pLib->CloseLibrary();
  11.189 -		m_pLib = NULL;
  11.190 -		m_pAPI = NULL;
  11.191 -		return false;
  11.192 -	}
  11.193 -
  11.194 -	/* Load as MM:S */
  11.195 -	if (m_pAPI->IsMetamodExtension())
  11.196 -	{
  11.197 -		bool already;
  11.198 -		m_PlId = g_pMMPlugins->Load(m_Path.c_str(), g_PLID, already, error, maxlength);
  11.199 -
  11.200 -		// Check the plugin didn't refuse load
  11.201 -		Pl_Status status;
  11.202 -		
  11.203 -#ifndef METAMOD_PLAPI_VERSION
  11.204 -		const char *file;
  11.205 -		PluginId source;
  11.206 -#endif
  11.207 -		
  11.208 -		if (!m_PlId || (
  11.209 -#ifndef METAMOD_PLAPI_VERSION
  11.210 -			g_pMMPlugins->Query(m_PlId, file, status, source)
  11.211 -#else
  11.212 -			g_pMMPlugins->Query(m_PlId, NULL, &status, NULL)
  11.213 -#endif			
  11.214 -			&& status < Pl_Paused))
  11.215 -		{
  11.216 -			m_pLib->CloseLibrary();
  11.217 -			m_pLib = NULL;
  11.218 -			m_pAPI = NULL;
  11.219 -			return false;
  11.220 -		}
  11.221 -	}
  11.222 -
  11.223 -	if (!CExtension::Load(error, maxlength))
  11.224 -	{
  11.225 -		if (m_pAPI->IsMetamodExtension())
  11.226 -		{
  11.227 -			if (m_PlId)
  11.228 -			{
  11.229 -				char dummy[255];
  11.230 -				g_pMMPlugins->Unload(m_PlId, true, dummy, sizeof(dummy));
  11.231 -				m_PlId = 0;
  11.232 -			}
  11.233 -		}
  11.234 -		m_pLib->CloseLibrary();
  11.235 -		m_pLib = NULL;
  11.236 -		m_pAPI = NULL;
  11.237 -		return false;
  11.238 -	}
  11.239 -
  11.240 -	return true;
  11.241 -}
  11.242 -
  11.243 -void CRemoteExtension::Unload()
  11.244 -{
  11.245 -}
  11.246 -
  11.247 -void CLocalExtension::Unload()
  11.248 -{
  11.249 -	if (m_pAPI != NULL && m_PlId)
  11.250 -	{
  11.251 -		char temp_buffer[255];
  11.252 -		g_pMMPlugins->Unload(m_PlId, true, temp_buffer, sizeof(temp_buffer));
  11.253 -		m_PlId = 0;
  11.254 -	}
  11.255 -
  11.256 -	if (m_pLib != NULL)
  11.257 -	{
  11.258 -		m_pLib->CloseLibrary();
  11.259 -		m_pLib = NULL;
  11.260 -	}
  11.261 -}
  11.262 -
  11.263 -bool CRemoteExtension::Reload(char *error, size_t maxlength)
  11.264 -{
  11.265 -	snprintf(error, maxlength, "Remote extensions do not support reloading");
  11.266 -	return false;
  11.267 -}
  11.268 -
  11.269 -bool CLocalExtension::Reload(char *error, size_t maxlength)
  11.270 -{
  11.271 -	if (m_pLib == NULL) // FIXME: just load it instead?
  11.272 -		return false;
  11.273 -	
  11.274 -	m_pAPI->OnExtensionUnload();
  11.275 -	Unload();
  11.276 -	
  11.277 -	return Load(error, maxlength);
  11.278 -}
  11.279 -
  11.280 -bool CRemoteExtension::IsExternal()
  11.281 -{
  11.282 -	return true;
  11.283 -}
  11.284 -
  11.285 -bool CLocalExtension::IsExternal()
  11.286 -{
  11.287 -	return false;
  11.288 -}
  11.289 -
  11.290 -CExtension::~CExtension()
  11.291 -{
  11.292 -	DestroyIdentity();
  11.293 -}
  11.294 -
  11.295 -bool CExtension::PerformAPICheck(char *error, size_t maxlength)
  11.296 -{
  11.297 -	if (!m_pAPI)
  11.298 -	{
  11.299 -		snprintf(error, maxlength, "No IExtensionInterface instance provided");
  11.300 -		return false;
  11.301 -	}
  11.302 -	
  11.303 -	if (m_pAPI->GetExtensionVersion() > SMINTERFACE_EXTENSIONAPI_VERSION)
  11.304 -	{
  11.305 -		snprintf(error, maxlength, "Extension version is too new to load (%d, max is %d)", m_pAPI->GetExtensionVersion(), SMINTERFACE_EXTENSIONAPI_VERSION);
  11.306 -		return false;
  11.307 -	}
  11.308 -
  11.309 -	return true;
  11.310 -}
  11.311 -
  11.312 -bool CExtension::Load(char *error, size_t maxlength)
  11.313 -{
  11.314 -	CreateIdentity();
  11.315 -	if (!m_pAPI->OnExtensionLoad(this, &g_ShareSys, error, maxlength, !g_SourceMod.IsMapLoading()))
  11.316 -	{
  11.317 -		DestroyIdentity();
  11.318 -		return false;
  11.319 -	}
  11.320 -	else
  11.321 -	{
  11.322 -		/* Check if we're past load time */
  11.323 -		if (!g_SourceMod.IsMapLoading())
  11.324 -		{
  11.325 -			m_pAPI->OnExtensionsAllLoaded();
  11.326 -		}
  11.327 -	}
  11.328 -
  11.329 -	return true;
  11.330 -}
  11.331 -
  11.332 -void CExtension::CreateIdentity()
  11.333 -{
  11.334 -	if (m_pIdentToken != NULL)
  11.335 -	{
  11.336 -		return;
  11.337 -	}
  11.338 -
  11.339 -	m_pIdentToken = g_ShareSys.CreateIdentity(g_ExtType, this);
  11.340 -}
  11.341 -
  11.342 -void CExtension::DestroyIdentity()
  11.343 -{
  11.344 -	if (m_pIdentToken == NULL)
  11.345 -	{
  11.346 -		return;
  11.347 -	}
  11.348 -
  11.349 -	g_ShareSys.DestroyIdentity(m_pIdentToken);
  11.350 -	m_pIdentToken = NULL;
  11.351 -}
  11.352 -
  11.353 -void CExtension::MarkAllLoaded()
  11.354 -{
  11.355 -	assert(m_bFullyLoaded == false);
  11.356 -	if (!m_bFullyLoaded)
  11.357 -	{
  11.358 -		m_bFullyLoaded = true;
  11.359 -		m_pAPI->OnExtensionsAllLoaded();
  11.360 -	}
  11.361 -}
  11.362 -
  11.363 -void CExtension::AddPlugin(CPlugin *pPlugin)
  11.364 -{
  11.365 -	/* Unfortunately we have to do this :( */
  11.366 -	if (m_Dependents.find(pPlugin) != m_Dependents.end())
  11.367 -	{
  11.368 -		m_Dependents.push_back(pPlugin);
  11.369 -	}
  11.370 -}
  11.371 -
  11.372 -void CExtension::SetError(const char *error)
  11.373 -{
  11.374 -	m_Error.assign(error);
  11.375 -}
  11.376 -
  11.377 -IExtensionInterface *CExtension::GetAPI()
  11.378 -{
  11.379 -	return m_pAPI;
  11.380 -}
  11.381 -
  11.382 -const char *CExtension::GetFilename()
  11.383 -{
  11.384 -	return m_RealFile.c_str();
  11.385 -}
  11.386 -
  11.387 -const char *CExtension::GetPath() const
  11.388 -{
  11.389 -	return m_Path.c_str();
  11.390 -}
  11.391 -
  11.392 -IdentityToken_t *CExtension::GetIdentity()
  11.393 -{
  11.394 -	return m_pIdentToken;
  11.395 -}
  11.396 -
  11.397 -bool CRemoteExtension::IsLoaded()
  11.398 -{
  11.399 -	return (m_pAPI != NULL);
  11.400 -}
  11.401 -
  11.402 -bool CLocalExtension::IsLoaded()
  11.403 -{
  11.404 -	return (m_pLib != NULL);
  11.405 -}
  11.406 -
  11.407 -void CExtension::AddDependency(const IfaceInfo *pInfo)
  11.408 -{
  11.409 -	if (m_Deps.find(*pInfo) == m_Deps.end())
  11.410 -	{
  11.411 -		m_Deps.push_back(*pInfo);
  11.412 -	}
  11.413 -}
  11.414 -
  11.415 -bool operator ==(const IfaceInfo &i1, const IfaceInfo &i2)
  11.416 -{
  11.417 -	return (i1.iface == i2.iface) && (i1.owner == i2.owner);
  11.418 -}
  11.419 -
  11.420 -void CExtension::AddChildDependent(CExtension *pOther, SMInterface *iface)
  11.421 -{
  11.422 -	IfaceInfo info;
  11.423 -	info.iface = iface;
  11.424 -	info.owner = pOther;
  11.425 -
  11.426 -	List<IfaceInfo>::iterator iter;
  11.427 -	for (iter = m_ChildDeps.begin();
  11.428 -		 iter != m_ChildDeps.end();
  11.429 -		 iter++)
  11.430 -	{
  11.431 -		IfaceInfo &other = (*iter);
  11.432 -		if (other == info)
  11.433 -		{
  11.434 -			return;
  11.435 -		}
  11.436 -	}
  11.437 -
  11.438 -	m_ChildDeps.push_back(info);
  11.439 -}
  11.440 -
  11.441 -ITERATOR *CExtension::FindFirstDependency(IExtension **pOwner, SMInterface **pInterface)
  11.442 -{
  11.443 -	List<IfaceInfo>::iterator iter = m_Deps.begin();
  11.444 -
  11.445 -	if (iter == m_Deps.end())
  11.446 -	{
  11.447 -		return NULL;
  11.448 -	}
  11.449 -
  11.450 -	if (pOwner)
  11.451 -	{
  11.452 -		*pOwner = (*iter).owner;
  11.453 -	}
  11.454 -	if (pInterface)
  11.455 -	{
  11.456 -		*pInterface = (*iter).iface;
  11.457 -	}
  11.458 -
  11.459 -	List<IfaceInfo>::iterator *pIter = new List<IfaceInfo>::iterator(iter);
  11.460 -
  11.461 -	return (ITERATOR *)pIter;
  11.462 -}
  11.463 -
  11.464 -bool CExtension::FindNextDependency(ITERATOR *iter, IExtension **pOwner, SMInterface **pInterface)
  11.465 -{
  11.466 -	List<IfaceInfo>::iterator *pIter = (List<IfaceInfo>::iterator *)iter;
  11.467 -	List<IfaceInfo>::iterator _iter;
  11.468 -
  11.469 -	if (_iter == m_Deps.end())
  11.470 -	{
  11.471 -		return false;
  11.472 -	}
  11.473 -
  11.474 -	_iter++;
  11.475 -
  11.476 -	if (pOwner)
  11.477 -	{
  11.478 -		*pOwner = (*_iter).owner;
  11.479 -	}
  11.480 -	if (pInterface)
  11.481 -	{
  11.482 -		*pInterface = (*_iter).iface;
  11.483 -	}
  11.484 -
  11.485 -	*pIter = _iter;
  11.486 -
  11.487 -	if (_iter == m_Deps.end())
  11.488 -	{
  11.489 -		return false;
  11.490 -	}
  11.491 -
  11.492 -	return true;
  11.493 -}
  11.494 -
  11.495 -void CExtension::FreeDependencyIterator(ITERATOR *iter)
  11.496 -{
  11.497 -	List<IfaceInfo>::iterator *pIter = (List<IfaceInfo>::iterator *)iter;
  11.498 -
  11.499 -	delete pIter;
  11.500 -}
  11.501 -
  11.502 -void CExtension::AddInterface(SMInterface *pInterface)
  11.503 -{
  11.504 -	m_Interfaces.push_back(pInterface);
  11.505 -}
  11.506 -
  11.507 -bool CExtension::IsRunning(char *error, size_t maxlength)
  11.508 -{
  11.509 -	if (!IsLoaded())
  11.510 -	{
  11.511 -		if (error)
  11.512 -		{
  11.513 -			snprintf(error, maxlength, "%s", m_Error.c_str());
  11.514 -		}
  11.515 -		return false;
  11.516 -	}
  11.517 -
  11.518 -	return m_pAPI->QueryRunning(error, maxlength);
  11.519 -}
  11.520 -
  11.521 -void CExtension::AddLibrary(const char *library)
  11.522 -{
  11.523 -	m_Libraries.push_back(library);
  11.524 -}
  11.525 -
  11.526 -/*********************
  11.527 - * EXTENSION MANAGER *
  11.528 - *********************/
  11.529 -
  11.530 -void CExtensionManager::OnSourceModAllInitialized()
  11.531 -{
  11.532 -	g_ExtType = g_ShareSys.CreateIdentType("EXTENSION");
  11.533 -	g_PluginSys.AddPluginsListener(this);
  11.534 -	g_RootMenu.AddRootConsoleCommand("exts", "Manage extensions", this);
  11.535 -	g_ShareSys.AddInterface(NULL, this);
  11.536 -}
  11.537 -
  11.538 -void CExtensionManager::OnSourceModShutdown()
  11.539 -{
  11.540 -	g_RootMenu.RemoveRootConsoleCommand("exts", this);
  11.541 -	g_ShareSys.DestroyIdentType(g_ExtType);
  11.542 -}
  11.543 -
  11.544 -void CExtensionManager::Shutdown()
  11.545 -{
  11.546 -	List<CExtension *>::iterator iter;
  11.547 -
  11.548 -	while ((iter = m_Libs.begin()) != m_Libs.end())
  11.549 -	{
  11.550 -		UnloadExtension((*iter));
  11.551 -	}
  11.552 -}
  11.553 -
  11.554 -void CExtensionManager::TryAutoload()
  11.555 -{
  11.556 -	char path[PLATFORM_MAX_PATH];
  11.557 -
  11.558 -	g_SourceMod.BuildPath(Path_SM, path, sizeof(path), "extensions");
  11.559 -
  11.560 -	IDirectory *pDir = g_LibSys.OpenDirectory(path);
  11.561 -	if (!pDir)
  11.562 -	{
  11.563 -		return;
  11.564 -	}
  11.565 -
  11.566 -	const char *lfile;
  11.567 -	size_t len;
  11.568 -	while (pDir->MoreFiles())
  11.569 -	{
  11.570 -		if (pDir->IsEntryDirectory())
  11.571 -		{
  11.572 -			pDir->NextEntry();
  11.573 -			continue;
  11.574 -		}
  11.575 -
  11.576 -		lfile = pDir->GetEntryName();
  11.577 -		len = strlen(lfile);
  11.578 -		if (len <= 9) /* size of ".autoload" */
  11.579 -		{
  11.580 -			pDir->NextEntry();
  11.581 -			continue;
  11.582 -		}
  11.583 -
  11.584 -		if (strcmp(&lfile[len - 9], ".autoload") != 0)
  11.585 -		{
  11.586 -			pDir->NextEntry();
  11.587 -			continue;
  11.588 -		}
  11.589 -
  11.590 -		char file[PLATFORM_MAX_PATH];
  11.591 -		len = UTIL_Format(file, sizeof(file), "%s", lfile);
  11.592 -		strcpy(&file[len - 9], ".ext");
  11.593 -
  11.594 -		LoadAutoExtension(file);
  11.595 -		
  11.596 -		pDir->NextEntry();
  11.597 -	}
  11.598 -}
  11.599 -
  11.600 -IExtension *CExtensionManager::LoadAutoExtension(const char *path, bool bErrorOnMissing)
  11.601 -{
  11.602 -	/* Remove platform extension if it's there. Compat hack. */
  11.603 -	const char *ext = g_LibSys.GetFileExtension(path);
  11.604 -	if (strcmp(ext, PLATFORM_LIB_EXT) == 0)
  11.605 -	{
  11.606 -		char path2[PLATFORM_MAX_PATH];
  11.607 -		UTIL_Format(path2, sizeof(path2), "%s", path);
  11.608 -		path2[strlen(path) - strlen(PLATFORM_LIB_EXT) - 1] = '\0';
  11.609 -		return LoadAutoExtension(path2, bErrorOnMissing);
  11.610 -	}
  11.611 -
  11.612 -	IExtension *pAlready;
  11.613 -	if ((pAlready=FindExtensionByFile(path)) != NULL)
  11.614 -	{
  11.615 -		return pAlready;
  11.616 -	}
  11.617 -
  11.618 -	char error[256];
  11.619 -	CExtension *p = new CLocalExtension(path);
  11.620 -
  11.621 -	/* We put us in the list beforehand so extensions that check for each other
  11.622 -	 * won't recursively load each other.
  11.623 -	 */
  11.624 -	m_Libs.push_back(p);
  11.625 -
  11.626 -	if (!p->Load(error, sizeof(error)) || !p->IsLoaded())
  11.627 -	{
  11.628 -		if (bErrorOnMissing || g_LibSys.IsPathFile(p->GetPath()))
  11.629 -		{
  11.630 -			g_Logger.LogError("[SM] Unable to load extension \"%s\": %s", path, error);
  11.631 -		}
  11.632 -
  11.633 -		p->SetError(error);
  11.634 -	}
  11.635 -
  11.636 -	return p;
  11.637 -}
  11.638 -
  11.639 -IExtension *CExtensionManager::FindExtensionByFile(const char *file)
  11.640 -{
  11.641 -	List<CExtension *>::iterator iter;
  11.642 -	CExtension *pExt;
  11.643 -
  11.644 -	/* Chomp off the path */
  11.645 -	char lookup[PLATFORM_MAX_PATH];
  11.646 -	g_LibSys.GetFileFromPath(lookup, sizeof(lookup), file);
  11.647 -
  11.648 -	for (iter=m_Libs.begin(); iter!=m_Libs.end(); iter++)
  11.649 -	{
  11.650 -		pExt = (*iter);
  11.651 -		if (pExt->IsSameFile(lookup))
  11.652 -		{
  11.653 -			return pExt;
  11.654 -		}
  11.655 -	}
  11.656 -
  11.657 -	return NULL;
  11.658 -}
  11.659 -
  11.660 -IExtension *CExtensionManager::FindExtensionByName(const char *ext)
  11.661 -{
  11.662 -	List<CExtension *>::iterator iter;
  11.663 -	CExtension *pExt;
  11.664 -	IExtensionInterface *pAPI;
  11.665 -	const char *name;
  11.666 -
  11.667 -	for (iter=m_Libs.begin(); iter!=m_Libs.end(); iter++)
  11.668 -	{
  11.669 -		pExt = (*iter);
  11.670 -		if (!pExt->IsLoaded())
  11.671 -		{
  11.672 -			continue;
  11.673 -		}
  11.674 -		if ((pAPI = pExt->GetAPI()) == NULL)
  11.675 -		{
  11.676 -			continue;
  11.677 -		}
  11.678 -		name = pAPI->GetExtensionName();
  11.679 -		if (!name)
  11.680 -		{
  11.681 -			continue;
  11.682 -		}
  11.683 -		if (strcmp(name, ext) == 0)
  11.684 -		{
  11.685 -			return pExt;
  11.686 -		}
  11.687 -	}
  11.688 -
  11.689 -	return NULL;
  11.690 -}
  11.691 -
  11.692 -IExtension *CExtensionManager::LoadExtension(const char *file, char *error, size_t maxlength)
  11.693 -{
  11.694 -	/* Remove platform extension if it's there. Compat hack. */
  11.695 -	const char *ext = g_LibSys.GetFileExtension(file);
  11.696 -	if (strcmp(ext, PLATFORM_LIB_EXT) == 0)
  11.697 -	{
  11.698 -		char path2[PLATFORM_MAX_PATH];
  11.699 -		UTIL_Format(path2, sizeof(path2), "%s", file);
  11.700 -		path2[strlen(file) - strlen(PLATFORM_LIB_EXT) - 1] = '\0';
  11.701 -		return LoadExtension(path2, error, maxlength);
  11.702 -	}
  11.703 -
  11.704 -	IExtension *pAlready;
  11.705 -	if ((pAlready=FindExtensionByFile(file)) != NULL)
  11.706 -	{
  11.707 -		return pAlready;
  11.708 -	}
  11.709 -
  11.710 -	CExtension *pExt = new CLocalExtension(file);
  11.711 -
  11.712 -	if (!pExt->Load(error, maxlength) || !pExt->IsLoaded())
  11.713 -	{
  11.714 -		pExt->Unload();
  11.715 -		delete pExt;
  11.716 -		return NULL;
  11.717 -	}
  11.718 -
  11.719 -	/* :TODO: do QueryRunning check if the map is loaded */
  11.720 -
  11.721 -	m_Libs.push_back(pExt);
  11.722 -
  11.723 -	return pExt;
  11.724 -}
  11.725 -
  11.726 -void CExtensionManager::BindDependency(IExtension *pRequester, IfaceInfo *pInfo)
  11.727 -{
  11.728 -	CExtension *pExt = (CExtension *)pRequester;
  11.729 -	CExtension *pOwner = (CExtension *)pInfo->owner;
  11.730 -
  11.731 -	pExt->AddDependency(pInfo);
  11.732 -
  11.733 -	IExtensionInterface *pAPI = pExt->GetAPI();
  11.734 -	if (pAPI && !pAPI->QueryInterfaceDrop(pInfo->iface))
  11.735 -	{
  11.736 -		pOwner->AddChildDependent(pExt, pInfo->iface);
  11.737 -	}
  11.738 -}
  11.739 -
  11.740 -void CExtensionManager::AddRawDependency(IExtension *ext, IdentityToken_t *other, void *iface)
  11.741 -{
  11.742 -	CExtension *pExt = (CExtension *)ext;
  11.743 -	CExtension *pOwner = GetExtensionFromIdent(other);
  11.744 -
  11.745 -	IfaceInfo info;
  11.746 -
  11.747 -	info.iface = (SMInterface *)iface;
  11.748 -	info.owner = pOwner;
  11.749 -
  11.750 -	pExt->AddDependency(&info);
  11.751 -	pOwner->AddChildDependent(pExt, (SMInterface *)iface);
  11.752 -}
  11.753 -
  11.754 -void CExtensionManager::AddInterface(IExtension *pOwner, SMInterface *pInterface)
  11.755 -{
  11.756 -	CExtension *pExt = (CExtension *)pOwner;
  11.757 -
  11.758 -	pExt->AddInterface(pInterface);
  11.759 -}
  11.760 -
  11.761 -void CExtensionManager::BindChildPlugin( IExtension *pParent, CPlugin *pPlugin )
  11.762 -{
  11.763 -	CExtension *pExt = (CExtension *)pParent;
  11.764 -
  11.765 -	pExt->AddPlugin(pPlugin);
  11.766 -}
  11.767 -
  11.768 -void CExtensionManager::OnPluginDestroyed(IPlugin *plugin)
  11.769 -{
  11.770 -	List<CExtension *>::iterator iter;
  11.771 -
  11.772 -	for (iter=m_Libs.begin(); iter!=m_Libs.end(); iter++)
  11.773 -	{
  11.774 -		(*iter)->DropRefsTo((CPlugin *)plugin);
  11.775 -	}
  11.776 -}
  11.777 -
  11.778 -CExtension *CExtensionManager::FindByOrder(unsigned int num)
  11.779 -{
  11.780 -	if (num < 1 || num > m_Libs.size())
  11.781 -	{
  11.782 -		return NULL;
  11.783 -	}
  11.784 -
  11.785 -	List<CExtension *>::iterator iter = m_Libs.begin();
  11.786 -
  11.787 -	while (iter != m_Libs.end())
  11.788 -	{
  11.789 -		if (--num == 0)
  11.790 -		{
  11.791 -			return (*iter);
  11.792 -		}
  11.793 -		iter++;
  11.794 -	}
  11.795 -
  11.796 -	return NULL;
  11.797 -}
  11.798 -
  11.799 -bool CExtensionManager::UnloadExtension(IExtension *_pExt)
  11.800 -{
  11.801 -	if (!_pExt)
  11.802 -	{
  11.803 -		return false;
  11.804 -	}
  11.805 -
  11.806 -	CExtension *pExt = (CExtension *)_pExt;
  11.807 -
  11.808 -	if (m_Libs.find(pExt) == m_Libs.end())
  11.809 -	{
  11.810 -		return false;
  11.811 -	}
  11.812 -
  11.813 -	/* Tell it to unload */
  11.814 -	if (pExt->IsLoaded())
  11.815 -	{
  11.816 -		IExtensionInterface *pAPI = pExt->GetAPI();
  11.817 -		pAPI->OnExtensionUnload();
  11.818 -	}
  11.819 -
  11.820 -	/* First remove us from internal lists */
  11.821 -	g_ShareSys.RemoveInterfaces(_pExt);
  11.822 -	m_Libs.remove(pExt);
  11.823 -
  11.824 -	List<CExtension *> UnloadQueue;
  11.825 -
  11.826 -	/* Handle dependencies */
  11.827 -	if (pExt->IsLoaded())
  11.828 -	{
  11.829 -		/* Unload any dependent plugins */
  11.830 -		List<CPlugin *>::iterator p_iter = pExt->m_Dependents.begin();
  11.831 -		while (p_iter != pExt->m_Dependents.end())
  11.832 -		{
  11.833 -			/* We have to manually unlink ourselves here, since we're no longer being managed */
  11.834 -			g_PluginSys.UnloadPlugin((*p_iter));
  11.835 -			p_iter = pExt->m_Dependents.erase(p_iter);
  11.836 -		}
  11.837 -
  11.838 -		List<String>::iterator s_iter;
  11.839 -		for (s_iter = pExt->m_Libraries.begin();
  11.840 -			 s_iter != pExt->m_Libraries.end();
  11.841 -			 s_iter++)
  11.842 -		{
  11.843 -			g_PluginSys.OnLibraryAction((*s_iter).c_str(), LibraryAction_Removed);
  11.844 -		}
  11.845 -
  11.846 -		/* Notify and/or unload all dependencies */
  11.847 -		List<CExtension *>::iterator c_iter;
  11.848 -		CExtension *pDep;
  11.849 -		IExtensionInterface *pAPI;
  11.850 -		for (c_iter = m_Libs.begin(); c_iter != m_Libs.end(); c_iter++)
  11.851 -		{
  11.852 -			pDep = (*c_iter);
  11.853 -			if ((pAPI=pDep->GetAPI()) == NULL)
  11.854 -			{
  11.855 -				continue;
  11.856 -			}
  11.857 -			if (pDep == pExt)
  11.858 -			{
  11.859 -				continue;
  11.860 -			}
  11.861 -			/* Now, get its dependency list */
  11.862 -			bool dropped = false;
  11.863 -			List<IfaceInfo>::iterator i_iter = pDep->m_Deps.begin();
  11.864 -			while (i_iter != pDep->m_Deps.end())
  11.865 -			{
  11.866 -				if ((*i_iter).owner == _pExt)
  11.867 -				{
  11.868 -					if (!pAPI->QueryInterfaceDrop((*i_iter).iface))
  11.869 -					{
  11.870 -						if (!dropped)
  11.871 -						{
  11.872 -							dropped = true;
  11.873 -							UnloadQueue.push_back(pDep);
  11.874 -						}
  11.875 -					}
  11.876 -					pAPI->NotifyInterfaceDrop((*i_iter).iface);
  11.877 -					i_iter = pDep->m_Deps.erase(i_iter);
  11.878 -				}
  11.879 -				else
  11.880 -				{
  11.881 -					i_iter++;
  11.882 -				}
  11.883 -			}
  11.884 -			/* Flush out any back references to this plugin */
  11.885 -			i_iter = pDep->m_ChildDeps.begin();
  11.886 -			while (i_iter != pDep->m_ChildDeps.end())
  11.887 -			{
  11.888 -				if ((*i_iter).owner == pExt)
  11.889 -				{
  11.890 -					i_iter = pDep->m_ChildDeps.erase(i_iter);
  11.891 -				}
  11.892 -				else
  11.893 -				{
  11.894 -					i_iter++;
  11.895 -				}
  11.896 -			}
  11.897 -		}
  11.898 -
  11.899 -		/* Unbind our natives from Core */
  11.900 -		pExt->DropEverything();
  11.901 -	}
  11.902 -
  11.903 -	IdentityToken_t *pIdentity;
  11.904 -	if ((pIdentity = pExt->GetIdentity()) != NULL)
  11.905 -	{
  11.906 -		SMGlobalClass *glob = SMGlobalClass::head;
  11.907 -		while (glob)
  11.908 -		{
  11.909 -			glob->OnSourceModIdentityDropped(pIdentity);
  11.910 -			glob = glob->m_pGlobalClassNext;
  11.911 -		}
  11.912 -	}
  11.913 -
  11.914 -	pExt->Unload();
  11.915 -	delete pExt;
  11.916 -
  11.917 -	List<CExtension *>::iterator iter;
  11.918 -	for (iter=UnloadQueue.begin(); iter!=UnloadQueue.end(); iter++)
  11.919 -	{
  11.920 -		/* NOTE: This is safe because the unload function backs out of anything not present */
  11.921 -		UnloadExtension((*iter));
  11.922 -	}
  11.923 -
  11.924 -	return true;
  11.925 -}
  11.926 -
  11.927 -void CExtensionManager::MarkAllLoaded()
  11.928 -{
  11.929 -	List<CExtension *>::iterator iter;
  11.930 -	CExtension *pExt;
  11.931 -
  11.932 -	for (iter=m_Libs.begin(); iter!=m_Libs.end(); iter++)
  11.933 -	{
  11.934 -		pExt = (*iter);
  11.935 -		if (!pExt->IsLoaded())
  11.936 -		{
  11.937 -			continue;
  11.938 -		}
  11.939 -		if (pExt->m_bFullyLoaded)
  11.940 -		{
  11.941 -			continue;
  11.942 -		}
  11.943 -		pExt->MarkAllLoaded();
  11.944 -	}
  11.945 -}
  11.946 -
  11.947 -void CExtensionManager::AddDependency(IExtension *pSource, const char *file, bool required, bool autoload)
  11.948 -{
  11.949 -	/* This function doesn't really need to do anything now.  We make sure the 
  11.950 -	 * other extension is loaded, but handling of dependencies is really done 
  11.951 -	 * by the interface fetcher.
  11.952 -	 */
  11.953 -	if (required || autoload)
  11.954 -	{
  11.955 -		LoadAutoExtension(file);
  11.956 -	}
  11.957 -}
  11.958 -
  11.959 -void CExtensionManager::OnRootConsoleCommand(const char *cmdname, const CCommand &command)
  11.960 -{
  11.961 -	int argcount = command.ArgC();
  11.962 -	if (argcount >= 3)
  11.963 -	{
  11.964 -		const char *cmd = command.Arg(2);
  11.965 -		if (strcmp(cmd, "list") == 0)
  11.966 -		{
  11.967 -			List<CExtension *>::iterator iter;
  11.968 -			CExtension *pExt;
  11.969 -			unsigned int num = 1;
  11.970 -			switch (m_Libs.size())
  11.971 -			{
  11.972 -			case 1:
  11.973 -				{
  11.974 -					g_RootMenu.ConsolePrint("[SM] Displaying 1 extension:");
  11.975 -					break;
  11.976 -				}
  11.977 -			case 0:
  11.978 -				{
  11.979 -					g_RootMenu.ConsolePrint("[SM] No extensions are loaded.");
  11.980 -					break;
  11.981 -				}
  11.982 -			default:
  11.983 -				{
  11.984 -					g_RootMenu.ConsolePrint("[SM] Displaying %d extensions:", m_Libs.size());
  11.985 -					break;
  11.986 -				}
  11.987 -			}
  11.988 -			for (iter=m_Libs.begin(); iter!=m_Libs.end(); iter++,num++)
  11.989 -			{
  11.990 -				pExt = (*iter);
  11.991 -				if (pExt->IsLoaded())
  11.992 -				{
  11.993 -					char error[255];
  11.994 -					if (!pExt->IsRunning(error, sizeof(error)))
  11.995 -					{
  11.996 -						g_RootMenu.ConsolePrint("[%02d] <FAILED> file \"%s\": %s", num, pExt->GetFilename(), error);
  11.997 -					}
  11.998 -					else
  11.999 -					{
 11.1000 -						IExtensionInterface *pAPI = pExt->GetAPI();
 11.1001 -						const char *name = pAPI->GetExtensionName();
 11.1002 -						const char *version = pAPI->GetExtensionVerString();
 11.1003 -						const char *descr = pAPI->GetExtensionDescription();
 11.1004 -						g_RootMenu.ConsolePrint("[%02d] %s (%s): %s", num, name, version, descr);
 11.1005 -					}
 11.1006 -				} else {
 11.1007 -					g_RootMenu.ConsolePrint("[%02d] <FAILED> file \"%s\": %s", num, pExt->GetFilename(), pExt->m_Error.c_str());
 11.1008 -				}
 11.1009 -			}
 11.1010 -			return;
 11.1011 -		}
 11.1012 -		else if (strcmp(cmd, "load") == 0)
 11.1013 -		{
 11.1014 -			if (argcount < 4)
 11.1015 -			{
 11.1016 -				g_RootMenu.ConsolePrint("[SM] Usage: sm exts load <file>");
 11.1017 -				return;
 11.1018 -			}
 11.1019 -
 11.1020 -			const char *filename = command.Arg(3);
 11.1021 -			char path[PLATFORM_MAX_PATH];
 11.1022 -			char error[256];
 11.1023 -
 11.1024 -			UTIL_Format(path, sizeof(path), "%s%s%s", filename, !strstr(filename, ".ext") ? ".ext" : "",
 11.1025 -				!strstr(filename, "." PLATFORM_LIB_EXT) ? "." PLATFORM_LIB_EXT : "");
 11.1026 -			
 11.1027 -			if (FindExtensionByFile(path) != NULL)
 11.1028 -			{
 11.1029 -				g_RootMenu.ConsolePrint("[SM] Extension %s is already loaded.", path);
 11.1030 -				return;
 11.1031 -			}
 11.1032 -			
 11.1033 -			if (LoadExtension(path, error, sizeof(error)))
 11.1034 -			{
 11.1035 -				g_RootMenu.ConsolePrint("[SM] Loaded extension %s successfully.", path);
 11.1036 -			} else
 11.1037 -			{
 11.1038 -				g_RootMenu.ConsolePrint("[SM] Extension %s failed to load: %s", path, error);
 11.1039 -			}
 11.1040 -			
 11.1041 -			return;
 11.1042 -		}
 11.1043 -		else if (strcmp(cmd, "info") == 0)
 11.1044 -		{
 11.1045 -			if (argcount < 4)
 11.1046 -			{
 11.1047 -				g_RootMenu.ConsolePrint("[SM] Usage: sm exts info <#>");
 11.1048 -				return;
 11.1049 -			}
 11.1050 -
 11.1051 -			const char *sId = command.Arg(3);
 11.1052 -			unsigned int id = atoi(sId);
 11.1053 -			if (id <= 0)
 11.1054 -			{
 11.1055 -				g_RootMenu.ConsolePrint("[SM] Usage: sm exts info <#>");
 11.1056 -				return;
 11.1057 -			}
 11.1058 -
 11.1059 -			if (m_Libs.size() == 0)
 11.1060 -			{
 11.1061 -				g_RootMenu.ConsolePrint("[SM] No extensions are loaded.");
 11.1062 -				return;
 11.1063 -			}
 11.1064 -
 11.1065 -			if (id > m_Libs.size())
 11.1066 -			{
 11.1067 -				g_RootMenu.ConsolePrint("[SM] No extension was found with id %d.", id);
 11.1068 -				return;
 11.1069 -			}
 11.1070 -
 11.1071 -			List<CExtension *>::iterator iter = m_Libs.begin();
 11.1072 -			CExtension *pExt = NULL;
 11.1073 -			while (iter != m_Libs.end())
 11.1074 -			{
 11.1075 -				if (--id == 0)
 11.1076 -				{
 11.1077 -					pExt = (*iter);
 11.1078 -					break;
 11.1079 -				}
 11.1080 -				iter++;
 11.1081 -			}
 11.1082 -			/* This should never happen */
 11.1083 -			if (!pExt)
 11.1084 -			{
 11.1085 -				g_RootMenu.ConsolePrint("[SM] No extension was found with id %d.", id);
 11.1086 -				return;
 11.1087 -			}
 11.1088 -
 11.1089 -			if (!pExt->IsLoaded())
 11.1090 -			{
 11.1091 -				g_RootMenu.ConsolePrint(" File: %s", pExt->GetFilename());
 11.1092 -				g_RootMenu.ConsolePrint(" Loaded: No (%s)", pExt->m_Error.c_str());
 11.1093 -			}
 11.1094 -			else
 11.1095 -			{
 11.1096 -				char error[255];
 11.1097 -				if (!pExt->IsRunning(error, sizeof(error)))
 11.1098 -				{
 11.1099 -					g_RootMenu.ConsolePrint(" File: %s", pExt->GetFilename());
 11.1100 -					g_RootMenu.ConsolePrint(" Loaded: Yes");
 11.1101 -					g_RootMenu.ConsolePrint(" Running: No (%s)", error);
 11.1102 -				}
 11.1103 -				else
 11.1104 -				{
 11.1105 -					IExtensionInterface *pAPI = pExt->GetAPI();
 11.1106 -					g_RootMenu.ConsolePrint(" File: %s", pExt->GetFilename());
 11.1107 -					g_RootMenu.ConsolePrint(" Loaded: Yes (version %s)", pAPI->GetExtensionVerString());
 11.1108 -					g_RootMenu.ConsolePrint(" Name: %s (%s)", pAPI->GetExtensionName(), pAPI->GetExtensionDescription());
 11.1109 -					g_RootMenu.ConsolePrint(" Author: %s (%s)", pAPI->GetExtensionAuthor(), pAPI->GetExtensionURL());
 11.1110 -					g_RootMenu.ConsolePrint(" Binary info: API version %d (compiled %s)", pAPI->GetExtensionVersion(), pAPI->GetExtensionDateString());
 11.1111 -
 11.1112 -					if (pExt->IsExternal())
 11.1113 -					{
 11.1114 -						g_RootMenu.ConsolePrint(" Method: Loaded by Metamod:Source, attached to SourceMod");
 11.1115 -					}
 11.1116 -					else if (pAPI->IsMetamodExtension())
 11.1117 -					{
 11.1118 -						g_RootMenu.ConsolePrint(" Method: Loaded by SourceMod, attached to Metamod:Source");
 11.1119 -					}
 11.1120 -					else
 11.1121 -					{
 11.1122 -						g_RootMenu.ConsolePrint(" Method: Loaded by SourceMod");
 11.1123 -					}
 11.1124 -				}
 11.1125 -			}
 11.1126 -			return;
 11.1127 -		}
 11.1128 -		else if (strcmp(cmd, "unload") == 0)
 11.1129 -		{
 11.1130 -			if (argcount < 4)
 11.1131 -			{
 11.1132 -				g_RootMenu.ConsolePrint("[SM] Usage: sm exts unload <#> [code]");
 11.1133 -				return;
 11.1134 -			}
 11.1135 -
 11.1136 -			const char *arg = command.Arg(3);
 11.1137 -			unsigned int num = atoi(arg);
 11.1138 -			CExtension *pExt = FindByOrder(num);
 11.1139 -
 11.1140 -			if (!pExt)
 11.1141 -			{
 11.1142 -				g_RootMenu.ConsolePrint("[SM] Extension number %d was not found.", num);
 11.1143 -				return;
 11.1144 -			}
 11.1145 -
 11.1146 -			if (argcount > 4 && pExt->unload_code)
 11.1147 -			{
 11.1148 -				const char *unload = command.Arg(4);
 11.1149 -				if (pExt->unload_code == (unsigned)atoi(unload))
 11.1150 -				{
 11.1151 -					char filename[PLATFORM_MAX_PATH];
 11.1152 -					snprintf(filename, PLATFORM_MAX_PATH, "%s", pExt->GetFilename());
 11.1153 -					UnloadExtension(pExt);
 11.1154 -					g_RootMenu.ConsolePrint("[SM] Extension %s is now unloaded.", filename);
 11.1155 -				}
 11.1156 -				else
 11.1157 -				{
 11.1158 -					g_RootMenu.ConsolePrint("[SM] Please try again, the correct unload code is \"%d\"", pExt->unload_code);
 11.1159 -				}
 11.1160 -				return;
 11.1161 -			}
 11.1162 -
 11.1163 -			if (!pExt->IsLoaded() 
 11.1164 -				|| (!pExt->m_ChildDeps.size() && !pExt->m_Dependents.size()))
 11.1165 -			{
 11.1166 -				char filename[PLATFORM_MAX_PATH];
 11.1167 -				snprintf(filename, PLATFORM_MAX_PATH, "%s", pExt->GetFilename());
 11.1168 -				UnloadExtension(pExt);
 11.1169 -				g_RootMenu.ConsolePrint("[SM] Extension %s is now unloaded.", filename);
 11.1170 -				return;
 11.1171 -			}
 11.1172 -			else
 11.1173 -			{
 11.1174 -				List<CPlugin *> plugins;
 11.1175 -				if (pExt->m_ChildDeps.size())
 11.1176 -				{
 11.1177 -					g_RootMenu.ConsolePrint("[SM] Unloading %s will unload the following extensions: ", pExt->GetFilename());
 11.1178 -					List<CExtension *>::iterator iter;
 11.1179 -					CExtension *pOther;
 11.1180 -					/* Get list of all extensions */
 11.1181 -					for (iter=m_Libs.begin(); iter!=m_Libs.end(); iter++)
 11.1182 -					{
 11.1183 -						List<IfaceInfo>::iterator i_iter;
 11.1184 -						pOther = (*iter);
 11.1185 -						if (!pOther->IsLoaded() || pOther == pExt)
 11.1186 -						{
 11.1187 -							continue;
 11.1188 -						}
 11.1189 -						/* Get their dependencies */
 11.1190 -						for (i_iter=pOther->m_Deps.begin();
 11.1191 -							 i_iter!=pOther->m_Deps.end();
 11.1192 -							 i_iter++)
 11.1193 -						{
 11.1194 -							/* Is this dependency to us? */
 11.1195 -							if ((*i_iter).owner != pExt)
 11.1196 -							{
 11.1197 -								continue;
 11.1198 -							}
 11.1199 -							/* Will our dependent care? */
 11.1200 -							if (!pExt->GetAPI()->QueryInterfaceDrop((*i_iter).iface))
 11.1201 -							{
 11.1202 -								g_RootMenu.ConsolePrint(" -> %s", pExt->GetFilename());
 11.1203 -								/* Add to plugin unload list */
 11.1204 -								List<CPlugin *>::iterator p_iter;
 11.1205 -								for (p_iter=pOther->m_Dependents.begin();
 11.1206 -									 p_iter!=pOther->m_Dependents.end();
 11.1207 -									 p_iter++)
 11.1208 -								{
 11.1209 -									if (plugins.find((*p_iter)) == plugins.end())
 11.1210 -									{
 11.1211 -										plugins.push_back((*p_iter));
 11.1212 -									}
 11.1213 -								}
 11.1214 -							}
 11.1215 -						}
 11.1216 -					}
 11.1217 -				}
 11.1218 -				if (pExt->m_Dependents.size())
 11.1219 -				{
 11.1220 -					g_RootMenu.ConsolePrint("[SM] Unloading %s will unload the following plugins: ", pExt->GetFilename());
 11.1221 -					List<CPlugin *>::iterator iter;
 11.1222 -					CPlugin *pPlugin;
 11.1223 -					for (iter = pExt->m_Dependents.begin(); iter != pExt->m_Dependents.end(); iter++)
 11.1224 -					{
 11.1225 -						pPlugin = (*iter);
 11.1226 -						if (plugins.find(pPlugin) == plugins.end())
 11.1227 -						{
 11.1228 -							plugins.push_back(pPlugin);
 11.1229 -						}
 11.1230 -					}
 11.1231 -					for (iter = plugins.begin(); iter != plugins.end(); iter++)
 11.1232 -					{
 11.1233 -						pPlugin = (*iter);
 11.1234 -						g_RootMenu.ConsolePrint(" -> %s", pPlugin->GetFilename());
 11.1235 -					}
 11.1236 -				}
 11.1237 -				srand(static_cast<int>(time(NULL)));
 11.1238 -				pExt->unload_code = (rand() % 877) + 123;	//123 to 999
 11.1239 -				g_RootMenu.ConsolePrint("[SM] To verify unloading %s, please use the following: ", pExt->GetFilename());
 11.1240 -				g_RootMenu.ConsolePrint("[SM] sm exts unload %d %d", num, pExt->unload_code);
 11.1241 -
 11.1242 -				return;
 11.1243 -			}
 11.1244 -		}
 11.1245 -		else if (strcmp(cmd, "reload") == 0)
 11.1246 -		{
 11.1247 -			if (argcount < 4)
 11.1248 -			{
 11.1249 -				g_RootMenu.ConsolePrint("[SM] Usage: sm exts reload <#>");
 11.1250 -				return;
 11.1251 -			}
 11.1252 -			
 11.1253 -			const char *arg = command.Arg(3);
 11.1254 -			unsigned int num = atoi(arg);
 11.1255 -			CExtension *pExt = FindByOrder(num);
 11.1256 -
 11.1257 -			if (!pExt)
 11.1258 -			{
 11.1259 -				g_RootMenu.ConsolePrint("[SM] Extension number %d was not found.", num);
 11.1260 -				return;
 11.1261 -			}
 11.1262 -			
 11.1263 -			if (pExt->IsLoaded())
 11.1264 -			{
 11.1265 -				char filename[PLATFORM_MAX_PATH];
 11.1266 -				char error[255];
 11.1267 -				
 11.1268 -				snprintf(filename, PLATFORM_MAX_PATH, "%s", pExt->GetFilename());
 11.1269 -				
 11.1270 -				if (pExt->Reload(error, sizeof(error)))
 11.1271 -				{
 11.1272 -					g_RootMenu.ConsolePrint("[SM] Extension %s is now reloaded.", filename);
 11.1273 -				}
 11.1274 -				else
 11.1275 -				{
 11.1276 -					g_RootMenu.ConsolePrint("[SM] Extension %s failed to reload: %s", filename, error);
 11.1277 -				}
 11.1278 -					
 11.1279 -				return;
 11.1280 -			} 
 11.1281 -			else
 11.1282 -			{
 11.1283 -				g_RootMenu.ConsolePrint("[SM] Extension %s is not loaded.", pExt->GetFilename());
 11.1284 -				
 11.1285 -				return;
 11.1286 -			}
 11.1287 -			
 11.1288 -		}
 11.1289 -	}
 11.1290 -
 11.1291 -	g_RootMenu.ConsolePrint("SourceMod Extensions Menu:");
 11.1292 -	g_RootMenu.DrawGenericOption("info", "Extra extension information");
 11.1293 -	g_RootMenu.DrawGenericOption("list", "List extensions");
 11.1294 -	g_RootMenu.DrawGenericOption("load", "Load an extension");
 11.1295 -	g_RootMenu.DrawGenericOption("reload", "Reload an extension");
 11.1296 -	g_RootMenu.DrawGenericOption("unload", "Unload an extension");
 11.1297 -}
 11.1298 -
 11.1299 -void CExtensionManager::ListExtensionsToClient(CPlayer *player, const CCommand &args)
 11.1300 -{
 11.1301 -	char buffer[256];
 11.1302 -	int numExtensions = m_Libs.size();
 11.1303 -	edict_t *edict = player->GetEdict();
 11.1304 -	unsigned int id = 0;
 11.1305 -	unsigned int start = 0;
 11.1306 -
 11.1307 -	if (!numExtensions)
 11.1308 -	{
 11.1309 -		ClientConsolePrint(edict, "[SM] No extensions found.");
 11.1310 -		return;
 11.1311 -	}
 11.1312 -
 11.1313 -	if (args.ArgC() > 2)
 11.1314 -	{
 11.1315 -		start = atoi(args.Arg(2));
 11.1316 -	}
 11.1317 -
 11.1318 -	CExtension *ext;
 11.1319 -	SourceHook::List<CExtension *>::iterator iter;
 11.1320 -
 11.1321 -	for (iter = m_Libs.begin();
 11.1322 -		 iter != m_Libs.end();
 11.1323 -		 iter++)
 11.1324 -	{
 11.1325 -		ext = (*iter);
 11.1326 -
 11.1327 -		char error[255];
 11.1328 -		if (!ext->IsRunning(error, sizeof(error)))
 11.1329 -		{
 11.1330 -			continue;
 11.1331 -		}
 11.1332 -
 11.1333 -		id++;
 11.1334 -		if (id < start)
 11.1335 -		{
 11.1336 -			continue;
 11.1337 -		}
 11.1338 -
 11.1339 -		if (id - start > 10)
 11.1340 -		{
 11.1341 -			break;
 11.1342 -		}
 11.1343 -
 11.1344 -		IExtensionInterface *api = ext->GetAPI();
 11.1345 -
 11.1346 -		const char *name = api->GetExtensionName();
 11.1347 -		const char *version = api->GetExtensionVerString();
 11.1348 -		const char *author = api->GetExtensionAuthor();
 11.1349 -		const char *description = api->GetExtensionDescription();
 11.1350 -
 11.1351 -		size_t len = UTIL_Format(buffer, sizeof(buffer), " \"%s\"", name);
 11.1352 -
 11.1353 -		if (version != NULL && IS_STR_FILLED(version))
 11.1354 -		{
 11.1355 -			len += UTIL_Format(&buffer[len], sizeof(buffer)-len, " (%s)", version);
 11.1356 -		}
 11.1357 -
 11.1358 -		if (author != NULL && IS_STR_FILLED(author))
 11.1359 -		{
 11.1360 -			len += UTIL_Format(&buffer[len], sizeof(buffer)-len, " by %s", author);
 11.1361 -		}
 11.1362 -
 11.1363 -		if (description != NULL && IS_STR_FILLED(description))
 11.1364 -		{
 11.1365 -			len += UTIL_Format(&buffer[len], sizeof(buffer)-len, ": %s", description);
 11.1366 -		}
 11.1367 -
 11.1368 -
 11.1369 -		ClientConsolePrint(edict, "%s", buffer);
 11.1370 -	}
 11.1371 -
 11.1372 -	while (iter != m_Libs.end())
 11.1373 -	{
 11.1374 -		char error[255];
 11.1375 -		if ((*iter)->IsRunning(error, sizeof(error)))
 11.1376 -		{
 11.1377 -			break;
 11.1378 -		}
 11.1379 -	}
 11.1380 -
 11.1381 -	if (iter != m_Libs.end())
 11.1382 -	{
 11.1383 -		ClientConsolePrint(edict, "To see more, type \"sm exts %d\"", id);
 11.1384 -	}
 11.1385 -}
 11.1386 -
 11.1387 -CExtension *CExtensionManager::GetExtensionFromIdent(IdentityToken_t *ptr)
 11.1388 -{
 11.1389 -	if (ptr->type == g_ExtType)
 11.1390 -	{
 11.1391 -		return (CExtension *)(ptr->ptr);
 11.1392 -	}
 11.1393 -
 11.1394 -	return NULL;
 11.1395 -}
 11.1396 -
 11.1397 -CExtensionManager::CExtensionManager()
 11.1398 -{
 11.1399 -}
 11.1400 -
 11.1401 -CExtensionManager::~CExtensionManager()
 11.1402 -{
 11.1403 -}
 11.1404 -
 11.1405 -void CExtensionManager::AddLibrary(IExtension *pSource, const char *library)
 11.1406 -{
 11.1407 -	CExtension *pExt = (CExtension *)pSource;
 11.1408 -	pExt->AddLibrary(library);
 11.1409 -	g_PluginSys.OnLibraryAction(library, LibraryAction_Added);
 11.1410 -}
 11.1411 -
 11.1412 -bool CExtensionManager::LibraryExists(const char *library)
 11.1413 -{
 11.1414 -	CExtension *pExt;
 11.1415 -
 11.1416 -	for (List<CExtension *>::iterator iter = m_Libs.begin();
 11.1417 -		 iter != m_Libs.end();
 11.1418 -		 iter++)
 11.1419 -	{
 11.1420 -		pExt = (*iter);
 11.1421 -		for (List<String>::iterator s_iter = pExt->m_Libraries.begin();
 11.1422 -			 s_iter != pExt->m_Libraries.end();
 11.1423 -			 s_iter++)
 11.1424 -		{
 11.1425 -			if ((*s_iter).compare(library) == 0)
 11.1426 -			{
 11.1427 -				return true;
 11.1428 -			}
 11.1429 -		}
 11.1430 -	}
 11.1431 -
 11.1432 -	return false;
 11.1433 -}
 11.1434 -
 11.1435 -IExtension *CExtensionManager::LoadExternal(IExtensionInterface *pInterface,
 11.1436 -											const char *filepath,
 11.1437 -											const char *filename,
 11.1438 -											char *error,
 11.1439 -											size_t maxlength)
 11.1440 -{
 11.1441 -	IExtension *pAlready;
 11.1442 -	if ((pAlready=FindExtensionByFile(filename)) != NULL)
 11.1443 -	{
 11.1444 -		return pAlready;
 11.1445 -	}
 11.1446 -
 11.1447 -	CExtension *pExt = new CRemoteExtension(pInterface, filename, filepath);
 11.1448 -
 11.1449 -	if (!pExt->Load(error, maxlength) || !pExt->IsLoaded())
 11.1450 -	{
 11.1451 -		pExt->Unload();
 11.1452 -		delete pExt;
 11.1453 -		return NULL;
 11.1454 -	}
 11.1455 -
 11.1456 -	m_Libs.push_back(pExt);
 11.1457 -
 11.1458 -	return pExt;
 11.1459 -}
 11.1460 -
 11.1461 -void CExtensionManager::CallOnCoreMapStart(edict_t *pEdictList, int edictCount, int clientMax)
 11.1462 -{
 11.1463 -	IExtensionInterface *pAPI;
 11.1464 -	List<CExtension *>::iterator iter;
 11.1465 -
 11.1466 -	for (iter=m_Libs.begin(); iter!=m_Libs.end(); iter++)
 11.1467 -	{
 11.1468 -		if ((pAPI = (*iter)->GetAPI()) == NULL)
 11.1469 -		{
 11.1470 -			continue;
 11.1471 -		}
 11.1472 -		if (pAPI->GetExtensionVersion() > 3)
 11.1473 -		{
 11.1474 -			pAPI->OnCoreMapStart(pEdictList, edictCount, clientMax);
 11.1475 -		}
 11.1476 -	}
 11.1477 -}
 11.1478 -
 11.1479 -bool CLocalExtension::IsSameFile(const char *file)
 11.1480 -{
 11.1481 -	/* Only care about the shortened name. */
 11.1482 -	return strcmp(file, m_File.c_str()) == 0;
 11.1483 -}
 11.1484 -
 11.1485 -bool CRemoteExtension::IsSameFile(const char *file)
 11.1486 -{
 11.1487 -	/* :TODO: this could be better, but no one uses this API anyway. */
 11.1488 -	return strcmp(file, m_Path.c_str()) == 0;
 11.1489 -}
 11.1490 -
    12.1 --- a/core/ExtensionSys.h	Fri Mar 29 12:28:02 2013 -0400
    12.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    12.3 @@ -1,198 +0,0 @@
    12.4 -/**
    12.5 - * vim: set ts=4 :
    12.6 - * =============================================================================
    12.7 - * SourceMod
    12.8 - * Copyright (C) 2004-2008 AlliedModders LLC.  All rights reserved.
    12.9 - * =============================================================================
   12.10 - *
   12.11 - * This program is free software; you can redistribute it and/or modify it under
   12.12 - * the terms of the GNU General Public License, version 3.0, as published by the
   12.13 - * Free Software Foundation.
   12.14 - * 
   12.15 - * This program is distributed in the hope that it will be useful, but WITHOUT
   12.16 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   12.17 - * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
   12.18 - * details.
   12.19 - *
   12.20 - * You should have received a copy of the GNU General Public License along with
   12.21 - * this program.  If not, see <http://www.gnu.org/licenses/>.
   12.22 - *
   12.23 - * As a special exception, AlliedModders LLC gives you permission to link the
   12.24 - * code of this program (as well as its derivative works) to "Half-Life 2," the
   12.25 - * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
   12.26 - * by the Valve Corporation.  You must obey the GNU General Public License in
   12.27 - * all respects for all other code used.  Additionally, AlliedModders LLC grants
   12.28 - * this exception to all derivative works.  AlliedModders LLC defines further
   12.29 - * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
   12.30 - * or <http://www.sourcemod.net/license.php>.
   12.31 - *
   12.32 - * Version: $Id$
   12.33 - */
   12.34 -
   12.35 -#ifndef _INCLUDE_SOURCEMOD_EXTENSION_SYSTEM_H_
   12.36 -#define _INCLUDE_SOURCEMOD_EXTENSION_SYSTEM_H_
   12.37 -
   12.38 -#include <IExtensionSys.h>
   12.39 -#include <ILibrarySys.h>
   12.40 -#include <sh_list.h>
   12.41 -#include <sh_string.h>
   12.42 -#include <sm_trie_tpl.h>
   12.43 -#include "sm_globals.h"
   12.44 -#include "ShareSys.h"
   12.45 -#include <ISmmAPI.h>
   12.46 -#include <IPluginSys.h>
   12.47 -#include <IRootConsoleMenu.h>
   12.48 -#include "PluginSys.h"
   12.49 -#include "NativeOwner.h"
   12.50 -
   12.51 -class CPlayer;
   12.52 -
   12.53 -using namespace SourceMod;
   12.54 -using namespace SourceHook;
   12.55 -
   12.56 -class CExtension;
   12.57 -
   12.58 -struct sm_extnative_t
   12.59 -{
   12.60 -	CExtension *owner;
   12.61 -	const sp_nativeinfo_t *info;
   12.62 -};
   12.63 -
   12.64 -class CExtension : 
   12.65 -	public IExtension,
   12.66 -	public CNativeOwner
   12.67 -{
   12.68 -	friend class CExtensionManager;
   12.69 -public:
   12.70 -	virtual ~CExtension();
   12.71 -public: //IExtension
   12.72 -	IExtensionInterface *GetAPI();
   12.73 -	const char *GetFilename();
   12.74 -	const char *GetPath() const;
   12.75 -	IdentityToken_t *GetIdentity();
   12.76 -	ITERATOR *FindFirstDependency(IExtension **pOwner, SMInterface **pInterface);
   12.77 -	bool FindNextDependency(ITERATOR *iter, IExtension **pOwner, SMInterface **pInterface);
   12.78 -	void FreeDependencyIterator(ITERATOR *iter);
   12.79 -	bool IsRunning(char *error, size_t maxlength);
   12.80 -public:
   12.81 -	void SetError(const char *error);
   12.82 -	void AddDependency(const IfaceInfo *pInfo);
   12.83 -	void AddChildDependent(CExtension *pOther, SMInterface *iface);
   12.84 -	void AddInterface(SMInterface *pInterface);
   12.85 -	void AddPlugin(CPlugin *pPlugin);
   12.86 -	void MarkAllLoaded();
   12.87 -	void AddLibrary(const char *library);
   12.88 -public:
   12.89 -	virtual bool Load(char *error, size_t maxlength);
   12.90 -	virtual bool IsLoaded() =0;
   12.91 -	virtual void Unload() =0;
   12.92 -	virtual bool Reload(char *error, size_t maxlength) =0;
   12.93 -	virtual bool IsSameFile(const char* file) =0;
   12.94 -protected:
   12.95 -	void Initialize(const char *filename, const char *path);
   12.96 -	bool PerformAPICheck(char *error, size_t maxlength);
   12.97 -	void CreateIdentity();
   12.98 -	void DestroyIdentity();
   12.99 -protected:
  12.100 -	IdentityToken_t *m_pIdentToken;
  12.101 -	IExtensionInterface *m_pAPI;
  12.102 -	String m_File;
  12.103 -	String m_RealFile;
  12.104 -	String m_Path;
  12.105 -	String m_Error;
  12.106 -	List<IfaceInfo> m_Deps;			/** Dependencies */
  12.107 -	List<IfaceInfo> m_ChildDeps;	/** Children who might depend on us */
  12.108 -	List<SMInterface *> m_Interfaces;
  12.109 -	List<String> m_Libraries;
  12.110 -	unsigned int unload_code;
  12.111 -	bool m_bFullyLoaded;
  12.112 -};
  12.113 -
  12.114 -class CLocalExtension : public CExtension
  12.115 -{
  12.116 -public:
  12.117 -	CLocalExtension(const char *filename);
  12.118 -public:
  12.119 -	bool Load(char *error, size_t maxlength);
  12.120 -	bool IsLoaded();
  12.121 -	void Unload();
  12.122 -	bool Reload(char *error, size_t maxlength);
  12.123 -	bool IsExternal();
  12.124 -	bool IsSameFile(const char *file);
  12.125 -private:
  12.126 -	PluginId m_PlId;
  12.127 -	ILibrary *m_pLib;
  12.128 -};
  12.129 -
  12.130 -class CRemoteExtension : public CExtension
  12.131 -{
  12.132 -public:
  12.133 -	CRemoteExtension(IExtensionInterface *pAPI, const char *filename, const char *path);
  12.134 -public:
  12.135 -	bool Load(char *error, size_t maxlength);
  12.136 -	bool IsLoaded();
  12.137 -	void Unload();
  12.138 -	bool Reload(char *error, size_t maxlength);
  12.139 -	bool IsExternal();
  12.140 -	bool IsSameFile(const char *file);
  12.141 -};
  12.142 -
  12.143 -class CExtensionManager : 
  12.144 -	public IExtensionManager,
  12.145 -	public SMGlobalClass,
  12.146 -	public IPluginsListener,
  12.147 -	public IRootConsoleCommand
  12.148 -{
  12.149 -public:
  12.150 -	CExtensionManager();
  12.151 -	~CExtensionManager();
  12.152 -public: //SMGlobalClass
  12.153 -	void OnSourceModAllInitialized();
  12.154 -	void OnSourceModShutdown();
  12.155 -public: //IExtensionManager
  12.156 -	IExtension *LoadExtension(const char *path, 
  12.157 -		char *error,
  12.158 -		size_t maxlength);
  12.159 -	bool UnloadExtension(IExtension *pExt);
  12.160 -	IExtension *FindExtensionByFile(const char *file);
  12.161 -	IExtension *FindExtensionByName(const char *ext);
  12.162 -	IExtension *LoadExternal(IExtensionInterface *pInterface,
  12.163 -		const char *filepath,
  12.164 -		const char *filename,
  12.165 -		char *error,
  12.166 -		size_t maxlength);
  12.167 -public: //IPluginsListener
  12.168 -	void OnPluginDestroyed(IPlugin *plugin);
  12.169 -public: //IRootConsoleCommand
  12.170 -	void OnRootConsoleCommand(const char *cmdname, const CCommand &command);
  12.171 -public:
  12.172 -	IExtension *LoadAutoExtension(const char *path, bool bErrorOnMissing=true);
  12.173 -	void BindDependency(IExtension *pOwner, IfaceInfo *pInfo);
  12.174 -	void AddInterface(IExtension *pOwner, SMInterface *pInterface);
  12.175 -	void BindChildPlugin(IExtension *pParent, CPlugin *pPlugin);
  12.176 -	void MarkAllLoaded();
  12.177 -	void AddDependency(IExtension *pSource, const char *file, bool required, bool autoload);
  12.178 -	void TryAutoload();
  12.179 -	void AddLibrary(IExtension *pSource, const char *library);
  12.180 -	bool LibraryExists(const char *library);
  12.181 -	void CallOnCoreMapStart(edict_t *pEdictList, int edictCount, int clientMax);
  12.182 -	void AddRawDependency(IExtension *ext, IdentityToken_t *other, void *iface);
  12.183 -public:
  12.184 -	void ListExtensionsToClient(CPlayer *player, const CCommand &args);
  12.185 -public:
  12.186 -	CExtension *GetExtensionFromIdent(IdentityToken_t *ptr);
  12.187 -	void Shutdown();
  12.188 -	CNativeOwner *GetNativeOwner(IExtension *pExt)
  12.189 -	{
  12.190 -		CExtension *p = (CExtension *)pExt;
  12.191 -		return p;
  12.192 -	}
  12.193 -private:
  12.194 -	CExtension *FindByOrder(unsigned int num);
  12.195 -private:
  12.196 -	List<CExtension *> m_Libs;
  12.197 -};
  12.198 -
  12.199 -extern CExtensionManager g_Extensions;
  12.200 -
  12.201 -#endif //_INCLUDE_SOURCEMOD_EXTENSION_SYSTEM_H_
    13.1 --- a/core/ForwardSys.cpp	Fri Mar 29 12:28:02 2013 -0400
    13.2 +++ b/core/ForwardSys.cpp	Fri Mar 29 11:37:29 2013 -0700
    13.3 @@ -33,8 +33,6 @@
    13.4  #include <stdarg.h>
    13.5  #include <string.h>
    13.6  #include "ForwardSys.h"
    13.7 -#include "PluginSys.h"
    13.8 -#include "ShareSys.h"
    13.9  #include "logic_bridge.h"
   13.10  
   13.11  CForwardManager g_Forwards;
   13.12 @@ -63,8 +61,8 @@
   13.13  
   13.14  void CForwardManager::OnSourceModAllInitialized()
   13.15  {
   13.16 -	g_PluginSys.AddPluginsListener(this);
   13.17 -	g_ShareSys.AddInterface(NULL, this);
   13.18 +	scripts->AddPluginsListener(this);
   13.19 +	sharesys->AddInterface(NULL, this);
   13.20  }
   13.21  
   13.22  IForward *CForwardManager::CreateForward(const char *name, ExecType et, unsigned int num_params, const ParamType *types, ...)
   13.23 @@ -79,7 +77,7 @@
   13.24  
   13.25  	if (fwd)
   13.26  	{
   13.27 -		g_PluginSys.AddFunctionsToForward(name, fwd);
   13.28 +		scripts->AddFunctionsToForward(name, fwd);
   13.29  
   13.30  		m_managed.push_back(fwd);
   13.31  	}
    14.1 --- a/core/HalfLife2.cpp	Fri Mar 29 12:28:02 2013 -0400
    14.2 +++ b/core/HalfLife2.cpp	Fri Mar 29 11:37:29 2013 -0700
    14.3 @@ -51,12 +51,12 @@
    14.4  
    14.5  typedef ICommandLine *(*FakeGetCommandLine)();
    14.6  
    14.7 -#if defined _WIN32
    14.8 -#define TIER0_NAME			"tier0.dll"
    14.9 -#define VSTDLIB_NAME		"vstdlib.dll"
   14.10 -#elif defined __APPLE__
   14.11 -#define TIER0_NAME			"libtier0.dylib"
   14.12 -#define VSTDLIB_NAME		"libvstdlib.dylib"
   14.13 +#if defined _WIN32
   14.14 +#define TIER0_NAME			"tier0.dll"
   14.15 +#define VSTDLIB_NAME		"vstdlib.dll"
   14.16 +#elif defined __APPLE__
   14.17 +#define TIER0_NAME			"libtier0.dylib"
   14.18 +#define VSTDLIB_NAME		"libvstdlib.dylib"
   14.19  #elif defined __linux__
   14.20  #if SOURCE_ENGINE == SE_ORANGEBOXVALVE || SOURCE_ENGINE == SE_CSS
   14.21  #define TIER0_NAME			"libtier0_srv.so"
   14.22 @@ -67,7 +67,7 @@
   14.23  #else
   14.24  #define TIER0_NAME			"tier0_i486.so"
   14.25  #define VSTDLIB_NAME		"vstdlib_i486.so"
   14.26 -#endif
   14.27 +#endif
   14.28  #endif
   14.29  
   14.30  CHalfLife2 g_HL2;
   14.31 @@ -157,7 +157,7 @@
   14.32  	m_HinTextMsg = g_UserMsgs.GetMessageIndex("HintText");
   14.33  	m_SayTextMsg = g_UserMsgs.GetMessageIndex("SayText");
   14.34  	m_VGUIMenu = g_UserMsgs.GetMessageIndex("VGUIMenu");
   14.35 -	g_ShareSys.AddInterface(NULL, this);
   14.36 +	sharesys->AddInterface(NULL, this);
   14.37  }
   14.38  
   14.39  void CHalfLife2::OnSourceModAllInitialized_Post()
   14.40 @@ -241,44 +241,44 @@
   14.41  
   14.42  	if (!g_LibSys.IsPathFile(path))
   14.43  	{
   14.44 -		g_Logger.LogError("Could not find path for: " TIER0_NAME);
   14.45 +		g_Logger.LogError("Could not find path for: " TIER0_NAME);
   14.46  		return;
   14.47  	}
   14.48  
   14.49  	ILibrary *lib = g_LibSys.OpenLibrary(path, error, sizeof(error));
   14.50  	m_pGetCommandLine = lib->GetSymbolAddress("CommandLine_Tier0");
   14.51  
   14.52 -	/* '_Tier0' dropped on Alien Swarm version */
   14.53 -	if (m_pGetCommandLine == NULL)
   14.54 -	{
   14.55 -		m_pGetCommandLine = lib->GetSymbolAddress("CommandLine");
   14.56 +	/* '_Tier0' dropped on Alien Swarm version */
   14.57 +	if (m_pGetCommandLine == NULL)
   14.58 +	{
   14.59 +		m_pGetCommandLine = lib->GetSymbolAddress("CommandLine");
   14.60  	}
   14.61  
   14.62 -	if (m_pGetCommandLine == NULL)
   14.63 -	{
   14.64 -		/* We probably have a Ship engine. */
   14.65 -		lib->CloseLibrary();
   14.66 -		g_SourceMod.BuildPath(Path_Game, path, sizeof(path), "../bin/" VSTDLIB_NAME);
   14.67 -		if (!g_LibSys.IsPathFile(path))
   14.68 -		{
   14.69 -			g_Logger.LogError("Could not find path for: " VSTDLIB_NAME);
   14.70 -			return;
   14.71 -		}
   14.72 -
   14.73 -		if ((lib = g_LibSys.OpenLibrary(path, error, sizeof(error))) == NULL)
   14.74 -		{
   14.75 -			g_Logger.LogError("Could not load %s: %s", path, error);
   14.76 -			return;
   14.77 -		}
   14.78 -
   14.79 -		m_pGetCommandLine = lib->GetSymbolAddress("CommandLine");
   14.80 -
   14.81 -		if (m_pGetCommandLine == NULL)
   14.82 -		{
   14.83 -			g_Logger.LogError("Could not locate any command line functionality");
   14.84 -		}
   14.85 -
   14.86 -		lib->CloseLibrary();
   14.87 +	if (m_pGetCommandLine == NULL)
   14.88 +	{
   14.89 +		/* We probably have a Ship engine. */
   14.90 +		lib->CloseLibrary();
   14.91 +		g_SourceMod.BuildPath(Path_Game, path, sizeof(path), "../bin/" VSTDLIB_NAME);
   14.92 +		if (!g_LibSys.IsPathFile(path))
   14.93 +		{
   14.94 +			g_Logger.LogError("Could not find path for: " VSTDLIB_NAME);
   14.95 +			return;
   14.96 +		}
   14.97 +
   14.98 +		if ((lib = g_LibSys.OpenLibrary(path, error, sizeof(error))) == NULL)
   14.99 +		{
  14.100 +			g_Logger.LogError("Could not load %s: %s", path, error);
  14.101 +			return;
  14.102 +		}
  14.103 +
  14.104 +		m_pGetCommandLine = lib->GetSymbolAddress("CommandLine");
  14.105 +
  14.106 +		if (m_pGetCommandLine == NULL)
  14.107 +		{
  14.108 +			g_Logger.LogError("Could not locate any command line functionality");
  14.109 +		}
  14.110 +
  14.111 +		lib->CloseLibrary();
  14.112  	}
  14.113  }
  14.114  
    15.1 --- a/core/HandleSys.cpp	Fri Mar 29 12:28:02 2013 -0400
    15.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    15.3 @@ -1,1129 +0,0 @@
    15.4 -/**
    15.5 - * vim: set ts=4 :
    15.6 - * =============================================================================
    15.7 - * SourceMod
    15.8 - * Copyright (C) 2004-2008 AlliedModders LLC.  All rights reserved.
    15.9 - * =============================================================================
   15.10 - *
   15.11 - * This program is free software; you can redistribute it and/or modify it under
   15.12 - * the terms of the GNU General Public License, version 3.0, as published by the
   15.13 - * Free Software Foundation.
   15.14 - * 
   15.15 - * This program is distributed in the hope that it will be useful, but WITHOUT
   15.16 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   15.17 - * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
   15.18 - * details.
   15.19 - *
   15.20 - * You should have received a copy of the GNU General Public License along with
   15.21 - * this program.  If not, see <http://www.gnu.org/licenses/>.
   15.22 - *
   15.23 - * As a special exception, AlliedModders LLC gives you permission to link the
   15.24 - * code of this program (as well as its derivative works) to "Half-Life 2," the
   15.25 - * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
   15.26 - * by the Valve Corporation.  You must obey the GNU General Public License in
   15.27 - * all respects for all other code used.  Additionally, AlliedModders LLC grants
   15.28 - * this exception to all derivative works.  AlliedModders LLC defines further
   15.29 - * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
   15.30 - * or <http://www.sourcemod.net/license.php>.
   15.31 - *
   15.32 - * Version: $Id$
   15.33 - */
   15.34 -
   15.35 -#include "HandleSys.h"
   15.36 -#include "ShareSys.h"
   15.37 -#include "PluginSys.h"
   15.38 -#include "ExtensionSys.h"
   15.39 -#include "Logger.h"
   15.40 -#include <assert.h>
   15.41 -#include <string.h>
   15.42 -#include "sm_stringutil.h"
   15.43 -
   15.44 -HandleSystem g_HandleSys;
   15.45 -
   15.46 -QHandle *ignore_handle;
   15.47 -
   15.48 -inline HandleType_t TypeParent(HandleType_t type)
   15.49 -{
   15.50 -	return (type & ~HANDLESYS_SUBTYPE_MASK);
   15.51 -}
   15.52 -
   15.53 -inline HandleError IdentityHandle(IdentityToken_t *token, unsigned int *index)
   15.54 -{
   15.55 -	return g_HandleSys.GetHandle(token->ident, g_ShareSys.GetIdentRoot(), &ignore_handle, index);
   15.56 -}
   15.57 -
   15.58 -HandleSystem::HandleSystem()
   15.59 -{
   15.60 -	m_Handles = new QHandle[HANDLESYS_MAX_HANDLES + 1];
   15.61 -	memset(m_Handles, 0, sizeof(QHandle) * (HANDLESYS_MAX_HANDLES + 1));
   15.62 -
   15.63 -	m_Types = new QHandleType[HANDLESYS_TYPEARRAY_SIZE];
   15.64 -	memset(m_Types, 0, sizeof(QHandleType) * HANDLESYS_TYPEARRAY_SIZE);
   15.65 -
   15.66 -	m_TypeLookup = sm_trie_create();
   15.67 -	m_strtab = new BaseStringTable(512);
   15.68 -
   15.69 -	m_TypeTail = 0;
   15.70 -}
   15.71 -
   15.72 -HandleSystem::~HandleSystem()
   15.73 -{
   15.74 -	delete [] m_Handles;
   15.75 -	delete [] m_Types;
   15.76 -	sm_trie_destroy(m_TypeLookup);
   15.77 -	delete m_strtab;
   15.78 -}
   15.79 -
   15.80 -
   15.81 -HandleType_t HandleSystem::CreateType(const char *name, 
   15.82 -									  IHandleTypeDispatch *dispatch, 
   15.83 -									  HandleType_t parent, 
   15.84 -									  const TypeAccess *typeAccess, 
   15.85 -									  const HandleAccess *hndlAccess, 
   15.86 -									  IdentityToken_t *ident,
   15.87 -									  HandleError *err)
   15.88 -{
   15.89 -	if (!dispatch)
   15.90 -	{
   15.91 -		if (err)
   15.92 -		{
   15.93 -			*err = HandleError_Parameter;
   15.94 -		}
   15.95 -		return 0;
   15.96 -	}
   15.97 -
   15.98 -	if (typeAccess && typeAccess->hsVersion > SMINTERFACE_HANDLESYSTEM_VERSION)
   15.99 -	{
  15.100 -		if (err)
  15.101 -		{
  15.102 -			*err = HandleError_Version;
  15.103 -		}
  15.104 -		return 0;
  15.105 -	}
  15.106 -
  15.107 -	if (hndlAccess && hndlAccess->hsVersion > SMINTERFACE_HANDLESYSTEM_VERSION)
  15.108 -	{
  15.109 -		if (err)
  15.110 -		{
  15.111 -			*err = HandleError_Version;
  15.112 -		}
  15.113 -		return 0;
  15.114 -	}
  15.115 -
  15.116 -	bool isChild = false;
  15.117 -
  15.118 -	if (parent != 0)
  15.119 -	{
  15.120 -		isChild = true;
  15.121 -		if (parent & HANDLESYS_SUBTYPE_MASK)
  15.122 -		{
  15.123 -			if (err)
  15.124 -			{
  15.125 -				*err = HandleError_NoInherit;
  15.126 -			}
  15.127 -			return 0;
  15.128 -		}
  15.129 -		if (parent >= HANDLESYS_TYPEARRAY_SIZE
  15.130 -			|| m_Types[parent].dispatch == NULL)
  15.131 -		{
  15.132 -			if (err)
  15.133 -			{
  15.134 -				*err = HandleError_Parameter;
  15.135 -			}
  15.136 -			return 0;
  15.137 -		}
  15.138 -		if (m_Types[parent].typeSec.access[HTypeAccess_Inherit] == false
  15.139 -			&& (m_Types[parent].typeSec.ident != ident))
  15.140 -		{
  15.141 -			if (err)
  15.142 -			{
  15.143 -				*err = HandleError_Access;
  15.144 -			}
  15.145 -			return 0;
  15.146 -		}
  15.147 -	}
  15.148 -
  15.149 -	if (name && name[0] != '\0')
  15.150 -	{
  15.151 -		if (sm_trie_retrieve(m_TypeLookup, name, NULL))
  15.152 -		{
  15.153 -			if (err)
  15.154 -			{
  15.155 -				*err = HandleError_Parameter;
  15.156 -			}
  15.157 -			return 0;
  15.158 -		}
  15.159 -	}
  15.160 -
  15.161 -	unsigned int index;
  15.162 -
  15.163 -	if (isChild)
  15.164 -	{
  15.165 -		QHandleType *pParent = &m_Types[parent];
  15.166 -		if (pParent->children >= HANDLESYS_MAX_SUBTYPES)
  15.167 -		{
  15.168 -			if (err)
  15.169 -			{
  15.170 -				*err = HandleError_Limit;
  15.171 -			}
  15.172 -			return 0;
  15.173 -		}
  15.174 -		index = 0;
  15.175 -		for (unsigned int i=1; i<=HANDLESYS_MAX_SUBTYPES; i++)
  15.176 -		{
  15.177 -			if (m_Types[parent + i].dispatch == NULL)
  15.178 -			{
  15.179 -				index = parent + i;
  15.180 -				break;
  15.181 -			}
  15.182 -		}
  15.183 -		if (!index)
  15.184 -		{
  15.185 -			if (err)
  15.186 -			{
  15.187 -				*err = HandleError_Limit;
  15.188 -			}
  15.189 -			return 0;
  15.190 -		}
  15.191 -		pParent->children++;
  15.192 -	} else {
  15.193 -		if (m_FreeTypes == 0)
  15.194 -		{
  15.195 -			/* Reserve another index */
  15.196 -			if (m_TypeTail >= HANDLESYS_TYPEARRAY_SIZE)
  15.197 -			{
  15.198 -				if (err)
  15.199 -				{
  15.200 -					*err = HandleError_Limit;
  15.201 -				}
  15.202 -				return 0;
  15.203 -			} else {
  15.204 -				m_TypeTail += (HANDLESYS_MAX_SUBTYPES + 1);
  15.205 -				index = m_TypeTail;
  15.206 -			}
  15.207 -		} else {
  15.208 -			/* The "free array" is compacted into the normal array for easiness */
  15.209 -			index = m_Types[m_FreeTypes--].freeID;
  15.210 -		}
  15.211 -	}
  15.212 -
  15.213 -	QHandleType *pType = &m_Types[index];
  15.214 -	
  15.215 -	pType->dispatch = dispatch;
  15.216 -	if (name && name[0] != '\0')
  15.217 -	{
  15.218 -		pType->nameIdx = m_strtab->AddString(name);
  15.219 -		sm_trie_insert(m_TypeLookup, name, (void *)pType);
  15.220 -	} else {
  15.221 -		pType->nameIdx = -1;
  15.222 -	}
  15.223 -
  15.224 -	pType->opened = 0;
  15.225 -
  15.226 -	if (typeAccess)
  15.227 -	{
  15.228 -		pType->typeSec = *typeAccess;
  15.229 -	} else {
  15.230 -		InitAccessDefaults(&pType->typeSec, NULL);
  15.231 -		pType->typeSec.ident = ident;
  15.232 -	}
  15.233 -
  15.234 -	if (hndlAccess)
  15.235 -	{
  15.236 -		pType->hndlSec = *hndlAccess;
  15.237 -	} else {
  15.238 -		InitAccessDefaults(NULL, &pType->hndlSec);
  15.239 -	}
  15.240 -
  15.241 -	if (!isChild)
  15.242 -	{
  15.243 -		pType->children = 0;
  15.244 -	}
  15.245 -
  15.246 -	return index;
  15.247 -}
  15.248 -
  15.249 -bool HandleSystem::FindHandleType(const char *name, HandleType_t *type)
  15.250 -{
  15.251 -	QHandleType *_type;
  15.252 -
  15.253 -	if (!sm_trie_retrieve(m_TypeLookup, name, (void **)&_type))
  15.254 -	{
  15.255 -		return false;
  15.256 -	}
  15.257 -
  15.258 -	unsigned int offset = _type - m_Types;
  15.259 -
  15.260 -	if (type)
  15.261 -	{
  15.262 -		*type = offset;
  15.263 -	}
  15.264 -
  15.265 -	return true;
  15.266 -}
  15.267 -
  15.268 -HandleError HandleSystem::TryAllocHandle(unsigned int *handle)
  15.269 -{
  15.270 -	if (m_FreeHandles == 0)
  15.271 -	{
  15.272 -		if (m_HandleTail >= HANDLESYS_MAX_HANDLES)
  15.273 -		{
  15.274 -			return HandleError_Limit;;
  15.275 -		}
  15.276 -		*handle = ++m_HandleTail;
  15.277 -	}
  15.278 -	else
  15.279 -	{
  15.280 -		*handle = m_Handles[m_FreeHandles--].freeID;
  15.281 -	}
  15.282 -
  15.283 -	return HandleError_None;
  15.284 -}
  15.285 -
  15.286 -HandleError HandleSystem::MakePrimHandle(HandleType_t type, 
  15.287 -						   QHandle **in_pHandle, 
  15.288 -						   unsigned int *in_index, 
  15.289 -						   Handle_t *in_handle,
  15.290 -						   IdentityToken_t *owner,
  15.291 -						   bool identity)
  15.292 -{
  15.293 -	HandleError err;
  15.294 -	unsigned int owner_index = 0;
  15.295 -
  15.296 -	if (owner && (IdentityHandle(owner, &owner_index) != HandleError_None))
  15.297 -	{
  15.298 -		return HandleError_Identity;
  15.299 -	}
  15.300 -
  15.301 -	unsigned int handle;
  15.302 -	if ((err = TryAllocHandle(&handle)) != HandleError_None)
  15.303 -	{
  15.304 -		if (!TryAndFreeSomeHandles()
  15.305 -			|| (err = TryAllocHandle(&handle)) != HandleError_None)
  15.306 -		{
  15.307 -			return err;
  15.308 -		}
  15.309 -	}
  15.310 -
  15.311 -	QHandle *pHandle = &m_Handles[handle];
  15.312 -	
  15.313 -	assert(pHandle->set == false);
  15.314 -
  15.315 -	if (++m_HSerial >= HANDLESYS_MAX_SERIALS)
  15.316 -	{
  15.317 -		m_HSerial = 1;
  15.318 -	}
  15.319 -
  15.320 -	/* Set essential information */
  15.321 -	pHandle->set = identity ? HandleSet_Identity : HandleSet_Used;
  15.322 -	pHandle->refcount = 1;
  15.323 -	pHandle->type = type;
  15.324 -	pHandle->serial = m_HSerial;
  15.325 -	pHandle->owner = owner;
  15.326 -	pHandle->ch_next = 0;
  15.327 -	pHandle->access_special = false;
  15.328 -	pHandle->is_destroying = false;
  15.329 -
  15.330 -	/* Create the hash value */
  15.331 -	Handle_t hash = pHandle->serial;
  15.332 -	hash <<= 16;
  15.333 -	hash |= handle;
  15.334 -
  15.335 -	/* Add a reference count to the type */
  15.336 -	m_Types[type].opened++;
  15.337 -
  15.338 -	/* Output */
  15.339 -	*in_pHandle = pHandle;
  15.340 -	*in_index = handle;
  15.341 -	*in_handle = hash;
  15.342 -
  15.343 -	/* Decode the identity token 
  15.344 -	 * For now, we don't allow nested ownership
  15.345 -	 */
  15.346 -	if (owner && !identity)
  15.347 -	{
  15.348 -		QHandle *pIdentity = &m_Handles[owner_index];
  15.349 -		if (pIdentity->ch_prev == 0)
  15.350 -		{
  15.351 -			pIdentity->ch_prev = handle;
  15.352 -			pIdentity->ch_next = handle;
  15.353 -			pHandle->ch_prev = 0;
  15.354 -		}
  15.355 -		else
  15.356 -		{
  15.357 -			/* Link previous node to us (forward) */
  15.358 -			m_Handles[pIdentity->ch_next].ch_next = handle;
  15.359 -			/* Link us to previous node (backwards) */
  15.360 -			pHandle->ch_prev = pIdentity->ch_next;
  15.361 -			/* Set new tail */
  15.362 -			pIdentity->ch_next = handle;
  15.363 -		}
  15.364 -		pIdentity->refcount++;
  15.365 -	}
  15.366 -	else
  15.367 -	{
  15.368 -		pHandle->ch_prev = 0;
  15.369 -	}
  15.370 -
  15.371 -	return HandleError_None;
  15.372 -}
  15.373 -
  15.374 -void HandleSystem::SetTypeSecurityOwner(HandleType_t type, IdentityToken_t *pToken)
  15.375 -{
  15.376 -	if (!type
  15.377 -		|| type >= HANDLESYS_TYPEARRAY_SIZE
  15.378 -		|| m_Types[type].dispatch == NULL)
  15.379 -	{
  15.380 -		return;
  15.381 -	}
  15.382 -
  15.383 -	m_Types[type].typeSec.ident = pToken;
  15.384 -}
  15.385 -
  15.386 -Handle_t HandleSystem::CreateHandleInt(HandleType_t type, 
  15.387 -									   void *object, 
  15.388 -									   const HandleSecurity *pSec,
  15.389 -									   HandleError *err, 
  15.390 -									   const HandleAccess *pAccess,
  15.391 -									   bool identity)
  15.392 -{
  15.393 -	IdentityToken_t *ident;
  15.394 -	IdentityToken_t *owner;
  15.395 -
  15.396 -	if (pSec)
  15.397 -	{
  15.398 -		ident = pSec->pIdentity;
  15.399 -		owner = pSec->pOwner;
  15.400 -	} else {
  15.401 -		ident = NULL;
  15.402 -		owner = NULL;
  15.403 -	}
  15.404 -
  15.405 -	if (!type 
  15.406 -		|| type >= HANDLESYS_TYPEARRAY_SIZE
  15.407 -		|| m_Types[type].dispatch == NULL)
  15.408 -	{
  15.409 -		if (err)
  15.410 -		{
  15.411 -			*err = HandleError_Parameter;
  15.412 -		}
  15.413 -		return 0;
  15.414 -	}
  15.415 -
  15.416 -	/* Check to see if we're allowed to create this handle type */
  15.417 -	QHandleType *pType = &m_Types[type];
  15.418 -	if (!pType->typeSec.access[HTypeAccess_Create]
  15.419 -	&& (!pType->typeSec.ident
  15.420 -		|| pType->typeSec.ident != ident))
  15.421 -	{
  15.422 -		if (err)
  15.423 -		{
  15.424 -			*err = HandleError_Access;
  15.425 -		}
  15.426 -		return 0;
  15.427 -	}
  15.428 -
  15.429 -	unsigned int index;
  15.430 -	Handle_t handle;
  15.431 -	QHandle *pHandle;
  15.432 -	HandleError _err;
  15.433 -
  15.434 -	if ((_err=MakePrimHandle(type, &pHandle, &index, &handle, owner, identity)) != HandleError_None)
  15.435 -	{
  15.436 -		if (err)
  15.437 -		{
  15.438 -			*err = _err;
  15.439 -		}
  15.440 -		return 0;
  15.441 -	}
  15.442 -
  15.443 -	if (pAccess)
  15.444 -	{
  15.445 -		pHandle->access_special = true;
  15.446 -		pHandle->sec = *pAccess;
  15.447 -	}
  15.448 -
  15.449 -	pHandle->object = object;
  15.450 -	pHandle->clone = 0;
  15.451 -
  15.452 -	return handle;
  15.453 -}
  15.454 -
  15.455 -Handle_t HandleSystem::CreateHandleEx(HandleType_t type, void *object, const HandleSecurity *pSec, const HandleAccess *pAccess, HandleError *err)
  15.456 -{
  15.457 -	return CreateHandleInt(type, object, pSec, err, pAccess, false);
  15.458 -}
  15.459 -
  15.460 -Handle_t HandleSystem::CreateHandle(HandleType_t type, void *object, IdentityToken_t *owner, IdentityToken_t *ident, HandleError *err)
  15.461 -{
  15.462 -	HandleSecurity sec;
  15.463 -
  15.464 -	sec.pIdentity = ident;
  15.465 -	sec.pOwner = owner;
  15.466 -
  15.467 -	return CreateHandleEx(type, object, &sec, NULL, err);
  15.468 -}
  15.469 -
  15.470 -bool HandleSystem::TypeCheck(HandleType_t intype, HandleType_t outtype)
  15.471 -{
  15.472 -	/* Check the type inheritance */
  15.473 -	if (intype & HANDLESYS_SUBTYPE_MASK)
  15.474 -	{
  15.475 -		if (intype != outtype
  15.476 -			&& (TypeParent(intype) != TypeParent(outtype)))
  15.477 -		{
  15.478 -			return false;
  15.479 -		}
  15.480 -	} else {
  15.481 -		if (intype != outtype)
  15.482 -		{
  15.483 -			return false;
  15.484 -		}
  15.485 -	}
  15.486 -
  15.487 -	return true;
  15.488 -}
  15.489 -
  15.490 -HandleError HandleSystem::GetHandle(Handle_t handle,
  15.491 -									IdentityToken_t *ident, 
  15.492 -									QHandle **in_pHandle, 
  15.493 -									unsigned int *in_index,
  15.494 -									bool ignoreFree)
  15.495 -{
  15.496 -	unsigned int serial = (handle >> 16);
  15.497 -	unsigned int index = (handle & HANDLESYS_HANDLE_MASK);
  15.498 -
  15.499 -	if (index == 0 || index > m_HandleTail || index > HANDLESYS_MAX_HANDLES)
  15.500 -	{
  15.501 -		return HandleError_Index;
  15.502 -	}
  15.503 -
  15.504 -	QHandle *pHandle = &m_Handles[index];
  15.505 -
  15.506 -	if (!pHandle->set
  15.507 -		|| (pHandle->set == HandleSet_Freed && !ignoreFree))
  15.508 -	{
  15.509 -		return HandleError_Freed;
  15.510 -	} else if (pHandle->set == HandleSet_Identity
  15.511 -			   && ident != g_ShareSys.GetIdentRoot())
  15.512 -	{
  15.513 -		/* Only IdentityHandle() can read this! */
  15.514 -		return HandleError_Identity;
  15.515 -	}
  15.516 -	if (pHandle->serial != serial)
  15.517 -	{
  15.518 -		return HandleError_Changed;
  15.519 -	}
  15.520 -
  15.521 -	*in_pHandle = pHandle;
  15.522 -	*in_index = index;
  15.523 -
  15.524 -	return HandleError_None;
  15.525 -}
  15.526 -
  15.527 -bool HandleSystem::CheckAccess(QHandle *pHandle, HandleAccessRight right, const HandleSecurity *pSecurity)
  15.528 -{
  15.529 -	QHandleType *pType = &m_Types[pHandle->type];
  15.530 -	unsigned int access;
  15.531 -
  15.532 -	if (pHandle->access_special)
  15.533 -	{
  15.534 -		access = pHandle->sec.access[right];
  15.535 -	} else {
  15.536 -		access = pType->hndlSec.access[right];
  15.537 -	}
  15.538 -
  15.539 -	/* Check if the type's identity matches */
  15.540 -	if (access & HANDLE_RESTRICT_IDENTITY)
  15.541 -	{
  15.542 -		IdentityToken_t *owner = pType->typeSec.ident;
  15.543 -		if (!owner
  15.544 -			|| (!pSecurity || pSecurity->pIdentity != owner))
  15.545 -		{
  15.546 -			return false;
  15.547 -		}
  15.548 -	}
  15.549 -
  15.550 -	/* Check if the owner is allowed */
  15.551 -	if (access & HANDLE_RESTRICT_OWNER)
  15.552 -	{
  15.553 -		IdentityToken_t *owner = pHandle->owner;
  15.554 -		if (owner
  15.555 -			&& (!pSecurity || pSecurity->pOwner != owner))
  15.556 -		{
  15.557 -			return false;
  15.558 -		}
  15.559 -	}
  15.560 -
  15.561 -	return true;
  15.562 -}
  15.563 -
  15.564 -HandleError HandleSystem::CloneHandle(QHandle *pHandle, unsigned int index, Handle_t *newhandle, IdentityToken_t *newOwner)
  15.565 -{
  15.566 -	/* Get a new Handle ID */
  15.567 -	unsigned int new_index;
  15.568 -	QHandle *pNewHandle;
  15.569 -	Handle_t new_handle;
  15.570 -	HandleError err;
  15.571 -
  15.572 -	if ((err=MakePrimHandle(pHandle->type, &pNewHandle, &new_index, &new_handle, newOwner)) != HandleError_None)
  15.573 -	{
  15.574 -		return err;
  15.575 -	}
  15.576 -
  15.577 -	/* Assign permissions from parent */
  15.578 -	if (pHandle->access_special)
  15.579 -	{
  15.580 -		pNewHandle->access_special = true;
  15.581 -		pNewHandle->sec = pHandle->sec;
  15.582 -	}
  15.583 -
  15.584 -	pNewHandle->clone = index;
  15.585 -	pNewHandle->object = NULL;
  15.586 -	pHandle->refcount++;
  15.587 -
  15.588 -	*newhandle = new_handle;
  15.589 -
  15.590 -	return HandleError_None;
  15.591 -}
  15.592 -
  15.593 -HandleError HandleSystem::CloneHandle(Handle_t handle, Handle_t *newhandle, IdentityToken_t *newOwner, const HandleSecurity *pSecurity)
  15.594 -{
  15.595 -	HandleError err;
  15.596 -	QHandle *pHandle;
  15.597 -	unsigned int index;
  15.598 -	IdentityToken_t *ident = pSecurity ? pSecurity->pIdentity : NULL;
  15.599 -
  15.600 -	if ((err=GetHandle(handle, ident, &pHandle, &index)) != HandleError_None)
  15.601 -	{
  15.602 -		return err;
  15.603 -	}
  15.604 -
  15.605 -	/* Identities cannot be cloned */
  15.606 -	if (pHandle->set == HandleSet_Identity)
  15.607 -	{
  15.608 -		return HandleError_Identity;
  15.609 -	}
  15.610 -
  15.611 -	/* Check if the handle can be cloned */
  15.612 -	if (!CheckAccess(pHandle, HandleAccess_Clone, pSecurity))
  15.613 -	{
  15.614 -		return HandleError_Access;
  15.615 -	}
  15.616 -
  15.617 -	/* Make sure we're not cloning a clone */
  15.618 -	if (pHandle->clone)
  15.619 -	{
  15.620 -		QHandle *pParent = &m_Handles[pHandle->clone];
  15.621 -		return CloneHandle(pParent, pHandle->clone, newhandle, newOwner);
  15.622 -	}
  15.623 -
  15.624 -	return CloneHandle(pHandle, index, newhandle, newOwner);
  15.625 -}
  15.626 -
  15.627 -Handle_t HandleSystem::FastCloneHandle(QHandle *pHandle, unsigned int index)
  15.628 -{
  15.629 -	if (pHandle->clone)
  15.630 -		return FastCloneHandle(&m_Handles[pHandle->clone], pHandle->clone);
  15.631 -
  15.632 -	Handle_t hndl;
  15.633 -	if (CloneHandle(pHandle, index, &hndl, g_pCoreIdent) != HandleError_None)
  15.634 -		return BAD_HANDLE;
  15.635 -
  15.636 -	return hndl;
  15.637 -}
  15.638 -
  15.639 -Handle_t HandleSystem::FastCloneHandle(Handle_t hndl)
  15.640 -{
  15.641 -	QHandle *pHandle;
  15.642 -	unsigned int index;
  15.643 -
  15.644 -	GetHandleUnchecked(hndl, pHandle, index);
  15.645 -
  15.646 -	return FastCloneHandle(pHandle, index);
  15.647 -}
  15.648 -
  15.649 -void HandleSystem::GetHandleUnchecked(Handle_t hndl, QHandle *& pHandle, unsigned int &index)
  15.650 -{
  15.651 -#ifndef NDEBUG
  15.652 -	unsigned int serial = (hndl >> 16);
  15.653 -#endif
  15.654 -	index = (hndl & HANDLESYS_HANDLE_MASK);
  15.655 -
  15.656 -	assert(index != 0 && index <= m_HandleTail && index < HANDLESYS_MAX_HANDLES);
  15.657 -
  15.658 -	pHandle = &m_Handles[index];
  15.659 -
  15.660 -	assert(pHandle->set && pHandle->set != HandleSet_Freed);
  15.661 -	assert(pHandle->serial == serial);
  15.662 -}
  15.663 -
  15.664 -HandleError HandleSystem::FreeHandle(QHandle *pHandle, unsigned int index)
  15.665 -{
  15.666 -	if (pHandle->is_destroying)
  15.667 -	{
  15.668 -		/* Someone tried to free this recursively.  
  15.669 -		 * We'll just ignore this safely.
  15.670 -		 */
  15.671 -		return HandleError_None;
  15.672 -	}
  15.673 -
  15.674 -	QHandleType *pType = &m_Types[pHandle->type];
  15.675 -
  15.676 -	if (pHandle->clone)
  15.677 -	{
  15.678 -		/* If we're a clone, decrease the parent reference count */
  15.679 -		QHandle *pMaster;
  15.680 -		unsigned int master;
  15.681 -
  15.682 -		/* Note that if we ever have per-handle security, we would need to re-check
  15.683 -		* the access on this Handle. */
  15.684 -		master = pHandle->clone;
  15.685 -		pMaster = &m_Handles[master];
  15.686 -
  15.687 -		/* Release the clone now */
  15.688 -		pHandle->is_destroying = true;
  15.689 -		ReleasePrimHandle(index);
  15.690 -
  15.691 -		/* Decrement the master's reference count */
  15.692 -		if (--pMaster->refcount == 0)
  15.693 -		{
  15.694 -			/* Type should be the same but do this anyway... */
  15.695 -			pType = &m_Types[pMaster->type];
  15.696 -			pMaster->is_destroying = true;
  15.697 -			if (pMaster->object)
  15.698 -			{
  15.699 -				pType->dispatch->OnHandleDestroy(pMaster->type, pMaster->object);
  15.700 -			}
  15.701 -			ReleasePrimHandle(master);
  15.702 -		}
  15.703 -	} else if (pHandle->set == HandleSet_Identity) {
  15.704 -		/* If we're an identity, skip all this stuff!
  15.705 -		 * NOTE: SHARESYS DOES NOT CARE ABOUT THE DESTRUCTOR
  15.706 -		 */
  15.707 -		pHandle->is_destroying = true;
  15.708 -		ReleasePrimHandle(index);
  15.709 -	} else {
  15.710 -		/* Decrement, free if necessary */
  15.711 -		if (--pHandle->refcount == 0)
  15.712 -		{
  15.713 -			pHandle->is_destroying = true;
  15.714 -			if (pHandle->object)
  15.715 -			{
  15.716 -				pType->dispatch->OnHandleDestroy(pHandle->type, pHandle->object);
  15.717 -			}
  15.718 -			ReleasePrimHandle(index);
  15.719 -		} else {
  15.720 -			/* We must be cloned, so mark ourselves as freed */
  15.721 -			pHandle->set = HandleSet_Freed;
  15.722 -			/* Now, unlink us, so we're not being tracked by the owner */
  15.723 -			if (pHandle->owner)
  15.724 -			{
  15.725 -				UnlinkHandleFromOwner(pHandle, index);
  15.726 -			}
  15.727 -		}
  15.728 -	}
  15.729 -
  15.730 -	return HandleError_None;
  15.731 -}
  15.732 -
  15.733 -HandleError HandleSystem::FreeHandle(Handle_t handle, const HandleSecurity *pSecurity)
  15.734 -{
  15.735 -	unsigned int index;
  15.736 -	QHandle *pHandle;
  15.737 -	HandleError err;
  15.738 -	IdentityToken_t *ident = pSecurity ? pSecurity->pIdentity : NULL;
  15.739 -
  15.740 -	if ((err=GetHandle(handle, ident, &pHandle, &index)) != HandleError_None)
  15.741 -	{
  15.742 -		return err;
  15.743 -	}
  15.744 -
  15.745 -	if (!CheckAccess(pHandle, HandleAccess_Delete, pSecurity))
  15.746 -	{
  15.747 -		return HandleError_Access;
  15.748 -	}
  15.749 -
  15.750 -	return FreeHandle(pHandle, index);
  15.751 -}
  15.752 -
  15.753 -HandleError HandleSystem::ReadHandle(Handle_t handle, HandleType_t type, const HandleSecurity *pSecurity, void **object)
  15.754 -{
  15.755 -	unsigned int index;
  15.756 -	QHandle *pHandle;
  15.757 -	HandleError err;
  15.758 -	IdentityToken_t *ident = pSecurity ? pSecurity->pIdentity : NULL;
  15.759 -
  15.760 -	if ((err=GetHandle(handle, ident, &pHandle, &index)) != HandleError_None)
  15.761 -	{
  15.762 -		return err;
  15.763 -	}
  15.764 -
  15.765 -	if (!CheckAccess(pHandle, HandleAccess_Read, pSecurity))
  15.766 -	{
  15.767 -		return HandleError_Access;
  15.768 -	}
  15.769 -
  15.770 -	/* Check the type inheritance */
  15.771 -	if (pHandle->type & HANDLESYS_SUBTYPE_MASK)
  15.772 -	{
  15.773 -		if (pHandle->type != type
  15.774 -			&& (TypeParent(pHandle->type) != TypeParent(type)))
  15.775 -		{
  15.776 -			return HandleError_Type;
  15.777 -		}
  15.778 -	} else if (type) {
  15.779 -		if (pHandle->type != type)
  15.780 -		{
  15.781 -			return HandleError_Type;
  15.782 -		}
  15.783 -	}
  15.784 -
  15.785 -	if (object)
  15.786 -	{
  15.787 -		/* if we're a clone, the rules change - object is ONLY in our reference */
  15.788 -		if (pHandle->clone)
  15.789 -		{
  15.790 -			pHandle = &m_Handles[pHandle->clone];
  15.791 -		}
  15.792 -		*object = pHandle->object;
  15.793 -	}
  15.794 -
  15.795 -	return HandleError_None;
  15.796 -}
  15.797 -
  15.798 -void HandleSystem::UnlinkHandleFromOwner(QHandle *pHandle, unsigned int index)
  15.799 -{
  15.800 -	/* Unlink us if necessary */
  15.801 -	unsigned int ident_index;
  15.802 -	if (IdentityHandle(pHandle->owner, &ident_index) != HandleError_None)
  15.803 -	{
  15.804 -		/* Uh-oh! */
  15.805 -		assert(pHandle->owner == 0);
  15.806 -		return;
  15.807 -	}
  15.808 -
  15.809 -	pHandle->owner = NULL;
  15.810 -
  15.811 -	/* Note that since 0 is an invalid handle, if any of these links are 0,
  15.812 -	* the data can still be set.
  15.813 -	*/
  15.814 -	QHandle *pIdentity = &m_Handles[ident_index];
  15.815 -
  15.816 -	/* Unlink case: We're the head AND tail node */
  15.817 -	if (index == pIdentity->ch_prev && index == pIdentity->ch_next)
  15.818 -	{
  15.819 -		pIdentity->ch_prev = 0;
  15.820 -		pIdentity->ch_next = 0;
  15.821 -	}
  15.822 -	/* Unlink case: We're the head node */
  15.823 -	else if (index == pIdentity->ch_prev) {
  15.824 -		/* Link us to the next in the chain */
  15.825 -		pIdentity->ch_prev = pHandle->ch_next;
  15.826 -		/* Patch up the previous link */
  15.827 -		m_Handles[pHandle->ch_next].ch_prev = 0;
  15.828 -	}
  15.829 -	/* Unlink case: We're the tail node */
  15.830 -	else if (index == pIdentity->ch_next) {
  15.831 -		/* Link us to the previous in the chain */
  15.832 -		pIdentity->ch_next = pHandle->ch_prev;
  15.833 -		/* Patch up the next link */
  15.834 -		m_Handles[pHandle->ch_prev].ch_next = 0;
  15.835 -	}
  15.836 -	/* Unlink case: We're in the middle! */
  15.837 -	else {
  15.838 -		/* Patch the forward reference */
  15.839 -		m_Handles[pHandle->ch_next].ch_prev = pHandle->ch_prev;
  15.840 -		/* Patch the backward reference */
  15.841 -		m_Handles[pHandle->ch_prev].ch_next = pHandle->ch_next;
  15.842 -	}
  15.843 -
  15.844 -	/* Lastly, decrease the reference count */
  15.845 -	pIdentity->refcount--;
  15.846 -}
  15.847 -
  15.848 -void HandleSystem::ReleasePrimHandle(unsigned int index)
  15.849 -{
  15.850 -	QHandle *pHandle = &m_Handles[index];
  15.851 -	HandleSet set = pHandle->set;
  15.852 -
  15.853 -	if (pHandle->owner && (set != HandleSet_Identity))
  15.854 -	{
  15.855 -		UnlinkHandleFromOwner(pHandle, index);
  15.856 -	}
  15.857 -
  15.858 -	/* Were we an identity ourself? */
  15.859 -	QHandle *pLocal;
  15.860 -	if (set == HandleSet_Identity)
  15.861 -	{
  15.862 -		/* Extra work to do.  We need to find everything connected to this identity and release it. */
  15.863 -		unsigned int ch_index;
  15.864 -#if defined _DEBUG
  15.865 -		unsigned int old_index = 0;
  15.866 -#endif
  15.867 -		while ((ch_index = pHandle->ch_next) != 0)
  15.868 -		{
  15.869 -			pLocal = &m_Handles[ch_index];
  15.870 -#if defined _DEBUG
  15.871 -			assert(old_index != ch_index);
  15.872 -			assert(pLocal->set == HandleSet_Used);
  15.873 -			old_index = ch_index;
  15.874 -#endif
  15.875 -			FreeHandle(pLocal, ch_index);
  15.876 -		}
  15.877 -	}
  15.878 -
  15.879 -	pHandle->set = HandleSet_None;
  15.880 -	m_Types[pHandle->type].opened--;
  15.881 -	m_Handles[++m_FreeHandles].freeID = index;
  15.882 -}
  15.883 -
  15.884 -bool HandleSystem::RemoveType(HandleType_t type, IdentityToken_t *ident)
  15.885 -{
  15.886 -	if (type == 0 || type >= HANDLESYS_TYPEARRAY_SIZE)
  15.887 -	{
  15.888 -		return false;
  15.889 -	}
  15.890 -
  15.891 -	QHandleType *pType = &m_Types[type];
  15.892 -
  15.893 -	if (pType->typeSec.ident
  15.894 -		&& pType->typeSec.ident != ident)
  15.895 -	{
  15.896 -		return false;
  15.897 -	}
  15.898 -
  15.899 -	if (pType->dispatch == NULL)
  15.900 -	{
  15.901 -		return false;
  15.902 -	}
  15.903 -
  15.904 -	/* Remove children if we have to */
  15.905 -	if (!(type & HANDLESYS_SUBTYPE_MASK))
  15.906 -	{
  15.907 -		QHandleType *childType;
  15.908 -		for (unsigned int i=1; i<=HANDLESYS_MAX_SUBTYPES; i++)
  15.909 -		{
  15.910 -			childType = &m_Types[type + i];
  15.911 -			if (childType->dispatch)
  15.912 -			{
  15.913 -				RemoveType(type + i, childType->typeSec.ident);
  15.914 -			}
  15.915 -		}
  15.916 -		/* Link us into the free chain */
  15.917 -		m_Types[++m_FreeTypes].freeID = type;
  15.918 -	}
  15.919 -
  15.920 -	/* Invalidate the type now */
  15.921 -	IHandleTypeDispatch *dispatch = pType->dispatch;
  15.922 -	pType->dispatch = NULL;
  15.923 -
  15.924 -	/* Make sure nothing is using this type. */
  15.925 -	if (pType->opened)
  15.926 -	{
  15.927 -		QHandle *pHandle;
  15.928 -		for (unsigned int i=1; i<=m_HandleTail; i++)
  15.929 -		{
  15.930 -			pHandle = &m_Handles[i];
  15.931 -			if (!pHandle->set || pHandle->type != type)
  15.932 -			{
  15.933 -				continue;
  15.934 -			}
  15.935 -
  15.936 -			FreeHandle(pHandle, i);
  15.937 -
  15.938 -			if (pType->opened == 0)
  15.939 -			{
  15.940 -				break;
  15.941 -			}
  15.942 -		}
  15.943 -	}
  15.944 -
  15.945 -	/* Remove it from the type cache. */
  15.946 -	if (pType->nameIdx != -1)
  15.947 -	{
  15.948 -		const char *typeName;
  15.949 -
  15.950 -		typeName = m_strtab->GetString(pType->nameIdx);
  15.951 -		sm_trie_delete(m_TypeLookup, typeName);
  15.952 -	}
  15.953 -
  15.954 -	return true;
  15.955 -}
  15.956 -
  15.957 -bool HandleSystem::InitAccessDefaults(TypeAccess *pTypeAccess, HandleAccess *pHandleAccess)
  15.958 -{
  15.959 -	if (pTypeAccess)
  15.960 -	{
  15.961 -		if (pTypeAccess->hsVersion > SMINTERFACE_HANDLESYSTEM_VERSION)
  15.962 -		{
  15.963 -			return false;
  15.964 -		}
  15.965 -		pTypeAccess->access[HTypeAccess_Create] = false;
  15.966 -		pTypeAccess->access[HTypeAccess_Inherit] = false;
  15.967 -		pTypeAccess->ident = NULL;
  15.968 -	}
  15.969 -
  15.970 -	if (pHandleAccess)
  15.971 -	{
  15.972 -		if (pHandleAccess->hsVersion > SMINTERFACE_HANDLESYSTEM_VERSION)
  15.973 -		{
  15.974 -			return false;
  15.975 -		}
  15.976 -
  15.977 -		pHandleAccess->access[HandleAccess_Clone] = 0;
  15.978 -		pHandleAccess->access[HandleAccess_Delete] = HANDLE_RESTRICT_OWNER;
  15.979 -		pHandleAccess->access[HandleAccess_Read] = HANDLE_RESTRICT_IDENTITY;
  15.980 -	}
  15.981 -
  15.982 -	return true;
  15.983 -}
  15.984 -
  15.985 -#define HANDLE_LOG_VERY_BAD(message, ...) \
  15.986 -	g_Logger.LogFatal(message, ##__VA_ARGS__); \
  15.987 -	g_Logger.LogError(message, ##__VA_ARGS__);
  15.988 -
  15.989 -bool HandleSystem::TryAndFreeSomeHandles()
  15.990 -{
  15.991 -	IPluginIterator *pl_iter = g_PluginSys.GetPluginIterator();
  15.992 -	IPlugin *highest_owner = NULL;
  15.993 -	unsigned int highest_handle_count = 0;
  15.994 -
  15.995 -	/* Search all plugins */
  15.996 -	while (pl_iter->MorePlugins())
  15.997 -	{
  15.998 -		IPlugin *plugin = pl_iter->GetPlugin();
  15.999 -		IdentityToken_t *identity = plugin->GetIdentity();
 15.1000 -		unsigned int handle_count = 0;
 15.1001 -
 15.1002 -		if (identity == NULL)
 15.1003 -		{
 15.1004 -			continue;
 15.1005 -		}
 15.1006 -
 15.1007 -		/* Search all handles */
 15.1008 -		for (unsigned int i = 1; i <= m_HandleTail; i++)
 15.1009 -		{
 15.1010 -			if (m_Handles[i].set != HandleSet_Used)
 15.1011 -			{
 15.1012 -				continue;
 15.1013 -			}
 15.1014 -			if (m_Handles[i].owner == identity)
 15.1015 -			{
 15.1016 -				handle_count++;
 15.1017 -			}
 15.1018 -		}
 15.1019 -
 15.1020 -		if (handle_count > highest_handle_count)
 15.1021 -		{
 15.1022 -			highest_owner = plugin;
 15.1023 -			highest_handle_count = handle_count;
 15.1024 -		}
 15.1025 -
 15.1026 -		pl_iter->NextPlugin();
 15.1027 -	}
 15.1028 -
 15.1029 -	if (highest_owner == NULL || highest_handle_count == 0)
 15.1030 -	{
 15.1031 -		return false;
 15.1032 -	}
 15.1033 -
 15.1034 -	HANDLE_LOG_VERY_BAD("[SM] MEMORY LEAK DETECTED IN PLUGIN (file \"%s\")", highest_owner->GetFilename());
 15.1035 -	HANDLE_LOG_VERY_BAD("[SM] Unloading plugin to free %d handles.", highest_handle_count);
 15.1036 -	HANDLE_LOG_VERY_BAD("[SM] Contact the author(s) of this plugin to correct this error.", highest_handle_count);
 15.1037 -
 15.1038 -	highest_owner->GetBaseContext()->ThrowNativeErrorEx(SP_ERROR_MEMACCESS, "Memory leak");
 15.1039 -
 15.1040 -	return g_PluginSys.UnloadPlugin(highest_owner);
 15.1041 -}
 15.1042 -
 15.1043 -void HandleSystem::Dump(HANDLE_REPORTER rep)
 15.1044 -{
 15.1045 -	unsigned int total_size = 0;
 15.1046 -	rep("%-10.10s\t%-20.20s\t%-20.20s\t%-10.10s", "Handle", "Owner", "Type", "Memory");
 15.1047 -	rep("--------------------------------------------------------------------------");
 15.1048 -	for (unsigned int i = 1; i <= m_HandleTail; i++)
 15.1049 -	{
 15.1050 -		if (m_Handles[i].set != HandleSet_Used)
 15.1051 -		{
 15.1052 -			continue;
 15.1053 -		}
 15.1054 -		/* Get the index */
 15.1055 -		unsigned int index = (m_Handles[i].serial << 16) | i;
 15.1056 -		/* Determine the owner */
 15.1057 -		const char *owner = "UNKNOWN";
 15.1058 -		if (m_Handles[i].owner)
 15.1059 -		{
 15.1060 -			IdentityToken_t *pOwner = m_Handles[i].owner;
 15.1061 -			if (pOwner == g_pCoreIdent)
 15.1062 -			{
 15.1063 -				owner = "CORE";
 15.1064 -			}
 15.1065 -			else if (pOwner == g_PluginSys.GetIdentity())
 15.1066 -			{
 15.1067 -				owner = "PLUGINSYS";
 15.1068 -			}
 15.1069 -			else
 15.1070 -			{
 15.1071 -				CExtension *ext = g_Extensions.GetExtensionFromIdent(pOwner);
 15.1072 -				if (ext)
 15.1073 -				{
 15.1074 -					owner = ext->GetFilename();
 15.1075 -				}
 15.1076 -				else
 15.1077 -				{
 15.1078 -					CPlugin *pPlugin = g_PluginSys.GetPluginFromIdentity(pOwner);
 15.1079 -					if (pPlugin)
 15.1080 -					{
 15.1081 -						owner = pPlugin->GetFilename();
 15.1082 -					}
 15.1083 -				}
 15.1084 -			}
 15.1085 -		}
 15.1086 -		else
 15.1087 -		{
 15.1088 -			owner = "NONE";
 15.1089 -		}
 15.1090 -		const char *type = "ANON";
 15.1091 -		QHandleType *pType = &m_Types[m_Handles[i].type];
 15.1092 -		unsigned int size = 0;
 15.1093 -		unsigned int parentIdx;
 15.1094 -		bool bresult;
 15.1095 -		if (pType->nameIdx != -1)
 15.1096 -		{
 15.1097 -			type = m_strtab->GetString(pType->nameIdx);
 15.1098 -		}
 15.1099 -
 15.1100 -		if ((parentIdx = m_Handles[i].clone) != 0)
 15.1101 -		{
 15.1102 -			if (m_Handles[parentIdx].refcount > 0)
 15.1103 -			{
 15.1104 -				size = 0;
 15.1105 -				bresult = true;
 15.1106 -			}
 15.1107 -			else
 15.1108 -			{
 15.1109 -				bresult = pType->dispatch->GetHandleApproxSize(m_Handles[parentIdx].type, m_Handles[parentIdx].object, &size);
 15.1110 -			}
 15.1111 -		}
 15.1112 -		else
 15.1113 -		{
 15.1114 -			bresult = pType->dispatch->GetHandleApproxSize(m_Handles[i].type, m_Handles[i].object, &size);
 15.1115 -		}
 15.1116 -
 15.1117 -		if (pType->dispatch->GetDispatchVersion() < HANDLESYS_MEMUSAGE_MIN_VERSION
 15.1118 -			|| !bresult)
 15.1119 -		{
 15.1120 -			rep("0x%08x\t%-20.20s\t%-20.20s\t%-10.10s", index, owner, type, "-1");
 15.1121 -		}
 15.1122 -		else
 15.1123 -		{
 15.1124 -			char buffer[32];
 15.1125 -			UTIL_Format(buffer, sizeof(buffer), "%d", size);
 15.1126 -			rep("0x%08x\t%-20.20s\t%-20.20s\t%-10.10s", index, owner, type, buffer);
 15.1127 -			total_size += size;
 15.1128 -		}
 15.1129 -	}
 15.1130 -	rep("-- Approximately %d bytes of memory are in use by Handles.\n", total_size);
 15.1131 -}
 15.1132 -
    16.1 --- a/core/HandleSys.h	Fri Mar 29 12:28:02 2013 -0400
    16.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    16.3 @@ -1,254 +0,0 @@
    16.4 -/**
    16.5 - * vim: set ts=4 :
    16.6 - * =============================================================================
    16.7 - * SourceMod
    16.8 - * Copyright (C) 2004-2008 AlliedModders LLC.  All rights reserved.
    16.9 - * =============================================================================
   16.10 - *
   16.11 - * This program is free software; you can redistribute it and/or modify it under
   16.12 - * the terms of the GNU General Public License, version 3.0, as published by the
   16.13 - * Free Software Foundation.
   16.14 - * 
   16.15 - * This program is distributed in the hope that it will be useful, but WITHOUT
   16.16 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   16.17 - * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
   16.18 - * details.
   16.19 - *
   16.20 - * You should have received a copy of the GNU General Public License along with
   16.21 - * this program.  If not, see <http://www.gnu.org/licenses/>.
   16.22 - *
   16.23 - * As a special exception, AlliedModders LLC gives you permission to link the
   16.24 - * code of this program (as well as its derivative works) to "Half-Life 2," the
   16.25 - * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
   16.26 - * by the Valve Corporation.  You must obey the GNU General Public License in
   16.27 - * all respects for all other code used.  Additionally, AlliedModders LLC grants
   16.28 - * this exception to all derivative works.  AlliedModders LLC defines further
   16.29 - * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
   16.30 - * or <http://www.sourcemod.net/license.php>.
   16.31 - *
   16.32 - * Version: $Id$
   16.33 - */
   16.34 -
   16.35 -#ifndef _INCLUDE_SOURCEMOD_HANDLESYSTEM_H_
   16.36 -#define _INCLUDE_SOURCEMOD_HANDLESYSTEM_H_
   16.37 -
   16.38 -#include <IHandleSys.h>
   16.39 -#include <stdio.h>
   16.40 -#include "sm_globals.h"
   16.41 -#include "sm_trie.h"
   16.42 -#include "sourcemod.h"
   16.43 -#include "sm_memtable.h"
   16.44 -
   16.45 -#define HANDLESYS_MAX_HANDLES		(1<<14)
   16.46 -#define HANDLESYS_MAX_TYPES			(1<<9)
   16.47 -#define HANDLESYS_MAX_SUBTYPES		0xF
   16.48 -#define HANDLESYS_SUBTYPE_MASK		0xF
   16.49 -#define HANDLESYS_TYPEARRAY_SIZE	(HANDLESYS_MAX_TYPES * (HANDLESYS_MAX_SUBTYPES + 1))
   16.50 -#define HANDLESYS_MAX_SERIALS		0xFFFF
   16.51 -#define HANDLESYS_SERIAL_MASK		0xFFFF0000
   16.52 -#define HANDLESYS_HANDLE_MASK		0x0000FFFF
   16.53 -
   16.54 -#define HANDLESYS_MEMUSAGE_MIN_VERSION		3
   16.55 -
   16.56 -/**
   16.57 - *   The QHandle is a nasty structure that compacts the handle system into a big vector.
   16.58 - * The members of the vector each encapsulate one Handle, however, they also act as nodes
   16.59 - * in an inlined linked list and an inlined vector.
   16.60 - *
   16.61 - *   The first of these lists is the 'freeID' list.  Each node from 1 to N (where N
   16.62 - * is the number of free nodes) has a 'freeID' that specifies a free Handle ID.  This
   16.63 - * is a quick hack to get around allocating a second base vector.
   16.64 - *
   16.65 - *   The second vector is the identity linked list.  An identity has its own handle, so
   16.66 - * these handles are used as sentinel nodes for index linking.  They point to the first and last
   16.67 - * index into the handle array.  Each subsequent Handle who is owned by that identity is mapped into
   16.68 - * that list.  This lets owning identities be unloaded in O(n) time.
   16.69 - *
   16.70 - *   Eventually, there may be a third list for type chains.
   16.71 - */
   16.72 -
   16.73 -enum HandleSet
   16.74 -{
   16.75 -	HandleSet_None = 0,
   16.76 -	HandleSet_Used,			/* The Handle is in use */
   16.77 -	HandleSet_Freed,		/* The "master" Handle of a clone chain is freed */
   16.78 -	HandleSet_Identity,		/* The Handle is a special identity */
   16.79 -};
   16.80 -
   16.81 -struct QHandle
   16.82 -{
   16.83 -	HandleType_t type;			/* Handle type */
   16.84 -	void *object;				/* Unmaintained object pointer */
   16.85 -	IdentityToken_t *owner;		/* Identity of object which owns this */
   16.86 -	unsigned int serial;		/* Serial no. for sanity checking */
   16.87 -	unsigned int refcount;		/* Reference count for safe destruction */
   16.88 -	unsigned int clone;			/* If non-zero, this is our cloned parent index */
   16.89 -	HandleSet set;				/* Information about the handle's state */
   16.90 -	bool access_special;		/* Whether or not access rules are special or type-derived */
   16.91 -	bool is_destroying;			/* Whether or not the handle is being destroyed */
   16.92 -	HandleAccess sec;			/* Security rules */
   16.93 -	/* The following variables are unrelated to the Handle array, and used 
   16.94 -	 * as an inlined chain of information */
   16.95 -	unsigned int freeID;		/* ID of a free handle in the free handle chain */
   16.96 -	/* Indexes into the handle array for owner membership.
   16.97 -	 * For identity roots, these are treated as the head/tail. */
   16.98 -	unsigned int ch_prev;		/* chained previous handle */
   16.99 -	unsigned int ch_next;		/* chained next handle */
  16.100 -};
  16.101 -
  16.102 -struct QHandleType
  16.103 -{
  16.104 -	IHandleTypeDispatch *dispatch;
  16.105 -	unsigned int freeID;
  16.106 -	unsigned int children;
  16.107 -	TypeAccess typeSec;
  16.108 -	HandleAccess hndlSec;
  16.109 -	unsigned int opened;
  16.110 -	int nameIdx;
  16.111 -};
  16.112 -
  16.113 -typedef void (HANDLE_REPORTER)(const char *str, ...);
  16.114 -
  16.115 -class HandleSystem : 
  16.116 -	public IHandleSys
  16.117 -{
  16.118 -	friend HandleError IdentityHandle(IdentityToken_t *token, unsigned int *index);
  16.119 -	friend class ShareSystem;
  16.120 -public:
  16.121 -	HandleSystem();
  16.122 -	~HandleSystem();
  16.123 -public: //IHandleSystem
  16.124 -
  16.125 -	HandleType_t CreateType(const char *name,
  16.126 -		IHandleTypeDispatch *dispatch,
  16.127 -		HandleType_t parent,
  16.128 -		const TypeAccess *typeAccess,
  16.129 -		const HandleAccess *hndlAccess,
  16.130 -		IdentityToken_t *ident,
  16.131 -		HandleError *err);
  16.132 -
  16.133 -	bool RemoveType(HandleType_t type, IdentityToken_t *ident);
  16.134 -
  16.135 -	bool FindHandleType(const char *name, HandleType_t *type);
  16.136 -
  16.137 -	Handle_t CreateHandle(HandleType_t type, 
  16.138 -		void *object,
  16.139 -		IdentityToken_t *owner,
  16.140 -		IdentityToken_t *ident,
  16.141 -		HandleError *err);
  16.142 -
  16.143 -	HandleError FreeHandle(Handle_t handle, const HandleSecurity *pSecurity);
  16.144 -
  16.145 -	HandleError CloneHandle(Handle_t handle, 
  16.146 -		Handle_t *newhandle, 
  16.147 -		IdentityToken_t *newOwner,
  16.148 -		const HandleSecurity *pSecurity);
  16.149 -
  16.150 -	HandleError ReadHandle(Handle_t handle, 
  16.151 -		HandleType_t type, 
  16.152 -		const HandleSecurity *pSecurity,
  16.153 -		void **object);
  16.154 -
  16.155 -	bool InitAccessDefaults(TypeAccess *pTypeAccess, HandleAccess *pHandleAccess);
  16.156 -
  16.157 -	bool TypeCheck(HandleType_t intype, HandleType_t outtype);
  16.158 -
  16.159 -	virtual Handle_t CreateHandleEx(HandleType_t type, 
  16.160 -		void *object,
  16.161 -		const HandleSecurity *pSec,
  16.162 -		const HandleAccess *pAccess,
  16.163 -		HandleError *err);
  16.164 -
  16.165 -	void Dump(HANDLE_REPORTER rep);
  16.166 -
  16.167 -	/* Bypasses security checks. */
  16.168 -	Handle_t FastCloneHandle(Handle_t hndl);
  16.169 -protected:
  16.170 -	/**
  16.171 -	 * Decodes a handle with sanity and security checking.
  16.172 -	 */
  16.173 -	HandleError GetHandle(Handle_t handle, 
  16.174 -						  IdentityToken_t *ident, 
  16.175 -						  QHandle **pHandle, 
  16.176 -						  unsigned int *index,
  16.177 -						  bool ignoreFree=false);
  16.178 -
  16.179 -	Handle_t FastCloneHandle(QHandle *pHandle, unsigned int index);
  16.180 -	void GetHandleUnchecked(Handle_t hndl, QHandle *& pHandle, unsigned int &index);
  16.181 -
  16.182 -	/**
  16.183 -	 * Creates a basic handle and sets its reference count to 1.
  16.184 -	 * Does not do any type or security checking.
  16.185 -	 */
  16.186 -	HandleError MakePrimHandle(HandleType_t type, 
  16.187 -							   QHandle **pHandle, 
  16.188 -							   unsigned int *index, 
  16.189 -							   HandleType_t *handle,
  16.190 -							   IdentityToken_t *owner,
  16.191 -							   bool identity=false);
  16.192 -
  16.193 -	/**
  16.194 -	 * Frees a primitive handle.  Does no object freeing, only reference count, bookkeeping, 
  16.195 -	 * and linked list maintenance.
  16.196 -	 * If used on an Identity handle, destroys all Handles under that identity.
  16.197 -	 */
  16.198 -	void ReleasePrimHandle(unsigned int index);
  16.199 -
  16.200 -	/**
  16.201 -	 * Sets the security owner of a type.
  16.202 -	 */
  16.203 -	void SetTypeSecurityOwner(HandleType_t type, IdentityToken_t *pToken);
  16.204 -
  16.205 -	/**
  16.206 -	 * Helper function to check access rights.
  16.207 -	 */
  16.208 -	bool CheckAccess(QHandle *pHandle, HandleAccessRight right, const HandleSecurity *pSecurity);
  16.209 -
  16.210 -	/** 
  16.211 -	 * Some wrappers for internal functions, so we can pass indexes instead of encoded handles.
  16.212 -	 */
  16.213 -	HandleError FreeHandle(QHandle *pHandle, unsigned int index);
  16.214 -	void UnlinkHandleFromOwner(QHandle *pHandle, unsigned int index);
  16.215 -	HandleError CloneHandle(QHandle *pHandle, unsigned int index, Handle_t *newhandle, IdentityToken_t *newOwner);
  16.216 -	Handle_t CreateHandleInt(HandleType_t type, void *object, const HandleSecurity *pSec, HandleError *err, const HandleAccess *pAccess, bool identity);
  16.217 -
  16.218 -	bool TryAndFreeSomeHandles();
  16.219 -	HandleError TryAllocHandle(unsigned int *handle);
  16.220 -private:
  16.221 -	QHandle *m_Handles;
  16.222 -	QHandleType *m_Types;
  16.223 -	Trie *m_TypeLookup;
  16.224 -	unsigned int m_TypeTail;
  16.225 -	unsigned int m_FreeTypes;
  16.226 -	unsigned int m_HandleTail;
  16.227 -	unsigned int m_FreeHandles;
  16.228 -	unsigned int m_HSerial;
  16.229 -	BaseStringTable *m_strtab;
  16.230 -};
  16.231 -
  16.232 -extern HandleSystem g_HandleSys;
  16.233 -
  16.234 -struct AutoHandleRooter
  16.235 -{
  16.236 -public:
  16.237 -	AutoHandleRooter(Handle_t hndl)
  16.238 -	{
  16.239 -		if (hndl != BAD_HANDLE)
  16.240 -			this->hndl = g_HandleSys.FastCloneHandle(hndl);
  16.241 -		else
  16.242 -			this->hndl = BAD_HANDLE;
  16.243 -	}
  16.244 -
  16.245 -	~AutoHandleRooter()
  16.246 -	{
  16.247 -		if (hndl != BAD_HANDLE)
  16.248 -		{
  16.249 -			HandleSecurity sec(g_pCoreIdent, g_pCoreIdent);
  16.250 -			g_HandleSys.FreeHandle(hndl, &sec);
  16.251 -		}
  16.252 -	}
  16.253 -private:
  16.254 -	Handle_t hndl;
  16.255 -};
  16.256 -
  16.257 -#endif //_INCLUDE_SOURCEMOD_HANDLESYSTEM_H_
    17.1 --- a/core/Logger.cpp	Fri Mar 29 12:28:02 2013 -0400
    17.2 +++ b/core/Logger.cpp	Fri Mar 29 11:37:29 2013 -0700
    17.3 @@ -545,12 +545,19 @@
    17.4  
    17.5  void Logger::LogFatal(const char *msg, ...)
    17.6  {
    17.7 +	va_list ap;
    17.8 +	va_start(ap, msg);
    17.9 +	LogFatalEx(msg, ap);
   17.10 +	va_end(ap);
   17.11 +}
   17.12 +
   17.13 +void Logger::LogFatalEx(const char *msg, va_list ap)
   17.14 +{
   17.15  	/* :TODO: make this print all pretty-like
   17.16  	 * In fact, the pretty log printing function should be abstracted. 
   17.17  	 * It's already implemented twice which is bad.
   17.18  	 */
   17.19  
   17.20 -	va_list ap;
   17.21  	char path[PLATFORM_MAX_PATH];
   17.22  
   17.23  	g_SourceMod.BuildPath(Path_Game, path, sizeof(path), "sourcemod_fatal.log");
   17.24 @@ -559,9 +566,7 @@
   17.25  	if (fp)
   17.26  	{
   17.27  		m_Active = true;
   17.28 -		va_start(ap, msg);
   17.29  		LogToOpenFileEx(fp, msg, ap);
   17.30 -		va_end(ap);
   17.31  		m_Active = false;
   17.32  		fclose(fp);
   17.33  	}
    18.1 --- a/core/Logger.h	Fri Mar 29 12:28:02 2013 -0400
    18.2 +++ b/core/Logger.h	Fri Mar 29 11:37:29 2013 -0700
    18.3 @@ -78,6 +78,7 @@
    18.4  	void LogError(const char *msg, ...);
    18.5  	void LogErrorEx(const char *msg, va_list ap); 
    18.6  	void LogFatal(const char *msg, ...);
    18.7 +	void LogFatalEx(const char *msg, va_list ap);
    18.8  	void LogToOpenFile(FILE *fp, const char *msg, ...);
    18.9  	void LogToOpenFileEx(FILE *fp, const char *msg, va_list ap);
   18.10  	/* This version does not print to console, and is thus thread-safe */
    19.1 --- a/core/MenuManager.cpp	Fri Mar 29 12:28:02 2013 -0400
    19.2 +++ b/core/MenuManager.cpp	Fri Mar 29 11:37:29 2013 -0700
    19.3 @@ -38,8 +38,6 @@
    19.4  #include "sourcemm_api.h"
    19.5  #include "PlayerManager.h"
    19.6  #include "MenuStyle_Valve.h"
    19.7 -#include "ShareSys.h"
    19.8 -#include "HandleSys.h"
    19.9  #include "sourcemm_api.h"
   19.10  #include "logic_bridge.h"
   19.11  
   19.12 @@ -56,24 +54,24 @@
   19.13  
   19.14  void MenuManager::OnSourceModAllInitialized()
   19.15  {
   19.16 -	g_ShareSys.AddInterface(NULL, this);
   19.17 +	sharesys->AddInterface(NULL, this);
   19.18  
   19.19  	HandleAccess access;
   19.20 -	g_HandleSys.InitAccessDefaults(NULL, &access);
   19.21 +	handlesys->InitAccessDefaults(NULL, &access);
   19.22  
   19.23  	/* Deny cloning to menus */
   19.24  	access.access[HandleAccess_Clone] = HANDLE_RESTRICT_OWNER|HANDLE_RESTRICT_IDENTITY;
   19.25 -	m_MenuType = g_HandleSys.CreateType("IBaseMenu", this, 0, NULL, &access, g_pCoreIdent, NULL);
   19.26 +	m_MenuType = handlesys->CreateType("IBaseMenu", this, 0, NULL, &access, g_pCoreIdent, NULL);
   19.27  
   19.28  	/* Also deny deletion to styles */
   19.29  	access.access[HandleAccess_Delete] = HANDLE_RESTRICT_OWNER|HANDLE_RESTRICT_IDENTITY;
   19.30 -	m_StyleType = g_HandleSys.CreateType("IMenuStyle", this, 0, NULL, &access, g_pCoreIdent, NULL);
   19.31 +	m_StyleType = handlesys->CreateType("IMenuStyle", this, 0, NULL, &access, g_pCoreIdent, NULL);
   19.32  }
   19.33  
   19.34  void MenuManager::OnSourceModAllShutdown()
   19.35  {
   19.36 -	g_HandleSys.RemoveType(m_MenuType, g_pCoreIdent);
   19.37 -	g_HandleSys.RemoveType(m_StyleType, g_pCoreIdent);
   19.38 +	handlesys->RemoveType(m_MenuType, g_pCoreIdent);
   19.39 +	handlesys->RemoveType(m_StyleType, g_pCoreIdent);
   19.40  }
   19.41  
   19.42  void MenuManager::OnHandleDestroy(HandleType_t type, void *object)
   19.43 @@ -112,7 +110,7 @@
   19.44  		return BAD_HANDLE;
   19.45  	}
   19.46  
   19.47 -	return g_HandleSys.CreateHandle(m_MenuType, menu, pOwner, g_pCoreIdent, NULL);
   19.48 +	return handlesys->CreateHandle(m_MenuType, menu, pOwner, g_pCoreIdent, NULL);
   19.49  }
   19.50  
   19.51  Handle_t MenuManager::CreateStyleHandle(IMenuStyle *style)
   19.52 @@ -122,7 +120,7 @@
   19.53  		return BAD_HANDLE;
   19.54  	}
   19.55  
   19.56 -	return g_HandleSys.CreateHandle(m_StyleType, style, g_pCoreIdent, g_pCoreIdent, NULL);
   19.57 +	return handlesys->CreateHandle(m_StyleType, style, g_pCoreIdent, g_pCoreIdent, NULL);
   19.58  }
   19.59  
   19.60  HandleError MenuManager::ReadMenuHandle(Handle_t handle, IBaseMenu **menu)
   19.61 @@ -132,7 +130,7 @@
   19.62  	sec.pIdentity = g_pCoreIdent;
   19.63  	sec.pOwner = NULL;
   19.64  
   19.65 -	return g_HandleSys.ReadHandle(handle, m_MenuType, &sec, (void **)menu);
   19.66 +	return handlesys->ReadHandle(handle, m_MenuType, &sec, (void **)menu);
   19.67  }
   19.68  
   19.69  HandleError MenuManager::ReadStyleHandle(Handle_t handle, IMenuStyle **style)
   19.70 @@ -142,7 +140,7 @@
   19.71  	sec.pIdentity = g_pCoreIdent;
   19.72  	sec.pOwner = g_pCoreIdent;
   19.73  
   19.74 -	return g_HandleSys.ReadHandle(handle, m_StyleType, &sec, (void **)style);
   19.75 +	return handlesys->ReadHandle(handle, m_StyleType, &sec, (void **)style);
   19.76  }
   19.77  
   19.78  bool MenuManager::SetDefaultStyle(IMenuStyle *style)
    20.1 --- a/core/MenuStyle_Base.cpp	Fri Mar 29 12:28:02 2013 -0400
    20.2 +++ b/core/MenuStyle_Base.cpp	Fri Mar 29 11:37:29 2013 -0700
    20.3 @@ -34,11 +34,12 @@
    20.4  #include "MenuStyle_Base.h"
    20.5  #include "PlayerManager.h"
    20.6  #include "MenuManager.h"
    20.7 -#include "HandleSys.h"
    20.8  #include "CellRecipientFilter.h"
    20.9  #if defined MENU_DEBUG
   20.10  #include "Logger.h"
   20.11  #endif
   20.12 +#include "logic_bridge.h"
   20.13 +#include "AutoHandleRooter.h"
   20.14  
   20.15  BaseMenuStyle::BaseMenuStyle() : m_WatchList(256), m_hHandle(BAD_HANDLE)
   20.16  {
   20.17 @@ -818,7 +819,7 @@
   20.18  
   20.19  		m_hHandle = BAD_HANDLE;
   20.20  		m_bDeleting = true;
   20.21 -		g_HandleSys.FreeHandle(hndl, &sec);
   20.22 +		handlesys->FreeHandle(hndl, &sec);
   20.23  	}
   20.24  
   20.25  	m_pHandler->OnMenuDestroy(this);
    21.1 --- a/core/NativeInvoker.cpp	Fri Mar 29 12:28:02 2013 -0400
    21.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    21.3 @@ -1,379 +0,0 @@
    21.4 -/**
    21.5 - * vim: set ts=4 :
    21.6 - * =============================================================================
    21.7 - * SourcePawn
    21.8 - * Copyright (C) 2004-2009 AlliedModders LLC.  All rights reserved.
    21.9 - * =============================================================================
   21.10 - *
   21.11 - * This program is free software; you can redistribute it and/or modify it under
   21.12 - * the terms of the GNU General Public License, version 3.0, as published by the
   21.13 - * Free Software Foundation.
   21.14 - * 
   21.15 - * This program is distributed in the hope that it will be useful, but WITHOUT
   21.16 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   21.17 - * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
   21.18 - * details.
   21.19 - *
   21.20 - * You should have received a copy of the GNU General Public License along with
   21.21 - * this program.  If not, see <http://www.gnu.org/licenses/>.
   21.22 - *
   21.23 - * As a special exception, AlliedModders LLC gives you permission to link the
   21.24 - * code of this program (as well as its derivative works) to "Half-Life 2," the
   21.25 - * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
   21.26 - * by the Valve Corporation.  You must obey the GNU General Public License in
   21.27 - * all respects for all other code used.  Additionally, AlliedModders LLC grants
   21.28 - * this exception to all derivative works.  AlliedModders LLC defines further
   21.29 - * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
   21.30 - * or <http://www.sourcemod.net/license.php>.
   21.31 - *
   21.32 - * Version: $Id$
   21.33 - */
   21.34 -
   21.35 -#include "NativeInvoker.h"
   21.36 -#include "ShareSys.h"
   21.37 -
   21.38 -NativeInterface g_NInvoke;
   21.39 -
   21.40 -NativeInvoker::NativeInvoker()
   21.41 -{
   21.42 -}
   21.43 -
   21.44 -NativeInvoker::~NativeInvoker()
   21.45 -{
   21.46 -}
   21.47 -
   21.48 -const char *NativeInterface::GetInterfaceName()
   21.49 -{
   21.50 -	return SMINTERFACE_NINVOKE_NAME;
   21.51 -}
   21.52 -
   21.53 -unsigned int NativeInterface::GetInterfaceVersion()
   21.54 -{
   21.55 -	return SMINTERFACE_NINVOKE_VERSION;
   21.56 -}
   21.57 -
   21.58 -void NativeInterface::OnSourceModAllInitialized()
   21.59 -{
   21.60 -	g_ShareSys.AddInterface(NULL, &g_NInvoke);
   21.61 -}
   21.62 -
   21.63 -IPluginRuntime *NativeInterface::CreateRuntime(const char *name, size_t bytes)
   21.64 -{
   21.65 -	return g_pSourcePawn2->CreateEmptyRuntime(name, bytes);
   21.66 -}
   21.67 -
   21.68 -INativeInvoker *NativeInterface::CreateInvoker()
   21.69 -{
   21.70 -	return new NativeInvoker();
   21.71 -}
   21.72 -
   21.73 -bool NativeInvoker::Start(IPluginContext *pContext, const char *name)
   21.74 -{
   21.75 -	NativeEntry *entry;
   21.76 -	
   21.77 -	entry = g_ShareSys.FindNative(name);
   21.78 -	if (entry == NULL)
   21.79 -	{
   21.80 -		return false;
   21.81 -	}
   21.82 -
   21.83 -	native = NULL;
   21.84 -	if (entry->replacement.owner != NULL)
   21.85 -	{
   21.86 -		native = entry->replacement.func;
   21.87 -	}
   21.88 -	else if (entry->owner != NULL)
   21.89 -	{
   21.90 -		native = entry->func;
   21.91 -	}
   21.92 -
   21.93 -	if (native == NULL)
   21.94 -	{
   21.95 -		return false;
   21.96 -	}
   21.97 -
   21.98 -	this->pContext = pContext;
   21.99 -
  21.100 -	m_curparam = 0;
  21.101 -	m_errorstate = SP_ERROR_NONE;
  21.102 -
  21.103 -	return true;
  21.104 -}
  21.105 -
  21.106 -cell_t NativeInvoker::PushCell(cell_t cell)
  21.107 -{
  21.108 -	if (m_curparam >= SP_MAX_EXEC_PARAMS)
  21.109 -	{
  21.110 -		return SetError(SP_ERROR_PARAMS_MAX);
  21.111 -	}
  21.112 -
  21.113 -	m_info[m_curparam].marked = false;
  21.114 -	m_params[m_curparam] = cell;
  21.115 -	m_curparam++;
  21.116 -
  21.117 -	return SP_ERROR_NONE;
  21.118 -}
  21.119 -
  21.120 -int NativeInvoker::PushCellByRef(cell_t *cell, int flags)
  21.121 -{
  21.122 -	return PushArray(cell, 1, flags);
  21.123 -}
  21.124 -
  21.125 -int NativeInvoker::PushFloat(float number)
  21.126 -{
  21.127 -	cell_t val = *(cell_t *)&number;
  21.128 -
  21.129 -	return PushCell(val);
  21.130 -}
  21.131 -
  21.132 -int NativeInvoker::PushFloatByRef(float *number, int flags)
  21.133 -{
  21.134 -	return PushCellByRef((cell_t *)number, flags);
  21.135 -}
  21.136 -
  21.137 -int NativeInvoker::PushArray(cell_t *inarray, unsigned int cells, int copyback)
  21.138 -{
  21.139 -	if (m_curparam >= SP_MAX_EXEC_PARAMS)
  21.140 -	{
  21.141 -		return SetError(SP_ERROR_PARAMS_MAX);
  21.142 -	}
  21.143 -
  21.144 -	ParamInfo *info = &m_info[m_curparam];
  21.145 -
  21.146 -	info->flags = inarray ? copyback : 0;
  21.147 -	info->marked = true;
  21.148 -	info->size = cells;
  21.149 -	info->str.is_sz = false;
  21.150 -	info->orig_addr = inarray;
  21.151 -
  21.152 -	m_curparam++;
  21.153 -
  21.154 -	return SP_ERROR_NONE;
  21.155 -}
  21.156 -
  21.157 -int NativeInvoker::PushString(const char *string)
  21.158 -{
  21.159 -	return _PushString(string, SM_PARAM_STRING_COPY, 0, strlen(string)+1);
  21.160 -}
  21.161 -
  21.162 -int NativeInvoker::PushStringEx(char *buffer, size_t length, int sz_flags, int cp_flags)
  21.163 -{
  21.164 -	return _PushString(buffer, sz_flags, cp_flags, length);
  21.165 -}
  21.166 -
  21.167 -int NativeInvoker::_PushString(const char *string, int sz_flags, int cp_flags, size_t len)
  21.168 -{
  21.169 -	if (m_curparam >= SP_MAX_EXEC_PARAMS)
  21.170 -	{
  21.171 -		return SetError(SP_ERROR_PARAMS_MAX);
  21.172 -	}
  21.173 -
  21.174 -	ParamInfo *info = &m_info[m_curparam];
  21.175 -
  21.176 -	info->marked = true;
  21.177 -	info->orig_addr = (cell_t *)string;
  21.178 -	info->flags = cp_flags;
  21.179 -	info->size = len;
  21.180 -	info->str.sz_flags = sz_flags;
  21.181 -	info->str.is_sz = true;
  21.182 -
  21.183 -	m_curparam++;
  21.184 -
  21.185 -	return SP_ERROR_NONE;
  21.186 -}
  21.187 -
  21.188 -void NativeInvoker::Cancel()
  21.189 -{
  21.190 -	if (pContext == NULL)
  21.191 -	{
  21.192 -		return;
  21.193 -	}
  21.194 -
  21.195 -	m_errorstate = SP_ERROR_NONE;
  21.196 -	m_curparam = 0;
  21.197 -	pContext = NULL;
  21.198 -	native = NULL;
  21.199 -}
  21.200 -
  21.201 -int NativeInvoker::SetError(int err)
  21.202 -{
  21.203 -	m_errorstate = err;
  21.204 -	return err;
  21.205 -}
  21.206 -
  21.207 -int NativeInvoker::Invoke(cell_t *result)
  21.208 -{
  21.209 -	int err = SP_ERROR_NONE;
  21.210 -
  21.211 -	if (pContext == NULL)
  21.212 -	{
  21.213 -		return SP_ERROR_INVALID_NATIVE;
  21.214 -	}
  21.215 -
  21.216 -	if (m_errorstate != SP_ERROR_NONE)
  21.217 -	{
  21.218 -		err = m_errorstate;
  21.219 -		Cancel();
  21.220 -		return err;
  21.221 -	}
  21.222 -
  21.223 -	cell_t tresult;
  21.224 -
  21.225 -	if (result == NULL)
  21.226 -	{
  21.227 -		result = &tresult;
  21.228 -	}
  21.229 -
  21.230 -	//This is for re-entrancy!
  21.231 -	IPluginContext *ctx = pContext;
  21.232 -	cell_t _temp_params[SP_MAX_EXEC_PARAMS + 1];
  21.233 -	cell_t *temp_params = &_temp_params[1];
  21.234 -	ParamInfo temp_info[SP_MAX_EXEC_PARAMS];
  21.235 -	unsigned int numparams = m_curparam;
  21.236 -	unsigned int i;
  21.237 -	bool docopies = true;
  21.238 -
  21.239 -	if (numparams)
  21.240 -	{
  21.241 -		//Save the info locally, then reset it for re-entrant calls.
  21.242 -		memcpy(temp_info, m_info, numparams * sizeof(ParamInfo));
  21.243 -	}
  21.244 -	m_curparam = 0;
  21.245 -	pContext = NULL;
  21.246 -
  21.247 -	/* Initialize 0th parameter */
  21.248 -	_temp_params[0] = numparams;
  21.249 -
  21.250 -	/* Browse the parameters and build arrays */
  21.251 -	for (i = 0; i < numparams; i++)
  21.252 -	{
  21.253 -		/* Is this marked as an array? */
  21.254 -		if (temp_info[i].marked)
  21.255 -		{
  21.256 -			if (!temp_info[i].str.is_sz)
  21.257 -			{
  21.258 -				/* Allocate a normal/generic array */
  21.259 -				if ((err = ctx->HeapAlloc(temp_info[i].size, 
  21.260 -										  &temp_info[i].local_addr,
  21.261 -										  &temp_info[i].phys_addr))
  21.262 -					!= SP_ERROR_NONE)
  21.263 -				{
  21.264 -					break;
  21.265 -				}
  21.266 -				if (temp_info[i].orig_addr)
  21.267 -				{
  21.268 -					memcpy(temp_info[i].phys_addr, temp_info[i].orig_addr, sizeof(cell_t) * temp_info[i].size);
  21.269 -				}
  21.270 -			}
  21.271 -			else
  21.272 -			{
  21.273 -				/* Calculate cells required for the string */
  21.274 -				size_t cells = (temp_info[i].size + sizeof(cell_t) - 1) / sizeof(cell_t);
  21.275 -
  21.276 -				/* Allocate the buffer */
  21.277 -				if ((err = ctx->HeapAlloc(cells,
  21.278 -										  &temp_info[i].local_addr,
  21.279 -										  &temp_info[i].phys_addr))
  21.280 -					!= SP_ERROR_NONE)
  21.281 -				{
  21.282 -					break;
  21.283 -				}
  21.284 -				/* Copy original string if necessary */
  21.285 -				if ((temp_info[i].str.sz_flags & SM_PARAM_STRING_COPY) && (temp_info[i].orig_addr != NULL))
  21.286 -				{
  21.287 -					/* Cut off UTF-8 properly */
  21.288 -					if (temp_info[i].str.sz_flags & SM_PARAM_STRING_UTF8)
  21.289 -					{
  21.290 -						if ((err = ctx->StringToLocalUTF8(temp_info[i].local_addr, 
  21.291 -														  temp_info[i].size, 
  21.292 -														  (const char *)temp_info[i].orig_addr,
  21.293 -														  NULL))
  21.294 -							!= SP_ERROR_NONE)
  21.295 -						{
  21.296 -							break;
  21.297 -						}
  21.298 -					}
  21.299 -					/* Copy a binary blob */
  21.300 -					else if (temp_info[i].str.sz_flags & SM_PARAM_STRING_BINARY)
  21.301 -					{
  21.302 -						memmove(temp_info[i].phys_addr, temp_info[i].orig_addr, temp_info[i].size);
  21.303 -					}
  21.304 -					/* Copy ASCII characters */
  21.305 -					else
  21.306 -					{
  21.307 -						if ((err = ctx->StringToLocal(temp_info[i].local_addr,
  21.308 -													  temp_info[i].size,
  21.309 -													  (const char *)temp_info[i].orig_addr))
  21.310 -							!= SP_ERROR_NONE)
  21.311 -						{
  21.312 -							break;
  21.313 -						}
  21.314 -					}
  21.315 -				}
  21.316 -			} /* End array/string calculation */
  21.317 -			/* Update the pushed parameter with the byref local address */
  21.318 -			temp_params[i] = temp_info[i].local_addr;
  21.319 -		}
  21.320 -		else
  21.321 -		{
  21.322 -			/* Just copy the value normally */
  21.323 -			temp_params[i] = m_params[i];
  21.324 -		}
  21.325 -	}
  21.326 -
  21.327 -	/* Make the call if we can */
  21.328 -	if (err == SP_ERROR_NONE)
  21.329 -	{
  21.330 -		*result = native(ctx, _temp_params);
  21.331 -		if (ctx->GetLastNativeError() != SP_ERROR_NONE)
  21.332 -		{
  21.333 -			docopies = false;
  21.334 -			ctx->ClearLastNativeError();
  21.335 -		}
  21.336 -	}
  21.337 -	else
  21.338 -	{
  21.339 -		docopies = false;
  21.340 -	}
  21.341 -
  21.342 -	/* i should be equal to the last valid parameter + 1 */
  21.343 -	while (i--)
  21.344 -	{
  21.345 -		if (!temp_info[i].marked)
  21.346 -		{
  21.347 -			continue;
  21.348 -		}
  21.349 -
  21.350 -		if (docopies && (temp_info[i].flags & SM_PARAM_COPYBACK))
  21.351 -		{
  21.352 -			if (temp_info[i].orig_addr)
  21.353 -			{
  21.354 -				if (temp_info[i].str.is_sz)
  21.355 -				{
  21.356 -					memcpy(temp_info[i].orig_addr, temp_info[i].phys_addr, temp_info[i].size);
  21.357 -
  21.358 -				}
  21.359 -				else
  21.360 -				{
  21.361 -					if (temp_info[i].size == 1)
  21.362 -					{
  21.363 -						*temp_info[i].orig_addr = *(temp_info[i].phys_addr);
  21.364 -					}
  21.365 -					else
  21.366 -					{
  21.367 -						memcpy(temp_info[i].orig_addr, 
  21.368 -							temp_info[i].phys_addr, 
  21.369 -							temp_info[i].size * sizeof(cell_t));
  21.370 -					}
  21.371 -				}
  21.372 -			}
  21.373 -		}
  21.374 -
  21.375 -		if ((err = ctx->HeapPop(temp_info[i].local_addr)) != SP_ERROR_NONE)
  21.376 -		{
  21.377 -			return err;
  21.378 -		}
  21.379 -	}
  21.380 -
  21.381 -	return err;
  21.382 -}
    22.1 --- a/core/NativeInvoker.h	Fri Mar 29 12:28:02 2013 -0400
    22.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    22.3 @@ -1,98 +0,0 @@
    22.4 -/**
    22.5 - * vim: set ts=4 :
    22.6 - * =============================================================================
    22.7 - * SourceMod
    22.8 - * Copyright (C) 2004-2009 AlliedModders LLC.  All rights reserved.
    22.9 - * =============================================================================
   22.10 - *
   22.11 - * This program is free software; you can redistribute it and/or modify it under
   22.12 - * the terms of the GNU General Public License, version 3.0, as published by the
   22.13 - * Free Software Foundation.
   22.14 - * 
   22.15 - * This program is distributed in the hope that it will be useful, but WITHOUT
   22.16 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   22.17 - * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
   22.18 - * details.
   22.19 - *
   22.20 - * You should have received a copy of the GNU General Public License along with
   22.21 - * this program.  If not, see <http://www.gnu.org/licenses/>.
   22.22 - *
   22.23 - * As a special exception, AlliedModders LLC gives you permission to link the
   22.24 - * code of this program (as well as its derivative works) to "Half-Life 2," the
   22.25 - * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
   22.26 - * by the Valve Corporation.  You must obey the GNU General Public License in
   22.27 - * all respects for all other code used.  Additionally, AlliedModders LLC grants
   22.28 - * this exception to all derivative works.  AlliedModders LLC defines further
   22.29 - * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
   22.30 - * or <http://www.sourcemod.net/license.php>.
   22.31 - *
   22.32 - * Version: $Id$
   22.33 - */
   22.34 -
   22.35 -#ifndef _INCLUDE_SOURCEMOD_NATIVE_INVOKER_H_
   22.36 -#define _INCLUDE_SOURCEMOD_NATIVE_INVOKER_H_
   22.37 -
   22.38 -#include "sm_globals.h"
   22.39 -#include <INativeInvoker.h>
   22.40 -
   22.41 -struct ParamInfo
   22.42 -{
   22.43 -	int flags;			/* Copy-back flags */
   22.44 -	bool marked;		/* Whether this is marked as being used */
   22.45 -	cell_t local_addr;	/* Local address to free */
   22.46 -	cell_t *phys_addr;	/* Physical address of our copy */
   22.47 -	cell_t *orig_addr;	/* Original address to copy back to */
   22.48 -	ucell_t size;		/* Size of array in bytes */
   22.49 -	struct
   22.50 -	{
   22.51 -		bool is_sz;		/* is a string */
   22.52 -		int sz_flags;	/* has sz flags */
   22.53 -	} str;
   22.54 -};
   22.55 -
   22.56 -class NativeInvoker : public INativeInvoker
   22.57 -{
   22.58 -public:
   22.59 -	NativeInvoker();
   22.60 -	~NativeInvoker();
   22.61 -public: /* ICallable */
   22.62 -	int PushCell(cell_t cell);
   22.63 -	int PushCellByRef(cell_t *cell, int flags=SM_PARAM_COPYBACK);
   22.64 -	int PushFloat(float number);
   22.65 -	int PushFloatByRef(float *number, int flags=SM_PARAM_COPYBACK);
   22.66 -	int PushArray(cell_t *inarray, unsigned int cells, int flags=0);
   22.67 -	int PushString(const char *string);
   22.68 -	int PushStringEx(char *buffer, size_t length, int sz_flags, int cp_flags);
   22.69 -	void Cancel();
   22.70 -public: /* INativeInvoker */
   22.71 -	bool Start(IPluginContext *pContext, const char *name);
   22.72 -	int Invoke(cell_t *result);
   22.73 -private:
   22.74 -	int _PushString(const char *string, int sz_flags, int cp_flags, size_t len);
   22.75 -	int SetError(int err);
   22.76 -private:
   22.77 -	IPluginContext *pContext;
   22.78 -	SPVM_NATIVE_FUNC native;
   22.79 -	cell_t m_params[SP_MAX_EXEC_PARAMS];
   22.80 -	ParamInfo m_info[SP_MAX_EXEC_PARAMS];
   22.81 -	unsigned int m_curparam;
   22.82 -	int m_errorstate;
   22.83 -};
   22.84 -
   22.85 -class NativeInterface : 
   22.86 -	public INativeInterface,
   22.87 -	public SMGlobalClass
   22.88 -{
   22.89 -public: /* SMGlobalClass */
   22.90 -	void OnSourceModAllInitialized();
   22.91 -public: /* SMInterface */
   22.92 -	unsigned int GetInterfaceVersion();
   22.93 -	const char *GetInterfaceName();
   22.94 -public: /* INativeInvoker */
   22.95 -	IPluginRuntime *CreateRuntime(const char *name, size_t bytes);
   22.96 -	INativeInvoker *CreateInvoker();
   22.97 -};
   22.98 -
   22.99 -extern NativeInterface g_NInvoke;
  22.100 -
  22.101 -#endif /* _INCLUDE_SOURCEMOD_NATIVE_INVOKER_H_ */
    23.1 --- a/core/NativeOwner.cpp	Fri Mar 29 12:28:02 2013 -0400
    23.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    23.3 @@ -1,144 +0,0 @@
    23.4 -#include "NativeOwner.h"
    23.5 -#include "ShareSys.h"
    23.6 -#include "PluginSys.h"
    23.7 -
    23.8 -CNativeOwner::CNativeOwner() : m_nMarkSerial(0)
    23.9 -{
   23.10 -}
   23.11 -
   23.12 -void CNativeOwner::SetMarkSerial(unsigned int serial)
   23.13 -{
   23.14 -	m_nMarkSerial = serial;
   23.15 -}
   23.16 -
   23.17 -unsigned int CNativeOwner::GetMarkSerial()
   23.18 -{
   23.19 -	return m_nMarkSerial;
   23.20 -}
   23.21 -
   23.22 -void CNativeOwner::AddDependent(CPlugin *pPlugin)
   23.23 -{
   23.24 -	m_Dependents.push_back(pPlugin);
   23.25 -}
   23.26 -
   23.27 -void CNativeOwner::AddWeakRef(const WeakNative & ref)
   23.28 -{
   23.29 -	m_WeakRefs.push_back(ref);
   23.30 -}
   23.31 -
   23.32 -void CNativeOwner::AddNatives(const sp_nativeinfo_t *natives)
   23.33 -{
   23.34 -	NativeEntry *pEntry;
   23.35 -
   23.36 -	for (unsigned int i = 0; natives[i].func != NULL && natives[i].name != NULL; i++)
   23.37 -	{
   23.38 -		if ((pEntry = g_ShareSys.AddNativeToCache(this, &natives[i])) == NULL)
   23.39 -		{
   23.40 -			continue;
   23.41 -		}
   23.42 -
   23.43 -		m_Natives.push_back(pEntry);
   23.44 -	}
   23.45 -}
   23.46 -
   23.47 -void CNativeOwner::PropogateMarkSerial(unsigned int serial)
   23.48 -{
   23.49 -	CNativeOwner *pOwner;
   23.50 -	List<CPlugin *>::iterator iter;
   23.51 -
   23.52 -	for (iter = m_Dependents.begin();
   23.53 -		 iter != m_Dependents.end();
   23.54 -		 iter++)
   23.55 -	{
   23.56 -		pOwner = (*iter);
   23.57 -		pOwner->SetMarkSerial(serial);
   23.58 -	}
   23.59 -}
   23.60 -
   23.61 -void CNativeOwner::UnbindWeakRef(const WeakNative & ref)
   23.62 -{
   23.63 -	sp_native_t *native;
   23.64 -	IPluginContext *pContext;
   23.65 -
   23.66 -	pContext = ref.pl->GetBaseContext();
   23.67 -	if ((pContext->GetNativeByIndex(ref.idx, &native)) == SP_ERROR_NONE)
   23.68 -	{
   23.69 -		/* If there is no reference, the native must be unbound */
   23.70 -		if (ref.entry == NULL)
   23.71 -		{
   23.72 -			native->status = SP_NATIVE_UNBOUND;
   23.73 -			native->pfn = NULL;
   23.74 -		}
   23.75 -		/* If we've cached a reference, it's a core native we can 
   23.76 -		 * rebind back to its original (this was a replacement).
   23.77 -		 */
   23.78 -		else
   23.79 -		{
   23.80 -			native->pfn = ref.entry->func;
   23.81 -		}
   23.82 -	}
   23.83 -}
   23.84 -
   23.85 -void CNativeOwner::DropEverything()
   23.86 -{
   23.87 -	NativeEntry *pEntry;
   23.88 -	List<WeakNative>::iterator iter;
   23.89 -	List<NativeEntry *>::iterator ntv_iter;
   23.90 -
   23.91 -	/* Unbind and remove all weak references to us */
   23.92 -	iter = m_WeakRefs.begin();
   23.93 -	while (iter != m_WeakRefs.end())
   23.94 -	{
   23.95 -		UnbindWeakRef((*iter));
   23.96 -		iter = m_WeakRefs.erase(iter);
   23.97 -	}
   23.98 -
   23.99 -	/* Unmark our replacement natives */
  23.100 -	ntv_iter = m_ReplacedNatives.begin();
  23.101 -	while (ntv_iter != m_ReplacedNatives.end())
  23.102 -	{
  23.103 -		pEntry = (*ntv_iter);
  23.104 -		pEntry->replacement.func = NULL;
  23.105 -		pEntry->replacement.owner = NULL;
  23.106 -		ntv_iter = m_ReplacedNatives.erase(ntv_iter);
  23.107 -	}
  23.108 -
  23.109 -	/* Strip all of our natives from the cache */
  23.110 -	ntv_iter = m_Natives.begin();
  23.111 -	while (ntv_iter != m_Natives.end())
  23.112 -	{
  23.113 -		g_ShareSys.ClearNativeFromCache(this, (*ntv_iter)->name);
  23.114 -		ntv_iter = m_Natives.erase(ntv_iter);
  23.115 -	}
  23.116 -}
  23.117 -
  23.118 -void CNativeOwner::DropWeakRefsTo(CPlugin *pPlugin)
  23.119 -{
  23.120 -	List<WeakNative>::iterator iter;
  23.121 -
  23.122 -	iter = m_WeakRefs.begin();
  23.123 -	while (iter != m_WeakRefs.end())
  23.124 -	{
  23.125 -		WeakNative & ref = (*iter);
  23.126 -
  23.127 -		if (ref.pl == pPlugin)
  23.128 -		{
  23.129 -			iter = m_WeakRefs.erase(iter);
  23.130 -		}
  23.131 -		else
  23.132 -		{
  23.133 -			iter++;
  23.134 -		}
  23.135 -	}
  23.136 -}
  23.137 -
  23.138 -void CNativeOwner::DropRefsTo(CPlugin *pPlugin)
  23.139 -{
  23.140 -	m_Dependents.remove(pPlugin);
  23.141 -	DropWeakRefsTo(pPlugin);
  23.142 -}
  23.143 -
  23.144 -void CNativeOwner::AddReplacedNative(NativeEntry *pEntry)
  23.145 -{
  23.146 -	m_ReplacedNatives.push_back(pEntry);
  23.147 -}
    24.1 --- a/core/NativeOwner.h	Fri Mar 29 12:28:02 2013 -0400
    24.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    24.3 @@ -1,59 +0,0 @@
    24.4 -#ifndef _INCLUDE_SOURCEMOD_NATIVE_OWNER_H_
    24.5 -#define _INCLUDE_SOURCEMOD_NATIVE_OWNER_H_
    24.6 -
    24.7 -#include <sp_vm_types.h>
    24.8 -#include <sh_list.h>
    24.9 -
   24.10 -class CPlugin;
   24.11 -struct NativeEntry;
   24.12 -
   24.13 -struct WeakNative
   24.14 -{
   24.15 -	WeakNative(CPlugin *plugin, uint32_t index) : 
   24.16 -		pl(plugin), idx(index), entry(NULL)
   24.17 -	{
   24.18 -		pl = plugin;
   24.19 -		idx = index;
   24.20 -	}
   24.21 -	WeakNative(CPlugin *plugin, uint32_t index, NativeEntry *pEntry) : 
   24.22 -		pl(plugin), idx(index), entry(pEntry)
   24.23 -	{
   24.24 -		pl = plugin;
   24.25 -		idx = index;
   24.26 -	}
   24.27 -	CPlugin *pl;
   24.28 -	uint32_t idx;
   24.29 -	NativeEntry *entry;
   24.30 -};
   24.31 -
   24.32 -using namespace SourceHook;
   24.33 -
   24.34 -class CNativeOwner
   24.35 -{
   24.36 -public:
   24.37 -	CNativeOwner();
   24.38 -public:
   24.39 -	virtual void DropEverything();
   24.40 -public:
   24.41 -	void AddNatives(const sp_nativeinfo_t *info);
   24.42 -public:
   24.43 -	void SetMarkSerial(unsigned int serial);
   24.44 -	unsigned int GetMarkSerial();
   24.45 -	void PropogateMarkSerial(unsigned int serial);
   24.46 -public:
   24.47 -	void AddDependent(CPlugin *pPlugin);
   24.48 -	void AddWeakRef(const WeakNative & ref);
   24.49 -	void DropRefsTo(CPlugin *pPlugin);
   24.50 -	void AddReplacedNative(NativeEntry *pEntry);
   24.51 -private:
   24.52 -	void DropWeakRefsTo(CPlugin *pPlugin);
   24.53 -	void UnbindWeakRef(const WeakNative & ref);
   24.54 -protected:
   24.55 -	List<CPlugin *> m_Dependents;
   24.56 -	unsigned int m_nMarkSerial;
   24.57 -	List<WeakNative> m_WeakRefs;
   24.58 -	List<NativeEntry *> m_Natives;
   24.59 -	List<NativeEntry *> m_ReplacedNatives;
   24.60 -};
   24.61 -
   24.62 -#endif //_INCLUDE_SOURCEMOD_NATIVE_OWNER_H_
    25.1 --- a/core/PlayerManager.cpp	Fri Mar 29 12:28:02 2013 -0400
    25.2 +++ b/core/PlayerManager.cpp	Fri Mar 29 11:37:29 2013 -0700
    25.3 @@ -31,7 +31,6 @@
    25.4  
    25.5  #include "PlayerManager.h"
    25.6  #include "ForwardSys.h"
    25.7 -#include "ShareSys.h"
    25.8  #include "AdminCache.h"
    25.9  #include "ConCmdManager.h"
   25.10  #include "MenuStyle_Valve.h"
   25.11 @@ -45,7 +44,6 @@
   25.12  #include <inetchannel.h>
   25.13  #include <iclient.h>
   25.14  #include <IGameConfigs.h>
   25.15 -#include "ExtensionSys.h"
   25.16  #include <sourcemod_version.h>
   25.17  #include "ConsoleDetours.h"
   25.18  #include "logic_bridge.h"
   25.19 @@ -141,7 +139,7 @@
   25.20  	SH_ADD_HOOK(IServerGameClients, ClientSettingsChanged, serverClients, SH_MEMBER(this, &PlayerManager::OnClientSettingsChanged), true);
   25.21  	SH_ADD_HOOK(IServerGameDLL, ServerActivate, gamedll, SH_MEMBER(this, &PlayerManager::OnServerActivate), true);
   25.22  
   25.23 -	g_ShareSys.AddInterface(NULL, this);
   25.24 +	sharesys->AddInterface(NULL, this);
   25.25  
   25.26  	ParamType p1[] = {Param_Cell, Param_String, Param_Cell};
   25.27  	ParamType p2[] = {Param_Cell};
   25.28 @@ -278,11 +276,11 @@
   25.29  		g_NumPlayersToAuth = &m_AuthQueue[0];
   25.30  	}
   25.31  
   25.32 -	g_PluginSys.SyncMaxClients(m_maxClients);
   25.33 +	scripts->SyncMaxClients(m_maxClients);
   25.34  
   25.35  	g_OnMapStarted = true;
   25.36  
   25.37 -	g_Extensions.CallOnCoreMapStart(pEdictList, edictCount, m_maxClients);
   25.38 +	extsys->CallOnCoreMapStart(pEdictList, edictCount, m_maxClients);
   25.39  	m_onActivate->Execute(NULL);
   25.40  	m_onActivate2->Execute(NULL);
   25.41  
   25.42 @@ -779,6 +777,173 @@
   25.43  	engine->ClientPrintf(e, buffer);
   25.44  }
   25.45  
   25.46 +void ListExtensionsToClient(CPlayer *player, const CCommand &args)
   25.47 +{
   25.48 +	char buffer[256];
   25.49 +	unsigned int id = 0;
   25.50 +	unsigned int start = 0;
   25.51 +
   25.52 +	CVector<IExtension *> extensions;
   25.53 +	extsys->ListExtensions(&extensions);
   25.54 +
   25.55 +	if (!extensions.size())
   25.56 +	{
   25.57 +		ClientConsolePrint(player->GetEdict(), "[SM] No extensions found.");
   25.58 +		return;
   25.59 +	}
   25.60 +
   25.61 +	if (args.ArgC() > 2)
   25.62 +	{
   25.63 +		start = atoi(args.Arg(2));
   25.64 +	}
   25.65 +
   25.66 +	SourceHook::CVector<IExtension *>::iterator iter;
   25.67 +
   25.68 +	for (iter = extensions.begin();
   25.69 +		 iter != extensions.end();
   25.70 +		 iter++)
   25.71 +	{
   25.72 +		IExtension *ext = (*iter);
   25.73 +
   25.74 +		char error[255];
   25.75 +		if (!ext->IsRunning(error, sizeof(error)))
   25.76 +		{
   25.77 +			continue;
   25.78 +		}
   25.79 +
   25.80 +		id++;
   25.81 +		if (id < start)
   25.82 +		{
   25.83 +			continue;
   25.84 +		}
   25.85 +
   25.86 +		if (id - start > 10)
   25.87 +		{
   25.88 +			break;
   25.89 +		}
   25.90 +
   25.91 +		IExtensionInterface *api = ext->GetAPI();
   25.92 +
   25.93 +		const char *name = api->GetExtensionName();
   25.94 +		const char *version = api->GetExtensionVerString();
   25.95 +		const char *author = api->GetExtensionAuthor();
   25.96 +		const char *description = api->GetExtensionDescription();
   25.97 +
   25.98 +		size_t len = UTIL_Format(buffer, sizeof(buffer), " \"%s\"", name);
   25.99 +
  25.100 +		if (version != NULL && version[0])
  25.101 +		{
  25.102 +			len += UTIL_Format(&buffer[len], sizeof(buffer)-len, " (%s)", version);
  25.103 +		}
  25.104 +
  25.105 +		if (author != NULL && author[0])
  25.106 +		{
  25.107 +			len += UTIL_Format(&buffer[len], sizeof(buffer)-len, " by %s", author);
  25.108 +		}
  25.109 +
  25.110 +		if (description != NULL && description[0])
  25.111 +		{
  25.112 +			len += UTIL_Format(&buffer[len], sizeof(buffer)-len, ": %s", description);
  25.113 +		}
  25.114 +
  25.115 +
  25.116 +		ClientConsolePrint(player->GetEdict(), "%s", buffer);
  25.117 +	}
  25.118 +
  25.119 +	for (; iter != extensions.end(); iter++)
  25.120 +	{
  25.121 +		char error[255];
  25.122 +		if ((*iter)->IsRunning(error, sizeof(error)))
  25.123 +		{
  25.124 +			break;
  25.125 +		}
  25.126 +	}
  25.127 +
  25.128 +	if (iter != extensions.end())
  25.129 +	{
  25.130 +		ClientConsolePrint(player->GetEdict(), "To see more, type \"sm exts %d\"", id);
  25.131 +	}
  25.132 +}
  25.133 +
  25.134 +void ListPluginsToClient(CPlayer *player, const CCommand &args)
  25.135 +{
  25.136 +	char buffer[256];
  25.137 +	unsigned int id = 0;
  25.138 +	edict_t *e = player->GetEdict();
  25.139 +	unsigned int start = 0;
  25.140 +
  25.141 +	CVector<SMPlugin *> plugins;
  25.142 +	scripts->ListPlugins(&plugins);
  25.143 +
  25.144 +	if (!plugins.size())
  25.145 +	{
  25.146 +		ClientConsolePrint(e, "[SM] No plugins found.");
  25.147 +		return;
  25.148 +	}
  25.149 +
  25.150 +	if (args.ArgC() > 2)
  25.151 +	{
  25.152 +		start = atoi(args.Arg(2));
  25.153 +	}
  25.154 +
  25.155 +	SourceHook::List<SMPlugin *> m_FailList;
  25.156 +
  25.157 +	CVector<SMPlugin *>::iterator iter = plugins.begin();
  25.158 +	for (; iter != plugins.end(); iter++)
  25.159 +	{
  25.160 +		SMPlugin *pl = *iter;
  25.161 +
  25.162 +		if (pl->GetStatus() != Plugin_Running)
  25.163 +		{
  25.164 +			continue;
  25.165 +		}
  25.166 +
  25.167 +		/* Count valid plugins */
  25.168 +		id++;
  25.169 +		if (id < start)
  25.170 +		{
  25.171 +			continue;
  25.172 +		}
  25.173 +
  25.174 +		if (id - start > 10)
  25.175 +		{
  25.176 +			break;
  25.177 +		}
  25.178 +
  25.179 +		size_t len;
  25.180 +		const sm_plugininfo_t *info = pl->GetPublicInfo();
  25.181 +		len = UTIL_Format(buffer, sizeof(buffer), " \"%s\"", (IS_STR_FILLED(info->name)) ? info->name : pl->GetFilename());
  25.182 +		if (IS_STR_FILLED(info->version))
  25.183 +		{
  25.184 +			len += UTIL_Format(&buffer[len], sizeof(buffer)-len, " (%s)", info->version);
  25.185 +		}
  25.186 +		if (IS_STR_FILLED(info->author))
  25.187 +		{
  25.188 +			UTIL_Format(&buffer[len], sizeof(buffer)-len, " by %s", info->author);
  25.189 +		}
  25.190 +		else
  25.191 +		{
  25.192 +			UTIL_Format(&buffer[len], sizeof(buffer)-len, " %s", pl->GetFilename());
  25.193 +		}
  25.194 +		ClientConsolePrint(e, "%s", buffer);
  25.195 +	}
  25.196 +
  25.197 +	/* See if we can get more plugins */
  25.198 +	for (; iter != plugins.end(); iter++)
  25.199 +	{
  25.200 +		if ((*iter)->GetStatus() == Plugin_Running)
  25.201 +		{
  25.202 +			break;
  25.203 +		}
  25.204 +	}
  25.205 +
  25.206 +	/* Do we actually have more plugins? */
  25.207 +	if (iter != plugins.end())
  25.208 +	{
  25.209 +		ClientConsolePrint(e, "To see more, type \"sm plugins %d\"", id);
  25.210 +	}
  25.211 +}
  25.212 +
  25.213  #if SOURCE_ENGINE >= SE_ORANGEBOX
  25.214  void PlayerManager::OnClientCommand(edict_t *pEntity, const CCommand &args)
  25.215  {
  25.216 @@ -800,12 +965,12 @@
  25.217  	{
  25.218  		if (args.ArgC() > 1 && strcmp(args.Arg(1), "plugins") == 0)
  25.219  		{
  25.220 -			g_PluginSys.ListPluginsToClient(pPlayer, args);
  25.221 +			ListPluginsToClient(pPlayer, args);
  25.222  			RETURN_META(MRES_SUPERCEDE);
  25.223  		}
  25.224  		else if (args.ArgC() > 1 && strcmp(args.Arg(1), "exts") == 0)
  25.225  		{
  25.226 -			g_Extensions.ListExtensionsToClient(pPlayer, args);
  25.227 +			ListExtensionsToClient(pPlayer, args);
  25.228  			RETURN_META(MRES_SUPERCEDE);
  25.229  		}
  25.230  		else if (args.ArgC() > 1 && strcmp(args.Arg(1), "credits") == 0)
  25.231 @@ -1641,9 +1806,9 @@
  25.232  	m_AuthID.assign(steamid);
  25.233  }
  25.234  
  25.235 -// Ensure a valid AuthString is set before calling.
  25.236 -void CPlayer::Authorize()
  25.237 -{
  25.238 +// Ensure a valid AuthString is set before calling.
  25.239 +void CPlayer::Authorize()
  25.240 +{
  25.241  	m_IsAuthorized = true;
  25.242  }
  25.243  
  25.244 @@ -1690,9 +1855,9 @@
  25.245  
  25.246  const char *CPlayer::GetAuthString(bool validated)
  25.247  {
  25.248 -	if (validated && !IsAuthStringValidated())
  25.249 -	{
  25.250 -		return NULL;
  25.251 +	if (validated && !IsAuthStringValidated())
  25.252 +	{
  25.253 +		return NULL;
  25.254  	}
  25.255  
  25.256  	return m_AuthID.c_str();
  25.257 @@ -1752,15 +1917,15 @@
  25.258  	return m_IsAuthorized;
  25.259  }
  25.260  
  25.261 -bool CPlayer::IsAuthStringValidated()
  25.262 +bool CPlayer::IsAuthStringValidated()
  25.263  {     
  25.264  #if SOURCE_ENGINE >= SE_ORANGEBOX
  25.265 -	if (g_Players.m_bAuthstringValidation && !g_HL2.IsLANServer())
  25.266 -	{
  25.267 -		return engine->IsClientFullyAuthenticated(m_pEdict);
  25.268 -	}
  25.269 -#endif
  25.270 -
  25.271 +	if (g_Players.m_bAuthstringValidation && !g_HL2.IsLANServer())
  25.272 +	{
  25.273 +		return engine->IsClientFullyAuthenticated(m_pEdict);
  25.274 +	}
  25.275 +#endif
  25.276 +
  25.277  	return true;
  25.278  }
  25.279  
    26.1 --- a/core/PluginSys.cpp	Fri Mar 29 12:28:02 2013 -0400
    26.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    26.3 @@ -1,2700 +0,0 @@
    26.4 -/**
    26.5 - * vim: set ts=4 :
    26.6 - * =============================================================================
    26.7 - * SourceMod
    26.8 - * Copyright (C) 2004-2008 AlliedModders LLC.  All rights reserved.
    26.9 - * =============================================================================
   26.10 - *
   26.11 - * This program is free software; you can redistribute it and/or modify it under
   26.12 - * the terms of the GNU General Public License, version 3.0, as published by the
   26.13 - * Free Software Foundation.
   26.14 - * 
   26.15 - * This program is distributed in the hope that it will be useful, but WITHOUT
   26.16 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   26.17 - * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
   26.18 - * details.
   26.19 - *
   26.20 - * You should have received a copy of the GNU General Public License along with
   26.21 - * this program.  If not, see <http://www.gnu.org/licenses/>.
   26.22 - *
   26.23 - * As a special exception, AlliedModders LLC gives you permission to link the
   26.24 - * code of this program (as well as its derivative works) to "Half-Life 2," the
   26.25 - * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
   26.26 - * by the Valve Corporation.  You must obey the GNU General Public License in
   26.27 - * all respects for all other code used.  Additionally, AlliedModders LLC grants
   26.28 - * this exception to all derivative works.  AlliedModders LLC defines further
   26.29 - * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
   26.30 - * or <http://www.sourcemod.net/license.php>.
   26.31 - *
   26.32 - * Version: $Id$
   26.33 - */
   26.34 -
   26.35 -#include <stdio.h>
   26.36 -#include "PluginSys.h"
   26.37 -#include "ShareSys.h"
   26.38 -#include "LibrarySys.h"
   26.39 -#include "HandleSys.h"
   26.40 -#include "ForwardSys.h"
   26.41 -#include "sourcemm_api.h"
   26.42 -#include "sourcemod.h"
   26.43 -#include "Logger.h"
   26.44 -#include "ExtensionSys.h"
   26.45 -#include "sm_srvcmds.h"
   26.46 -#include "sm_stringutil.h"
   26.47 -#include "ConCmdManager.h"
   26.48 -#include "PlayerManager.h"
   26.49 -#include "CoreConfig.h"
   26.50 -#include "logic_bridge.h"
   26.51 -
   26.52 -CPluginManager g_PluginSys;
   26.53 -HandleType_t g_PluginType = 0;
   26.54 -IdentityType_t g_PluginIdent = 0;
   26.55 -
   26.56 -CPlugin::CPlugin(const char *file)
   26.57 -{
   26.58 -	static int MySerial = 0;
   26.59 -
   26.60 -	m_type = PluginType_Private;
   26.61 -	m_status = Plugin_Uncompiled;
   26.62 -	m_bSilentlyFailed = false;
   26.63 -	m_serial = ++MySerial;
   26.64 -	m_pRuntime = NULL;
   26.65 -	m_errormsg[sizeof(m_errormsg) - 1] = '\0';
   26.66 -	UTIL_Format(m_filename, sizeof(m_filename), "%s", file);
   26.67 -	m_handle = 0;
   26.68 -	m_ident = NULL;
   26.69 -	m_pProps = sm_trie_create();
   26.70 -	m_FakeNativesMissing = false;
   26.71 -	m_LibraryMissing = false;
   26.72 -	m_bGotAllLoaded = false;
   26.73 -	m_pPhrases = translator->CreatePhraseCollection();
   26.74 -	m_MaxClientsVar = NULL;
   26.75 -}
   26.76 -
   26.77 -CPlugin::~CPlugin()
   26.78 -{
   26.79 -	if (m_handle)
   26.80 -	{
   26.81 -		HandleSecurity sec;
   26.82 -		sec.pOwner = g_PluginSys.GetIdentity();
   26.83 -		sec.pIdentity = sec.pOwner;
   26.84 -
   26.85 -		g_HandleSys.FreeHandle(m_handle, &sec);
   26.86 -		g_ShareSys.DestroyIdentity(m_ident);
   26.87 -	}
   26.88 -
   26.89 -	if (m_pRuntime != NULL)
   26.90 -	{
   26.91 -		delete m_pRuntime;
   26.92 -		m_pRuntime = NULL;
   26.93 -	}
   26.94 -
   26.95 -	if (m_pProps)
   26.96 -	{
   26.97 -		sm_trie_destroy(m_pProps);
   26.98 -	}
   26.99 -	for (size_t i=0; i<m_configs.size(); i++)
  26.100 -	{
  26.101 -		delete m_configs[i];
  26.102 -	}
  26.103 -	m_configs.clear();
  26.104 -	if (m_pPhrases != NULL)
  26.105 -	{
  26.106 -		m_pPhrases->Destroy();
  26.107 -		m_pPhrases = NULL;
  26.108 -	}
  26.109 -}
  26.110 -
  26.111 -void CPlugin::InitIdentity()
  26.112 -{
  26.113 -	if (!m_handle)
  26.114 -	{
  26.115 -		m_ident = g_ShareSys.CreateIdentity(g_PluginIdent, this);
  26.116 -		m_handle = g_HandleSys.CreateHandle(g_PluginType, this, g_PluginSys.GetIdentity(), g_PluginSys.GetIdentity(), NULL);
  26.117 -		m_pRuntime->GetDefaultContext()->SetKey(1, m_ident);
  26.118 -		m_pRuntime->GetDefaultContext()->SetKey(2, (IPlugin *)this);
  26.119 -	}
  26.120 -}
  26.121 -
  26.122 -unsigned int CPlugin::CalcMemUsage()
  26.123 -{
  26.124 -	unsigned int base_size = 
  26.125 -		sizeof(CPlugin) 
  26.126 -		+ sizeof(IdentityToken_t)
  26.127 -		+ (m_configs.size() * (sizeof(AutoConfig *) + sizeof(AutoConfig)))
  26.128 -		+ sm_trie_mem_usage(m_pProps);
  26.129 -
  26.130 -	for (unsigned int i = 0; i < m_configs.size(); i++)
  26.131 -	{
  26.132 -		base_size += m_configs[i]->autocfg.size();
  26.133 -		base_size += m_configs[i]->folder.size();
  26.134 -	}
  26.135 -
  26.136 -	for (List<String>::iterator i = m_Libraries.begin();
  26.137 -		 i != m_Libraries.end();
  26.138 -		 i++)
  26.139 -	{
  26.140 -		base_size += (*i).size();
  26.141 -	}
  26.142 -
  26.143 -	for (List<String>::iterator i = m_RequiredLibs.begin();
  26.144 -		 i != m_RequiredLibs.end();
  26.145 -		 i++)
  26.146 -	{
  26.147 -		base_size += (*i).size();
  26.148 -	}
  26.149 -
  26.150 -	return base_size;
  26.151 -}
  26.152 -
  26.153 -Handle_t CPlugin::GetMyHandle()
  26.154 -{
  26.155 -	return m_handle;
  26.156 -}
  26.157 -
  26.158 -CPlugin *CPlugin::CreatePlugin(const char *file, char *error, size_t maxlength)
  26.159 -{
  26.160 -	char fullpath[PLATFORM_MAX_PATH];
  26.161 -	g_SourceMod.BuildPath(Path_SM, fullpath, sizeof(fullpath), "plugins/%s", file);
  26.162 -	FILE *fp = fopen(fullpath, "rb");
  26.163 -
  26.164 -	CPlugin *pPlugin = new CPlugin(file);
  26.165 -
  26.166 -	if (!fp)
  26.167 -	{
  26.168 -		if (error)
  26.169 -		{
  26.170 -			UTIL_Format(error, maxlength, "Unable to open file");
  26.171 -		}
  26.172 -		pPlugin->m_status = Plugin_BadLoad;
  26.173 -		return pPlugin;
  26.174 -	}
  26.175 -
  26.176 -	fclose(fp);
  26.177 -
  26.178 -	return pPlugin;
  26.179 -}
  26.180 -
  26.181 -bool CPlugin::GetProperty(const char *prop, void **ptr, bool remove/* =false */)
  26.182 -{
  26.183 -	bool exists = sm_trie_retrieve(m_pProps, prop, ptr);
  26.184 -
  26.185 -	if (exists && remove)
  26.186 -	{
  26.187 -		sm_trie_delete(m_pProps, prop);
  26.188 -	}
  26.189 -
  26.190 -	return exists;
  26.191 -}
  26.192 -
  26.193 -bool CPlugin::SetProperty(const char *prop, void *ptr)
  26.194 -{
  26.195 -	return sm_trie_insert(m_pProps, prop, ptr);
  26.196 -}
  26.197 -
  26.198 -IPluginRuntime *CPlugin::GetRuntime()
  26.199 -{
  26.200 -	return m_pRuntime;
  26.201 -}
  26.202 -
  26.203 -void CPlugin::SetErrorState(PluginStatus status, const char *error_fmt, ...)
  26.204 -{
  26.205 -	PluginStatus old_status = m_status;
  26.206 -	m_status = status;
  26.207 -
  26.208 -	if (old_status == Plugin_Running)
  26.209 -	{
  26.210 -		/* Tell everyone we're now paused */
  26.211 -		g_PluginSys._SetPauseState(this, true);
  26.212 -	}
  26.213 -
  26.214 -	va_list ap;
  26.215 -	va_start(ap, error_fmt);
  26.216 -	UTIL_FormatArgs(m_errormsg, sizeof(m_errormsg), error_fmt, ap);
  26.217 -	va_end(ap);
  26.218 -
  26.219 -	if (m_pRuntime != NULL)
  26.220 -	{
  26.221 -		m_pRuntime->SetPauseState(true);
  26.222 -	}
  26.223 -}
  26.224 -
  26.225 -bool CPlugin::UpdateInfo()
  26.226 -{
  26.227 -	/* Now grab the info */
  26.228 -	uint32_t idx;
  26.229 -	IPluginContext *base = GetBaseContext();
  26.230 -	int err = base->FindPubvarByName("myinfo", &idx);
  26.231 -
  26.232 -	memset(&m_info, 0, sizeof(m_info));
  26.233 -
  26.234 -	if (err == SP_ERROR_NONE)
  26.235 -	{
  26.236 -		struct sm_plugininfo_c_t
  26.237 -		{
  26.238 -			cell_t name;
  26.239 -			cell_t description;
  26.240 -			cell_t author;
  26.241 -			cell_t version;
  26.242 -			cell_t url;
  26.243 -		};
  26.244 -		sm_plugininfo_c_t *cinfo;
  26.245 -		cell_t local_addr;
  26.246 -
  26.247 -		base->GetPubvarAddrs(idx, &local_addr, (cell_t **)&cinfo);
  26.248 -		base->LocalToString(cinfo->name, (char **)&m_info.name);
  26.249 -		base->LocalToString(cinfo->description, (char **)&m_info.description);
  26.250 -		base->LocalToString(cinfo->author, (char **)&m_info.author);
  26.251 -		base->LocalToString(cinfo->url, (char **)&m_info.url);
  26.252 -		base->LocalToString(cinfo->version, (char **)&m_info.version);
  26.253 -	}
  26.254 -
  26.255 -	m_info.author = m_info.author ? m_info.author : "";
  26.256 -	m_info.description = m_info.description ? m_info.description : "";
  26.257 -	m_info.name = m_info.name ? m_info.name : "";
  26.258 -	m_info.url = m_info.url ? m_info.url : "";
  26.259 -	m_info.version = m_info.version ? m_info.version : "";
  26.260 -
  26.261 -	if ((err = base->FindPubvarByName("__version", &idx)) == SP_ERROR_NONE)
  26.262 -	{
  26.263 -		struct __version_info
  26.264 -		{
  26.265 -			cell_t version;
  26.266 -			cell_t filevers;
  26.267 -			cell_t date;
  26.268 -			cell_t time;
  26.269 -		};
  26.270 -		__version_info *info;
  26.271 -		cell_t local_addr;
  26.272 -		const char *pDate, *pTime, *pFileVers;
  26.273 -
  26.274 -		pDate = "";
  26.275 -		pTime = "";
  26.276 -
  26.277 -		base->GetPubvarAddrs(idx, &local_addr, (cell_t **)&info);
  26.278 -		m_FileVersion = info->version;
  26.279 -		if (m_FileVersion >= 4)
  26.280 -		{
  26.281 -			base->LocalToString(info->date, (char **)&pDate);
  26.282 -			base->LocalToString(info->time, (char **)&pTime);
  26.283 -			UTIL_Format(m_DateTime, sizeof(m_DateTime), "%s %s", pDate, pTime);
  26.284 -		}
  26.285 -		if (m_FileVersion > 5)
  26.286 -		{
  26.287 -			base->LocalToString(info->filevers, (char **)&pFileVers);
  26.288 -			SetErrorState(Plugin_Failed, "Newer SourceMod required (%s or higher)", pFileVers);
  26.289 -			return false;
  26.290 -		}
  26.291 -	}
  26.292 -	else
  26.293 -	{
  26.294 -		m_FileVersion = 0;
  26.295 -	}
  26.296 -
  26.297 -	if ((err = base->FindPubvarByName("MaxClients", &idx)) == SP_ERROR_NONE)
  26.298 -	{
  26.299 -		base->GetPubvarByIndex(idx, &m_MaxClientsVar);
  26.300 -	}
  26.301 -
  26.302 -	return true;
  26.303 -}
  26.304 -
  26.305 -void CPlugin::SyncMaxClients(int max_clients)
  26.306 -{
  26.307 -	if (m_MaxClientsVar == NULL)
  26.308 -	{
  26.309 -		return;
  26.310 -	}
  26.311 -
  26.312 -	*m_MaxClientsVar->offs = max_clients;
  26.313 -}
  26.314 -
  26.315 -void CPlugin::Call_OnPluginStart()
  26.316 -{
  26.317 -	if (m_status != Plugin_Loaded)
  26.318 -	{
  26.319 -		return;
  26.320 -	}
  26.321 -
  26.322 -	m_status = Plugin_Running;
  26.323 -
  26.324 -	SyncMaxClients(g_Players.MaxClients());
  26.325 -
  26.326 -	cell_t result;
  26.327 -	IPluginFunction *pFunction = m_pRuntime->GetFunctionByName("OnPluginStart");
  26.328 -	if (!pFunction)
  26.329 -	{
  26.330 -		return;
  26.331 -	}
  26.332 -
  26.333 -	int err;
  26.334 -	if ((err=pFunction->Execute(&result)) != SP_ERROR_NONE)
  26.335 -	{
  26.336 -		SetErrorState(Plugin_Error, "Error detected in plugin startup (see error logs)");
  26.337 -	}
  26.338 -}
  26.339 -
  26.340 -void CPlugin::Call_OnPluginEnd()
  26.341 -{
  26.342 -	if (m_status > Plugin_Paused)
  26.343 -	{
  26.344 -		return;
  26.345 -	}
  26.346 -
  26.347 -	cell_t result;
  26.348 -	IPluginFunction *pFunction = m_pRuntime->GetFunctionByName("OnPluginEnd");
  26.349 -	if (!pFunction)
  26.350 -	{
  26.351 -		return;
  26.352 -	}
  26.353 -
  26.354 -	pFunction->Execute(&result);
  26.355 -}
  26.356 -
  26.357 -void CPlugin::Call_OnAllPluginsLoaded()
  26.358 -{
  26.359 -	if (m_status > Plugin_Paused)
  26.360 -	{
  26.361 -		return;
  26.362 -	}
  26.363 -
  26.364 -	if (m_bGotAllLoaded)
  26.365 -	{
  26.366 -		return;
  26.367 -	}
  26.368 -
  26.369 -	m_bGotAllLoaded = true;
  26.370 -
  26.371 -	cell_t result;
  26.372 -	IPluginFunction *pFunction = m_pRuntime->GetFunctionByName("OnAllPluginsLoaded");
  26.373 -	if (pFunction != NULL)
  26.374 -	{
  26.375 -		pFunction->Execute(&result);
  26.376 -	}
  26.377 -
  26.378 -	if (g_SourceMod.IsMapRunning())
  26.379 -	{
  26.380 -		if ((pFunction = m_pRuntime->GetFunctionByName("OnMapStart")) != NULL)
  26.381 -		{
  26.382 -			pFunction->Execute(NULL);
  26.383 -		}
  26.384 -	}
  26.385 -
  26.386 -	if (SM_AreConfigsExecuted())
  26.387 -	{
  26.388 -		SM_ExecuteForPlugin(GetBaseContext());
  26.389 -	}
  26.390 -}
  26.391 -
  26.392 -APLRes CPlugin::Call_AskPluginLoad(char *error, size_t maxlength)
  26.393 -{
  26.394 -	if (m_status != Plugin_Created)
  26.395 -	{
  26.396 -		return APLRes_Failure;
  26.397 -	}
  26.398 -
  26.399 -	m_status = Plugin_Loaded;
  26.400 -
  26.401 -	int err;
  26.402 -	cell_t result;
  26.403 -	bool haveNewAPL = false;
  26.404 -	IPluginFunction *pFunction = m_pRuntime->GetFunctionByName("AskPluginLoad2");
  26.405 -
  26.406 -	if (pFunction) 
  26.407 -	{
  26.408 -		haveNewAPL = true;
  26.409 -	}
  26.410 -	else if (!(pFunction = m_pRuntime->GetFunctionByName("AskPluginLoad")))
  26.411 -	{
  26.412 -		return APLRes_Success;
  26.413 -	}
  26.414 -
  26.415 -	pFunction->PushCell(m_handle);
  26.416 -	pFunction->PushCell(g_PluginSys.IsLateLoadTime() ? 1 : 0);
  26.417 -	pFunction->PushStringEx(error, maxlength, 0, SM_PARAM_COPYBACK);
  26.418 -	pFunction->PushCell(maxlength);
  26.419 -	if ((err=pFunction->Execute(&result)) != SP_ERROR_NONE)
  26.420 -	{
  26.421 -		return APLRes_Failure;
  26.422 -	}
  26.423 -
  26.424 -	if (haveNewAPL) 
  26.425 -	{
  26.426 -		return (APLRes)result;
  26.427 -	}
  26.428 -	else if (result)
  26.429 -	{
  26.430 -		return APLRes_Success;
  26.431 -	}
  26.432 -	else
  26.433 -	{
  26.434 -		return APLRes_Failure;
  26.435 -	}
  26.436 -}
  26.437 -
  26.438 -void *CPlugin::GetPluginStructure()
  26.439 -{
  26.440 -	return NULL;
  26.441 -}
  26.442 -
  26.443 -IPluginContext *CPlugin::GetBaseContext()
  26.444 -{
  26.445 -	if (m_pRuntime == NULL)
  26.446 -	{
  26.447 -		return NULL;
  26.448 -	}
  26.449 -
  26.450 -	return m_pRuntime->GetDefaultContext();
  26.451 -}
  26.452 -
  26.453 -sp_context_t *CPlugin::GetContext()
  26.454 -{
  26.455 -	return NULL;
  26.456 -}
  26.457 -
  26.458 -const char *CPlugin::GetFilename()
  26.459 -{
  26.460 -	return m_filename;
  26.461 -}
  26.462 -
  26.463 -PluginType CPlugin::GetType()
  26.464 -{
  26.465 -	return m_type;
  26.466 -}
  26.467 -
  26.468 -const sm_plugininfo_t *CPlugin::GetPublicInfo()
  26.469 -{
  26.470 -	if (GetStatus() >= Plugin_Created)
  26.471 -	{
  26.472 -		return NULL;
  26.473 -	}
  26.474 -	return &m_info;
  26.475 -}
  26.476 -
  26.477 -unsigned int CPlugin::GetSerial()
  26.478 -{
  26.479 -	return m_serial;
  26.480 -}
  26.481 -
  26.482 -PluginStatus CPlugin::GetStatus()
  26.483 -{
  26.484 -	return m_status;
  26.485 -}
  26.486 -
  26.487 -bool CPlugin::IsSilentlyFailed()
  26.488 -{
  26.489 -	return m_bSilentlyFailed;
  26.490 -}
  26.491 -
  26.492 -bool CPlugin::IsDebugging()
  26.493 -{
  26.494 -	if (m_pRuntime == NULL)
  26.495 -	{
  26.496 -		return false;
  26.497 -	}
  26.498 -
  26.499 -	return true;
  26.500 -}
  26.501 -
  26.502 -void CPlugin::SetSilentlyFailed(bool sf)
  26.503 -{
  26.504 -	m_bSilentlyFailed = sf;
  26.505 -}
  26.506 -
  26.507 -void CPlugin::LibraryActions(LibraryAction action)
  26.508 -{
  26.509 -	List<String>::iterator iter;
  26.510 -	for (iter = m_Libraries.begin();
  26.511 -		iter != m_Libraries.end();
  26.512 -		iter++)
  26.513 -	{
  26.514 -		g_PluginSys.OnLibraryAction((*iter).c_str(), action);
  26.515 -	}
  26.516 -}
  26.517 -
  26.518 -bool CPlugin::SetPauseState(bool paused)
  26.519 -{
  26.520 -	if (paused && GetStatus() != Plugin_Running)
  26.521 -	{
  26.522 -		return false;
  26.523 -	} else if (!paused && GetStatus() != Plugin_Paused) {
  26.524 -		return false;
  26.525 -	}
  26.526 -
  26.527 -	if (paused)
  26.528 -	{
  26.529 -		LibraryActions(LibraryAction_Removed);
  26.530 -	}
  26.531 -
  26.532 -	IPluginFunction *pFunction = m_pRuntime->GetFunctionByName("OnPluginPauseChange");
  26.533 -	if (pFunction)
  26.534 -	{
  26.535 -		cell_t result;
  26.536 -		pFunction->PushCell(paused ? 1 : 0);
  26.537 -		pFunction->Execute(&result);
  26.538 -	}
  26.539 -
  26.540 -	if (paused)
  26.541 -	{
  26.542 -		m_status = Plugin_Paused;
  26.543 -		m_pRuntime->SetPauseState(true);
  26.544 -	} else {
  26.545 -		m_status = Plugin_Running;
  26.546 -		m_pRuntime->SetPauseState(false);
  26.547 -	}
  26.548 -
  26.549 -	g_PluginSys._SetPauseState(this, paused);
  26.550 -
  26.551 -	if (!paused)
  26.552 -	{
  26.553 -		LibraryActions(LibraryAction_Added);
  26.554 -	}
  26.555 -
  26.556 -	return true;
  26.557 -}
  26.558 -
  26.559 -IdentityToken_t *CPlugin::GetIdentity()
  26.560 -{
  26.561 -	return m_ident;
  26.562 -}
  26.563 -
  26.564 -bool CPlugin::IsRunnable()
  26.565 -{
  26.566 -	return (m_status <= Plugin_Paused) ? true : false;
  26.567 -}
  26.568 -
  26.569 -time_t CPlugin::GetFileTimeStamp()
  26.570 -{
  26.571 -	char path[PLATFORM_MAX_PATH];
  26.572 -	g_SourceMod.BuildPath(Path_SM, path, sizeof(path), "plugins/%s", m_filename);
  26.573 -#ifdef PLATFORM_WINDOWS
  26.574 -	struct _stat s;
  26.575 -	if (_stat(path, &s) != 0)
  26.576 -#elif defined PLATFORM_POSIX
  26.577 -	struct stat s;
  26.578 -	if (stat(path, &s) != 0)
  26.579 -#endif
  26.580 -	{
  26.581 -		return 0;
  26.582 -	}
  26.583 -	else
  26.584 -	{
  26.585 -		return s.st_mtime;
  26.586 -	}
  26.587 -}
  26.588 -
  26.589 -time_t CPlugin::GetTimeStamp()
  26.590 -{
  26.591 -	return m_LastAccess;
  26.592 -}
  26.593 -
  26.594 -void CPlugin::SetTimeStamp(time_t t)
  26.595 -{
  26.596 -	m_LastAccess = t;
  26.597 -}
  26.598 -
  26.599 -IPhraseCollection *CPlugin::GetPhrases()
  26.600 -{
  26.601 -	return m_pPhrases;
  26.602 -}
  26.603 -
  26.604 -void CPlugin::DependencyDropped(CPlugin *pOwner)
  26.605 -{
  26.606 -	if (!m_pRuntime)
  26.607 -	{
  26.608 -		return;
  26.609 -	}
  26.610 -
  26.611 -	List<String>::iterator reqlib_iter;
  26.612 -	List<String>::iterator lib_iter;
  26.613 -	for (lib_iter=pOwner->m_Libraries.begin(); lib_iter!=pOwner->m_Libraries.end(); lib_iter++)
  26.614 -	{
  26.615 -		for (reqlib_iter=m_RequiredLibs.begin(); reqlib_iter!=m_RequiredLibs.end(); reqlib_iter++)
  26.616 -		{
  26.617 -			if ((*reqlib_iter) == (*lib_iter))
  26.618 -			{
  26.619 -				m_LibraryMissing = true;
  26.620 -			}
  26.621 -		}	
  26.622 -	}
  26.623 -
  26.624 -	List<NativeEntry *>::iterator iter;
  26.625 -	NativeEntry *pNative;
  26.626 -	sp_native_t *native;
  26.627 -	uint32_t idx;
  26.628 -	unsigned int unbound = 0;
  26.629 -
  26.630 -	for (iter = pOwner->m_Natives.begin();
  26.631 -		 iter != pOwner->m_Natives.end();
  26.632 -		 iter++)
  26.633 -	{
  26.634 -		pNative = (*iter);
  26.635 -		/* Find this native! */
  26.636 -		if (m_pRuntime->FindNativeByName(pNative->name, &idx) != SP_ERROR_NONE)
  26.637 -		{
  26.638 -			continue;
  26.639 -		}
  26.640 -		/* Unbind it */
  26.641 -		m_pRuntime->GetNativeByIndex(idx, &native);
  26.642 -		native->pfn = NULL;
  26.643 -		native->status = SP_NATIVE_UNBOUND;
  26.644 -		unbound++;
  26.645 -	}
  26.646 -
  26.647 -	if (unbound)
  26.648 -	{
  26.649 -		m_FakeNativesMissing = true;
  26.650 -	}
  26.651 -
  26.652 -	/* :IDEA: in the future, add native trapping? */
  26.653 -	if (m_FakeNativesMissing || m_LibraryMissing)
  26.654 -	{
  26.655 -		SetErrorState(Plugin_Error, "Depends on plugin: %s", pOwner->GetFilename());
  26.656 -	}
  26.657 -}
  26.658 -
  26.659 -unsigned int CPlugin::GetConfigCount()
  26.660 -{
  26.661 -	return (unsigned int)m_configs.size();
  26.662 -}
  26.663 -
  26.664 -AutoConfig *CPlugin::GetConfig(unsigned int i)
  26.665 -{
  26.666 -	if (i >= GetConfigCount())
  26.667 -	{
  26.668 -		return NULL;
  26.669 -	}
  26.670 -
  26.671 -	return m_configs[i];
  26.672 -}
  26.673 -
  26.674 -void CPlugin::AddConfig(bool autoCreate, const char *cfg, const char *folder)
  26.675 -{
  26.676 -	/* Do a check for duplicates to prevent double-execution */
  26.677 -	for (size_t i = 0; i < m_configs.size(); i++)
  26.678 -	{
  26.679 -		if (m_configs[i]->autocfg.compare(cfg) == 0
  26.680 -			&& m_configs[i]->folder.compare(folder) == 0
  26.681 -			&& m_configs[i]->create == autoCreate)
  26.682 -		{
  26.683 -			return;
  26.684 -		}
  26.685 -	}
  26.686 -
  26.687 -	AutoConfig *c = new AutoConfig;
  26.688 -
  26.689 -	c->autocfg = cfg;
  26.690 -	c->folder = folder;
  26.691 -	c->create = autoCreate;
  26.692 -
  26.693 -	m_configs.push_back(c);
  26.694 -}
  26.695 -
  26.696 -void CPlugin::DropEverything()
  26.697 -{
  26.698 -	CPlugin *pOther;
  26.699 -	List<CPlugin *>::iterator iter;
  26.700 -	List<WeakNative>::iterator wk_iter;
  26.701 -
  26.702 -	/* Tell everyone that depends on us that we're about to drop */
  26.703 -	for (iter = m_Dependents.begin();
  26.704 -		 iter != m_Dependents.end(); 
  26.705 -		 iter++)
  26.706 -	{
  26.707 -		pOther = (*iter);
  26.708 -		pOther->DependencyDropped(this);
  26.709 -	}
  26.710 -
  26.711 -	/* Note: we don't care about things we depend on. 
  26.712 -	 * The reason is that extensions have their own cleanup 
  26.713 -	 * code for plugins.  Although the "right" design would be 
  26.714 -	 * to centralize that here, i'm omitting it for now.  Thus, 
  26.715 -	 * the code below to walk the plugins list will suffice.
  26.716 -	 */
  26.717 -	
  26.718 -	/* Other plugins could be holding weak references that were 
  26.719 -	 * added by us.  We need to clean all of those up now.
  26.720 -	 */
  26.721 -	for (iter = g_PluginSys.m_plugins.begin();
  26.722 -		 iter != g_PluginSys.m_plugins.end();
  26.723 -		 iter++)
  26.724 -	{
  26.725 -		(*iter)->DropRefsTo(this);
  26.726 -	}
  26.727 -
  26.728 -	/* Proceed with the rest of the necessities. */
  26.729 -	CNativeOwner::DropEverything();
  26.730 -}
  26.731 -
  26.732 -bool CPlugin::AddFakeNative(IPluginFunction *pFunc, const char *name, SPVM_FAKENATIVE_FUNC func)
  26.733 -{
  26.734 -	NativeEntry *pEntry;
  26.735 -
  26.736 -	if ((pEntry = g_ShareSys.AddFakeNative(pFunc, name, func)) == NULL)
  26.737 -	{
  26.738 -		return false;
  26.739 -	}
  26.740 -
  26.741 -	m_Natives.push_back(pEntry);
  26.742 -
  26.743 -	return true;
  26.744 -}
  26.745 -
  26.746 -/*******************
  26.747 - * PLUGIN ITERATOR *
  26.748 - *******************/
  26.749 -
  26.750 -CPluginManager::CPluginIterator::CPluginIterator(List<CPlugin *> *_mylist)
  26.751 -{
  26.752 -	mylist = _mylist;
  26.753 -	Reset();
  26.754 -}
  26.755 -
  26.756 -IPlugin *CPluginManager::CPluginIterator::GetPlugin()
  26.757 -{
  26.758 -	return (*current);
  26.759 -}
  26.760 -
  26.761 -bool CPluginManager::CPluginIterator::MorePlugins()
  26.762 -{
  26.763 -	return (current != mylist->end());
  26.764 -}
  26.765 -
  26.766 -void CPluginManager::CPluginIterator::NextPlugin()
  26.767 -{
  26.768 -	current++;
  26.769 -}
  26.770 -
  26.771 -void CPluginManager::CPluginIterator::Release()
  26.772 -{
  26.773 -	g_PluginSys.ReleaseIterator(this);
  26.774 -}
  26.775 -
  26.776 -CPluginManager::CPluginIterator::~CPluginIterator()
  26.777 -{
  26.778 -}
  26.779 -
  26.780 -void CPluginManager::CPluginIterator::Reset()
  26.781 -{
  26.782 -	current = mylist->begin();
  26.783 -}
  26.784 -
  26.785 -/******************
  26.786 - * PLUGIN MANAGER *
  26.787 - ******************/
  26.788 -
  26.789 -CPluginManager::CPluginManager()
  26.790 -{
  26.791 -	m_LoadLookup = sm_trie_create();
  26.792 -	m_AllPluginsLoaded = false;
  26.793 -	m_MyIdent = NULL;
  26.794 -	m_LoadingLocked = false;
  26.795 -	
  26.796 -	m_bBlockBadPlugins = true;
  26.797 -}
  26.798 -
  26.799 -CPluginManager::~CPluginManager()
  26.800 -{
  26.801 -	/* :NOTICE: 
  26.802 -	 * Ignore the fact that there might be plugins in the cache.
  26.803 -	 * This usually means that Core is not being unloaded properly, and everything
  26.804 -	 * will crash anyway.  YAY
  26.805 -	 */
  26.806 -	sm_trie_destroy(m_LoadLookup);
  26.807 -
  26.808 -	CStack<CPluginManager::CPluginIterator *>::iterator iter;
  26.809 -	for (iter=m_iters.begin(); iter!=m_iters.end(); iter++)
  26.810 -	{
  26.811 -		delete (*iter);
  26.812 -	}
  26.813 -	m_iters.popall();
  26.814 -}
  26.815 -
  26.816 -void CPluginManager::Shutdown()
  26.817 -{
  26.818 -	List<CPlugin *>::iterator iter;
  26.819 -
  26.820 -	while ((iter = m_plugins.begin()) != m_plugins.end())
  26.821 -	{
  26.822 -		UnloadPlugin(*iter);
  26.823 -	}
  26.824 -}
  26.825 -
  26.826 -void CPluginManager::LoadAll_FirstPass(const char *config, const char *basedir)
  26.827 -{
  26.828 -	/* First read in the database of plugin settings */
  26.829 -	m_AllPluginsLoaded = false;
  26.830 -	LoadPluginsFromDir(basedir, NULL);
  26.831 -}
  26.832 -
  26.833 -void CPluginManager::LoadPluginsFromDir(const char *basedir, const char *localpath)
  26.834 -{
  26.835 -	char base_path[PLATFORM_MAX_PATH];
  26.836 -
  26.837 -	/* Form the current path to start reading from */
  26.838 -	if (localpath == NULL)
  26.839 -	{
  26.840 -		g_LibSys.PathFormat(base_path, sizeof(base_path), "%s", basedir);
  26.841 -	} else {
  26.842 -		g_LibSys.PathFormat(base_path, sizeof(base_path), "%s/%s", basedir, localpath);
  26.843 -	}
  26.844 -
  26.845 -	IDirectory *dir = g_LibSys.OpenDirectory(base_path);
  26.846 -
  26.847 -	if (!dir)
  26.848 -	{
  26.849 -		char error[256];
  26.850 -		g_LibSys.GetPlatformError(error, sizeof(error));
  26.851 -		g_Logger.LogError("[SM] Failure reading from plugins path: %s", localpath);
  26.852 -		g_Logger.LogError("[SM] Platform returned error: %s", error);
  26.853 -		return;
  26.854 -	}
  26.855 -
  26.856 -	while (dir->MoreFiles())
  26.857 -	{
  26.858 -		if (dir->IsEntryDirectory() 
  26.859 -			&& (strcmp(dir->GetEntryName(), ".") != 0)
  26.860 -			&& (strcmp(dir->GetEntryName(), "..") != 0)
  26.861 -			&& (strcmp(dir->GetEntryName(), "disabled") != 0)
  26.862 -			&& (strcmp(dir->GetEntryName(), "optional") != 0))
  26.863 -		{
  26.864 -			char new_local[PLATFORM_MAX_PATH];
  26.865 -			if (localpath == NULL)
  26.866 -			{
  26.867 -				/* If no path yet, don't add a former slash */
  26.868 -				UTIL_Format(new_local, sizeof(new_local), "%s", dir->GetEntryName());
  26.869 -			} else {
  26.870 -				g_LibSys.PathFormat(new_local, sizeof(new_local), "%s/%s", localpath, dir->GetEntryName());
  26.871 -			}
  26.872 -			LoadPluginsFromDir(basedir, new_local);
  26.873 -		} else if (dir->IsEntryFile()) {
  26.874 -			const char *name = dir->GetEntryName();
  26.875 -			size_t len = strlen(name);
  26.876 -			if (len >= 4
  26.877 -				&& strcmp(&name[len-4], ".smx") == 0)
  26.878 -			{
  26.879 -				/* If the filename matches, load the plugin */
  26.880 -				char plugin[PLATFORM_MAX_PATH];
  26.881 -				if (localpath == NULL)
  26.882 -				{
  26.883 -					UTIL_Format(plugin, sizeof(plugin), "%s", name);
  26.884 -				} else {
  26.885 -					g_LibSys.PathFormat(plugin, sizeof(plugin), "%s/%s", localpath, name);
  26.886 -				}
  26.887 -				LoadAutoPlugin(plugin);
  26.888 -			}
  26.889 -		}
  26.890 -		dir->NextEntry();
  26.891 -	}
  26.892 -	g_LibSys.CloseDirectory(dir);
  26.893 -}
  26.894 -
  26.895 -LoadRes CPluginManager::_LoadPlugin(CPlugin **_plugin, const char *path, bool debug, PluginType type, char error[], size_t maxlength)
  26.896 -{
  26.897 -	if (m_LoadingLocked)
  26.898 -	{
  26.899 -		return LoadRes_NeverLoad;
  26.900 -	}
  26.901 -
  26.902 -	int err;
  26.903 -
  26.904 -	/**
  26.905 -	 * Does this plugin already exist?
  26.906 -	 */
  26.907 -	CPlugin *pPlugin;
  26.908 -	if (sm_trie_retrieve(m_LoadLookup, path, (void **)&pPlugin))
  26.909 -	{
  26.910 -		/* Check to see if we should try reloading it */
  26.911 -		if (pPlugin->GetStatus() == Plugin_BadLoad
  26.912 -			|| pPlugin->GetStatus() == Plugin_Error
  26.913 -			|| pPlugin->GetStatus() == Plugin_Failed)
  26.914 -		{
  26.915 -			UnloadPlugin(pPlugin);
  26.916 -		}
  26.917 -		else
  26.918 -		{
  26.919 -			if (_plugin)
  26.920 -			{
  26.921 -				*_plugin = pPlugin;
  26.922 -			}
  26.923 -			return LoadRes_AlreadyLoaded;
  26.924 -		}
  26.925 -	}
  26.926 -
  26.927 -	pPlugin = CPlugin::CreatePlugin(path, error, maxlength);
  26.928 -
  26.929 -	assert(pPlugin != NULL);
  26.930 -
  26.931 -	pPlugin->m_type = PluginType_MapUpdated;
  26.932 -
  26.933 -	ICompilation *co = NULL;
  26.934 -
  26.935 -	if (pPlugin->m_status == Plugin_Uncompiled)
  26.936 -	{
  26.937 -		co = g_pSourcePawn2->StartCompilation();
  26.938 -	}
  26.939 -
  26.940 -	/* Do the actual compiling */
  26.941 -	if (co != NULL)
  26.942 -	{
  26.943 -		char fullpath[PLATFORM_MAX_PATH];
  26.944 -		g_SourceMod.BuildPath(Path_SM, fullpath, sizeof(fullpath), "plugins/%s", pPlugin->m_filename);
  26.945 -
  26.946 -		pPlugin->m_pRuntime = g_pSourcePawn2->LoadPlugin(co, fullpath, &err);
  26.947 -		if (pPlugin->m_pRuntime == NULL)
  26.948 -		{
  26.949 -			if (error)
  26.950 -			{
  26.951 -				UTIL_Format(error, 
  26.952 -					maxlength, 
  26.953 -					"Unable to load plugin (error %d: %s)", 
  26.954 -					err, 
  26.955 -					g_pSourcePawn2->GetErrorString(err));
  26.956 -			}
  26.957 -			pPlugin->m_status = Plugin_BadLoad;
  26.958 -		}
  26.959 -		else
  26.960 -		{
  26.961 -			if (pPlugin->UpdateInfo())
  26.962 -			{
  26.963 -				pPlugin->m_status = Plugin_Created;
  26.964 -			}
  26.965 -			else
  26.966 -			{
  26.967 -				if (error)
  26.968 -				{
  26.969 -					UTIL_Format(error, maxlength, "%s", pPlugin->m_errormsg);
  26.970 -				}
  26.971 -			}
  26.972 -		}
  26.973 -	}
  26.974 -	
  26.975 -	if (pPlugin->GetStatus() == Plugin_Created)
  26.976 -	{
  26.977 -		unsigned char *pCodeHash = pPlugin->m_pRuntime->GetCodeHash();
  26.978 -		
  26.979 -		char codeHashBuf[40];
  26.980 -		UTIL_Format(codeHashBuf, 40, "plugin_");
  26.981 -		for (int i = 0; i < 16; i++)
  26.982 -			UTIL_Format(codeHashBuf + 7 + (i * 2), 3, "%02x", pCodeHash[i]);
  26.983 -		
  26.984 -		const char *bulletinUrl = g_pGameConf->GetKeyValue(codeHashBuf);
  26.985 -		if (bulletinUrl != NULL)
  26.986 -		{
  26.987 -			if (m_bBlockBadPlugins)
  26.988 -			{
  26.989 -				if (error)
  26.990 -				{
  26.991 -					if (bulletinUrl[0] != '\0')
  26.992 -					{
  26.993 -						UTIL_Format(error, maxlength, "Known malware detected and blocked. See %s for more info", bulletinUrl);
  26.994 -					} else {
  26.995 -						UTIL_Format(error, maxlength, "Possible malware or illegal plugin detected and blocked");
  26.996 -					}
  26.997 -				}
  26.998 -				pPlugin->m_status = Plugin_BadLoad;
  26.999 -			} else {
 26.1000 -				if (bulletinUrl[0] != '\0')
 26.1001 -				{
 26.1002 -					g_Logger.LogMessage("%s: Known malware detected. See %s for more info, blocking disabled in core.cfg", pPlugin->GetFilename(), bulletinUrl);
 26.1003 -				} else {
 26.1004 -					g_Logger.LogMessage("%s: Possible malware or illegal plugin detected, blocking disabled in core.cfg", pPlugin->GetFilename());
 26.1005 -				}
 26.1006 -			}
 26.1007 -		}
 26.1008 -	}
 26.1009 -
 26.1010 -	LoadRes loadFailure = LoadRes_Failure;
 26.1011 -	/* Get the status */
 26.1012 -	if (pPlugin->GetStatus() == Plugin_Created)
 26.1013 -	{
 26.1014 -		/* First native pass - add anything from Core */
 26.1015 -		g_ShareSys.BindNativesToPlugin(pPlugin, true);
 26.1016 -		pPlugin->InitIdentity();
 26.1017 -		APLRes result = pPlugin->Call_AskPluginLoad(error, maxlength);  
 26.1018 -		switch (result)
 26.1019 -		{
 26.1020 -		case APLRes_Success:
 26.1021 -			/* Autoload any modules */
 26.1022 -			LoadOrRequireExtensions(pPlugin, 1, error, maxlength);
 26.1023 -			break;
 26.1024 -		case APLRes_Failure:
 26.1025 -			pPlugin->SetErrorState(Plugin_Failed, "%s", error);
 26.1026 -			loadFailure = LoadRes_Failure;
 26.1027 -			break;
 26.1028 -		case APLRes_SilentFailure:
 26.1029 -			pPlugin->SetErrorState(Plugin_Failed, "%s", error);
 26.1030 -			loadFailure = LoadRes_SilentFailure;
 26.1031 -			pPlugin->SetSilentlyFailed(true);
 26.1032 -			break;
 26.1033 -		default:
 26.1034 -			assert(false);
 26.1035 -		}
 26.1036 -	}
 26.1037 -
 26.1038 -	/* Save the time stamp */
 26.1039 -	time_t t = pPlugin->GetFileTimeStamp();
 26.1040 -	pPlugin->SetTimeStamp(t);
 26.1041 -
 26.1042 -	if (_plugin)
 26.1043 -	{
 26.1044 -		*_plugin = pPlugin;
 26.1045 -	}
 26.1046 -
 26.1047 -	return (pPlugin->GetStatus() == Plugin_Loaded) ? LoadRes_Successful : loadFailure;
 26.1048 -}
 26.1049 -
 26.1050 -IPlugin *CPluginManager::LoadPlugin(const char *path, bool debug, PluginType type, char error[], size_t maxlength, bool *wasloaded)
 26.1051 -{
 26.1052 -	CPlugin *pl;
 26.1053 -	LoadRes res;
 26.1054 -
 26.1055 -	*wasloaded = false;
 26.1056 -	if ((res=_LoadPlugin(&pl, path, true, type, error, maxlength)) == LoadRes_Failure)
 26.1057 -	{
 26.1058 -		delete pl;
 26.1059 -		return NULL;
 26.1060 -	}
 26.1061 -
 26.1062 -	if (res == LoadRes_AlreadyLoaded)
 26.1063 -	{
 26.1064 -		*wasloaded = true;
 26.1065 -		return pl;
 26.1066 -	}
 26.1067 -
 26.1068 -	if (res == LoadRes_NeverLoad)
 26.1069 -	{
 26.1070 -		if (error)
 26.1071 -		{
 26.1072 -			if (m_LoadingLocked)
 26.1073 -			{
 26.1074 -				UTIL_Format(error, maxlength, "There is a global plugin loading lock in effect");
 26.1075 -			}
 26.1076 -			else
 26.1077 -			{
 26.1078 -				UTIL_Format(error, maxlength, "This plugin is blocked from loading (see plugin_settings.cfg)");
 26.1079 -			}
 26.1080 -		}
 26.1081 -		return NULL;
 26.1082 -	}
 26.1083 -
 26.1084 -	AddPlugin(pl);
 26.1085 -
 26.1086 -	/* Run second pass if we need to */
 26.1087 -	if (IsLateLoadTime() && pl->GetStatus() == Plugin_Loaded)
 26.1088 -	{
 26.1089 -		if (!RunSecondPass(pl, error, maxlength))
 26.1090 -		{
 26.1091 -			UnloadPlugin(pl);
 26.1092 -			return NULL;
 26.1093 -		}
 26.1094 -		pl->Call_OnAllPluginsLoaded();
 26.1095 -	}
 26.1096 -
 26.1097 -	return pl;
 26.1098 -}
 26.1099 -
 26.1100 -void CPluginManager::LoadAutoPlugin(const char *plugin)
 26.1101 -{
 26.1102 -	CPlugin *pl = NULL;
 26.1103 -	LoadRes res;
 26.1104 -	char error[255] = "Unknown error";
 26.1105 -
 26.1106 -	if ((res=_LoadPlugin(&pl, plugin, false, PluginType_MapUpdated, error, sizeof(error))) == LoadRes_Failure)
 26.1107 -	{
 26.1108 -		g_Logger.LogError("[SM] Failed to load plugin \"%s\": %s.", plugin, error);
 26.1109 -		pl->SetErrorState(
 26.1110 -			pl->GetStatus() <= Plugin_Created ? Plugin_BadLoad : pl->GetStatus(), 
 26.1111 -			"%s",
 26.1112 -			error);
 26.1113 -	}
 26.1114 -
 26.1115 -	if (res == LoadRes_Successful || res == LoadRes_Failure || res == LoadRes_SilentFailure)
 26.1116 -	{
 26.1117 -		AddPlugin(pl);
 26.1118 -	}
 26.1119 -}
 26.1120 -
 26.1121 -void CPluginManager::AddPlugin(CPlugin *pPlugin)
 26.1122 -{
 26.1123 -	List<IPluginsListener *>::iterator iter;
 26.1124 -	IPluginsListener *pListener;
 26.1125 -
 26.1126 -	for (iter=m_listeners.begin(); iter!=m_listeners.end(); iter++)
 26.1127 -	{
 26.1128 -		pListener = (*iter);
 26.1129 -		pListener->OnPluginCreated(pPlugin);
 26.1130 -	}
 26.1131 -
 26.1132 -	m_plugins.push_back(pPlugin);
 26.1133 -	sm_trie_insert(m_LoadLookup, pPlugin->m_filename, pPlugin);
 26.1134 -}
 26.1135 -
 26.1136 -void CPluginManager::LoadAll_SecondPass()
 26.1137 -{
 26.1138 -	List<CPlugin *>::iterator iter;
 26.1139 -	CPlugin *pPlugin;
 26.1140 -
 26.1141 -	char error[256];
 26.1142 -	for (iter=m_plugins.begin(); iter!=m_plugins.end(); iter++)
 26.1143 -	{
 26.1144 -		pPlugin = (*iter);
 26.1145 -		if (pPlugin->GetStatus() == Plugin_Loaded)
 26.1146 -		{
 26.1147 -			error[0] = '\0';
 26.1148 -			if (!RunSecondPass(pPlugin, error, sizeof(error)))
 26.1149 -			{
 26.1150 -				g_Logger.LogError("[SM] Unable to load plugin \"%s\": %s", pPlugin->GetFilename(), error);
 26.1151 -				pPlugin->SetErrorState(Plugin_Failed, "%s", error);
 26.1152 -			}
 26.1153 -		}
 26.1154 -	}
 26.1155 -
 26.1156 -	m_AllPluginsLoaded = true;
 26.1157 -}
 26.1158 -
 26.1159 -bool CPluginManager::FindOrRequirePluginDeps(CPlugin *pPlugin, char *error, size_t maxlength)
 26.1160 -{
 26.1161 -	struct _pl
 26.1162 -	{
 26.1163 -		cell_t name;
 26.1164 -		cell_t file;
 26.1165 -		cell_t required;
 26.1166 -	} *pl;
 26.1167 -
 26.1168 -	IPluginContext *pBase = pPlugin->GetBaseContext();
 26.1169 -	uint32_t num = pBase->GetPubVarsNum();
 26.1170 -	sp_pubvar_t *pubvar;
 26.1171 -	char *name, *file;
 26.1172 -	char pathfile[PLATFORM_MAX_PATH];
 26.1173 -
 26.1174 -	for (uint32_t i=0; i<num; i++)
 26.1175 -	{
 26.1176 -		if (pBase->GetPubvarByIndex(i, &pubvar) != SP_ERROR_NONE)
 26.1177 -		{
 26.1178 -			continue;
 26.1179 -		}
 26.1180 -		if (strncmp(pubvar->name, "__pl_", 5) == 0)
 26.1181 -		{
 26.1182 -			pl = (_pl *)pubvar->offs;
 26.1183 -			if (pBase->LocalToString(pl->file, &file) != SP_ERROR_NONE)
 26.1184 -			{
 26.1185 -				continue;
 26.1186 -			}
 26.1187 -			if (pBase->LocalToString(pl->name, &name) != SP_ERROR_NONE)
 26.1188 -			{
 26.1189 -				continue;
 26.1190 -			}
 26.1191 -			g_LibSys.GetFileFromPath(pathfile, sizeof(pathfile), pPlugin->GetFilename());
 26.1192 -			if (strcmp(pathfile, file) == 0)
 26.1193 -			{
 26.1194 -				continue;
 26.1195 -			}
 26.1196 -			if (pl->required == false)
 26.1197 -			{
 26.1198 -				IPluginFunction *pFunc;
 26.1199 -				char buffer[64];
 26.1200 -				UTIL_Format(buffer, sizeof(buffer), "__pl_%s_SetNTVOptional", &pubvar->name[5]);
 26.1201 -				if ((pFunc=pBase->GetFunctionByName(buffer)))
 26.1202 -				{
 26.1203 -					cell_t res;
 26.1204 -					pFunc->Execute(&res);
 26.1205 -					if (pPlugin->GetBaseContext()->GetLastNativeError() != SP_ERROR_NONE)
 26.1206 -					{
 26.1207 -						if (error)
 26.1208 -						{
 26.1209 -							UTIL_Format(error, maxlength, "Fatal error during initializing plugin load");
 26.1210 -						}
 26.1211 -						return false;
 26.1212 -					}
 26.1213 -				}
 26.1214 -			}
 26.1215 -			else
 26.1216 -			{
 26.1217 -				/* Check that we aren't registering the same library twice */
 26.1218 -				if (pPlugin->m_RequiredLibs.find(name) == pPlugin->m_RequiredLibs.end())
 26.1219 -				{
 26.1220 -					pPlugin->m_RequiredLibs.push_back(name);
 26.1221 -				}
 26.1222 -				else
 26.1223 -				{
 26.1224 -					continue;
 26.1225 -				}
 26.1226 -				List<CPlugin *>::iterator iter;
 26.1227 -				CPlugin *pl;
 26.1228 -				bool found = false;
 26.1229 -				for (iter=m_plugins.begin(); iter!=m_plugins.end(); iter++)
 26.1230 -				{
 26.1231 -					pl = (*iter);
 26.1232 -					if (pl->m_Libraries.find(name) != pl->m_Libraries.end())
 26.1233 -					{
 26.1234 -						found = true;
 26.1235 -						break;
 26.1236 -					}
 26.1237 -				}
 26.1238 -				if (!found)
 26.1239 -				{
 26.1240 -					if (error)
 26.1241 -					{
 26.1242 -						UTIL_Format(error, maxlength, "Could not find required plugin \"%s\"", name);
 26.1243 -					}
 26.1244 -					return false;
 26.1245 -				}
 26.1246 -			}
 26.1247 -		}
 26.1248 -	}
 26.1249 -
 26.1250 -	return true;
 26.1251 -}
 26.1252 -
 26.1253 -bool CPluginManager::LoadOrRequireExtensions(CPlugin *pPlugin, unsigned int pass, char *error, size_t maxlength)
 26.1254 -{
 26.1255 -	/* Find any extensions this plugin needs */
 26.1256 -	struct _ext
 26.1257 -	{
 26.1258 -		cell_t name;
 26.1259 -		cell_t file;
 26.1260 -		cell_t autoload;
 26.1261 -		cell_t required;
 26.1262 -	} *ext;
 26.1263 -
 26.1264 -	IPluginContext *pBase = pPlugin->GetBaseContext();
 26.1265 -	uint32_t num = pBase->GetPubVarsNum();
 26.1266 -	sp_pubvar_t *pubvar;
 26.1267 -	IExtension *pExt;
 26.1268 -	char path[PLATFORM_MAX_PATH];
 26.1269 -	char *file, *name;
 26.1270 -	for (uint32_t i=0; i<num; i++)
 26.1271 -	{
 26.1272 -		if (pBase->GetPubvarByIndex(i, &pubvar) != SP_ERROR_NONE)
 26.1273 -		{
 26.1274 -			continue;
 26.1275 -		}
 26.1276 -		if (strncmp(pubvar->name, "__ext_", 6) == 0)
 26.1277 -		{
 26.1278 -			ext = (_ext *)pubvar->offs;
 26.1279 -			if (pBase->LocalToString(ext->file, &file) != SP_ERROR_NONE)
 26.1280 -			{
 26.1281 -				continue;
 26.1282 -			}
 26.1283 -			if (pBase->LocalToString(ext->name, &name) != SP_ERROR_NONE)
 26.1284 -			{
 26.1285 -				continue;
 26.1286 -			}
 26.1287 -			if (pass == 1)
 26.1288 -			{
 26.1289 -				/* Attempt to auto-load if necessary */
 26.1290 -				if (ext->autoload)
 26.1291 -				{
 26.1292 -					g_LibSys.PathFormat(path, PLATFORM_MAX_PATH, "%s", file);
 26.1293 -					bool bErrorOnMissing = ext->required ? true : false;
 26.1294 -					g_Extensions.LoadAutoExtension(path, bErrorOnMissing);
 26.1295 -				}
 26.1296 -			}
 26.1297 -			else if (pass == 2)
 26.1298 -			{
 26.1299 -				/* Is this required? */
 26.1300 -				if (ext->required)
 26.1301 -				{
 26.1302 -					g_LibSys.PathFormat(path, PLATFORM_MAX_PATH, "%s", file);
 26.1303 -					if ((pExt = g_Extensions.FindExtensionByFile(path)) == NULL)
 26.1304 -					{
 26.1305 -						pExt = g_Extensions.FindExtensionByName(name);
 26.1306 -					}
 26.1307 -					/* :TODO: should we bind to unloaded extensions?
 26.1308 -					 * Currently the extension manager will ignore this.
 26.1309 -					 */
 26.1310 -					if (!pExt || !pExt->IsRunning(NULL, 0))
 26.1311 -					{
 26.1312 -						if (error)
 26.1313 -						{
 26.1314 -							UTIL_Format(error, maxlength, "Required extension \"%s\" file(\"%s\") not running", name, file);
 26.1315 -						}
 26.1316 -						return false;
 26.1317 -					}
 26.1318 -					else
 26.1319 -					{
 26.1320 -						g_Extensions.BindChildPlugin(pExt, pPlugin);
 26.1321 -					}
 26.1322 -				}
 26.1323 -				else
 26.1324 -				{
 26.1325 -					IPluginFunction *pFunc;
 26.1326 -					char buffer[64];
 26.1327 -					UTIL_Format(buffer, sizeof(buffer), "__ext_%s_SetNTVOptional", &pubvar->name[6]);
 26.1328 -
 26.1329 -					if ((pFunc = pBase->GetFunctionByName(buffer)) != NULL)
 26.1330 -					{
 26.1331 -						cell_t res;
 26.1332 -						pFunc->Execute(&res);
 26.1333 -						if (pPlugin->GetBaseContext()->GetLastNativeError() != SP_ERROR_NONE)
 26.1334 -						{
 26.1335 -							if (error)
 26.1336 -							{
 26.1337 -								UTIL_Format(error, maxlength, "Fatal error during plugin initialization (ext req)");
 26.1338 -							}
 26.1339 -							return false;
 26.1340 -						}
 26.1341 -					}
 26.1342 -				}
 26.1343 -			}
 26.1344 -		}
 26.1345 -	}
 26.1346 -
 26.1347 -	return true;
 26.1348 -}
 26.1349 -
 26.1350 -bool CPluginManager::RunSecondPass(CPlugin *pPlugin, char *error, size_t maxlength)
 26.1351 -{
 26.1352 -	/* Second pass for extension requirements */
 26.1353 -	if (!LoadOrRequireExtensions(pPlugin, 2, error, maxlength))
 26.1354 -	{
 26.1355 -		return false;
 26.1356 -	}
 26.1357 -
 26.1358 -	if (!FindOrRequirePluginDeps(pPlugin, error, maxlength))
 26.1359 -	{
 26.1360 -		return false;
 26.1361 -	}
 26.1362 -
 26.1363 -	/* Run another binding pass */
 26.1364 -	g_ShareSys.BindNativesToPlugin(pPlugin, false);
 26.1365 -
 26.1366 -	/* Find any unbound natives. Right now, these are not allowed. */
 26.1367 -	IPluginContext *pContext = pPlugin->GetBaseContext();
 26.1368 -	uint32_t num = pContext->GetNativesNum();
 26.1369 -	sp_native_t *native;
 26.1370 -	for (unsigned int i=0; i<num; i++)
 26.1371 -	{
 26.1372 -		if (pContext->GetNativeByIndex(i, &native) != SP_ERROR_NONE)
 26.1373 -		{
 26.1374 -			break;
 26.1375 -		}
 26.1376 -		if (native->status == SP_NATIVE_UNBOUND
 26.1377 -			&& native->name[0] != '@'
 26.1378 -			&& !(native->flags & SP_NTVFLAG_OPTIONAL))
 26.1379 -		{
 26.1380 -			if (error)
 26.1381 -			{
 26.1382 -				UTIL_Format(error, maxlength, "Native \"%s\" was not found", native->name);
 26.1383 -			}
 26.1384 -			return false;
 26.1385 -		}
 26.1386 -	}
 26.1387 -
 26.1388 -	/* Finish by telling all listeners */
 26.1389 -	List<IPluginsListener *>::iterator iter;
 26.1390 -	IPluginsListener *pListener;
 26.1391 -	for (iter=m_listeners.begin(); iter!=m_listeners.end(); iter++)
 26.1392 -	{
 26.1393 -		pListener = (*iter);
 26.1394 -		pListener->OnPluginLoaded(pPlugin);
 26.1395 -	}
 26.1396 -	
 26.1397 -	/* Tell this plugin to finish initializing itself */
 26.1398 -	pPlugin->Call_OnPluginStart();
 26.1399 -
 26.1400 -	/* Now, if we have fake natives, go through all plugins that might need rebinding */
 26.1401 -	if (pPlugin->GetStatus() <= Plugin_Paused && pPlugin->m_Natives.size())
 26.1402 -	{
 26.1403 -		List<CPlugin *>::iterator pl_iter;
 26.1404 -		CPlugin *pOther;
 26.1405 -		for (pl_iter = m_plugins.begin();
 26.1406 -			 pl_iter != m_plugins.end();
 26.1407 -			 pl_iter++)
 26.1408 -		{
 26.1409 -			pOther = (*pl_iter);
 26.1410 -			if ((pOther->GetStatus() == Plugin_Error
 26.1411 -				&& (pOther->m_FakeNativesMissing || pOther->m_LibraryMissing))
 26.1412 -				|| pOther->m_FakeNativesMissing)
 26.1413 -			{
 26.1414 -				TryRefreshDependencies(pOther);
 26.1415 -			}
 26.1416 -			else if ((pOther->GetStatus() == Plugin_Running
 26.1417 -					  || pOther->GetStatus() == Plugin_Paused)
 26.1418 -					 && pOther != pPlugin)
 26.1419 -			{
 26.1420 -				List<NativeEntry *>::iterator nv_iter;
 26.1421 -				for (nv_iter = pPlugin->m_Natives.begin();
 26.1422 -					 nv_iter != pPlugin->m_Natives.end();
 26.1423 -					 nv_iter++)
 26.1424 -				{
 26.1425 -					g_ShareSys.BindNativeToPlugin(pOther, (*nv_iter));
 26.1426 -				}
 26.1427 -			}
 26.1428 -		}
 26.1429 -	}
 26.1430 -
 26.1431 -	/* Go through our libraries and tell other plugins they're added */
 26.1432 -	List<String>::iterator s_iter;
 26.1433 -	for (s_iter = pPlugin->m_Libraries.begin();
 26.1434 -		s_iter != pPlugin->m_Libraries.end();
 26.1435 -		s_iter++)
 26.1436 -	{
 26.1437 -		OnLibraryAction((*s_iter).c_str(), LibraryAction_Added);
 26.1438 -	}
 26.1439 -
 26.1440 -	/* :TODO: optimize? does this even matter? */
 26.1441 -	pPlugin->GetPhrases()->AddPhraseFile("core.phrases");
 26.1442 -
 26.1443 -	return true;
 26.1444 -}
 26.1445 -
 26.1446 -void CPluginManager::TryRefreshDependencies(CPlugin *pPlugin)
 26.1447 -{
 26.1448 -	assert(pPlugin->GetBaseContext() != NULL);
 26.1449 -
 26.1450 -	g_ShareSys.BindNativesToPlugin(pPlugin, false);
 26.1451 -
 26.1452 -	List<String>::iterator lib_iter;
 26.1453 -	List<String>::iterator req_iter;
 26.1454 -	List<CPlugin *>::iterator pl_iter;
 26.1455 -	CPlugin *pl;
 26.1456 -	for (req_iter=pPlugin->m_RequiredLibs.begin(); req_iter!=pPlugin->m_RequiredLibs.end(); req_iter++)
 26.1457 -	{
 26.1458 -		bool found = false;
 26.1459 -		for (pl_iter=m_plugins.begin(); pl_iter!=m_plugins.end(); pl_iter++)
 26.1460 -		{
 26.1461 -			pl = (*pl_iter);
 26.1462 -			for (lib_iter=pl->m_Libraries.begin(); lib_iter!=pl->m_Libraries.end(); lib_iter++)
 26.1463 -			{
 26.1464 -				if ((*req_iter) == (*lib_iter))
 26.1465 -				{
 26.1466 -					found = true;
 26.1467 -				}
 26.1468 -			}
 26.1469 -		}
 26.1470 -		if (!found)
 26.1471 -		{
 26.1472 -			pPlugin->SetErrorState(Plugin_Error, "Library not found: %s", (*req_iter).c_str());
 26.1473 -			return;
 26.1474 -		}
 26.1475 -	}
 26.1476 -
 26.1477 -	/* Find any unbound natives
 26.1478 -	 * Right now, these are not allowed
 26.1479 -	 */
 26.1480 -	IPluginContext *pContext = pPlugin->GetBaseContext();
 26.1481 -	uint32_t num = pContext->GetNativesNum();
 26.1482 -	sp_native_t *native;
 26.1483 -	for (unsigned int i=0; i<num; i++)
 26.1484 -	{
 26.1485 -		if (pContext->GetNativeByIndex(i, &native) != SP_ERROR_NONE)
 26.1486 -		{
 26.1487 -			break;
 26.1488 -		}
 26.1489 -		if (native->status == SP_NATIVE_UNBOUND
 26.1490 -			&& native->name[0] != '@'
 26.1491 -			&& !(native->flags & SP_NTVFLAG_OPTIONAL))
 26.1492 -		{
 26.1493 -			pPlugin->SetErrorState(Plugin_Error, "Native not found: %s", native->name);
 26.1494 -			return;
 26.1495 -		}
 26.1496 -	}
 26.1497 -
 26.1498 -	if (pPlugin->GetStatus() == Plugin_Error)
 26.1499 -	{
 26.1500 -		/* If we got here, all natives are okay again! */
 26.1501 -		pPlugin->m_status = Plugin_Running;
 26.1502 -		if (pPlugin->m_pRuntime->IsPaused())
 26.1503 -		{
 26.1504 -			pPlugin->m_pRuntime->SetPauseState(false);
 26.1505 -			_SetPauseState(pPlugin, false);
 26.1506 -		}
 26.1507 -	}
 26.1508 -}
 26.1509 -
 26.1510 -bool CPluginManager::UnloadPlugin(IPlugin *plugin)
 26.1511 -{
 26.1512 -	CPlugin *pPlugin = (CPlugin *)plugin;
 26.1513 -
 26.1514 -	/* This prevents removal during insertion or anything else weird */
 26.1515 -	if (m_plugins.find(pPlugin) == m_plugins.end())
 26.1516 -	{
 26.1517 -		return false;
 26.1518 -	}
 26.1519 -
 26.1520 -	IPluginContext *pContext = plugin->GetBaseContext();
 26.1521 -	if (pContext != NULL && pContext->IsInExec())
 26.1522 -	{
 26.1523 -		char buffer[255];
 26.1524 -		UTIL_Format(buffer, sizeof(buffer), "sm plugins unload %s\n", plugin->GetFilename());
 26.1525 -		engine->ServerCommand(buffer);
 26.1526 -		return false;
 26.1527 -	}
 26.1528 -
 26.1529 -	/* Remove us from the lookup table and linked list */
 26.1530 -	m_plugins.remove(pPlugin);
 26.1531 -	sm_trie_delete(m_LoadLookup, pPlugin->m_filename);
 26.1532 -
 26.1533 -	/* Go through our libraries and tell other plugins they're gone */
 26.1534 -	List<String>::iterator s_iter;
 26.1535 -	for (s_iter = pPlugin->m_Libraries.begin();
 26.1536 -		 s_iter != pPlugin->m_Libraries.end();
 26.1537 -		 s_iter++)
 26.1538 -	{
 26.1539 -		OnLibraryAction((*s_iter).c_str(), LibraryAction_Removed);
 26.1540 -	}
 26.1541 -
 26.1542 -	List<IPluginsListener *>::iterator iter;
 26.1543 -	IPluginsListener *pListener;
 26.1544 -
 26.1545 -	if (pPlugin->GetStatus() <= Plugin_Error)
 26.1546 -	{
 26.1547 -		/* Notify plugin */
 26.1548 -		pPlugin->Call_OnPluginEnd();
 26.1549 -
 26.1550 -		/* Notify listeners of unloading */
 26.1551 -		for (iter=m_listeners.begin(); iter!=m_listeners.end(); iter++)
 26.1552 -		{
 26.1553 -			pListener = (*iter);
 26.1554 -			pListener->OnPluginUnloaded(pPlugin);
 26.1555 -		}
 26.1556 -	}
 26.1557 -
 26.1558 -	pPlugin->DropEverything();
 26.1559 -
 26.1560 -	for (iter=m_listeners.begin(); iter!=m_listeners.end(); iter++)
 26.1561 -	{
 26.1562 -		/* Notify listeners of destruction */
 26.1563 -		pListener = (*iter);
 26.1564 -		pListener->OnPluginDestroyed(pPlugin);
 26.1565 -	}
 26.1566 -	
 26.1567 -	/* Tell the plugin to delete itself */
 26.1568 -	delete pPlugin;
 26.1569 -
 26.1570 -	return true;
 26.1571 -}
 26.1572 -
 26.1573 -IPlugin *CPluginManager::FindPluginByContext(const sp_context_t *ctx)
 26.1574 -{
 26.1575 -	IPlugin *pPlugin;
 26.1576 -	IPluginContext *pContext;
 26.1577 -
 26.1578 -	pContext = reinterpret_cast<IPluginContext *>(const_cast<sp_context_t *>(ctx));
 26.1579 -
 26.1580 -	if (pContext->GetKey(2, (void **)&pPlugin))
 26.1581 -	{
 26.1582 -		return pPlugin;
 26.1583 -	}
 26.1584 -
 26.1585 -	return NULL;
 26.1586 -}
 26.1587 -
 26.1588 -CPlugin *CPluginManager::GetPluginByCtx(const sp_context_t *ctx)
 26.1589 -{
 26.1590 -	return (CPlugin *)FindPluginByContext(ctx);
 26.1591 -}
 26.1592 -
 26.1593 -unsigned int CPluginManager::GetPluginCount()
 26.1594 -{
 26.1595 -	return m_plugins.size();
 26.1596 -}
 26.1597 -
 26.1598 -void CPluginManager::AddPluginsListener(IPluginsListener *listener)
 26.1599 -{
 26.1600 -	m_listeners.push_back(listener);
 26.1601 -}
 26.1602 -
 26.1603 -void CPluginManager::RemovePluginsListener(IPluginsListener *listener)
 26.1604 -{
 26.1605 -	m_listeners.remove(listener);
 26.1606 -}
 26.1607 -
 26.1608 -IPluginIterator *CPluginManager::GetPluginIterator()
 26.1609 -{
 26.1610 -	if (m_iters.empty())
 26.1611 -	{
 26.1612 -		return new CPluginIterator(&m_plugins);
 26.1613 -	} else {
 26.1614 -		CPluginIterator *iter = m_iters.front();
 26.1615 -		m_iters.pop();
 26.1616 -		iter->Reset();
 26.1617 -		return iter;
 26.1618 -	}
 26.1619 -}
 26.1620 -
 26.1621 -void CPluginManager::ReleaseIterator(CPluginIterator *iter)
 26.1622 -{
 26.1623 -	m_iters.push(iter);
 26.1624 -}
 26.1625 -
 26.1626 -bool CPluginManager::TestAliasMatch(const char *alias, const char *localpath)
 26.1627 -{
 26.1628 -	/* As an optimization, we do not call strlen, but compute the length in the first pass */
 26.1629 -	size_t alias_len = 0;
 26.1630 -	size_t local_len = 0;
 26.1631 -
 26.1632 -	const char *ptr = alias;
 26.1633 -	unsigned int alias_explicit_paths = 0;
 26.1634 -	unsigned int alias_path_end = 0;
 26.1635 -	while (*ptr != '\0')
 26.1636 -	{
 26.1637 -		if (*ptr == '\\' || *ptr == '/')
 26.1638 -		{
 26.1639 -			alias_explicit_paths++;
 26.1640 -			alias_path_end = alias_len;
 26.1641 -		}
 26.1642 -		alias_len++;
 26.1643 -		ptr++;
 26.1644 -	}
 26.1645 -
 26.1646 -	if (alias_explicit_paths && alias_path_end == alias_len - 1)
 26.1647 -	{
 26.1648 -		/* Trailing slash is totally invalid here */
 26.1649 -		return false;
 26.1650 -	}
 26.1651 -
 26.1652 -	ptr = localpath;
 26.1653 -	unsigned int local_explicit_paths = 0;
 26.1654 -	unsigned int local_path_end = 0;
 26.1655 -	while (*ptr != '\0')
 26.1656 -	{
 26.1657 -		if (*ptr == '\\' || *ptr == '/')
 26.1658 -		{
 26.1659 -			local_explicit_paths++;
 26.1660 -			local_path_end = local_len;
 26.1661 -		}
 26.1662 -		local_len++;
 26.1663 -		ptr++;
 26.1664 -	}
 26.1665 -
 26.1666 -	/* If the alias has more explicit paths than the real path,
 26.1667 -	 * no match will be possible.
 26.1668 -	 */
 26.1669 -	if (alias_explicit_paths > local_explicit_paths)
 26.1670 -	{
 26.1671 -		return false;
 26.1672 -	}
 26.1673 -
 26.1674 -	if (alias_explicit_paths)
 26.1675 -	{
 26.1676 -		/* We need to find if the paths match now.  For example, these should all match:
 26.1677 -		 * csdm     csdm
 26.1678 -		 * csdm     optional/csdm
 26.1679 -		 * csdm/ban optional/crab/csdm/ban
 26.1680 -		*/
 26.1681 -		const char *aliasptr = alias;
 26.1682 -		const char *localptr = localpath;
 26.1683 -		bool match = true;
 26.1684 -		do
 26.1685 -		{
 26.1686 -			if (*aliasptr != *localptr)
 26.1687 -			{
 26.1688 -				/* We have to knock one path off */
 26.1689 -				local_explicit_paths--;
 26.1690 -				if (alias_explicit_paths > local_explicit_paths)
 26.1691 -				{
 26.1692 -					/* Skip out if we're gonna have an impossible match */
 26.1693 -					return false;
 26.1694 -				}
 26.1695 -				/* Eat up localptr tokens until we get a result */
 26.1696 -				while (((localptr - localpath) < (int)local_path_end)
 26.1697 -					&& *localptr != '/'
 26.1698 -					&& *localptr != '\\')
 26.1699 -				{
 26.1700 -					localptr++;
 26.1701 -				}
 26.1702 -				/* Check if we hit the end of our searchable area.
 26.1703 -				 * This probably isn't possible because of the path 
 26.1704 -				 * count check, but it's a good idea anyway.
 26.1705 -				 */
 26.1706 -				if ((localptr - localpath) >= (int)local_path_end)
 26.1707 -				{
 26.1708 -					return false;
 26.1709 -				} else {
 26.1710 -					/* Consume the slash token */
 26.1711 -					localptr++;
 26.1712 -				}
 26.1713 -				/* Reset the alias pointer so we can continue consuming */
 26.1714 -				aliasptr = alias;
 26.1715 -				match = false;
 26.1716 -				continue;
 26.1717 -			}
 26.1718 -			/* Note:
 26.1719 -			 * This is safe because if localptr terminates early, aliasptr will too
 26.1720 -			 */
 26.1721 -			do
 26.1722 -			{
 26.1723 -				/* We should never reach the end of the string because of this check. */
 26.1724 -				bool aliasend = (aliasptr - alias) > (int)alias_path_end;
 26.1725 -				bool localend = (localptr - localpath) > (int)local_path_end;
 26.1726 -				if (aliasend || localend)
 26.1727 -				{
 26.1728 -					if (aliasend && localend)
 26.1729 -					{
 26.1730 -						/* we matched, and we can break out now */
 26.1731 -						match = true;
 26.1732 -						break;
 26.1733 -					}
 26.1734 -					/* Otherwise, we've hit the end somehow and rest won't match up.  Break out. */
 26.1735 -					match = false;
 26.1736 -					break;
 26.1737 -				}
 26.1738 -
 26.1739 -				/* If we got here, it's safe to compare the next two tokens */
 26.1740 -				if (*localptr != *aliasptr)
 26.1741 -				{
 26.1742 -					match = false;
 26.1743 -					break;
 26.1744 -				}
 26.1745 -				localptr++;
 26.1746 -				aliasptr++;
 26.1747 -			} while (true);
 26.1748 -		} while (!match);
 26.1749 -	}
 26.1750 -
 26.1751 -	/* If we got here, it's time to compare filenames */
 26.1752 -	const char *aliasptr = alias;
 26.1753 -	const char *localptr = localpath;
 26.1754 -
 26.1755 -	if (alias_explicit_paths)
 26.1756 -	{
 26.1757 -		aliasptr = &alias[alias_path_end + 1];
 26.1758 -	}
 26.1759 -
 26.1760 -	if (local_explicit_paths)
 26.1761 -	{
 26.1762 -		localptr = &localpath[local_path_end + 1];
 26.1763 -	}
 26.1764 -
 26.1765 -	while (true)
 26.1766 -	{
 26.1767 -		if (*aliasptr == '*')
 26.1768 -		{
 26.1769 -			/* First, see if this is the last character */
 26.1770 -			if ((unsigned)(aliasptr - alias) == alias_len - 1)
 26.1771 -			{
 26.1772 -				/* If so, there's no need to match anything else */
 26.1773 -				return true;
 26.1774 -			}
 26.1775 -			/* Otherwise, we need to search for an appropriate matching sequence in local.
 26.1776 -			 * Note that we only need to search up to the next asterisk.
 26.1777 -			 */
 26.1778 -			aliasptr++;
 26.1779 -			bool match = true;
 26.1780 -			const char *local_orig = localptr;
 26.1781 -			do
 26.1782 -			{
 26.1783 -				match = true;
 26.1784 -				while (*aliasptr != '\0' && *aliasptr != '*')
 26.1785 -				{
 26.1786 -					/* Since aliasptr is never '\0', localptr hitting the end will fail */
 26.1787 -					if (*aliasptr != *localptr)
 26.1788 -					{
 26.1789 -						match = false;
 26.1790 -						break;
 26.1791 -					}
 26.1792 -					aliasptr++;
 26.1793 -					localptr++;
 26.1794 -				}
 26.1795 -				if (!match)
 26.1796 -				{
 26.1797 -					/* If we didn't get a match, we need to advance the search stream.
 26.1798 -					 * This will let us skip tokens while still searching for another match.
 26.1799 -					 */
 26.1800 -					localptr = ++local_orig;
 26.1801 -					/* Make sure we don't go out of bounds */
 26.1802 -					if (*localptr == '\0')
 26.1803 -					{
 26.1804 -						break;
 26.1805 -					}
 26.1806 -				}
 26.1807 -			} while (!match);
 26.1808 -
 26.1809 -			if (!match)
 26.1810 -			{
 26.1811 -				return false;
 26.1812 -			} else {
 26.1813 -				/* If we got a match, move on to the next token */
 26.1814 -				continue;
 26.1815 -			}
 26.1816 -		} else if (*aliasptr == '\0') {
 26.1817 -			if (*localptr == '\0'
 26.1818 -				||
 26.1819 -				strcmp(localptr, ".smx") == 0)
 26.1820 -			{
 26.1821 -				return true;
 26.1822 -			} else {
 26.1823 -				return false;
 26.1824 -			}
 26.1825 -		} else if (*aliasptr != *localptr) {
 26.1826 -			return false;
 26.1827 -		}
 26.1828 -		aliasptr++;
 26.1829 -		localptr++;
 26.1830 -	}
 26.1831 -
 26.1832 -	return true;
 26.1833 -}
 26.1834 -
 26.1835 -bool CPluginManager::IsLateLoadTime() const
 26.1836 -{
 26.1837 -	return (m_AllPluginsLoaded || !g_SourceMod.IsMapLoading());
 26.1838 -}
 26.1839 -
 26.1840 -void CPluginManager::OnSourceModAllInitialized()
 26.1841 -{
 26.1842 -	m_MyIdent = g_ShareSys.CreateCoreIdentity();
 26.1843 -
 26.1844 -	HandleAccess sec;
 26.1845 -	g_HandleSys.InitAccessDefaults(NULL, &sec);
 26.1846 -
 26.1847 -	sec.access[HandleAccess_Delete] = HANDLE_RESTRICT_IDENTITY;
 26.1848 -	sec.access[HandleAccess_Clone] = HANDLE_RESTRICT_IDENTITY;
 26.1849 -
 26.1850 -	g_PluginType = g_HandleSys.CreateType("Plugin", this, 0, NULL, &sec, m_MyIdent, NULL);
 26.1851 -	g_PluginIdent = g_ShareSys.CreateIdentType("PLUGIN");
 26.1852 -
 26.1853 -	g_RootMenu.AddRootConsoleCommand("plugins", "Manage Plugins", this);
 26.1854 -
 26.1855 -	g_ShareSys.AddInterface(NULL, this);
 26.1856 -	
 26.1857 -	m_pOnLibraryAdded = g_Forwards.CreateForward("OnLibraryAdded", ET_Ignore, 1, NULL, Param_String);
 26.1858 -	m_pOnLibraryRemoved = g_Forwards.CreateForward("OnLibraryRemoved", ET_Ignore, 1, NULL, Param_String);
 26.1859 -}
 26.1860 -
 26.1861 -void CPluginManager::OnSourceModShutdown()
 26.1862 -{
 26.1863 -	g_RootMenu.RemoveRootConsoleCommand("plugins", this);
 26.1864 -
 26.1865 -	UnloadAll();
 26.1866 -
 26.1867 -	g_HandleSys.RemoveType(g_PluginType, m_MyIdent);
 26.1868 -	g_ShareSys.DestroyIdentType(g_PluginIdent);
 26.1869 -	g_ShareSys.DestroyIdentity(m_MyIdent);
 26.1870 -	
 26.1871 -	g_Forwards.ReleaseForward(m_pOnLibraryAdded);
 26.1872 -	g_Forwards.ReleaseForward(m_pOnLibraryRemoved);
 26.1873 -}
 26.1874 -
 26.1875 -ConfigResult CPluginManager::OnSourceModConfigChanged(const char *key, 
 26.1876 -												 const char *value, 
 26.1877 -												 ConfigSource source, 
 26.1878 -												 char *error, 
 26.1879 -												 size_t maxlength)
 26.1880 -{
 26.1881 -	if (strcmp(key, "BlockBadPlugins") == 0) {
 26.1882 -		if (strcasecmp(value, "yes") == 0)
 26.1883 -		{
 26.1884 -			m_bBlockBadPlugins = true;
 26.1885 -		} else if (strcasecmp(value, "no") == 0) {
 26.1886 -			m_bBlockBadPlugins = false;
 26.1887 -		} else {
 26.1888 -			UTIL_Format(error, maxlength, "Invalid value: must be \"yes\" or \"no\"");
 26.1889 -			return ConfigResult_Reject;
 26.1890 -		}
 26.1891 -		return ConfigResult_Accept;
 26.1892 -	}
 26.1893 -	return ConfigResult_Ignore;
 26.1894 -}
 26.1895 -
 26.1896 -void CPluginManager::OnHandleDestroy(HandleType_t type, void *object)
 26.1897 -{
 26.1898 -	/* We don't care about the internal object, actually */
 26.1899 -}
 26.1900 -
 26.1901 -bool CPluginManager::GetHandleApproxSize(HandleType_t type, void *object, unsigned int *pSize)
 26.1902 -{
 26.1903 -	*pSize = ((CPlugin *)object)->CalcMemUsage();
 26.1904 -	return true;
 26.1905 -}
 26.1906 -
 26.1907 -IPlugin *CPluginManager::PluginFromHandle(Handle_t handle, HandleError *err)
 26.1908 -{
 26.1909 -	IPlugin *pPlugin;
 26.1910 -	HandleError _err;
 26.1911 -
 26.1912 -	HandleSecurity sec;
 26.1913 -
 26.1914 -	sec.pOwner = NULL;
 26.1915 -	sec.pIdentity = m_MyIdent;
 26.1916 -
 26.1917 -	if ((_err=g_HandleSys.ReadHandle(handle, g_PluginType, &sec, (void **)&pPlugin)) != HandleError_None)
 26.1918 -	{
 26.1919 -		pPlugin = NULL;
 26.1920 -	}
 26.1921 -
 26.1922 -	if (err)
 26.1923 -	{
 26.1924 -		*err = _err;
 26.1925 -	}
 26.1926 -
 26.1927 -	return pPlugin;
 26.1928 -}
 26.1929 -
 26.1930 -CPlugin *CPluginManager::GetPluginByOrder(int num)
 26.1931 -{
 26.1932 -	if (num < 1 || num > (int)GetPluginCount())
 26.1933 -	{
 26.1934 -		return NULL;
 26.1935 -	}
 26.1936 -
 26.1937 -	CPlugin *pl;
 26.1938 -	int id = 1;
 26.1939 -
 26.1940 -	SourceHook::List<CPlugin *>::iterator iter;
 26.1941 -	for (iter = m_plugins.begin(); iter != m_plugins.end() && id < num; iter++, id++) {}
 26.1942 -
 26.1943 -	pl = *iter;
 26.1944 -
 26.1945 -	return pl;
 26.1946 -}
 26.1947 -
 26.1948 -const char *CPluginManager::GetStatusText(PluginStatus st)
 26.1949 -{
 26.1950 -	switch (st)
 26.1951 -	{
 26.1952 -	case Plugin_Running:
 26.1953 -		return "Running";
 26.1954 -	case Plugin_Paused:
 26.1955 -		return "Paused";
 26.1956 -	case Plugin_Error:
 26.1957 -		return "Error";
 26.1958 -	case Plugin_Uncompiled:
 26.1959 -		return "Uncompiled";
 26.1960 -	case Plugin_BadLoad:
 26.1961 -		return "Bad Load";
 26.1962 -	case Plugin_Failed:
 26.1963 -		return "Failed";
 26.1964 -	default:
 26.1965 -		assert(false);
 26.1966 -		return "-";
 26.1967 -	}
 26.1968 -}
 26.1969 -
 26.1970 -void CPluginManager::OnRootConsoleCommand(const char *cmdname, const CCommand &command)
 26.1971 -{
 26.1972 -	int argcount = command.ArgC();
 26.1973 -	if (argcount >= 3)
 26.1974 -	{
 26.1975 -		const char *cmd = command.Arg(2);
 26.1976 -		if (strcmp(cmd, "list") == 0)
 26.1977 -		{
 26.1978 -			char buffer[256];
 26.1979 -			unsigned int id = 1;
 26.1980 -			int plnum = GetPluginCount();
 26.1981 -
 26.1982 -			if (!plnum)
 26.1983 -			{
 26.1984 -				g_RootMenu.ConsolePrint("[SM] No plugins loaded");
 26.1985 -				return;
 26.1986 -			}
 26.1987 -			else
 26.1988 -			{
 26.1989 -				g_RootMenu.ConsolePrint("[SM] Listing %d plugin%s:", GetPluginCount(), (plnum > 1) ? "s" : "");
 26.1990 -			}
 26.1991 -
 26.1992 -			CPlugin *pl;
 26.1993 -			SourceHook::List<CPlugin *>::iterator iter;
 26.1994 -			SourceHook::List<CPlugin *> m_FailList;
 26.1995 -
 26.1996 -			for (iter = m_plugins.begin(); iter != m_plugins.end(); iter++, id++)
 26.1997 -			{
 26.1998 -				pl = (*iter);
 26.1999 -				assert(pl->GetStatus() != Plugin_Created);
 26.2000 -				int len = 0;
 26.2001 -				const sm_plugininfo_t *info = pl->GetPublicInfo();
 26.2002 -				if (pl->GetStatus() != Plugin_Running && !pl->IsSilentlyFailed())
 26.2003 -				{
 26.2004 -					len += UTIL_Format(buffer, sizeof(buffer), "  %02d <%s>", id, GetStatusText(pl->GetStatus()));
 26.2005 -
 26.2006 -					if (pl->GetStatus() <= Plugin_Error)
 26.2007 -					{
 26.2008 -						/* Plugin has failed to load. */
 26.2009 -						m_FailList.push_back(pl);
 26.2010 -					}
 26.2011 -				}
 26.2012 -				else
 26.2013 -				{
 26.2014 -					len += UTIL_Format(buffer, sizeof(buffer), "  %02d", id);
 26.2015 -				}
 26.2016 -				if (pl->GetStatus() < Plugin_Created)
 26.2017 -				{
 26.2018 -					if (pl->IsSilentlyFailed())
 26.2019 -						len += UTIL_Format(&buffer[len], sizeof(buffer)-len, " Disabled:");
 26.2020 -					len += UTIL_Format(&buffer[len], sizeof(buffer)-len, " \"%s\"", (IS_STR_FILLED(info->name)) ? info->name : pl->GetFilename());
 26.2021 -					if (IS_STR_FILLED(info->version))
 26.2022 -					{
 26.2023 -						len += UTIL_Format(&buffer[len], sizeof(buffer)-len, " (%s)", info->version);
 26.2024 -					}
 26.2025 -					if (IS_STR_FILLED(info->author))
 26.2026 -					{
 26.2027 -						UTIL_Format(&buffer[len], sizeof(buffer)-len, " by %s", info->author);
 26.2028 -					}
 26.2029 -				}
 26.2030 -				else
 26.2031 -				{
 26.2032 -					UTIL_Format(&buffer[len], sizeof(buffer)-len, " %s", pl->m_filename);
 26.2033 -				}
 26.2034 -				g_RootMenu.ConsolePrint("%s", buffer);
 26.2035 -			}
 26.2036 -
 26.2037 -			if (!m_FailList.empty())
 26.2038 -			{
 26.2039 -				g_RootMenu.ConsolePrint("Load Errors:");
 26.2040 -
 26.2041 -				SourceHook::List<CPlugin *>::iterator _iter;
 26.2042 -
 26.2043 -				CPlugin *pl;
 26.2044 -
 26.2045 -				for (_iter=m_FailList.begin(); _iter!=m_FailList.end(); _iter++)
 26.2046 -				{
 26.2047 -					pl = (CPlugin *)*_iter;
 26.2048 -					g_RootMenu.ConsolePrint("%s: %s",(IS_STR_FILLED(pl->GetPublicInfo()->name)) ? pl->GetPublicInfo()->name : pl->GetFilename(), pl->m_errormsg);
 26.2049 -				}
 26.2050 -			}
 26.2051 -
 26.2052 -			return;
 26.2053 -		}
 26.2054 -		else if (strcmp(cmd, "load") == 0)
 26.2055 -		{
 26.2056 -			if (argcount < 4)
 26.2057 -			{
 26.2058 -				g_RootMenu.ConsolePrint("[SM] Usage: sm plugins load <file>");
 26.2059 -				return;
 26.2060 -			}
 26.2061 -
 26.2062 -			char error[128];
 26.2063 -			bool wasloaded;
 26.2064 -			const char *filename = command.Arg(3);
 26.2065 -
 26.2066 -			char pluginfile[256];
 26.2067 -			const char *ext = g_LibSys.GetFileExtension(filename) ? "" : ".smx";
 26.2068 -			g_SourceMod.BuildPath(Path_None, pluginfile, sizeof(pluginfile), "%s%s", filename, ext);
 26.2069 -
 26.2070 -			IPlugin *pl = LoadPlugin(pluginfile, false, PluginType_MapUpdated, error, sizeof(error), &wasloaded);
 26.2071 -
 26.2072 -			if (wasloaded)
 26.2073 -			{
 26.2074 -				g_RootMenu.ConsolePrint("[SM] Plugin %s is already loaded.", pluginfile);
 26.2075 -				return;
 26.2076 -			}
 26.2077 -
 26.2078 -			if (pl)
 26.2079 -			{
 26.2080 -				g_RootMenu.ConsolePrint("[SM] Loaded plugin %s successfully.", pluginfile);
 26.2081 -			}
 26.2082 -			else
 26.2083 -			{
 26.2084 -				g_RootMenu.ConsolePrint("[SM] Plugin %s failed to load: %s.", pluginfile, error);
 26.2085 -			}
 26.2086 -
 26.2087 -			return;
 26.2088 -		}
 26.2089 -		else if (strcmp(cmd, "unload") == 0)
 26.2090 -		{
 26.2091 -			if (argcount < 4)
 26.2092 -			{
 26.2093 -				g_RootMenu.ConsolePrint("[SM] Usage: sm plugins unload <#|file>");
 26.2094 -				return;
 26.2095 -			}
 26.2096 -
 26.2097 -			CPlugin *pl;
 26.2098 -			char *end;
 26.2099 -			const char *arg = command.Arg(3);
 26.2100 -			int id = strtol(arg, &end, 10);
 26.2101 -
 26.2102 -			if (*end == '\0')
 26.2103 -			{
 26.2104 -				pl = GetPluginByOrder(id);
 26.2105 -				if (!pl)
 26.2106 -				{
 26.2107 -					g_RootMenu.ConsolePrint("[SM] Plugin index %d not found.", id);
 26.2108 -					return;
 26.2109 -				}
 26.2110 -			}
 26.2111 -			else
 26.2112 -			{
 26.2113 -				char pluginfile[256];
 26.2114 -				const char *ext = g_LibSys.GetFileExtension(arg) ? "" : ".smx";
 26.2115 -				g_SourceMod.BuildPath(Path_None, pluginfile, sizeof(pluginfile), "%s%s", arg, ext);
 26.2116 -
 26.2117 -				if (!sm_trie_retrieve(m_LoadLookup, pluginfile, (void **)&pl))
 26.2118 -				{
 26.2119 -					g_RootMenu.ConsolePrint("[SM] Plugin %s is not loaded.", pluginfile);
 26.2120 -					return;
 26.2121 -				}
 26.2122 -			}
 26.2123 -
 26.2124 -			char name[PLATFORM_MAX_PATH];
 26.2125 -
 26.2126 -			if (pl->GetStatus() < Plugin_Created)
 26.2127 -			{
 26.2128 -				const sm_plugininfo_t *info = pl->GetPublicInfo();
 26.2129 -				UTIL_Format(name, sizeof(name), (IS_STR_FILLED(info->name)) ? info->name : pl->GetFilename());
 26.2130 -			}
 26.2131 -			else
 26.2132 -			{
 26.2133 -				UTIL_Format(name, sizeof(name), "%s", pl->GetFilename());
 26.2134 -			}
 26.2135 -
 26.2136 -			if (UnloadPlugin(pl))
 26.2137 -			{
 26.2138 -				g_RootMenu.ConsolePrint("[SM] Plugin %s unloaded successfully.", name);
 26.2139 -			}
 26.2140 -			else
 26.2141 -			{
 26.2142 -				g_RootMenu.ConsolePrint("[SM] Failed to unload plugin %s.", name);
 26.2143 -			}
 26.2144 -
 26.2145 -			return;
 26.2146 -		}
 26.2147 -		else if (strcmp(cmd, "unload_all") == 0)
 26.2148 -		{
 26.2149 -			g_PluginSys.UnloadAll();
 26.2150 -			g_RootMenu.ConsolePrint("[SM] All plugins have been unloaded.");
 26.2151 -			return;
 26.2152 -		}
 26.2153 -		else if (strcmp(cmd, "load_lock") == 0)
 26.2154 -		{
 26.2155 -			if (m_LoadingLocked)
 26.2156 -			{
 26.2157 -				g_RootMenu.ConsolePrint("[SM] There is already a loading lock in effect.");
 26.2158 -			}
 26.2159 -			else
 26.2160 -			{
 26.2161 -				m_LoadingLocked = true;
 26.2162 -				g_RootMenu.ConsolePrint("[SM] Loading is now locked; no plugins will be loaded or re-loaded.");
 26.2163 -			}
 26.2164 -			return;
 26.2165 -		}
 26.2166 -		else if (strcmp(cmd, "load_unlock") == 0)
 26.2167 -		{
 26.2168 -			if (m_LoadingLocked)
 26.2169 -			{
 26.2170 -				m_LoadingLocked = false;
 26.2171 -				g_RootMenu.ConsolePrint("[SM] The loading lock is no longer in effect.");
 26.2172 -			}
 26.2173 -			else
 26.2174 -			{
 26.2175 -				g_RootMenu.ConsolePrint("[SM] There was no loading lock in effect.");
 26.2176 -			}
 26.2177 -			return;
 26.2178 -		}
 26.2179 -		else if (strcmp(cmd, "info") == 0)
 26.2180 -		{
 26.2181 -			if (argcount < 4)
 26.2182 -			{
 26.2183 -				g_RootMenu.ConsolePrint("[SM] Usage: sm plugins info <#>");
 26.2184 -				return;
 26.2185 -			}
 26.2186 -
 26.2187 -			CPlugin *pl;
 26.2188 -			char *end;
 26.2189 -			const char *arg = command.Arg(3);
 26.2190 -			int id = strtol(arg, &end, 10);
 26.2191 -
 26.2192 -			if (*end == '\0')
 26.2193 -			{
 26.2194 -				pl = GetPluginByOrder(id);
 26.2195 -				if (!pl)
 26.2196 -				{
 26.2197 -					g_RootMenu.ConsolePrint("[SM] Plugin index %d not found.", id);
 26.2198 -					return;
 26.2199 -				}
 26.2200 -			}
 26.2201 -			else
 26.2202 -			{
 26.2203 -				char pluginfile[256];
 26.2204 -				const char *ext = g_LibSys.GetFileExtension(arg) ? "" : ".smx";
 26.2205 -				g_SourceMod.BuildPath(Path_None, pluginfile, sizeof(pluginfile), "%s%s", arg, ext);
 26.2206 -
 26.2207 -				if (!sm_trie_retrieve(m_LoadLookup, pluginfile, (void **)&pl))
 26.2208 -				{
 26.2209 -					g_RootMenu.ConsolePrint("[SM] Plugin %s is not loaded.", pluginfile);
 26.2210 -					return;
 26.2211 -				}
 26.2212 -			}
 26.2213 -
 26.2214 -			const sm_plugininfo_t *info = pl->GetPublicInfo();
 26.2215 -
 26.2216 -			g_RootMenu.ConsolePrint("  Filename: %s", pl->GetFilename());
 26.2217 -			if (pl->GetStatus() <= Plugin_Error)
 26.2218 -			{
 26.2219 -				if (IS_STR_FILLED(info->name))
 26.2220 -				{
 26.2221 -					if (IS_STR_FILLED(info->description))
 26.2222 -					{
 26.2223 -						g_RootMenu.ConsolePrint("  Title: %s (%s)", info->name, info->description);
 26.2224 -					} else {
 26.2225 -						g_RootMenu.ConsolePrint("  Title: %s", info->name);
 26.2226 -					}
 26.2227 -				}
 26.2228 -				if (IS_STR_FILLED(info->author))
 26.2229 -				{
 26.2230 -					g_RootMenu.ConsolePrint("  Author: %s", info->author);
 26.2231 -				}
 26.2232 -				if (IS_STR_FILLED(info->version))
 26.2233 -				{
 26.2234 -					g_RootMenu.ConsolePrint("  Version: %s", info->version);
 26.2235 -				}
 26.2236 -				if (IS_STR_FILLED(info->url))
 26.2237 -				{
 26.2238 -					g_RootMenu.ConsolePrint("  URL: %s", info->url);
 26.2239 -				}
 26.2240 -				if (pl->GetStatus() == Plugin_Error)
 26.2241 -				{
 26.2242 -					g_RootMenu.ConsolePrint("  Error: %s", pl->m_errormsg);
 26.2243 -				}
 26.2244 -				else
 26.2245 -				{
 26.2246 -					if (pl->GetStatus() == Plugin_Running)
 26.2247 -					{
 26.2248 -						g_RootMenu.ConsolePrint("  Status: running");
 26.2249 -					}
 26.2250 -					else
 26.2251 -					{
 26.2252 -						g_RootMenu.ConsolePrint("  Status: not running");
 26.2253 -					}
 26.2254 -
 26.2255 -					const char *typestr = "";
 26.2256 -					switch (pl->GetType())
 26.2257 -					{
 26.2258 -					case PluginType_MapUpdated:
 26.2259 -						typestr = "Map Change if Updated";
 26.2260 -						break;
 26.2261 -					case PluginType_MapOnly:
 26.2262 -						typestr = "Map Change";
 26.2263 -						break;
 26.2264 -					case PluginType_Private:
 26.2265 -					case PluginType_Global:
 26.2266 -						typestr = "Never";
 26.2267 -						break;
 26.2268 -					}
 26.2269 -
 26.2270 -					g_RootMenu.ConsolePrint("  Reloads: %s", typestr);
 26.2271 -				}
 26.2272 -				if (pl->m_FileVersion >= 3)
 26.2273 -				{
 26.2274 -					g_RootMenu.ConsolePrint("  Timestamp: %s", pl->m_DateTime);
 26.2275 -				}
 26.2276 -				
 26.2277 -				unsigned char *pCodeHash = pl->m_pRuntime->GetCodeHash();
 26.2278 -				unsigned char *pDataHash = pl->m_pRuntime->GetDataHash();
 26.2279 -				
 26.2280 -				char combinedHash[33];
 26.2281 -				for (int i = 0; i < 16; i++)
 26.2282 -					UTIL_Format(combinedHash + (i * 2), 3, "%02x", pCodeHash[i] ^ pDataHash[i]);
 26.2283 -				
 26.2284 -				g_RootMenu.ConsolePrint("  Hash: %s", combinedHash);
 26.2285 -			}
 26.2286 -			else
 26.2287 -			{
 26.2288 -				g_RootMenu.ConsolePrint("  Load error: %s", pl->m_errormsg);
 26.2289 -				if (pl->GetStatus() < Plugin_Created)
 26.2290 -				{
 26.2291 -					g_RootMenu.ConsolePrint("  File info: (title \"%s\") (version \"%s\")", 
 26.2292 -											info->name ? info->name : "<none>",
 26.2293 -											info->version ? info->version : "<none>");
 26.2294 -					if (IS_STR_FILLED(info->url))
 26.2295 -					{
 26.2296 -						g_RootMenu.ConsolePrint("  File URL: %s", info->url);
 26.2297 -					}
 26.2298 -				}
 26.2299 -			}
 26.2300 -
 26.2301 -			return;
 26.2302 -		}
 26.2303 -		else if (strcmp(cmd, "refresh") == 0)
 26.2304 -		{
 26.2305 -			g_SourceMod.DoGlobalPluginLoads();
 26.2306 -			g_RootMenu.ConsolePrint("[SM] The plugin list has been refreshed and reloaded.");
 26.2307 -			return;
 26.2308 -		}
 26.2309 -		else if (strcmp(cmd, "reload") == 0)
 26.2310 -		{
 26.2311 -			if (argcount < 4)
 26.2312 -			{
 26.2313 -				g_RootMenu.ConsolePrint("[SM] Usage: sm plugins reload <#|file>");
 26.2314 -				return;
 26.2315 -			}
 26.2316 -
 26.2317 -			CPlugin *pl;
 26.2318 -			char *end;
 26.2319 -			const char *arg = command.Arg(3);
 26.2320 -			int id = strtol(arg, &end, 10);
 26.2321 -
 26.2322 -			if (*end == '\0')
 26.2323 -			{
 26.2324 -				pl = GetPluginByOrder(id);
 26.2325 -				if (!pl)
 26.2326 -				{
 26.2327 -					g_RootMenu.ConsolePrint("[SM] Plugin index %d not found.", id);
 26.2328 -					return;
 26.2329 -				}
 26.2330 -			}
 26.2331 -			else
 26.2332 -			{
 26.2333 -				char pluginfile[256];
 26.2334 -				const char *ext = g_LibSys.GetFileExtension(arg) ? "" : ".smx";
 26.2335 -				g_SourceMod.BuildPath(Path_None, pluginfile, sizeof(pluginfile), "%s%s", arg, ext);
 26.2336 -
 26.2337 -				if (!sm_trie_retrieve(m_LoadLookup, pluginfile, (void **)&pl))
 26.2338 -				{
 26.2339 -					g_RootMenu.ConsolePrint("[SM] Plugin %s is not loaded.", pluginfile);
 26.2340 -					return;
 26.2341 -				}
 26.2342 -			}
 26.2343 -
 26.2344 -			char name[PLATFORM_MAX_PATH];
 26.2345 -			const sm_plugininfo_t *info = pl->GetPublicInfo();
 26.2346 -			if (pl->GetStatus() <= Plugin_Paused) 
 26.2347 -				strcpy(name, (IS_STR_FILLED(info->name)) ? info->name : pl->GetFilename());
 26.2348 -			else
 26.2349 -				strcpy(name, pl->GetFilename());
 26.2350 -
 26.2351 -			if (ReloadPlugin(pl))
 26.2352 -			{
 26.2353 -				g_RootMenu.ConsolePrint("[SM] Plugin %s reloaded successfully.", name);
 26.2354 -			}
 26.2355 -			else
 26.2356 -			{
 26.2357 -				g_RootMenu.ConsolePrint("[SM] Failed to reload plugin %s.", name);
 26.2358 -			}
 26.2359 -
 26.2360 -			return;
 26.2361 -		}
 26.2362 -	}
 26.2363 -
 26.2364 -	/* Draw the main menu */
 26.2365 -	g_RootMenu.ConsolePrint("SourceMod Plugins Menu:");
 26.2366 -	g_RootMenu.DrawGenericOption("info", "Information about a plugin");
 26.2367 -	g_RootMenu.DrawGenericOption("list", "Show loaded plugins");
 26.2368 -	g_RootMenu.DrawGenericOption("load", "Load a plugin");
 26.2369 -	g_RootMenu.DrawGenericOption("load_lock", "Prevents any more plugins from being loaded");
 26.2370 -	g_RootMenu.DrawGenericOption("load_unlock", "Re-enables plugin loading");
 26.2371 -	g_RootMenu.DrawGenericOption("refresh", "Reloads/refreshes all plugins in the plugins folder");
 26.2372 -	g_RootMenu.DrawGenericOption("reload", "Reloads a plugin");
 26.2373 -	g_RootMenu.DrawGenericOption("unload", "Unload a plugin");
 26.2374 -	g_RootMenu.DrawGenericOption("unload_all", "Unloads all plugins");
 26.2375 -}
 26.2376 -
 26.2377 -bool CPluginManager::ReloadPlugin(CPlugin *pl)
 26.2378 -{
 26.2379 -	List<CPlugin *>::iterator iter;
 26.2380 -	char filename[PLATFORM_MAX_PATH];
 26.2381 -	bool wasloaded;
 26.2382 -	PluginType ptype;
 26.2383 -	IPlugin *newpl;
 26.2384 -	int id = 1;
 26.2385 -
 26.2386 -	strcpy(filename, pl->m_filename);
 26.2387 -	ptype = pl->GetType();
 26.2388 -
 26.2389 -	for (iter=m_plugins.begin(); iter!=m_plugins.end(); iter++, id++)
 26.2390 -	{
 26.2391 -		if ((*iter) == pl)
 26.2392 -		{
 26.2393 -			break;
 26.2394 -		}
 26.2395 -	}
 26.2396 -
 26.2397 -	if (!UnloadPlugin(pl))
 26.2398 -	{
 26.2399 -		return false;
 26.2400 -	}
 26.2401 -	if (!(newpl=LoadPlugin(filename, true, ptype, NULL, 0, &wasloaded)))
 26.2402 -	{
 26.2403 -		return false;
 26.2404 -	}
 26.2405 -
 26.2406 -	for (iter=m_plugins.begin(); iter!=m_plugins.end(); iter++)
 26.2407 -	{
 26.2408 -		if ((*iter) == (CPlugin *)newpl)
 26.2409 -		{
 26.2410 -			m_plugins.erase(iter);
 26.2411 -			break;
 26.2412 -		}
 26.2413 -	}
 26.2414 -
 26.2415 -	int i;
 26.2416 -	for (i=1, iter=m_plugins.begin(); iter!=m_plugins.end() && i<id; iter++, i++)
 26.2417 -	{
 26.2418 -	}
 26.2419 -	m_plugins.insert(iter, (CPlugin *)newpl);
 26.2420 -
 26.2421 -	return true;
 26.2422 -}
 26.2423 -
 26.2424 -void CPluginManager::ReloadOrUnloadPlugins()
 26.2425 -{
 26.2426 -	/* If we're in a load lock, just skip this whole bit. */
 26.2427 -	if (m_LoadingLocked)
 26.2428 -	{
 26.2429 -		return;
 26.2430 -	}
 26.2431 -
 26.2432 -	List<CPlugin *>::iterator iter;
 26.2433 -	List<CPlugin *> tmp_list = m_plugins;
 26.2434 -	CPlugin *pl;
 26.2435 -	time_t t;
 26.2436 -
 26.2437 -	for (iter=tmp_list.begin(); iter!=tmp_list.end(); iter++)
 26.2438 -	{
 26.2439 -		pl = (*iter);
 26.2440 -		if (pl->GetType() ==  PluginType_MapOnly)
 26.2441 -		{
 26.2442 -			UnloadPlugin((IPlugin *)pl);
 26.2443 -		}
 26.2444 -		else if (pl->GetType() == PluginType_MapUpdated)
 26.2445 -		{
 26.2446 -			t = pl->GetFileTimeStamp();
 26.2447 -			if (!t || t > pl->GetTimeStamp())
 26.2448 -			{
 26.2449 -				pl->SetTimeStamp(t);
 26.2450 -				UnloadPlugin((IPlugin *)pl);
 26.2451 -			}
 26.2452 -		}
 26.2453 -	}
 26.2454 -}
 26.2455 -
 26.2456 -void CPluginManager::_SetPauseState(CPlugin *pl, bool paused)
 26.2457 -{
 26.2458 -	List<IPluginsListener *>::iterator iter;
 26.2459 -	IPluginsListener *pListener;
 26.2460 -	for (iter=m_listeners.begin(); iter!=m_listeners.end(); iter++)
 26.2461 -	{
 26.2462 -		pListener = (*iter);
 26.2463 -		pListener->OnPluginPauseChange(pl, paused);
 26.2464 -	}	
 26.2465 -}
 26.2466 -
 26.2467 -void CPluginManager::AddFunctionsToForward(const char *name, IChangeableForward *pForward)
 26.2468 -{
 26.2469 -	List<CPlugin *>::iterator iter;
 26.2470 -	CPlugin *pPlugin;
 26.2471 -	IPluginFunction *pFunction;
 26.2472 -
 26.2473 -	for (iter = m_plugins.begin(); iter != m_plugins.end(); iter++)
 26.2474 -	{
 26.2475 -		pPlugin = (*iter);
 26.2476 -
 26.2477 -		if (pPlugin->GetStatus() <= Plugin_Paused)
 26.2478 -		{
 26.2479 -			pFunction = pPlugin->GetBaseContext()->GetFunctionByName(name);
 26.2480 -
 26.2481 -			if (pFunction)
 26.2482 -			{
 26.2483 -				pForward->AddFunction(pFunction);
 26.2484 -			}
 26.2485 -		}
 26.2486 -	}
 26.2487 -}
 26.2488 -
 26.2489 -CPlugin *CPluginManager::GetPluginFromIdentity(IdentityToken_t *pToken)
 26.2490 -{
 26.2491 -	if (pToken->type != g_PluginIdent)
 26.2492 -	{
 26.2493 -		return NULL;
 26.2494 -	}
 26.2495 -
 26.2496 -	return (CPlugin *)(pToken->ptr);
 26.2497 -}
 26.2498 -
 26.2499 -void CPluginManager::OnLibraryAction(const char *lib, LibraryAction action)
 26.2500 -{
 26.2501 -	switch (action)
 26.2502 -	{
 26.2503 -	case LibraryAction_Removed:
 26.2504 -		m_pOnLibraryRemoved->PushString(lib);
 26.2505 -		m_pOnLibraryRemoved->Execute(NULL);
 26.2506 -		break;
 26.2507 -	case LibraryAction_Added:
 26.2508 -		m_pOnLibraryAdded->PushString(lib);
 26.2509 -		m_pOnLibraryAdded->Execute(NULL);
 26.2510 -		break;
 26.2511 -	}
 26.2512 -}
 26.2513 -
 26.2514 -bool CPluginManager::LibraryExists(const char *lib)
 26.2515 -{
 26.2516 -	List<CPlugin *>::iterator iter;
 26.2517 -
 26.2518 -	for (iter=m_plugins.begin();
 26.2519 -		 iter!=m_plugins.end();
 26.2520 -		 iter++)
 26.2521 -	{
 26.2522 -		CPlugin *pl = (*iter);
 26.2523 -		if (pl->GetStatus() != Plugin_Running)
 26.2524 -		{
 26.2525 -			continue;
 26.2526 -		}
 26.2527 -		List<String>::iterator s_iter;
 26.2528 -		for (s_iter = pl->m_Libraries.begin();
 26.2529 -			 s_iter != pl->m_Libraries.end();
 26.2530 -			 s_iter++)
 26.2531 -		{
 26.2532 -			if ((*s_iter).compare(lib) == 0)
 26.2533 -			{
 26.2534 -				return true;
 26.2535 -			}
 26.2536 -		}
 26.2537 -	}
 26.2538 -
 26.2539 -	return false;
 26.2540 -}
 26.2541 -
 26.2542 -void CPluginManager::AllPluginsLoaded()
 26.2543 -{
 26.2544 -	List<CPlugin *>::iterator iter;
 26.2545 -	CPlugin *pl;
 26.2546 -
 26.2547 -	for (iter=m_plugins.begin(); iter!=m_plugins.end(); iter++)
 26.2548 -	{
 26.2549 -		pl = (*iter);
 26.2550 -		pl->Call_OnAllPluginsLoaded();
 26.2551 -	}
 26.2552 -}
 26.2553 -
 26.2554 -void CPluginManager::UnloadAll()
 26.2555 -{
 26.2556 -	List<CPlugin *>::iterator iter;
 26.2557 -	while ( (iter = m_plugins.begin()) != m_plugins.end() )
 26.2558 -	{
 26.2559 -		UnloadPlugin((*iter));
 26.2560 -	}
 26.2561 -}
 26.2562 -
 26.2563 -int CPluginManager::GetOrderOfPlugin(IPlugin *pl)
 26.2564 -{
 26.2565 -	int id = 1;
 26.2566 -	List<CPlugin *>::iterator iter;
 26.2567 -
 26.2568 -	for (iter = m_plugins.begin(); iter != m_plugins.end(); iter++, id++)
 26.2569 -	{
 26.2570 -		if ((*iter) == pl)
 26.2571 -		{
 26.2572 -			return id;
 26.2573 -		}
 26.2574 -	}
 26.2575 -
 26.2576 -	return -1;
 26.2577 -}
 26.2578 -
 26.2579 -CPlugin *CPluginManager::FindPluginByConsoleArg(const char *arg)
 26.2580 -{
 26.2581 -	int id;
 26.2582 -	char *end;
 26.2583 -	CPlugin *pl;
 26.2584 -	
 26.2585 -	id = strtol(arg, &end, 10);
 26.2586 -
 26.2587 -	if (*end == '\0')
 26.2588 -	{
 26.2589 -		pl = GetPluginByOrder(id);
 26.2590 -		if (!pl)
 26.2591 -		{
 26.2592 -			return NULL;
 26.2593 -		}
 26.2594 -	}
 26.2595 -	else
 26.2596 -	{
 26.2597 -		char pluginfile[256];
 26.2598 -		const char *ext = g_LibSys.GetFileExtension(arg) ? "" : ".smx";
 26.2599 -		UTIL_Format(pluginfile, sizeof(pluginfile), "%s%s", arg, ext);
 26.2600 -
 26.2601 -		if (!sm_trie_retrieve(m_LoadLookup, pluginfile, (void **)&pl))
 26.2602 -		{
 26.2603 -			return NULL;
 26.2604 -		}
 26.2605 -	}
 26.2606 -
 26.2607 -	return pl;
 26.2608 -}
 26.2609 -
 26.2610 -void CPluginManager::OnSourceModMaxPlayersChanged(int newvalue)
 26.2611 -{
 26.2612 -	SyncMaxClients(newvalue);
 26.2613 -}
 26.2614 -
 26.2615 -void CPluginManager::SyncMaxClients(int max_clients)
 26.2616 -{
 26.2617 -	List<CPlugin *>::iterator iter;
 26.2618 -
 26.2619 -	for (iter = m_plugins.begin(); iter != m_plugins.end(); iter++)
 26.2620 -	{
 26.2621 -		(*iter)->SyncMaxClients(max_clients);
 26.2622 -	}
 26.2623 -}
 26.2624 -
 26.2625 -void CPluginManager::ListPluginsToClient(CPlayer *player, const CCommand &args)
 26.2626 -{
 26.2627 -	char buffer[256];
 26.2628 -	unsigned int id = 0;
 26.2629 -	int plnum = GetPluginCount();
 26.2630 -	edict_t *e = player->GetEdict();
 26.2631 -	unsigned int start = 0;
 26.2632 -
 26.2633 -	if (!plnum)
 26.2634 -	{
 26.2635 -		ClientConsolePrint(e, "[SM] No plugins found.");
 26.2636 -		return;
 26.2637 -	}
 26.2638 -
 26.2639 -	if (args.ArgC() > 2)
 26.2640 -	{
 26.2641 -		start = atoi(args.Arg(2));
 26.2642 -	}
 26.2643 -
 26.2644 -	CPlugin *pl;
 26.2645 -	SourceHook::List<CPlugin *>::iterator iter;
 26.2646 -	SourceHook::List<CPlugin *> m_FailList;
 26.2647 -
 26.2648 -	for (iter = m_plugins.begin();
 26.2649 -		 iter != m_plugins.end();
 26.2650 -		 iter++)
 26.2651 -	{
 26.2652 -		pl = (*iter);
 26.2653 -
 26.2654 -		if (pl->GetStatus() != Plugin_Running)
 26.2655 -		{
 26.2656 -			continue;
 26.2657 -		}
 26.2658 -
 26.2659 -		/* Count valid plugins */
 26.2660 -		id++;
 26.2661 -		if (id < start)
 26.2662 -		{
 26.2663 -			continue;
 26.2664 -		}
 26.2665 -
 26.2666 -		if (id - start > 10)
 26.2667 -		{
 26.2668 -			break;
 26.2669 -		}
 26.2670 -
 26.2671 -		size_t len;
 26.2672 -		const sm_plugininfo_t *info = pl->GetPublicInfo();
 26.2673 -		len = UTIL_Format(buffer, sizeof(buffer), " \"%s\"", (IS_STR_FILLED(info->name)) ? info->name : pl->GetFilename());
 26.2674 -		if (IS_STR_FILLED(info->version))
 26.2675 -		{
 26.2676 -			len += UTIL_Format(&buffer[len], sizeof(buffer)-len, " (%s)", info->version);
 26.2677 -		}
 26.2678 -		if (IS_STR_FILLED(info->author))
 26.2679 -		{
 26.2680 -			UTIL_Format(&buffer[len], sizeof(buffer)-len, " by %s", info->author);
 26.2681 -		}
 26.2682 -		else
 26.2683 -		{
 26.2684 -			UTIL_Format(&buffer[len], sizeof(buffer)-len, " %s", pl->m_filename);
 26.2685 -		}
 26.2686 -		ClientConsolePrint(e, "%s", buffer);
 26.2687 -	}
 26.2688 -
 26.2689 -	/* See if we can get more plugins */
 26.2690 -	while (iter != m_plugins.end())
 26.2691 -	{
 26.2692 -		if ((*iter)->GetStatus() == Plugin_Running)
 26.2693 -		{
 26.2694 -			break;
 26.2695 -		}
 26.2696 -	}
 26.2697 -
 26.2698 -	/* Do we actually have more plugins? */
 26.2699 -	if (iter != m_plugins.end())
 26.2700 -	{
 26.2701 -		ClientConsolePrint(e, "To see more, type \"sm plugins %d\"", id);
 26.2702 -	}
 26.2703 -}
    27.1 --- a/core/PluginSys.h	Fri Mar 29 12:28:02 2013 -0400
    27.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    27.3 @@ -1,491 +0,0 @@
    27.4 -/**
    27.5 - * vim: set ts=4 :
    27.6 - * =============================================================================
    27.7 - * SourceMod
    27.8 - * Copyright (C) 2004-2010 AlliedModders LLC.  All rights reserved.
    27.9 - * =============================================================================
   27.10 - *
   27.11 - * This program is free software; you can redistribute it and/or modify it under
   27.12 - * the terms of the GNU General Public License, version 3.0, as published by the
   27.13 - * Free Software Foundation.
   27.14 - * 
   27.15 - * This program is distributed in the hope that it will be useful, but WITHOUT
   27.16 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   27.17 - * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
   27.18 - * details.
   27.19 - *
   27.20 - * You should have received a copy of the GNU General Public License along with
   27.21 - * this program.  If not, see <http://www.gnu.org/licenses/>.
   27.22 - *
   27.23 - * As a special exception, AlliedModders LLC gives you permission to link the
   27.24 - * code of this program (as well as its derivative works) to "Half-Life 2," the
   27.25 - * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
   27.26 - * by the Valve Corporation.  You must obey the GNU General Public License in
   27.27 - * all respects for all other code used.  Additionally, AlliedModders LLC grants
   27.28 - * this exception to all derivative works.  AlliedModders LLC defines further
   27.29 - * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
   27.30 - * or <http://www.sourcemod.net/license.php>.
   27.31 - *
   27.32 - * Version: $Id$
   27.33 - */
   27.34 -
   27.35 -#ifndef _INCLUDE_SOURCEMOD_PLUGINSYSTEM_H_
   27.36 -#define _INCLUDE_SOURCEMOD_PLUGINSYSTEM_H_
   27.37 -
   27.38 -#include <time.h>
   27.39 -#include <errno.h>
   27.40 -#include <sys/stat.h>
   27.41 -#include <IPluginSys.h>
   27.42 -#include <IHandleSys.h>
   27.43 -#include <IForwardSys.h>
   27.44 -#include <sh_list.h>
   27.45 -#include <sh_stack.h>
   27.46 -#include <sh_vector.h>
   27.47 -#include <sh_string.h>
   27.48 -#include "sm_globals.h"
   27.49 -#include "sm_trie.h"
   27.50 -#include "sourcemod.h"
   27.51 -#include <IRootConsoleMenu.h>
   27.52 -#if SOURCE_ENGINE >= SE_ALIENSWARM
   27.53 -#include "convar_sm_swarm.h"
   27.54 -#elif SOURCE_ENGINE >= SE_LEFT4DEAD
   27.55 -#include "convar_sm_l4d.h"
   27.56 -#elif SOURCE_ENGINE >= SE_ORANGEBOX
   27.57 -#include "convar_sm_ob.h"
   27.58 -#else
   27.59 -#include "convar_sm.h"
   27.60 -#endif
   27.61 -#include "ITranslator.h"
   27.62 -#include "IGameConfigs.h"
   27.63 -#include "NativeOwner.h"
   27.64 -#include "ShareSys.h"
   27.65 -
   27.66 -class CPlayer;
   27.67 -
   27.68 -using namespace SourceHook;
   27.69 -
   27.70 -/**
   27.71 - * NOTES:
   27.72 - *
   27.73 - * UPDATE 2008-03-11: These comments are horribly out of date.  They paint a good overall 
   27.74 - * picture of how PluginSys works, but things like dependencies and fake natives have 
   27.75 - * complicated things quite a bit.
   27.76 - *
   27.77 - *  Currently this system needs a lot of work but it's good skeletally.  Plugin creation 
   27.78 - * is done without actually compiling anything.  This is done by Load functions in the 
   27.79 - * manager.  This will need a rewrite when we add context switching.
   27.80 - *
   27.81 - *  The plugin object itself has a few things to note.  The most important is that it stores
   27.82 - * a table of function objects.  The manager marshals allocation and freeing of these objects.
   27.83 - * The plugin object can be in erroneous states, they are:
   27.84 - *   Plugin_Error   --> Some error occurred any time during or after compilation.
   27.85 - *						This error can be cleared since the plugin itself is valid.
   27.86 - *						However, the state itself being set prevents any runtime action.
   27.87 - *   Plugin_BadLoad	--> The plugin failed to load entirely and nothing can be done to save it.
   27.88 - *
   27.89 - *  If a plugin fails to load externally, it is never added to the internal tracker.  However, 
   27.90 - * plugins that failed to load from the internal loading mechanism are always tracked.  This 
   27.91 - * allows users to see which automatically loaded plugins failed, and makes the interface a bit
   27.92 - * more flexible.
   27.93 - *
   27.94 - *  Once a plugin is compiled, it sets its own state to Plugin_Created.  This state is still invalid
   27.95 - * for execution.  SourceMod is a two pass system, and even though the second pass is not implemented
   27.96 - * yet, it is structured so Plugin_Created must be switched to Plugin_Running in the second pass.  When
   27.97 - * implemented, a Created plugin will be switched to Error in the second pass if it not loadable.
   27.98 - *
   27.99 - *  The two pass loading mechanism is described below.  Modules/natives are not implemented yet.
  27.100 - * PASS ONE: All loadable plugins are found and have the following steps performed:
  27.101 - *			 1.  Loading and compilation is attempted.
  27.102 - *			 2.  If successful, all natives from Core are added.
  27.103 - *			 3.  OnPluginLoad() is called.
  27.104 - *			 4.  If failed, any user natives are scrapped and the process halts here.
  27.105 - *			 5.  If successful, the plugin is ready for Pass 2.
  27.106 - * INTERMEDIATE:
  27.107 - *			 1.  All forced modules are loaded.
  27.108 - * PASS TWO: All loaded plugins are found and have these steps performed:
  27.109 - *			 1. Any modules referenced in the plugin that are not already loaded, are loaded.
  27.110 - *			 2. If any module fails to load and the plugin requires it, load fails and jump to step 6.
  27.111 - *			 3. If any natives are unresolved, check if they are found in the user-natives pool.
  27.112 - *			 4. If yes, load succeeds.  If not, natives are passed through a native acceptance filter.
  27.113 - *			 5. If the filter fails, the plugin is marked as failed.
  27.114 - *			 6. If the plugin has failed to load at this point, any dynamic natives it has added are scrapped.
  27.115 - *			    Furthermore, any plugin that referenced these natives must now have pass 2 re-ran.
  27.116 - * PASS THREE (not a real pass):
  27.117 - *			 7. Once all plugins are deemed to be loaded, OnPluginStart() is called
  27.118 - */
  27.119 -
  27.120 -enum LoadRes
  27.121 -{
  27.122 -	LoadRes_Successful,
  27.123 -	LoadRes_AlreadyLoaded,
  27.124 -	LoadRes_Failure,
  27.125 -	LoadRes_SilentFailure,
  27.126 -	LoadRes_NeverLoad
  27.127 -};
  27.128 -
  27.129 -enum APLRes
  27.130 -{
  27.131 -	APLRes_Success,
  27.132 -	APLRes_Failure,
  27.133 -	APLRes_SilentFailure
  27.134 -};
  27.135 -
  27.136 -enum LibraryAction
  27.137 -{
  27.138 -	LibraryAction_Removed,
  27.139 -	LibraryAction_Added
  27.140 -};
  27.141 -
  27.142 -struct AutoConfig
  27.143 -{
  27.144 -	String autocfg;
  27.145 -	String folder;
  27.146 -	bool create;
  27.147 -};
  27.148 -
  27.149 -class CPlugin;
  27.150 -
  27.151 -class CPlugin : 
  27.152 -	public IPlugin,
  27.153 -	public CNativeOwner
  27.154 -{
  27.155 -	friend class CPluginManager;
  27.156 -	friend class CFunction;
  27.157 -public:
  27.158 -	CPlugin(const char *file);
  27.159 -	~CPlugin();
  27.160 -public:
  27.161 -	PluginType GetType();
  27.162 -	SourcePawn::IPluginContext *GetBaseContext();
  27.163 -	sp_context_t *GetContext();
  27.164 -	void *GetPluginStructure();
  27.165 -	const char *GetFilename();
  27.166 -	bool IsDebugging();
  27.167 -	PluginStatus GetStatus();
  27.168 -	bool IsSilentlyFailed();
  27.169 -	void SetSilentlyFailed(bool sf);
  27.170 -	const sm_plugininfo_t *GetPublicInfo();
  27.171 -	bool SetPauseState(bool paused);
  27.172 -	unsigned int GetSerial();
  27.173 -	IdentityToken_t *GetIdentity();
  27.174 -	unsigned int CalcMemUsage();
  27.175 -	bool SetProperty(const char *prop, void *ptr);
  27.176 -	bool GetProperty(const char *prop, void **ptr, bool remove=false);
  27.177 -	void DropEverything();
  27.178 -	SourcePawn::IPluginRuntime *GetRuntime();
  27.179 -public:
  27.180 -	/**
  27.181 -	 * Creates a plugin object with default values.
  27.182 -	 *   If an error buffer is specified, and an error occurs, the error will be copied to the buffer
  27.183 -	 * and NULL will be returned.
  27.184 -	 *   If an error buffer is not specified, the error will be copied to an internal buffer and 
  27.185 -	 * a valid (but error-stated) CPlugin will be returned.
  27.186 -	 */
  27.187 -	static CPlugin *CreatePlugin(const char *file, char *error, size_t maxlength);
  27.188 -public:
  27.189 -
  27.190 -	/**
  27.191 -	 * Sets an error state on the plugin
  27.192 -	 */
  27.193 -	void SetErrorState(PluginStatus status, const char *error_fmt, ...);
  27.194 -
  27.195 -	/**
  27.196 -	 * Initializes the plugin's identity information
  27.197 -	 */
  27.198 -	void InitIdentity();
  27.199 -
  27.200 -	/**
  27.201 -	 * Calls the OnPluginLoad function, and sets any failed states if necessary.
  27.202 -	 * NOTE: Valid pre-states are: Plugin_Created
  27.203 -	 * NOTE: If validated, plugin state is changed to Plugin_Loaded
  27.204 -	 *
  27.205 -	 * If the error buffer is NULL, the error message is cached locally.
  27.206 -	 */
  27.207 -	APLRes Call_AskPluginLoad(char *error, size_t maxlength);
  27.208 -
  27.209 -	/**
  27.210 -	 * Calls the OnPluginStart function.
  27.211 -	 * NOTE: Valid pre-states are: Plugin_Created
  27.212 -	 * NOTE: Post-state will be Plugin_Running
  27.213 -	 */
  27.214 -	void Call_OnPluginStart();
  27.215 -
  27.216 -	/**
  27.217 -	 * Calls the OnPluginEnd function.
  27.218 -	 */
  27.219 -	void Call_OnPluginEnd();
  27.220 -
  27.221 -	/**
  27.222 -	 * Calls the OnAllPluginsLoaded function.
  27.223 -	 */
  27.224 -	void Call_OnAllPluginsLoaded();
  27.225 -
  27.226 -	/**
  27.227 -	 * Returns true if a plugin is usable.
  27.228 -	 */
  27.229 -	bool IsRunnable();
  27.230 -
  27.231 -	/**
  27.232 -	 * Get languages info.
  27.233 -	 */
  27.234 -	IPhraseCollection *GetPhrases();
  27.235 -public:
  27.236 -	/**
  27.237 -	 * Returns the modification time during last plugin load.
  27.238 -	 */
  27.239 -	time_t GetTimeStamp();
  27.240 -
  27.241 -	/**
  27.242 -	 * Returns the current modification time of the plugin file.
  27.243 -	 */
  27.244 -	time_t GetFileTimeStamp();
  27.245 -
  27.246 -	/** 
  27.247 -	 * Returns true if the plugin was running, but is now invalid.
  27.248 -	 */
  27.249 -	bool WasRunning();
  27.250 -
  27.251 -	Handle_t GetMyHandle();
  27.252 -
  27.253 -	bool AddFakeNative(IPluginFunction *pFunc, const char *name, SPVM_FAKENATIVE_FUNC func);
  27.254 -	void AddConfig(bool autoCreate, const char *cfg, const char *folder);
  27.255 -	unsigned int GetConfigCount();
  27.256 -	AutoConfig *GetConfig(unsigned int i);
  27.257 -	inline void AddLibrary(const char *name)
  27.258 -	{
  27.259 -		m_Libraries.push_back(name);
  27.260 -	}
  27.261 -	void LibraryActions(LibraryAction action);
  27.262 -	void SyncMaxClients(int max_clients);
  27.263 -protected:
  27.264 -	bool UpdateInfo();
  27.265 -	void SetTimeStamp(time_t t);
  27.266 -	void DependencyDropped(CPlugin *pOwner);
  27.267 -private:
  27.268 -	PluginType m_type;
  27.269 -	char m_filename[PLATFORM_MAX_PATH];
  27.270 -	PluginStatus m_status;
  27.271 -	bool m_bSilentlyFailed;
  27.272 -	unsigned int m_serial;
  27.273 -	sm_plugininfo_t m_info;
  27.274 -	char m_errormsg[256];
  27.275 -	time_t m_LastAccess;
  27.276 -	IdentityToken_t *m_ident;
  27.277 -	Handle_t m_handle;
  27.278 -	bool m_WasRunning;
  27.279 -	IPhraseCollection *m_pPhrases;
  27.280 -	List<String> m_RequiredLibs;
  27.281 -	List<String> m_Libraries;
  27.282 -	Trie *m_pProps;
  27.283 -	bool m_FakeNativesMissing;
  27.284 -	bool m_LibraryMissing;
  27.285 -	CVector<AutoConfig *> m_configs;
  27.286 -	bool m_bGotAllLoaded;
  27.287 -	int m_FileVersion;
  27.288 -	char m_DateTime[256];
  27.289 -	IPluginRuntime *m_pRuntime;
  27.290 -	IPluginContext *m_pContext;
  27.291 -	sp_pubvar_t *m_MaxClientsVar;
  27.292 -};
  27.293 -
  27.294 -class CPluginManager : 
  27.295 -	public IPluginManager,
  27.296 -	public SMGlobalClass,
  27.297 -	public IHandleTypeDispatch,
  27.298 -	public IRootConsoleCommand
  27.299 -{
  27.300 -	friend class CPlugin;
  27.301 -public:
  27.302 -	CPluginManager();
  27.303 -	~CPluginManager();
  27.304 -public:
  27.305 -	/* Implements iterator class */
  27.306 -	class CPluginIterator : public IPluginIterator
  27.307 -	{
  27.308 -	public:
  27.309 -		CPluginIterator(List<CPlugin *> *mylist);
  27.310 -		virtual ~CPluginIterator();
  27.311 -		virtual bool MorePlugins();
  27.312 -		virtual IPlugin *GetPlugin();
  27.313 -		virtual void NextPlugin();
  27.314 -		void Release();
  27.315 -	public:
  27.316 -		void Reset();
  27.317 -	private:
  27.318 -		List<CPlugin *> *mylist;
  27.319 -		List<CPlugin *>::iterator current;
  27.320 -	};
  27.321 -	friend class CPluginManager::CPluginIterator;
  27.322 -public: //IPluginManager
  27.323 -	IPlugin *LoadPlugin(const char *path, 
  27.324 -								bool debug,
  27.325 -								PluginType type,
  27.326 -								char error[],
  27.327 -								size_t maxlength,
  27.328 -								bool *wasloaded);
  27.329 -	bool UnloadPlugin(IPlugin *plugin);
  27.330 -	IPlugin *FindPluginByContext(const sp_context_t *ctx);
  27.331 -	unsigned int GetPluginCount();
  27.332 -	IPluginIterator *GetPluginIterator();
  27.333 -	void AddPluginsListener(IPluginsListener *listener);
  27.334 -	void RemovePluginsListener(IPluginsListener *listener);
  27.335 -public: //SMGlobalClass
  27.336 -	void OnSourceModAllInitialized();
  27.337 -	void OnSourceModShutdown();
  27.338 -	ConfigResult OnSourceModConfigChanged(const char *key, const char *value, ConfigSource source, char *error, size_t maxlength);
  27.339 -	void OnSourceModMaxPlayersChanged(int newvalue);
  27.340 -public: //IHandleTypeDispatch
  27.341 -	void OnHandleDestroy(HandleType_t type, void *object);
  27.342 -	bool GetHandleApproxSize(HandleType_t type, void *object, unsigned int *pSize);
  27.343 -public: //IRootConsoleCommand
  27.344 -	void OnRootConsoleCommand(const char *cmdname, const CCommand &command);
  27.345 -public:
  27.346 -	/**
  27.347 -	 * Loads all plugins not yet loaded
  27.348 -	 */
  27.349 -	void LoadAll_FirstPass(const char *config, const char *basedir);
  27.350 -
  27.351 -	/**
  27.352 -	 * Runs the second loading pass for all plugins
  27.353 -	 */
  27.354 -	void LoadAll_SecondPass();
  27.355 -
  27.356 -	/**
  27.357 -	 * Tests a plugin file mask against a local folder.
  27.358 -	 * The alias is searched backwards from localdir - i.e., given this input:
  27.359 -	 *   csdm/ban        csdm/ban
  27.360 -	 *   ban             csdm/ban
  27.361 -	 *   csdm/ban        optional/csdm/ban
  27.362 -	 * All of these will return true for an alias match.  
  27.363 -	 * Wildcards are allowed in the filename.
  27.364 -	 */
  27.365 -	bool TestAliasMatch(const char *alias, const char *localdir);
  27.366 -
  27.367 -	/** 
  27.368 -	 * Returns whether anything loaded will be a late load.
  27.369 -	 */
  27.370 -	bool IsLateLoadTime() const;
  27.371 -
  27.372 -	/**
  27.373 -	 * Converts a Handle to an IPlugin if possible.
  27.374 -	 */
  27.375 -	IPlugin *PluginFromHandle(Handle_t handle, HandleError *err);
  27.376 -
  27.377 -	/**
  27.378 -	 * Finds a plugin based on its index. (starts on index 1)
  27.379 -	 */
  27.380 -	CPlugin *GetPluginByOrder(int num);
  27.381 -
  27.382 -	int GetOrderOfPlugin(IPlugin *pl);
  27.383 -
  27.384 -	/** 
  27.385 -	 * Internal version of FindPluginByContext()
  27.386 -	 */
  27.387 -	CPlugin *GetPluginByCtx(const sp_context_t *ctx);
  27.388 -
  27.389 -	/**
  27.390 -	 * Gets status text for a status code 
  27.391 -	 */
  27.392 -	const char *GetStatusText(PluginStatus status);
  27.393 -
  27.394 -	/**
  27.395 -	* Reload or update plugins on level shutdown.
  27.396 -	*/
  27.397 -	void ReloadOrUnloadPlugins();
  27.398 -
  27.399 -	/**
  27.400 -	 * Add public functions from all running or paused
  27.401 -	 * plugins to the specified forward if the names match.
  27.402 -	 */
  27.403 -	void AddFunctionsToForward(const char *name, IChangeableForward *pForward);
  27.404 -
  27.405 -	/**
  27.406 -	 * Iterates through plugins to call OnAllPluginsLoaded.
  27.407 -	 */
  27.408 -	void AllPluginsLoaded();
  27.409 -
  27.410 -	CPlugin *GetPluginFromIdentity(IdentityToken_t *pToken);
  27.411 -
  27.412 -	void Shutdown();
  27.413 -
  27.414 -	void OnLibraryAction(const char *lib, LibraryAction action);
  27.415 -
  27.416 -	bool LibraryExists(const char *lib);
  27.417 -
  27.418 -	bool ReloadPlugin(CPlugin *pl);
  27.419 -
  27.420 -	void UnloadAll();
  27.421 -
  27.422 -	CPlugin *FindPluginByConsoleArg(const char *arg);
  27.423 -
  27.424 -	void SyncMaxClients(int max_clients);
  27.425 -
  27.426 -	void ListPluginsToClient(CPlayer *player, const CCommand &args);
  27.427 -private:
  27.428 -	LoadRes _LoadPlugin(CPlugin **pPlugin, const char *path, bool debug, PluginType type, char error[], size_t maxlength);
  27.429 -
  27.430 -	void LoadAutoPlugin(const char *plugin);
  27.431 -
  27.432 -	/**
  27.433 -	 * Recursively loads all plugins in the given directory.
  27.434 -	 */
  27.435 -	void LoadPluginsFromDir(const char *basedir, const char *localdir);
  27.436 -
  27.437 -	/**
  27.438 -	 * Adds a plugin object.  This is wrapped by LoadPlugin functions.
  27.439 -	 */
  27.440 -	void AddPlugin(CPlugin *pPlugin);
  27.441 -
  27.442 -	/**
  27.443 -	 * Runs the second loading pass on a plugin.
  27.444 -	 */
  27.445 -	bool RunSecondPass(CPlugin *pPlugin, char *error, size_t maxlength);
  27.446 -
  27.447 -	/**
  27.448 -	 * Runs an extension pass on a plugin.
  27.449 -	 */
  27.450 -	bool LoadOrRequireExtensions(CPlugin *pPlugin, unsigned int pass, char *error, size_t maxlength);
  27.451 -
  27.452 -	/**
  27.453 -	* Manages required natives.
  27.454 -	*/
  27.455 -	bool FindOrRequirePluginDeps(CPlugin *pPlugin, char *error, size_t maxlength);
  27.456 -
  27.457 -	void _SetPauseState(CPlugin *pPlugin, bool pause);
  27.458 -protected:
  27.459 -	/**
  27.460 -	 * Caching internal objects
  27.461 -	 */
  27.462 -	void ReleaseIterator(CPluginIterator *iter);
  27.463 -public:
  27.464 -	inline IdentityToken_t *GetIdentity()
  27.465 -	{
  27.466 -		return m_MyIdent;
  27.467 -	}
  27.468 -private:
  27.469 -	void TryRefreshDependencies(CPlugin *pOther);
  27.470 -private:
  27.471 -	List<IPluginsListener *> m_listeners;
  27.472 -	List<CPlugin *> m_plugins;
  27.473 -	CStack<CPluginManager::CPluginIterator *> m_iters;
  27.474 -	Trie *m_LoadLookup;
  27.475 -	bool m_AllPluginsLoaded;
  27.476 -	IdentityToken_t *m_MyIdent;
  27.477 -
  27.478 -	/* Dynamic native stuff */
  27.479 -	List<FakeNative *> m_Natives;
  27.480 -
  27.481 -	bool m_LoadingLocked;
  27.482 -	
  27.483 -	// Config
  27.484 -	bool m_bBlockBadPlugins;
  27.485 -	
  27.486 -	// Forwards
  27.487 -	IForward *m_pOnLibraryAdded;
  27.488 -	IForward *m_pOnLibraryRemoved;
  27.489 -};
  27.490 -
  27.491 -extern CPluginManager g_PluginSys;
  27.492 -
  27.493 -#endif //_INCLUDE_SOURCEMOD_PLUGINSYSTEM_H_
  27.494 -
    28.1 --- a/core/ShareSys.cpp	Fri Mar 29 12:28:02 2013 -0400
    28.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    28.3 @@ -1,611 +0,0 @@
    28.4 -/**
    28.5 - * vim: set ts=4 :
    28.6 - * =============================================================================
    28.7 - * SourceMod
    28.8 - * Copyright (C) 2004-2008 AlliedModders LLC.  All rights reserved.
    28.9 - * =============================================================================
   28.10 - *
   28.11 - * This program is free software; you can redistribute it and/or modify it under
   28.12 - * the terms of the GNU General Public License, version 3.0, as published by the
   28.13 - * Free Software Foundation.
   28.14 - * 
   28.15 - * This program is distributed in the hope that it will be useful, but WITHOUT
   28.16 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   28.17 - * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
   28.18 - * details.
   28.19 - *
   28.20 - * You should have received a copy of the GNU General Public License along with
   28.21 - * this program.  If not, see <http://www.gnu.org/licenses/>.
   28.22 - *
   28.23 - * As a special exception, AlliedModders LLC gives you permission to link the
   28.24 - * code of this program (as well as its derivative works) to "Half-Life 2," the
   28.25 - * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
   28.26 - * by the Valve Corporation.  You must obey the GNU General Public License in
   28.27 - * all respects for all other code used.  Additionally, AlliedModders LLC grants
   28.28 - * this exception to all derivative works.  AlliedModders LLC defines further
   28.29 - * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
   28.30 - * or <http://www.sourcemod.net/license.php>.
   28.31 - *
   28.32 - * Version: $Id$
   28.33 - */
   28.34 -
   28.35 -#include "ShareSys.h"
   28.36 -#include "HandleSys.h"
   28.37 -#include "ExtensionSys.h"
   28.38 -#include "LibrarySys.h"
   28.39 -#include "PluginSys.h"
   28.40 -#include "sm_stringutil.h"
   28.41 -
   28.42 -ShareSystem g_ShareSys;
   28.43 -static unsigned int g_mark_serial = 0;
   28.44 -
   28.45 -ShareSystem::ShareSystem()
   28.46 -{
   28.47 -	m_IdentRoot.ident = 0;
   28.48 -	m_TypeRoot = 0;
   28.49 -	m_IfaceType = 0;
   28.50 -	m_CoreType = 0;
   28.51 -}
   28.52 -
   28.53 -IdentityToken_t *ShareSystem::CreateCoreIdentity()
   28.54 -{
   28.55 -	if (!m_CoreType)
   28.56 -	{
   28.57 -		m_CoreType = CreateIdentType("CORE");
   28.58 -	}
   28.59 -
   28.60 -	return CreateIdentity(m_CoreType, this);
   28.61 -}
   28.62 -
   28.63 -void ShareSystem::Initialize()
   28.64 -{
   28.65 -	TypeAccess sec;
   28.66 -
   28.67 -	g_HandleSys.InitAccessDefaults(&sec, NULL);
   28.68 -	sec.ident = GetIdentRoot();
   28.69 -
   28.70 -	m_TypeRoot = g_HandleSys.CreateType("Identity", this, 0, &sec, NULL, NULL, NULL);
   28.71 -	m_IfaceType = g_HandleSys.CreateType("Interface", this, 0, NULL, NULL, GetIdentRoot(), NULL);
   28.72 -
   28.73 -	/* Initialize our static identity handle */
   28.74 -	m_IdentRoot.ident = g_HandleSys.CreateHandle(m_TypeRoot, NULL, NULL, GetIdentRoot(), NULL);
   28.75 -
   28.76 -	/* Add the Handle System and others... they are too innocent and pure to do it themselves */
   28.77 -	AddInterface(NULL, &g_HandleSys);
   28.78 -	AddInterface(NULL, &g_LibSys);
   28.79 -}
   28.80 -
   28.81 -void ShareSystem::OnSourceModShutdown()
   28.82 -{
   28.83 -	if (m_CoreType)
   28.84 -	{
   28.85 -		g_HandleSys.RemoveType(m_CoreType, GetIdentRoot());
   28.86 -	}
   28.87 -
   28.88 -	g_HandleSys.RemoveType(m_IfaceType, GetIdentRoot());
   28.89 -	g_HandleSys.RemoveType(m_TypeRoot, GetIdentRoot());
   28.90 -}
   28.91 -
   28.92 -IdentityType_t ShareSystem::FindIdentType(const char *name)
   28.93 -{
   28.94 -	HandleType_t type;
   28.95 -
   28.96 -	if (g_HandleSys.FindHandleType(name, &type))
   28.97 -	{
   28.98 -		if (g_HandleSys.TypeCheck(type, m_TypeRoot))
   28.99 -		{
  28.100 -			return type;
  28.101 -		}
  28.102 -	}
  28.103 -
  28.104 -	return 0;
  28.105 -}
  28.106 -
  28.107 -IdentityType_t ShareSystem::CreateIdentType(const char *name)
  28.108 -{
  28.109 -	if (!m_TypeRoot)
  28.110 -	{
  28.111 -		return 0;
  28.112 -	}
  28.113 -
  28.114 -	return g_HandleSys.CreateType(name, this, m_TypeRoot, NULL, NULL, GetIdentRoot(), NULL);
  28.115 -}
  28.116 -
  28.117 -void ShareSystem::OnHandleDestroy(HandleType_t type, void *object)
  28.118 -{
  28.119 -	/* THIS WILL NEVER BE CALLED FOR ANYTHING WITH THE IDENTITY TYPE */
  28.120 -}
  28.121 -
  28.122 -IdentityToken_t *ShareSystem::CreateIdentity(IdentityType_t type, void *ptr)
  28.123 -{
  28.124 -	if (!m_TypeRoot)
  28.125 -	{
  28.126 -		return 0;
  28.127 -	}
  28.128 -
  28.129 -	/* :TODO: Cache? */
  28.130 -	IdentityToken_t *pToken = new IdentityToken_t;
  28.131 -
  28.132 -	HandleSecurity sec;
  28.133 -	sec.pOwner = sec.pIdentity = GetIdentRoot();
  28.134 -
  28.135 -	pToken->ident = g_HandleSys.CreateHandleInt(type, NULL, &sec, NULL, NULL, true);
  28.136 -	pToken->ptr = ptr;
  28.137 -	pToken->type = type;
  28.138 -
  28.139 -	return pToken;
  28.140 -}
  28.141 -
  28.142 -bool ShareSystem::AddInterface(IExtension *myself, SMInterface *iface)
  28.143 -{
  28.144 -	if (!iface)
  28.145 -	{
  28.146 -		return false;
  28.147 -	}
  28.148 -
  28.149 -	IfaceInfo info;
  28.150 -
  28.151 -	info.owner = myself;
  28.152 -	info.iface = iface;
  28.153 -	
  28.154 -	m_Interfaces.push_back(info);
  28.155 -
  28.156 -	return true;
  28.157 -}
  28.158 -
  28.159 -bool ShareSystem::RequestInterface(const char *iface_name, 
  28.160 -								   unsigned int iface_vers, 
  28.161 -								   IExtension *myself, 
  28.162 -								   SMInterface **pIface)
  28.163 -{
  28.164 -	/* See if the interface exists */
  28.165 -	List<IfaceInfo>::iterator iter;
  28.166 -	SMInterface *iface;
  28.167 -	IExtension *iface_owner;
  28.168 -	bool found = false;
  28.169 -	for (iter=m_Interfaces.begin(); iter!=m_Interfaces.end(); iter++)
  28.170 -	{
  28.171 -		IfaceInfo &info = (*iter);
  28.172 -		iface = info.iface;
  28.173 -		if (strcmp(iface->GetInterfaceName(), iface_name) == 0)
  28.174 -		{
  28.175 -			if (iface->GetInterfaceVersion() == iface_vers
  28.176 -				|| iface->IsVersionCompatible(iface_vers))
  28.177 -			{
  28.178 -				iface_owner = info.owner;
  28.179 -				found = true;
  28.180 -				break;
  28.181 -			}
  28.182 -		}
  28.183 -	}
  28.184 -
  28.185 -	if (!found)
  28.186 -	{
  28.187 -		return false;
  28.188 -	}
  28.189 -
  28.190 -	/* Add a dependency node */
  28.191 -	if (iface_owner)
  28.192 -	{
  28.193 -		IfaceInfo info;
  28.194 -		info.iface = iface;
  28.195 -		info.owner = iface_owner;
  28.196 -		g_Extensions.BindDependency(myself, &info);
  28.197 -	}
  28.198 -
  28.199 -	if (pIface)
  28.200 -	{
  28.201 -		*pIface = iface;
  28.202 -	}
  28.203 -
  28.204 -	return true;
  28.205 -}
  28.206 -
  28.207 -void ShareSystem::AddNatives(IExtension *myself, const sp_nativeinfo_t *natives)
  28.208 -{
  28.209 -	CNativeOwner *pOwner;
  28.210 -
  28.211 -	pOwner = g_Extensions.GetNativeOwner(myself);
  28.212 -
  28.213 -	pOwner->AddNatives(natives);
  28.214 -}
  28.215 -
  28.216 -void ShareSystem::DestroyIdentity(IdentityToken_t *identity)
  28.217 -{
  28.218 -	HandleSecurity sec;
  28.219 -
  28.220 -	sec.pOwner = GetIdentRoot();
  28.221 -	sec.pIdentity = GetIdentRoot();
  28.222 -
  28.223 -	g_HandleSys.FreeHandle(identity->ident, &sec);
  28.224 -	delete identity;
  28.225 -}
  28.226 -
  28.227 -void ShareSystem::DestroyIdentType(IdentityType_t type)
  28.228 -{
  28.229 -	g_HandleSys.RemoveType(type, GetIdentRoot());
  28.230 -}
  28.231 -
  28.232 -void ShareSystem::RemoveInterfaces(IExtension *pExtension)
  28.233 -{
  28.234 -	List<IfaceInfo>::iterator iter = m_Interfaces.begin();
  28.235 -
  28.236 -	while (iter != m_Interfaces.end())
  28.237 -	{
  28.238 -		if ((*iter).owner == pExtension)
  28.239 -		{
  28.240 -			iter = m_Interfaces.erase(iter);
  28.241 -		}
  28.242 -		else
  28.243 -		{
  28.244 -			iter++;
  28.245 -		}
  28.246 -	}
  28.247 -}
  28.248 -
  28.249 -void ShareSystem::AddDependency(IExtension *myself, const char *filename, bool require, bool autoload)
  28.250 -{
  28.251 -	g_Extensions.AddDependency(myself, filename, require, autoload);
  28.252 -}
  28.253 -
  28.254 -void ShareSystem::RegisterLibrary(IExtension *myself, const char *name)
  28.255 -{
  28.256 -	g_Extensions.AddLibrary(myself, name);
  28.257 -}
  28.258 -
  28.259 -void ShareSystem::OverrideNatives(IExtension *myself, const sp_nativeinfo_t *natives)
  28.260 -{
  28.261 -	unsigned int i;
  28.262 -	NativeEntry *pEntry;
  28.263 -	CNativeOwner *pOwner;
  28.264 -
  28.265 -	pOwner = g_Extensions.GetNativeOwner(myself);
  28.266 -
  28.267 -	for (i = 0; natives[i].func != NULL && natives[i].name != NULL; i++)
  28.268 -	{
  28.269 -		if ((pEntry = FindNative(natives[i].name)) == NULL)
  28.270 -		{
  28.271 -			continue;
  28.272 -		}
  28.273 -
  28.274 -		if (pEntry->owner != g_pCoreNatives)
  28.275 -		{
  28.276 -			continue;
  28.277 -		}
  28.278 -
  28.279 -		if (pEntry->replacement.owner != NULL)
  28.280 -		{
  28.281 -			continue;
  28.282 -		}
  28.283 -
  28.284 -		/* Now it's safe to add the override */
  28.285 -		pEntry->replacement.func = natives[i].func;
  28.286 -		pEntry->replacement.owner = pOwner;
  28.287 -		pOwner->AddReplacedNative(pEntry);
  28.288 -	}
  28.289 -}
  28.290 -
  28.291 -NativeEntry *ShareSystem::FindNative(const char *name)
  28.292 -{
  28.293 -	NativeEntry **ppEntry;
  28.294 -
  28.295 -	if ((ppEntry = m_NtvCache.retrieve(name)) == NULL)
  28.296 -	{
  28.297 -		return NULL;
  28.298 -	}
  28.299 -
  28.300 -	return *ppEntry;
  28.301 -}
  28.302 -
  28.303 -void ShareSystem::BindNativesToPlugin(CPlugin *pPlugin, bool bCoreOnly)
  28.304 -{
  28.305 -	NativeEntry *pEntry;
  28.306 -	sp_native_t *native;
  28.307 -	uint32_t i, native_count;
  28.308 -	IPluginContext *pContext;
  28.309 -
  28.310 -	pContext = pPlugin->GetBaseContext();
  28.311 -
  28.312 -	/* Generate a new serial ID, mark our dependencies with it. */
  28.313 -	g_mark_serial++;
  28.314 -	pPlugin->PropogateMarkSerial(g_mark_serial);
  28.315 -
  28.316 -	native_count = pContext->GetNativesNum();
  28.317 -	for (i = 0; i < native_count; i++)
  28.318 -	{
  28.319 -		if (pContext->GetNativeByIndex(i, &native) != SP_ERROR_NONE)
  28.320 -		{
  28.321 -			continue;
  28.322 -		}
  28.323 -
  28.324 -		/* If we're bound, check if there is a replacement available.  
  28.325 -		 * If not, this native is totally finalized.
  28.326 -		 */
  28.327 -		if (native->status == SP_NATIVE_BOUND)
  28.328 -		{
  28.329 -			pEntry = (NativeEntry *)native->user;
  28.330 -			assert(pEntry != NULL);
  28.331 -			if (pEntry->replacement.owner == NULL
  28.332 -				|| (pEntry->replacement.owner != NULL 
  28.333 -				&&  pEntry->replacement.func == native->pfn))
  28.334 -			{
  28.335 -				continue;
  28.336 -			}
  28.337 -		}
  28.338 -		/* Otherwise, the native must be in our cache. */
  28.339 -		else if ((pEntry = FindNative(native->name)) == NULL)
  28.340 -		{
  28.341 -			continue;
  28.342 -		}
  28.343 -
  28.344 -		if (bCoreOnly && pEntry->owner != g_pCoreNatives)
  28.345 -		{
  28.346 -			continue;
  28.347 -		}
  28.348 -
  28.349 -		BindNativeToPlugin(pPlugin, native, i, pEntry);
  28.350 -	}
  28.351 -}
  28.352 -
  28.353 -void ShareSystem::BindNativeToPlugin(CPlugin *pPlugin, NativeEntry *pEntry)
  28.354 -{
  28.355 -	uint32_t i;
  28.356 -	sp_native_t *native;
  28.357 -	IPluginContext *pContext;
  28.358 -
  28.359 -	pContext = pPlugin->GetBaseContext();
  28.360 -
  28.361 -	if (pContext->FindNativeByName(pEntry->name, &i) != SP_ERROR_NONE)
  28.362 -	{
  28.363 -		return;
  28.364 -	}
  28.365 -	if (pContext->GetNativeByIndex(i, &native) != SP_ERROR_NONE)
  28.366 -	{
  28.367 -		return;
  28.368 -	}
  28.369 -
  28.370 -	if (native->status == SP_NATIVE_BOUND)
  28.371 -	{
  28.372 -		return;
  28.373 -	}
  28.374 -
  28.375 -	BindNativeToPlugin(pPlugin, native, i, pEntry);
  28.376 -}
  28.377 -
  28.378 -void ShareSystem::BindNativeToPlugin(CPlugin *pPlugin, 
  28.379 -									 sp_native_t *native,
  28.380 -									 uint32_t index,
  28.381 -									 NativeEntry *pEntry)
  28.382 -{
  28.383 -	/* Mark as bound... we do the rest next. */
  28.384 -	native->status = SP_NATIVE_BOUND;
  28.385 -	native->user = pEntry;
  28.386 -
  28.387 -	/* See if a replacement is available. */
  28.388 -	if (pEntry->replacement.owner != NULL)
  28.389 -	{
  28.390 -		/* Perform a replacement bind. */
  28.391 -		native->pfn = pEntry->replacement.func;
  28.392 -		pEntry->replacement.owner->AddWeakRef(WeakNative(pPlugin, index, pEntry));
  28.393 -	}
  28.394 -	else
  28.395 -	{
  28.396 -		/* Perform a normal bind. */
  28.397 -		native->pfn = pEntry->func;
  28.398 -
  28.399 -		/* We don't bother with dependency crap if the owner is Core. */
  28.400 -		if (pEntry->owner != g_pCoreNatives)
  28.401 -		{
  28.402 -			/* The native is optional, this is a special case */
  28.403 -			if ((native->flags & SP_NTVFLAG_OPTIONAL) == SP_NTVFLAG_OPTIONAL)
  28.404 -			{
  28.405 -				/* Only add if there is a valid owner. */
  28.406 -				if (pEntry->owner != NULL)
  28.407 -				{
  28.408 -					pEntry->owner->AddWeakRef(WeakNative(pPlugin, index));
  28.409 -				}
  28.410 -				else
  28.411 -				{
  28.412 -					native->status = SP_NATIVE_UNBOUND;
  28.413 -				}
  28.414 -			}
  28.415 -			/* Otherwise, we're a strong dependent and not a weak one */
  28.416 -			else
  28.417 -			{
  28.418 -				/* See if this has already been marked as a dependent.
  28.419 -				 * If it has, it means this relationship has already occurred, 
  28.420 -				 * and there is no reason to do it again.
  28.421 -				 */
  28.422 -				if (pEntry->owner != pPlugin 
  28.423 -					&& pEntry->owner->GetMarkSerial() != g_mark_serial)
  28.424 -				{
  28.425 -					/* This has not been marked as a dependency yet */
  28.426 -					//pPlugin->AddDependency(pEntry->owner);
  28.427 -					pEntry->owner->AddDependent(pPlugin);
  28.428 -					pEntry->owner->SetMarkSerial(g_mark_serial);
  28.429 -				}
  28.430 -			}
  28.431 -		}
  28.432 -	}
  28.433 -}
  28.434 -
  28.435 -NativeEntry *ShareSystem::AddNativeToCache(CNativeOwner *pOwner, const sp_nativeinfo_t *ntv)
  28.436 -{
  28.437 -	NativeEntry *pEntry;
  28.438 -
  28.439 -	if ((pEntry = FindNative(ntv->name)) == NULL)
  28.440 -	{
  28.441 -		pEntry = new NativeEntry;
  28.442 -
  28.443 -		pEntry->owner = pOwner;
  28.444 -		pEntry->name = ntv->name;
  28.445 -		pEntry->func = ntv->func;
  28.446 -		pEntry->replacement.func = NULL;
  28.447 -		pEntry->replacement.owner = NULL;
  28.448 -		pEntry->fake = NULL;
  28.449 -
  28.450 -		m_NtvCache.insert(ntv->name, pEntry);
  28.451 -
  28.452 -		return pEntry;
  28.453 -	}
  28.454 -
  28.455 -	if (pEntry->owner != NULL)
  28.456 -	{
  28.457 -		return NULL;
  28.458 -	}
  28.459 -
  28.460 -	pEntry->owner = pOwner;
  28.461 -	pEntry->func = ntv->func;
  28.462 -	pEntry->name = ntv->name;
  28.463 -
  28.464 -	return pEntry;
  28.465 -}
  28.466 -
  28.467 -void ShareSystem::ClearNativeFromCache(CNativeOwner *pOwner, const char *name)
  28.468 -{
  28.469 -	NativeEntry *pEntry;
  28.470 -
  28.471 -	if ((pEntry = FindNative(name)) == NULL)
  28.472 -	{
  28.473 -		return;
  28.474 -	}
  28.475 -
  28.476 -	if (pEntry->owner != pOwner)
  28.477 -	{
  28.478 -		return;
  28.479 -	}
  28.480 -
  28.481 -	if (pEntry->fake != NULL)
  28.482 -	{
  28.483 -		g_pSourcePawn2->DestroyFakeNative(pEntry->func);
  28.484 -		delete pEntry->fake;
  28.485 -		pEntry->fake = NULL;
  28.486 -	}
  28.487 -
  28.488 -	pEntry->func = NULL;
  28.489 -	pEntry->name = NULL;
  28.490 -	pEntry->owner = NULL;
  28.491 -	pEntry->replacement.func = NULL;
  28.492 -	pEntry->replacement.owner = NULL;
  28.493 -}
  28.494 -
  28.495 -NativeEntry *ShareSystem::AddFakeNative(IPluginFunction *pFunc, const char *name, SPVM_FAKENATIVE_FUNC func)
  28.496 -{
  28.497 -	FakeNative *pFake;
  28.498 -	NativeEntry *pEntry;
  28.499 -	SPVM_NATIVE_FUNC gate;
  28.500 -
  28.501 -	if ((pEntry = FindNative(name)) != NULL && pEntry->owner != NULL)
  28.502 -	{
  28.503 -		return NULL;
  28.504 -	}
  28.505 -
  28.506 -	pFake = new FakeNative;
  28.507 -
  28.508 -	if ((gate = g_pSourcePawn2->CreateFakeNative(func, pFake)) == NULL)
  28.509 -	{
  28.510 -		delete pFake;
  28.511 -		return NULL;
  28.512 -	}
  28.513 -
  28.514 -	if (pEntry == NULL)
  28.515 -	{
  28.516 -		pEntry = new NativeEntry;
  28.517 -		m_NtvCache.insert(name, pEntry);
  28.518 -	}
  28.519 -
  28.520 -	pFake->call = pFunc;
  28.521 -	pFake->ctx = pFunc->GetParentContext();
  28.522 -	strncopy(pFake->name, name, sizeof(pFake->name));
  28.523 -	
  28.524 -	pEntry->fake = pFake;
  28.525 -	pEntry->func = gate;
  28.526 -	pEntry->name = pFake->name;
  28.527 -	pEntry->owner = g_PluginSys.GetPluginByCtx(pFake->ctx->GetContext());
  28.528 -	pEntry->replacement.func = NULL;
  28.529 -	pEntry->replacement.owner = NULL;
  28.530 -
  28.531 -	return pEntry;
  28.532 -}
  28.533 -
  28.534 -void ShareSystem::AddCapabilityProvider(IExtension *myself, IFeatureProvider *provider,
  28.535 -		                                const char *name)
  28.536 -{
  28.537 -	if (m_caps.retrieve(name) != NULL)
  28.538 -		return;
  28.539 -
  28.540 -	Capability cap;
  28.541 -	cap.ext = myself;
  28.542 -	cap.provider = provider;
  28.543 -
  28.544 -	m_caps.insert(name, cap);
  28.545 -}
  28.546 -
  28.547 -void ShareSystem::DropCapabilityProvider(IExtension *myself, IFeatureProvider *provider,
  28.548 -		                                 const char *name)
  28.549 -{
  28.550 -	Capability *pCap = m_caps.retrieve(name);
  28.551 -	if (pCap == NULL)
  28.552 -		return;
  28.553 -
  28.554 -	if (pCap->ext != myself || pCap->provider != provider)
  28.555 -		return;
  28.556 -
  28.557 -	m_caps.remove(name);
  28.558 -}
  28.559 -
  28.560 -FeatureStatus ShareSystem::TestFeature(IPluginRuntime *pRuntime, FeatureType feature, 
  28.561 -                                       const char *name)
  28.562 -{
  28.563 -	switch (feature)
  28.564 -	{
  28.565 -	case FeatureType_Native:
  28.566 -		return TestNative(pRuntime, name);
  28.567 -	case FeatureType_Capability:
  28.568 -		return TestCap(name);
  28.569 -	default:
  28.570 -		break;
  28.571 -	}
  28.572 -
  28.573 -	return FeatureStatus_Unknown;
  28.574 -}
  28.575 -
  28.576 -FeatureStatus ShareSystem::TestNative(IPluginRuntime *pRuntime, const char *name)
  28.577 -{
  28.578 -	uint32_t index;
  28.579 -
  28.580 -	if (pRuntime->FindNativeByName(name, &index) == SP_ERROR_NONE)
  28.581 -	{
  28.582 -		sp_native_t *native;
  28.583 -		if (pRuntime->GetNativeByIndex(index, &native) == SP_ERROR_NONE)
  28.584 -		{
  28.585 -			if (native->status == SP_NATIVE_BOUND)
  28.586 -				return FeatureStatus_Available;
  28.587 -			else
  28.588 -				return FeatureStatus_Unknown;
  28.589 -		}
  28.590 -	}
  28.591 -
  28.592 -	NativeEntry *entry = FindNative(name);
  28.593 -	if (entry == NULL)
  28.594 -		return FeatureStatus_Unknown;
  28.595 -
  28.596 -	if ((entry->replacement.owner != NULL || entry->owner != NULL) &&
  28.597 -		(entry->replacement.func != NULL || entry->func != NULL))
  28.598 -	{
  28.599 -		return FeatureStatus_Available;
  28.600 -	}
  28.601 -	else
  28.602 -	{
  28.603 -		return FeatureStatus_Unavailable;
  28.604 -	}
  28.605 -}
  28.606 -
  28.607 -FeatureStatus ShareSystem::TestCap(const char *name)
  28.608 -{
  28.609 -	Capability *cap = m_caps.retrieve(name);
  28.610 -	if (cap == NULL)
  28.611 -		return FeatureStatus_Unknown;
  28.612 -
  28.613 -	return cap->provider->GetFeatureStatus(FeatureType_Capability, name);
  28.614 -}
    29.1 --- a/core/ShareSys.h	Fri Mar 29 12:28:02 2013 -0400
    29.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    29.3 @@ -1,164 +0,0 @@
    29.4 -/**
    29.5 - * vim: set ts=4 :
    29.6 - * =============================================================================
    29.7 - * SourceMod
    29.8 - * Copyright (C) 2004-2008 AlliedModders LLC.  All rights reserved.
    29.9 - * =============================================================================
   29.10 - *
   29.11 - * This program is free software; you can redistribute it and/or modify it under
   29.12 - * the terms of the GNU General Public License, version 3.0, as published by the
   29.13 - * Free Software Foundation.
   29.14 - * 
   29.15 - * This program is distributed in the hope that it will be useful, but WITHOUT
   29.16 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   29.17 - * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
   29.18 - * details.
   29.19 - *
   29.20 - * You should have received a copy of the GNU General Public License along with
   29.21 - * this program.  If not, see <http://www.gnu.org/licenses/>.
   29.22 - *
   29.23 - * As a special exception, AlliedModders LLC gives you permission to link the
   29.24 - * code of this program (as well as its derivative works) to "Half-Life 2," the
   29.25 - * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
   29.26 - * by the Valve Corporation.  You must obey the GNU General Public License in
   29.27 - * all respects for all other code used.  Additionally, AlliedModders LLC grants
   29.28 - * this exception to all derivative works.  AlliedModders LLC defines further
   29.29 - * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
   29.30 - * or <http://www.sourcemod.net/license.php>.
   29.31 - *
   29.32 - * Version: $Id$
   29.33 - */
   29.34 -
   29.35 -#ifndef _INCLUDE_SOURCEMOD_SHARESYSTEM_H_
   29.36 -#define _INCLUDE_SOURCEMOD_SHARESYSTEM_H_
   29.37 -
   29.38 -#include <IShareSys.h>
   29.39 -#include <IHandleSys.h>
   29.40 -#include <sh_list.h>
   29.41 -#include <sm_trie_tpl.h>
   29.42 -#include "sm_globals.h"
   29.43 -#include "sourcemod.h"
   29.44 -
   29.45 -using namespace SourceHook;
   29.46 -
   29.47 -namespace SourceMod
   29.48 -{
   29.49 -	struct IdentityToken_t
   29.50 -	{
   29.51 -		Handle_t ident;
   29.52 -		void *ptr;
   29.53 -		IdentityType_t type;
   29.54 -	};
   29.55 -};
   29.56 -
   29.57 -struct IfaceInfo
   29.58 -{
   29.59 -	bool operator ==(const IfaceInfo &info)
   29.60 -	{
   29.61 -		return (info.iface == iface && info.owner == owner);
   29.62 -	}
   29.63 -	SMInterface *iface;
   29.64 -	IExtension *owner;
   29.65 -};
   29.66 -
   29.67 -class CNativeOwner;
   29.68 -class CPlugin;
   29.69 -struct NativeEntry;
   29.70 -
   29.71 -struct ReplaceNative
   29.72 -{
   29.73 -	CNativeOwner *owner;
   29.74 -	SPVM_NATIVE_FUNC func;
   29.75 -};
   29.76 -
   29.77 -struct FakeNative
   29.78 -{
   29.79 -	char name[64];
   29.80 -	IPluginContext *ctx;
   29.81 -	IPluginFunction *call;
   29.82 -};
   29.83 -
   29.84 -struct NativeEntry
   29.85 -{
   29.86 -	CNativeOwner *owner;
   29.87 -	SPVM_NATIVE_FUNC func;
   29.88 -	const char *name;
   29.89 -	ReplaceNative replacement;
   29.90 -	FakeNative *fake;
   29.91 -};
   29.92 -
   29.93 -struct Capability
   29.94 -{
   29.95 -	IExtension *ext;
   29.96 -	IFeatureProvider *provider;
   29.97 -};
   29.98 -
   29.99 -class ShareSystem :
  29.100 -	public IShareSys,
  29.101 -	public SMGlobalClass,
  29.102 -	public IHandleTypeDispatch
  29.103 -{
  29.104 -	friend class CNativeOwner;
  29.105 -public:
  29.106 -	ShareSystem();
  29.107 -public: //IShareSys
  29.108 -	bool AddInterface(IExtension *myself, SMInterface *pIface);
  29.109 -	bool RequestInterface(const char *iface_name, 
  29.110 -		unsigned int iface_vers,
  29.111 -		IExtension *myself,
  29.112 -		SMInterface **pIface);
  29.113 -	void AddNatives(IExtension *myself, const sp_nativeinfo_t *natives);
  29.114 -	IdentityType_t CreateIdentType(const char *name);
  29.115 -	IdentityType_t FindIdentType(const char *name);
  29.116 -	IdentityToken_t *CreateIdentity(IdentityType_t type, void *ptr);
  29.117 -	void DestroyIdentType(IdentityType_t type);
  29.118 -	void DestroyIdentity(IdentityToken_t *identity);
  29.119 -	void AddDependency(IExtension *myself, const char *filename, bool require, bool autoload);
  29.120 -	void RegisterLibrary(IExtension *myself, const char *name);
  29.121 -	void OverrideNatives(IExtension *myself, const sp_nativeinfo_t *natives);
  29.122 -	void AddCapabilityProvider(IExtension *myself, IFeatureProvider *provider,
  29.123 -		                       const char *name);
  29.124 -	void DropCapabilityProvider(IExtension *myself, IFeatureProvider *provider,
  29.125 -		                        const char *name);
  29.126 -public: //SMGlobalClass
  29.127 -	/* Pre-empt in case anything tries to register idents early */
  29.128 -	void Initialize();
  29.129 -	void OnSourceModShutdown();
  29.130 -public: //IHandleTypeDispatch
  29.131 -	void OnHandleDestroy(HandleType_t type, void *object);
  29.132 -public:
  29.133 -	IdentityToken_t *CreateCoreIdentity();
  29.134 -	void RemoveInterfaces(IExtension *pExtension);
  29.135 -	FeatureStatus TestFeature(IPluginRuntime *pRuntime, FeatureType feature, const char *name);
  29.136 -	FeatureStatus TestNative(IPluginRuntime *pRuntime, const char *name);
  29.137 -	FeatureStatus TestCap(const char *name);
  29.138 -public:
  29.139 -	inline IdentityToken_t *GetIdentRoot()
  29.140 -	{
  29.141 -		return &m_IdentRoot;
  29.142 -	}
  29.143 -public:
  29.144 -	void BindNativesToPlugin(CPlugin *pPlugin, bool bCoreOnly);
  29.145 -	void BindNativeToPlugin(CPlugin *pPlugin, NativeEntry *pEntry);
  29.146 -	NativeEntry *AddFakeNative(IPluginFunction *pFunc, const char *name, SPVM_FAKENATIVE_FUNC func);
  29.147 -	NativeEntry *FindNative(const char *name);
  29.148 -private:
  29.149 -	NativeEntry *AddNativeToCache(CNativeOwner *pOwner, const sp_nativeinfo_t *ntv);
  29.150 -	void ClearNativeFromCache(CNativeOwner *pOwner, const char *name);
  29.151 -	void BindNativeToPlugin(CPlugin *pPlugin, 
  29.152 -		sp_native_t *ntv, 
  29.153 -		uint32_t index, 
  29.154 -		NativeEntry *pEntry);
  29.155 -private:
  29.156 -	List<IfaceInfo> m_Interfaces;
  29.157 -	HandleType_t m_TypeRoot;
  29.158 -	IdentityToken_t m_IdentRoot;
  29.159 -	HandleType_t m_IfaceType;
  29.160 -	IdentityType_t m_CoreType;
  29.161 -	KTrie<NativeEntry *> m_NtvCache;
  29.162 -	KTrie<Capability> m_caps;
  29.163 -};
  29.164 -
  29.165 -extern ShareSystem g_ShareSys;
  29.166 -
  29.167 -#endif //_INCLUDE_SOURCEMOD_SHARESYSTEM_H_
    30.1 --- a/core/TimerSys.cpp	Fri Mar 29 12:28:02 2013 -0400
    30.2 +++ b/core/TimerSys.cpp	Fri Mar 29 11:37:29 2013 -0700
    30.3 @@ -35,6 +35,7 @@
    30.4  #include "sourcemm_api.h"
    30.5  #include "frame_hooks.h"
    30.6  #include "ConVarManager.h"
    30.7 +#include "logic_bridge.h"
    30.8  
    30.9  #define TIMER_MIN_ACCURACY		0.1
   30.10  
   30.11 @@ -180,7 +181,7 @@
   30.12  
   30.13  void TimerSystem::OnSourceModAllInitialized()
   30.14  {
   30.15 -	g_ShareSys.AddInterface(NULL, this);
   30.16 +	sharesys->AddInterface(NULL, this);
   30.17  	m_pOnGameFrame = g_Forwards.CreateForward("OnGameFrame", ET_Ignore, 0, NULL);
   30.18  	m_pOnMapTimeLeftChanged = g_Forwards.CreateForward("OnMapTimeLeftChanged", ET_Ignore, 0, NULL);
   30.19  }
    31.1 --- a/core/TimerSys.h	Fri Mar 29 12:28:02 2013 -0400
    31.2 +++ b/core/TimerSys.h	Fri Mar 29 11:37:29 2013 -0700
    31.3 @@ -32,11 +32,11 @@
    31.4  #ifndef _INCLUDE_SOURCEMOD_CTIMERSYS_H_
    31.5  #define _INCLUDE_SOURCEMOD_CTIMERSYS_H_
    31.6  
    31.7 -#include "ShareSys.h"
    31.8  #include <ITimerSystem.h>
    31.9  #include <sh_stack.h>
   31.10  #include <sh_list.h>
   31.11  #include "sourcemm_api.h"
   31.12 +#include "sm_globals.h"
   31.13  
   31.14  using namespace SourceHook;
   31.15  using namespace SourceMod;
    32.1 --- a/core/UserMessages.cpp	Fri Mar 29 12:28:02 2013 -0400
    32.2 +++ b/core/UserMessages.cpp	Fri Mar 29 11:37:29 2013 -0700
    32.3 @@ -31,6 +31,7 @@
    32.4  
    32.5  #include "UserMessages.h"
    32.6  #include "sm_stringutil.h"
    32.7 +#include "logic_bridge.h"
    32.8  
    32.9  #if SOURCE_ENGINE == SE_DOTA
   32.10  #include <dota_usermessage_helpers.h>
   32.11 @@ -91,7 +92,7 @@
   32.12  
   32.13  void UserMessages::OnSourceModAllInitialized()
   32.14  {
   32.15 -	g_ShareSys.AddInterface(NULL, this);
   32.16 +	sharesys->AddInterface(NULL, this);
   32.17  }
   32.18  
   32.19  void UserMessages::OnSourceModAllShutdown()
    33.1 --- a/core/UserMessages.h	Fri Mar 29 12:28:02 2013 -0400
    33.2 +++ b/core/UserMessages.h	Fri Mar 29 11:37:29 2013 -0700
    33.3 @@ -32,12 +32,14 @@
    33.4  #ifndef _INCLUDE_SOURCEMOD_CUSERMESSAGES_H_
    33.5  #define _INCLUDE_SOURCEMOD_CUSERMESSAGES_H_
    33.6  
    33.7 -#include "ShareSys.h"
    33.8  #include <IUserMessages.h>
    33.9  #include "sourcemm_api.h"
   33.10  #include "sm_trie.h"
   33.11  #include "sm_stringutil.h"
   33.12  #include "CellRecipientFilter.h"
   33.13 +#include "sm_globals.h"
   33.14 +#include <sh_list.h>
   33.15 +#include <sh_stack.h>
   33.16  
   33.17  using namespace SourceHook;
   33.18  using namespace SourceMod;
    34.1 --- a/core/frame_hooks.cpp	Fri Mar 29 12:28:02 2013 -0400
    34.2 +++ b/core/frame_hooks.cpp	Fri Mar 29 11:37:29 2013 -0700
    34.3 @@ -38,6 +38,7 @@
    34.4  #include "CoreConfig.h"
    34.5  #include <sm_queue.h>
    34.6  #include <IThreader.h>
    34.7 +#include "sourcemod.h"
    34.8  
    34.9  static IMutex *frame_mutex;
   34.10  static Queue<FrameAction> *frame_queue;
    35.1 --- a/core/logic/AMBuilder	Fri Mar 29 12:28:02 2013 -0400
    35.2 +++ b/core/logic/AMBuilder	Fri Mar 29 11:37:29 2013 -0700
    35.3 @@ -47,9 +47,16 @@
    35.4  	'smn_handles.cpp',
    35.5  	'smn_datapacks.cpp',
    35.6  	'smn_gameconfigs.cpp',
    35.7 +	'smn_fakenatives.cpp',
    35.8  	'GameConfigs.cpp',
    35.9  	'sm_crc32.cpp',
   35.10  	'smn_profiler.cpp',
   35.11 +	'ShareSys.cpp',
   35.12 +	'PluginSys.cpp',
   35.13 +	'HandleSys.cpp',
   35.14 +	'NativeOwner.cpp',
   35.15 +	'NativeInvoker.cpp',
   35.16 +	'ExtensionSys.cpp',
   35.17  	'DebugReporter.cpp'
   35.18  	]
   35.19  if AMBuild.target['platform'] == 'windows':
    36.1 --- a/core/logic/AutoHandleRooter.h	Fri Mar 29 12:28:02 2013 -0400
    36.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    36.3 @@ -1,92 +0,0 @@
    36.4 -/**
    36.5 - * vim: set ts=4 sw=4 tw=99 noet :
    36.6 - * =============================================================================
    36.7 - * SourceMod
    36.8 - * Copyright (C) 2004-2009 AlliedModders LLC.  All rights reserved.
    36.9 - * =============================================================================
   36.10 - *
   36.11 - * This program is free software; you can redistribute it and/or modify it under
   36.12 - * the terms of the GNU General Public License, version 3.0, as published by the
   36.13 - * Free Software Foundation.
   36.14 - * 
   36.15 - * This program is distributed in the hope that it will be useful, but WITHOUT
   36.16 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   36.17 - * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
   36.18 - * details.
   36.19 - *
   36.20 - * You should have received a copy of the GNU General Public License along with
   36.21 - * this program.  If not, see <http://www.gnu.org/licenses/>.
   36.22 - *
   36.23 - * As a special exception, AlliedModders LLC gives you permission to link the
   36.24 - * code of this program (as well as its derivative works) to "Half-Life 2," the
   36.25 - * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
   36.26 - * by the Valve Corporation.  You must obey the GNU General Public License in
   36.27 - * all respects for all other code used.  Additionally, AlliedModders LLC grants
   36.28 - * this exception to all derivative works.  AlliedModders LLC defines further
   36.29 - * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
   36.30 - * or <http://www.sourcemod.net/license.php>.
   36.31 - *
   36.32 - * Version: $Id$
   36.33 - */
   36.34 -
   36.35 -#ifndef _INCLUDE_SOURCEMOD_AUTO_HANDLE_ROOTER_H_
   36.36 -#define _INCLUDE_SOURCEMOD_AUTO_HANDLE_ROOTER_H_
   36.37 -
   36.38 -#include "common_logic.h"
   36.39 -#include <IHandleSys.h>
   36.40 -
   36.41 -class AutoHandleRooter
   36.42 -{
   36.43 -public:
   36.44 -	AutoHandleRooter(Handle_t hndl)
   36.45 -	{
   36.46 -		if (hndl != BAD_HANDLE)
   36.47 -			this->hndl = handlesys->FastCloneHandle(hndl);
   36.48 -		else
   36.49 -			this->hndl = BAD_HANDLE;
   36.50 -	}
   36.51 -
   36.52 -	~AutoHandleRooter()
   36.53 -	{
   36.54 -		if (hndl != BAD_HANDLE)
   36.55 -		{
   36.56 -			HandleSecurity sec(g_pCoreIdent, g_pCoreIdent);
   36.57 -			handlesys->FreeHandle(hndl, &sec);
   36.58 -		}
   36.59 -	}
   36.60 -
   36.61 -	Handle_t getHandle()
   36.62 -	{
   36.63 -		return hndl;
   36.64 -	}
   36.65 -private:
   36.66 -	Handle_t hndl;
   36.67 -};
   36.68 -
   36.69 -class AutoHandleCloner
   36.70 -{
   36.71 -	Handle_t original;
   36.72 -	HandleSecurity sec;
   36.73 -	AutoHandleRooter ahr;
   36.74 -public:
   36.75 -	AutoHandleCloner(Handle_t original, HandleSecurity sec)
   36.76 -	  : original(original), sec(sec), ahr(original)
   36.77 -	{
   36.78 -	}
   36.79 -
   36.80 -	~AutoHandleCloner()
   36.81 -	{
   36.82 -		if (original != BAD_HANDLE)
   36.83 -		{
   36.84 -			handlesys->FreeHandle(original, &sec);
   36.85 -		}
   36.86 -	}
   36.87 -
   36.88 -	Handle_t getClone()
   36.89 -	{
   36.90 -		return ahr.getHandle();
   36.91 -	}
   36.92 -};
   36.93 -
   36.94 -#endif /* _INCLUDE_SOURCEMOD_AUTO_HANDLE_ROOTER_H_ */
   36.95 -
    37.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    37.2 +++ b/core/logic/ExtensionSys.cpp	Fri Mar 29 11:37:29 2013 -0700
    37.3 @@ -0,0 +1,1383 @@
    37.4 +/**
    37.5 + * vim: set ts=4 sw=4 tw=99 noet :
    37.6 + * =============================================================================
    37.7 + * SourceMod
    37.8 + * Copyright (C) 2004-2010 AlliedModders LLC.  All rights reserved.
    37.9 + * =============================================================================
   37.10 + *
   37.11 + * This program is free software; you can redistribute it and/or modify it under
   37.12 + * the terms of the GNU General Public License, version 3.0, as published by the
   37.13 + * Free Software Foundation.
   37.14 + * 
   37.15 + * This program is distributed in the hope that it will be useful, but WITHOUT
   37.16 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   37.17 + * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
   37.18 + * details.
   37.19 + *
   37.20 + * You should have received a copy of the GNU General Public License along with
   37.21 + * this program.  If not, see <http://www.gnu.org/licenses/>.
   37.22 + *
   37.23 + * As a special exception, AlliedModders LLC gives you permission to link the
   37.24 + * code of this program (as well as its derivative works) to "Half-Life 2," the
   37.25 + * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
   37.26 + * by the Valve Corporation.  You must obey the GNU General Public License in
   37.27 + * all respects for all other code used.  Additionally, AlliedModders LLC grants
   37.28 + * this exception to all derivative works.  AlliedModders LLC defines further
   37.29 + * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
   37.30 + * or <http://www.sourcemod.net/license.php>.
   37.31 + *
   37.32 + * Version: $Id$
   37.33 + */
   37.34 +
   37.35 +#include <stdlib.h>
   37.36 +#include "ExtensionSys.h"
   37.37 +#include <ILibrarySys.h>
   37.38 +#include <ISourceMod.h>
   37.39 +#include "common_logic.h"
   37.40 +#include "PluginSys.h"
   37.41 +
   37.42 +CExtensionManager g_Extensions;
   37.43 +IdentityType_t g_ExtType;
   37.44 +
   37.45 +void CExtension::Initialize(const char *filename, const char *path)
   37.46 +{
   37.47 +	m_pAPI = NULL;
   37.48 +	m_pIdentToken = NULL;
   37.49 +	unload_code = 0;
   37.50 +	m_bFullyLoaded = false;
   37.51 +	m_File.assign(filename);
   37.52 +	m_Path.assign(path);
   37.53 +	char real_name[PLATFORM_MAX_PATH];
   37.54 +	libsys->GetFileFromPath(real_name, sizeof(real_name), m_Path.c_str());
   37.55 +	m_RealFile.assign(real_name);
   37.56 +}
   37.57 +
   37.58 +CRemoteExtension::CRemoteExtension(IExtensionInterface *pAPI, const char *filename, const char *path)
   37.59 +{
   37.60 +	Initialize(filename, path);
   37.61 +	m_pAPI = pAPI;
   37.62 +}
   37.63 +
   37.64 +#if defined METAMOD_PLAPI_VERSION
   37.65 +#if SOURCE_ENGINE == SE_LEFT4DEAD
   37.66 +#define GAMEFIX "2.l4d"
   37.67 +#elif SOURCE_ENGINE == SE_LEFT4DEAD2
   37.68 +#define GAMEFIX "2.l4d2"
   37.69 +#elif SOURCE_ENGINE == SE_ALIENSWARM
   37.70 +#define GAMEFIX "2.swarm"
   37.71 +#elif SOURCE_ENGINE == SE_ORANGEBOX
   37.72 +#define GAMEFIX "2.ep2"
   37.73 +#elif SOURCE_ENGINE == SE_BLOODYGOODTIME
   37.74 +#define GAMEFIX "2.bgt"
   37.75 +#elif SOURCE_ENGINE == SE_EYE
   37.76 +#define GAMEFIX "2.eye"
   37.77 +#elif SOURCE_ENGINE == SE_CSS
   37.78 +#define GAMEFIX "2.css"
   37.79 +#elif SOURCE_ENGINE == SE_ORANGEBOXVALVE
   37.80 +#define GAMEFIX "2.ep2v"
   37.81 +#elif SOURCE_ENGINE == SE_DARKMESSIAH
   37.82 +#define GAMEFIX "2.darkm"
   37.83 +#elif SOURCE_ENGINE == SE_PORTAL2
   37.84 +#define GAMEFIX "2.portal2"
   37.85 +#elif SOURCE_ENGINE == SE_CSGO
   37.86 +#define GAMEFIX "2.csgo"
   37.87 +#elif SOURCE_ENGINE == SE_DOTA
   37.88 +#define GAMEFIX "2.dota"
   37.89 +#else
   37.90 +#define GAMEFIX "2.ep1"
   37.91 +#endif //(SOURCE_ENGINE == SE_LEFT4DEAD) || (SOURCE_ENGINE == SE_LEFT4DEAD2)
   37.92 +#else  //METAMOD_PLAPI_VERSION
   37.93 +#define GAMEFIX "1.ep1"
   37.94 +#endif //METAMOD_PLAPI_VERSION
   37.95 +
   37.96 +CLocalExtension::CLocalExtension(const char *filename)
   37.97 +{
   37.98 +	m_PlId = 0;
   37.99 +	m_pLib = NULL;
  37.100 +
  37.101 +	char path[PLATFORM_MAX_PATH];
  37.102 +
  37.103 +	/* Special case for new bintools binary */
  37.104 +	if (strcmp(filename, "bintools.ext") == 0)
  37.105 +	{
  37.106 +		goto normal;
  37.107 +	}
  37.108 +
  37.109 +	/* Zeroth, see if there is an engine specific build in the new place. */
  37.110 +	g_pSM->BuildPath(Path_SM,
  37.111 +		path,
  37.112 +		PLATFORM_MAX_PATH,
  37.113 +		"extensions/%s." GAMEFIX "." PLATFORM_LIB_EXT,
  37.114 +		filename);
  37.115 +
  37.116 +	if (libsys->IsPathFile(path))
  37.117 +	{
  37.118 +		goto found;
  37.119 +	}
  37.120 +
  37.121 +	/* First see if there is an engine specific build! */
  37.122 +	g_pSM->BuildPath(Path_SM, 
  37.123 +		path, 
  37.124 +		PLATFORM_MAX_PATH,
  37.125 +		"extensions/auto." GAMEFIX "/%s." PLATFORM_LIB_EXT,
  37.126 +		filename);
  37.127 +
  37.128 +	/* Try the "normal" version */
  37.129 +	if (!libsys->IsPathFile(path))
  37.130 +	{
  37.131 +		normal:
  37.132 +		g_pSM->BuildPath(Path_SM,
  37.133 +			path,
  37.134 +			PLATFORM_MAX_PATH,
  37.135 +			"extensions/%s." PLATFORM_LIB_EXT,
  37.136 +			filename);
  37.137 +	}
  37.138 +
  37.139 +found:
  37.140 +	Initialize(filename, path);
  37.141 +}
  37.142 +
  37.143 +bool CRemoteExtension::Load(char *error, size_t maxlength)
  37.144 +{
  37.145 +	if (!PerformAPICheck(error, maxlength))
  37.146 +	{
  37.147 +		m_pAPI = NULL;
  37.148 +		return false;
  37.149 +	}
  37.150 +
  37.151 +	if (!CExtension::Load(error, maxlength))
  37.152 +	{
  37.153 +		m_pAPI = NULL;
  37.154 +		return false;
  37.155 +	}
  37.156 +
  37.157 +	return true;
  37.158 +}
  37.159 +
  37.160 +bool CLocalExtension::Load(char *error, size_t maxlength)
  37.161 +{
  37.162 +	m_pLib = libsys->OpenLibrary(m_Path.c_str(), error, maxlength);
  37.163 +
  37.164 +	if (m_pLib == NULL)
  37.165 +	{
  37.166 +		return false;
  37.167 +	}
  37.168 +
  37.169 +	typedef IExtensionInterface *(*GETAPI)();
  37.170 +	GETAPI pfnGetAPI = NULL;
  37.171 +
  37.172 +	if ((pfnGetAPI=(GETAPI)m_pLib->GetSymbolAddress("GetSMExtAPI")) == NULL)
  37.173 +	{
  37.174 +		m_pLib->CloseLibrary();
  37.175 +		m_pLib = NULL;
  37.176 +		snprintf(error, maxlength, "Unable to find extension entry point");
  37.177 +		return false;
  37.178 +	}
  37.179 +
  37.180 +	m_pAPI = pfnGetAPI();
  37.181 +
  37.182 +	/* Check pointer and version */
  37.183 +	if (!PerformAPICheck(error, maxlength))
  37.184 +	{
  37.185 +		m_pLib->CloseLibrary();
  37.186 +		m_pLib = NULL;
  37.187 +		m_pAPI = NULL;
  37.188 +		return false;
  37.189 +	}
  37.190 +
  37.191 +	/* Load as MM:S */
  37.192 +	if (m_pAPI->IsMetamodExtension())
  37.193 +	{
  37.194 +		bool ok;
  37.195 +		m_PlId = smcore.LoadMMSPlugin(m_Path.c_str(), &ok, error, maxlength);
  37.196 +
  37.197 +		if (!m_PlId || !ok)
  37.198 +		{
  37.199 +			m_pLib->CloseLibrary();
  37.200 +			m_pLib = NULL;
  37.201 +			m_pAPI = NULL;
  37.202 +			return false;
  37.203 +		}
  37.204 +	}
  37.205 +
  37.206 +	if (!CExtension::Load(error, maxlength))
  37.207 +	{
  37.208 +		if (m_pAPI->IsMetamodExtension())
  37.209 +		{
  37.210 +			if (m_PlId)
  37.211 +			{
  37.212 +				smcore.UnloadMMSPlugin(m_PlId);
  37.213 +				m_PlId = 0;
  37.214 +			}
  37.215 +		}
  37.216 +		m_pLib->CloseLibrary();
  37.217 +		m_pLib = NULL;
  37.218 +		m_pAPI = NULL;
  37.219 +		return false;
  37.220 +	}
  37.221 +
  37.222 +	return true;
  37.223 +}
  37.224 +
  37.225 +void CRemoteExtension::Unload()
  37.226 +{
  37.227 +}
  37.228 +
  37.229 +void CLocalExtension::Unload()
  37.230 +{
  37.231 +	if (m_pAPI != NULL && m_PlId)
  37.232 +	{
  37.233 +		smcore.UnloadMMSPlugin(m_PlId);
  37.234 +		m_PlId = 0;
  37.235 +	}
  37.236 +
  37.237 +	if (m_pLib != NULL)
  37.238 +	{
  37.239 +		m_pLib->CloseLibrary();
  37.240 +		m_pLib = NULL;
  37.241 +	}
  37.242 +}
  37.243 +
  37.244 +bool CRemoteExtension::Reload(char *error, size_t maxlength)
  37.245 +{
  37.246 +	snprintf(error, maxlength, "Remote extensions do not support reloading");
  37.247 +	return false;
  37.248 +}
  37.249 +
  37.250 +bool CLocalExtension::Reload(char *error, size_t maxlength)
  37.251 +{
  37.252 +	if (m_pLib == NULL) // FIXME: just load it instead?
  37.253 +		return false;
  37.254 +	
  37.255 +	m_pAPI->OnExtensionUnload();
  37.256 +	Unload();
  37.257 +	
  37.258 +	return Load(error, maxlength);
  37.259 +}
  37.260 +
  37.261 +bool CRemoteExtension::IsExternal()
  37.262 +{
  37.263 +	return true;
  37.264 +}
  37.265 +
  37.266 +bool CLocalExtension::IsExternal()
  37.267 +{
  37.268 +	return false;
  37.269 +}
  37.270 +
  37.271 +CExtension::~CExtension()
  37.272 +{
  37.273 +	DestroyIdentity();
  37.274 +}
  37.275 +
  37.276 +bool CExtension::PerformAPICheck(char *error, size_t maxlength)
  37.277 +{
  37.278 +	if (!m_pAPI)
  37.279 +	{
  37.280 +		snprintf(error, maxlength, "No IExtensionInterface instance provided");
  37.281 +		return false;
  37.282 +	}
  37.283 +	
  37.284 +	if (m_pAPI->GetExtensionVersion() > SMINTERFACE_EXTENSIONAPI_VERSION)
  37.285 +	{
  37.286 +		snprintf(error, maxlength, "Extension version is too new to load (%d, max is %d)", m_pAPI->GetExtensionVersion(), SMINTERFACE_EXTENSIONAPI_VERSION);
  37.287 +		return false;
  37.288 +	}
  37.289 +
  37.290 +	return true;
  37.291 +}
  37.292 +
  37.293 +bool CExtension::Load(char *error, size_t maxlength)
  37.294 +{
  37.295 +	CreateIdentity();
  37.296 +	if (!m_pAPI->OnExtensionLoad(this, &g_ShareSys, error, maxlength, !smcore.IsMapLoading()))
  37.297 +	{
  37.298 +		DestroyIdentity();
  37.299 +		return false;
  37.300 +	}
  37.301 +	else
  37.302 +	{
  37.303 +		/* Check if we're past load time */
  37.304 +		if (!smcore.IsMapLoading())
  37.305 +		{
  37.306 +			m_pAPI->OnExtensionsAllLoaded();
  37.307 +		}
  37.308 +	}
  37.309 +
  37.310 +	return true;
  37.311 +}
  37.312 +
  37.313 +void CExtension::CreateIdentity()
  37.314 +{
  37.315 +	if (m_pIdentToken != NULL)
  37.316 +	{
  37.317 +		return;
  37.318 +	}
  37.319 +
  37.320 +	m_pIdentToken = g_ShareSys.CreateIdentity(g_ExtType, this);
  37.321 +}
  37.322 +
  37.323 +void CExtension::DestroyIdentity()
  37.324 +{
  37.325 +	if (m_pIdentToken == NULL)
  37.326 +	{
  37.327 +		return;
  37.328 +	}
  37.329 +
  37.330 +	g_ShareSys.DestroyIdentity(m_pIdentToken);
  37.331 +	m_pIdentToken = NULL;
  37.332 +}
  37.333 +
  37.334 +void CExtension::MarkAllLoaded()
  37.335 +{
  37.336 +	assert(m_bFullyLoaded == false);
  37.337 +	if (!m_bFullyLoaded)
  37.338 +	{
  37.339 +		m_bFullyLoaded = true;
  37.340 +		m_pAPI->OnExtensionsAllLoaded();
  37.341 +	}
  37.342 +}
  37.343 +
  37.344 +void CExtension::AddPlugin(CPlugin *pPlugin)
  37.345 +{
  37.346 +	/* Unfortunately we have to do this :( */
  37.347 +	if (m_Dependents.find(pPlugin) != m_Dependents.end())
  37.348 +	{
  37.349 +		m_Dependents.push_back(pPlugin);
  37.350 +	}
  37.351 +}
  37.352 +
  37.353 +void CExtension::SetError(const char *error)
  37.354 +{
  37.355 +	m_Error.assign(error);
  37.356 +}
  37.357 +
  37.358 +IExtensionInterface *CExtension::GetAPI()
  37.359 +{
  37.360 +	return m_pAPI;
  37.361 +}
  37.362 +
  37.363 +const char *CExtension::GetFilename()
  37.364 +{
  37.365 +	return m_RealFile.c_str();
  37.366 +}
  37.367 +
  37.368 +const char *CExtension::GetPath() const
  37.369 +{
  37.370 +	return m_Path.c_str();
  37.371 +}
  37.372 +
  37.373 +IdentityToken_t *CExtension::GetIdentity()
  37.374 +{
  37.375 +	return m_pIdentToken;
  37.376 +}
  37.377 +
  37.378 +bool CRemoteExtension::IsLoaded()
  37.379 +{
  37.380 +	return (m_pAPI != NULL);
  37.381 +}
  37.382 +
  37.383 +bool CLocalExtension::IsLoaded()
  37.384 +{
  37.385 +	return (m_pLib != NULL);
  37.386 +}
  37.387 +
  37.388 +void CExtension::AddDependency(const IfaceInfo *pInfo)
  37.389 +{
  37.390 +	if (m_Deps.find(*pInfo) == m_Deps.end())
  37.391 +	{
  37.392 +		m_Deps.push_back(*pInfo);
  37.393 +	}
  37.394 +}
  37.395 +
  37.396 +bool operator ==(const IfaceInfo &i1, const IfaceInfo &i2)
  37.397 +{
  37.398 +	return (i1.iface == i2.iface) && (i1.owner == i2.owner);
  37.399 +}
  37.400 +
  37.401 +void CExtension::AddChildDependent(CExtension *pOther, SMInterface *iface)
  37.402 +{
  37.403 +	IfaceInfo info;
  37.404 +	info.iface = iface;
  37.405 +	info.owner = pOther;
  37.406 +
  37.407 +	List<IfaceInfo>::iterator iter;
  37.408 +	for (iter = m_ChildDeps.begin();
  37.409 +		 iter != m_ChildDeps.end();
  37.410 +		 iter++)
  37.411 +	{
  37.412 +		IfaceInfo &other = (*iter);
  37.413 +		if (other == info)
  37.414 +		{
  37.415 +			return;
  37.416 +		}
  37.417 +	}
  37.418 +
  37.419 +	m_ChildDeps.push_back(info);
  37.420 +}
  37.421 +
  37.422 +ITERATOR *CExtension::FindFirstDependency(IExtension **pOwner, SMInterface **pInterface)
  37.423 +{
  37.424 +	List<IfaceInfo>::iterator iter = m_Deps.begin();
  37.425 +
  37.426 +	if (iter == m_Deps.end())
  37.427 +	{
  37.428 +		return NULL;
  37.429 +	}
  37.430 +
  37.431 +	if (pOwner)
  37.432 +	{
  37.433 +		*pOwner = (*iter).owner;
  37.434 +	}
  37.435 +	if (pInterface)
  37.436 +	{
  37.437 +		*pInterface = (*iter).iface;
  37.438 +	}
  37.439 +
  37.440 +	List<IfaceInfo>::iterator *pIter = new List<IfaceInfo>::iterator(iter);
  37.441 +
  37.442 +	return (ITERATOR *)pIter;
  37.443 +}
  37.444 +
  37.445 +bool CExtension::FindNextDependency(ITERATOR *iter, IExtension **pOwner, SMInterface **pInterface)
  37.446 +{
  37.447 +	List<IfaceInfo>::iterator *pIter = (List<IfaceInfo>::iterator *)iter;
  37.448 +	List<IfaceInfo>::iterator _iter;
  37.449 +
  37.450 +	if (_iter == m_Deps.end())
  37.451 +	{
  37.452 +		return false;
  37.453 +	}
  37.454 +
  37.455 +	_iter++;
  37.456 +
  37.457 +	if (pOwner)
  37.458 +	{
  37.459 +		*pOwner = (*_iter).owner;
  37.460 +	}
  37.461 +	if (pInterface)
  37.462 +	{
  37.463 +		*pInterface = (*_iter).iface;
  37.464 +	}
  37.465 +
  37.466 +	*pIter = _iter;
  37.467 +
  37.468 +	if (_iter == m_Deps.end())
  37.469 +	{
  37.470 +		return false;
  37.471 +	}
  37.472 +
  37.473 +	return true;
  37.474 +}
  37.475 +
  37.476 +void CExtension::FreeDependencyIterator(ITERATOR *iter)
  37.477 +{
  37.478 +	List<IfaceInfo>::iterator *pIter = (List<IfaceInfo>::iterator *)iter;
  37.479 +
  37.480 +	delete pIter;
  37.481 +}
  37.482 +
  37.483 +void CExtension::AddInterface(SMInterface *pInterface)
  37.484 +{
  37.485 +	m_Interfaces.push_back(pInterface);
  37.486 +}
  37.487 +
  37.488 +bool CExtension::IsRunning(char *error, size_t maxlength)
  37.489 +{
  37.490 +	if (!IsLoaded())
  37.491 +	{
  37.492 +		if (error)
  37.493 +		{
  37.494 +			snprintf(error, maxlength, "%s", m_Error.c_str());
  37.495 +		}
  37.496 +		return false;
  37.497 +	}
  37.498 +
  37.499 +	return m_pAPI->QueryRunning(error, maxlength);
  37.500 +}
  37.501 +
  37.502 +void CExtension::AddLibrary(const char *library)
  37.503 +{
  37.504 +	m_Libraries.push_back(library);
  37.505 +}
  37.506 +
  37.507 +/*********************
  37.508 + * EXTENSION MANAGER *
  37.509 + *********************/
  37.510 +
  37.511 +void CExtensionManager::OnSourceModAllInitialized()
  37.512 +{
  37.513 +	g_ExtType = g_ShareSys.CreateIdentType("EXTENSION");
  37.514 +	pluginsys->AddPluginsListener(this);
  37.515 +	g_ShareSys.AddInterface(NULL, this);
  37.516 +}
  37.517 +
  37.518 +void CExtensionManager::OnSourceModShutdown()
  37.519 +{
  37.520 +	pluginsys->RemovePluginsListener(this);
  37.521 +	g_ShareSys.DestroyIdentType(g_ExtType);
  37.522 +}
  37.523 +
  37.524 +void CExtensionManager::Shutdown()
  37.525 +{
  37.526 +	List<CExtension *>::iterator iter;
  37.527 +
  37.528 +	while ((iter = m_Libs.begin()) != m_Libs.end())
  37.529 +	{
  37.530 +		UnloadExtension((*iter));
  37.531 +	}
  37.532 +}
  37.533 +
  37.534 +void CExtensionManager::TryAutoload()
  37.535 +{
  37.536 +	char path[PLATFORM_MAX_PATH];
  37.537 +
  37.538 +	g_pSM->BuildPath(Path_SM, path, sizeof(path), "extensions");
  37.539 +
  37.540 +	IDirectory *pDir = libsys->OpenDirectory(path);
  37.541 +	if (!pDir)
  37.542 +	{
  37.543 +		return;
  37.544 +	}
  37.545 +
  37.546 +	const char *lfile;
  37.547 +	size_t len;
  37.548 +	while (pDir->MoreFiles())
  37.549 +	{
  37.550 +		if (pDir->IsEntryDirectory())
  37.551 +		{
  37.552 +			pDir->NextEntry();
  37.553 +			continue;
  37.554 +		}
  37.555 +
  37.556 +		lfile = pDir->GetEntryName();
  37.557 +		len = strlen(lfile);
  37.558 +		if (len <= 9) /* size of ".autoload" */
  37.559 +		{
  37.560 +			pDir->NextEntry();
  37.561 +			continue;
  37.562 +		}
  37.563 +
  37.564 +		if (strcmp(&lfile[len - 9], ".autoload") != 0)
  37.565 +		{
  37.566 +			pDir->NextEntry();
  37.567 +			continue;
  37.568 +		}
  37.569 +
  37.570 +		char file[PLATFORM_MAX_PATH];
  37.571 +		len = smcore.Format(file, sizeof(file), "%s", lfile);
  37.572 +		strcpy(&file[len - 9], ".ext");
  37.573 +
  37.574 +		LoadAutoExtension(file);
  37.575 +		
  37.576 +		pDir->NextEntry();
  37.577 +	}
  37.578 +}
  37.579 +
  37.580 +IExtension *CExtensionManager::LoadAutoExtension(const char *path)
  37.581 +{
  37.582 +	/* Remove platform extension if it's there. Compat hack. */
  37.583 +	const char *ext = libsys->GetFileExtension(path);
  37.584 +	if (strcmp(ext, PLATFORM_LIB_EXT) == 0)
  37.585 +	{
  37.586 +		char path2[PLATFORM_MAX_PATH];
  37.587 +		smcore.Format(path2, sizeof(path2), "%s", path);
  37.588 +		path2[strlen(path) - strlen(PLATFORM_LIB_EXT) - 1] = '\0';
  37.589 +		return LoadAutoExtension(path);
  37.590 +	}
  37.591 +
  37.592 +	IExtension *pAlready;
  37.593 +	if ((pAlready=FindExtensionByFile(path)) != NULL)
  37.594 +	{
  37.595 +		return pAlready;
  37.596 +	}
  37.597 +
  37.598 +	char error[256];
  37.599 +	CExtension *p = new CLocalExtension(path);
  37.600 +
  37.601 +	/* We put us in the list beforehand so extensions that check for each other
  37.602 +	 * won't recursively load each other.
  37.603 +	 */
  37.604 +	m_Libs.push_back(p);
  37.605 +
  37.606 +	if (!p->Load(error, sizeof(error)) || !p->IsLoaded())
  37.607 +	{
  37.608 +		smcore.LogError("[SM] Unable to load extension \"%s\": %s", path, error);
  37.609 +		p->SetError(error);
  37.610 +	}
  37.611 +
  37.612 +	return p;
  37.613 +}
  37.614 +
  37.615 +IExtension *CExtensionManager::FindExtensionByFile(const char *file)
  37.616 +{
  37.617 +	List<CExtension *>::iterator iter;
  37.618 +	CExtension *pExt;
  37.619 +
  37.620 +	/* Chomp off the path */
  37.621 +	char lookup[PLATFORM_MAX_PATH];
  37.622 +	libsys->GetFileFromPath(lookup, sizeof(lookup), file);
  37.623 +
  37.624 +	for (iter=m_Libs.begin(); iter!=m_Libs.end(); iter++)
  37.625 +	{
  37.626 +		pExt = (*iter);
  37.627 +		if (pExt->IsSameFile(lookup))
  37.628 +		{
  37.629 +			return pExt;
  37.630 +		}
  37.631 +	}
  37.632 +
  37.633 +	return NULL;
  37.634 +}
  37.635 +
  37.636 +IExtension *CExtensionManager::FindExtensionByName(const char *ext)
  37.637 +{
  37.638 +	List<CExtension *>::iterator iter;
  37.639 +	CExtension *pExt;
  37.640 +	IExtensionInterface *pAPI;
  37.641 +	const char *name;
  37.642 +
  37.643 +	for (iter=m_Libs.begin(); iter!=m_Libs.end(); iter++)
  37.644 +	{
  37.645 +		pExt = (*iter);
  37.646 +		if (!pExt->IsLoaded())
  37.647 +		{
  37.648 +			continue;
  37.649 +		}
  37.650 +		if ((pAPI = pExt->GetAPI()) == NULL)
  37.651 +		{
  37.652 +			continue;
  37.653 +		}
  37.654 +		name = pAPI->GetExtensionName();
  37.655 +		if (!name)
  37.656 +		{
  37.657 +			continue;
  37.658 +		}
  37.659 +		if (strcmp(name, ext) == 0)
  37.660 +		{
  37.661 +			return pExt;
  37.662 +		}
  37.663 +	}
  37.664 +
  37.665 +	return NULL;
  37.666 +}
  37.667 +
  37.668 +IExtension *CExtensionManager::LoadExtension(const char *file, char *error, size_t maxlength)
  37.669 +{
  37.670 +	/* Remove platform extension if it's there. Compat hack. */
  37.671 +	const char *ext = libsys->GetFileExtension(file);
  37.672 +	if (strcmp(ext, PLATFORM_LIB_EXT) == 0)
  37.673 +	{
  37.674 +		char path2[PLATFORM_MAX_PATH];
  37.675 +		smcore.Format(path2, sizeof(path2), "%s", file);
  37.676 +		path2[strlen(file) - strlen(PLATFORM_LIB_EXT) - 1] = '\0';
  37.677 +		return LoadExtension(path2, error, maxlength);
  37.678 +	}
  37.679 +
  37.680 +	IExtension *pAlready;
  37.681 +	if ((pAlready=FindExtensionByFile(file)) != NULL)
  37.682 +	{
  37.683 +		return pAlready;
  37.684 +	}
  37.685 +
  37.686 +	CExtension *pExt = new CLocalExtension(file);
  37.687 +
  37.688 +	if (!pExt->Load(error, maxlength) || !pExt->IsLoaded())
  37.689 +	{
  37.690 +		pExt->Unload();
  37.691 +		delete pExt;
  37.692 +		return NULL;
  37.693 +	}
  37.694 +
  37.695 +	/* :TODO: do QueryRunning check if the map is loaded */
  37.696 +
  37.697 +	m_Libs.push_back(pExt);
  37.698 +
  37.699 +	return pExt;
  37.700 +}
  37.701 +
  37.702 +void CExtensionManager::BindDependency(IExtension *pRequester, IfaceInfo *pInfo)
  37.703 +{
  37.704 +	CExtension *pExt = (CExtension *)pRequester;
  37.705 +	CExtension *pOwner = (CExtension *)pInfo->owner;
  37.706 +
  37.707 +	pExt->AddDependency(pInfo);
  37.708 +
  37.709 +	IExtensionInterface *pAPI = pExt->GetAPI();
  37.710 +	if (pAPI && !pAPI->QueryInterfaceDrop(pInfo->iface))
  37.711 +	{
  37.712 +		pOwner->AddChildDependent(pExt, pInfo->iface);
  37.713 +	}
  37.714 +}
  37.715 +
  37.716 +void CExtensionManager::AddRawDependency(IExtension *ext, IdentityToken_t *other, void *iface)
  37.717 +{
  37.718 +	CExtension *pExt = (CExtension *)ext;
  37.719 +	CExtension *pOwner = GetExtensionFromIdent(other);
  37.720 +
  37.721 +	IfaceInfo info;
  37.722 +
  37.723 +	info.iface = (SMInterface *)iface;
  37.724 +	info.owner = pOwner;
  37.725 +
  37.726 +	pExt->AddDependency(&info);
  37.727 +	pOwner->AddChildDependent(pExt, (SMInterface *)iface);
  37.728 +}
  37.729 +
  37.730 +void CExtensionManager::AddInterface(IExtension *pOwner, SMInterface *pInterface)
  37.731 +{
  37.732 +	CExtension *pExt = (CExtension *)pOwner;
  37.733 +
  37.734 +	pExt->AddInterface(pInterface);
  37.735 +}
  37.736 +
  37.737 +void CExtensionManager::BindChildPlugin(IExtension *pParent, SMPlugin *pPlugin)
  37.738 +{
  37.739 +	CExtension *pExt = (CExtension *)pParent;
  37.740 +
  37.741 +	pExt->AddPlugin(static_cast<CPlugin *>(pPlugin));
  37.742 +}
  37.743 +
  37.744 +void CExtensionManager::OnPluginDestroyed(IPlugin *plugin)
  37.745 +{
  37.746 +	List<CExtension *>::iterator iter;
  37.747 +
  37.748 +	for (iter=m_Libs.begin(); iter!=m_Libs.end(); iter++)
  37.749 +	{
  37.750 +		(*iter)->DropRefsTo(static_cast<CPlugin *>(plugin));
  37.751 +	}
  37.752 +}
  37.753 +
  37.754 +CExtension *CExtensionManager::FindByOrder(unsigned int num)
  37.755 +{
  37.756 +	if (num < 1 || num > m_Libs.size())
  37.757 +	{
  37.758 +		return NULL;
  37.759 +	}
  37.760 +
  37.761 +	List<CExtension *>::iterator iter = m_Libs.begin();
  37.762 +
  37.763 +	while (iter != m_Libs.end())
  37.764 +	{
  37.765 +		if (--num == 0)
  37.766 +		{
  37.767 +			return (*iter);
  37.768 +		}
  37.769 +		iter++;
  37.770 +	}
  37.771 +
  37.772 +	return NULL;
  37.773 +}
  37.774 +
  37.775 +bool CExtensionManager::UnloadExtension(IExtension *_pExt)
  37.776 +{
  37.777 +	if (!_pExt)
  37.778 +	{
  37.779 +		return false;
  37.780 +	}
  37.781 +
  37.782 +	CExtension *pExt = (CExtension *)_pExt;
  37.783 +
  37.784 +	if (m_Libs.find(pExt) == m_Libs.end())
  37.785 +	{
  37.786 +		return false;
  37.787 +	}
  37.788 +
  37.789 +	/* Tell it to unload */
  37.790 +	if (pExt->IsLoaded())
  37.791 +	{
  37.792 +		IExtensionInterface *pAPI = pExt->GetAPI();
  37.793 +		pAPI->OnExtensionUnload();
  37.794 +	}
  37.795 +
  37.796 +	/* First remove us from internal lists */
  37.797 +	g_ShareSys.RemoveInterfaces(_pExt);
  37.798 +	m_Libs.remove(pExt);
  37.799 +
  37.800 +	List<CExtension *> UnloadQueue;
  37.801 +
  37.802 +	/* Handle dependencies */
  37.803 +	if (pExt->IsLoaded())
  37.804 +	{
  37.805 +		/* Unload any dependent plugins */
  37.806 +		List<CPlugin *>::iterator p_iter = pExt->m_Dependents.begin();
  37.807 +		while (p_iter != pExt->m_Dependents.end())
  37.808 +		{
  37.809 +			/* We have to manually unlink ourselves here, since we're no longer being managed */
  37.810 +			scripts->UnloadPlugin((*p_iter));
  37.811 +			p_iter = pExt->m_Dependents.erase(p_iter);
  37.812 +		}
  37.813 +
  37.814 +		List<String>::iterator s_iter;
  37.815 +		for (s_iter = pExt->m_Libraries.begin();
  37.816 +			 s_iter != pExt->m_Libraries.end();
  37.817 +			 s_iter++)
  37.818 +		{
  37.819 +			scripts->OnLibraryAction((*s_iter).c_str(), LibraryAction_Removed);
  37.820 +		}
  37.821 +
  37.822 +		/* Notify and/or unload all dependencies */
  37.823 +		List<CExtension *>::iterator c_iter;
  37.824 +		CExtension *pDep;
  37.825 +		IExtensionInterface *pAPI;
  37.826 +		for (c_iter = m_Libs.begin(); c_iter != m_Libs.end(); c_iter++)
  37.827 +		{
  37.828 +			pDep = (*c_iter);
  37.829 +			if ((pAPI=pDep->GetAPI()) == NULL)
  37.830 +			{
  37.831 +				continue;
  37.832 +			}
  37.833 +			if (pDep == pExt)
  37.834 +			{
  37.835 +				continue;
  37.836 +			}
  37.837 +			/* Now, get its dependency list */
  37.838 +			bool dropped = false;
  37.839 +			List<IfaceInfo>::iterator i_iter = pDep->m_Deps.begin();
  37.840 +			while (i_iter != pDep->m_Deps.end())
  37.841 +			{
  37.842 +				if ((*i_iter).owner == _pExt)
  37.843 +				{
  37.844 +					if (!pAPI->QueryInterfaceDrop((*i_iter).iface))
  37.845 +					{
  37.846 +						if (!dropped)
  37.847 +						{
  37.848 +							dropped = true;
  37.849 +							UnloadQueue.push_back(pDep);
  37.850 +						}
  37.851 +					}
  37.852 +					pAPI->NotifyInterfaceDrop((*i_iter).iface);
  37.853 +					i_iter = pDep->m_Deps.erase(i_iter);
  37.854 +				}
  37.855 +				else
  37.856 +				{
  37.857 +					i_iter++;
  37.858 +				}
  37.859 +			}
  37.860 +			/* Flush out any back references to this plugin */
  37.861 +			i_iter = pDep->m_ChildDeps.begin();
  37.862 +			while (i_iter != pDep->m_ChildDeps.end())
  37.863 +			{
  37.864 +				if ((*i_iter).owner == pExt)
  37.865 +				{
  37.866 +					i_iter = pDep->m_ChildDeps.erase(i_iter);
  37.867 +				}
  37.868 +				else
  37.869 +				{
  37.870 +					i_iter++;
  37.871 +				}
  37.872 +			}
  37.873 +		}
  37.874 +
  37.875 +		/* Unbind our natives from Core */
  37.876 +		pExt->DropEverything();
  37.877 +	}
  37.878 +
  37.879 +	IdentityToken_t *pIdentity;
  37.880 +	if ((pIdentity = pExt->GetIdentity()) != NULL)
  37.881 +	{
  37.882 +		SMGlobalClass *glob = SMGlobalClass::head;
  37.883 +		while (glob)
  37.884 +		{
  37.885 +			glob->OnSourceModIdentityDropped(pIdentity);
  37.886 +			glob = glob->m_pGlobalClassNext;
  37.887 +		}
  37.888 +	}
  37.889 +
  37.890 +	pExt->Unload();
  37.891 +	delete pExt;
  37.892 +
  37.893 +	List<CExtension *>::iterator iter;
  37.894 +	for (iter=UnloadQueue.begin(); iter!=UnloadQueue.end(); iter++)
  37.895 +	{
  37.896 +		/* NOTE: This is safe because the unload function backs out of anything not present */
  37.897 +		UnloadExtension((*iter));
  37.898 +	}
  37.899 +
  37.900 +	return true;
  37.901 +}
  37.902 +
  37.903 +void CExtensionManager::MarkAllLoaded()
  37.904 +{
  37.905 +	List<CExtension *>::iterator iter;
  37.906 +	CExtension *pExt;
  37.907 +
  37.908 +	for (iter=m_Libs.begin(); iter!=m_Libs.end(); iter++)
  37.909 +	{
  37.910 +		pExt = (*iter);
  37.911 +		if (!pExt->IsLoaded())
  37.912 +		{
  37.913 +			continue;
  37.914 +		}
  37.915 +		if (pExt->m_bFullyLoaded)
  37.916 +		{
  37.917 +			continue;
  37.918 +		}
  37.919 +		pExt->MarkAllLoaded();
  37.920 +	}
  37.921 +}
  37.922 +
  37.923 +void CExtensionManager::AddDependency(IExtension *pSource, const char *file, bool required, bool autoload)
  37.924 +{
  37.925 +	/* This function doesn't really need to do anything now.  We make sure the 
  37.926 +	 * other extension is loaded, but handling of dependencies is really done 
  37.927 +	 * by the interface fetcher.
  37.928 +	 */
  37.929 +	if (required || autoload)
  37.930 +	{
  37.931 +		LoadAutoExtension(file);
  37.932 +	}
  37.933 +}
  37.934 +
  37.935 +void CExtensionManager::OnRootConsoleCommand(const char *cmdname, const CCommand &command)
  37.936 +{
  37.937 +	int argcount = smcore.Argc(command);
  37.938 +	if (argcount >= 3)
  37.939 +	{
  37.940 +		const char *cmd = smcore.Arg(command, 2);
  37.941 +		if (strcmp(cmd, "list") == 0)
  37.942 +		{
  37.943 +			List<CExtension *>::iterator iter;
  37.944 +			CExtension *pExt;
  37.945 +			unsigned int num = 1;
  37.946 +			switch (m_Libs.size())
  37.947 +			{
  37.948 +			case 1:
  37.949 +				{
  37.950 +					rootmenu->ConsolePrint("[SM] Displaying 1 extension:");
  37.951 +					break;
  37.952 +				}
  37.953 +			case 0:
  37.954 +				{
  37.955 +					rootmenu->ConsolePrint("[SM] No extensions are loaded.");
  37.956 +					break;
  37.957 +				}
  37.958 +			default:
  37.959 +				{
  37.960 +					rootmenu->ConsolePrint("[SM] Displaying %d extensions:", m_Libs.size());
  37.961 +					break;
  37.962 +				}
  37.963 +			}
  37.964 +			for (iter=m_Libs.begin(); iter!=m_Libs.end(); iter++,num++)
  37.965 +			{
  37.966 +				pExt = (*iter);
  37.967 +				if (pExt->IsLoaded())
  37.968 +				{
  37.969 +					char error[255];
  37.970 +					if (!pExt->IsRunning(error, sizeof(error)))
  37.971 +					{
  37.972 +						rootmenu->ConsolePrint("[%02d] <FAILED> file \"%s\": %s", num, pExt->GetFilename(), error);
  37.973 +					}
  37.974 +					else
  37.975 +					{
  37.976 +						IExtensionInterface *pAPI = pExt->GetAPI();
  37.977 +						const char *name = pAPI->GetExtensionName();
  37.978 +						const char *version = pAPI->GetExtensionVerString();
  37.979 +						const char *descr = pAPI->GetExtensionDescription();
  37.980 +						rootmenu->ConsolePrint("[%02d] %s (%s): %s", num, name, version, descr);
  37.981 +					}
  37.982 +				} else {
  37.983 +					rootmenu->ConsolePrint("[%02d] <FAILED> file \"%s\": %s", num, pExt->GetFilename(), pExt->m_Error.c_str());
  37.984 +				}
  37.985 +			}
  37.986 +			return;
  37.987 +		}
  37.988 +		else if (strcmp(cmd, "load") == 0)
  37.989 +		{
  37.990 +			if (argcount < 4)
  37.991 +			{
  37.992 +				rootmenu->ConsolePrint("[SM] Usage: sm exts load <file>");
  37.993 +				return;
  37.994 +			}
  37.995 +
  37.996 +			const char *filename = smcore.Arg(command, 3);
  37.997 +			char path[PLATFORM_MAX_PATH];
  37.998 +			char error[256];
  37.999 +
 37.1000 +			smcore.Format(path, sizeof(path), "%s%s%s", filename, !strstr(filename, ".ext") ? ".ext" : "",
 37.1001 +				!strstr(filename, "." PLATFORM_LIB_EXT) ? "." PLATFORM_LIB_EXT : "");
 37.1002 +			
 37.1003 +			if (FindExtensionByFile(path) != NULL)
 37.1004 +			{
 37.1005 +				rootmenu->ConsolePrint("[SM] Extension %s is already loaded.", path);
 37.1006 +				return;
 37.1007 +			}
 37.1008 +			
 37.1009 +			if (LoadExtension(path, error, sizeof(error)))
 37.1010 +			{
 37.1011 +				rootmenu->ConsolePrint("[SM] Loaded extension %s successfully.", path);
 37.1012 +			} else
 37.1013 +			{
 37.1014 +				rootmenu->ConsolePrint("[SM] Extension %s failed to load: %s", path, error);
 37.1015 +			}
 37.1016 +			
 37.1017 +			return;
 37.1018 +		}
 37.1019 +		else if (strcmp(cmd, "info") == 0)
 37.1020 +		{
 37.1021 +			if (argcount < 4)
 37.1022 +			{
 37.1023 +				rootmenu->ConsolePrint("[SM] Usage: sm exts info <#>");
 37.1024 +				return;
 37.1025 +			}
 37.1026 +
 37.1027 +			const char *sId = smcore.Arg(command, 3);
 37.1028 +			unsigned int id = atoi(sId);
 37.1029 +			if (id <= 0)
 37.1030 +			{
 37.1031 +				rootmenu->ConsolePrint("[SM] Usage: sm exts info <#>");
 37.1032 +				return;
 37.1033 +			}
 37.1034 +
 37.1035 +			if (m_Libs.size() == 0)
 37.1036 +			{
 37.1037 +				rootmenu->ConsolePrint("[SM] No extensions are loaded.");
 37.1038 +				return;
 37.1039 +			}
 37.1040 +
 37.1041 +			if (id > m_Libs.size())
 37.1042 +			{
 37.1043 +				rootmenu->ConsolePrint("[SM] No extension was found with id %d.", id);
 37.1044 +				return;
 37.1045 +			}
 37.1046 +
 37.1047 +			List<CExtension *>::iterator iter = m_Libs.begin();
 37.1048 +			CExtension *pExt = NULL;
 37.1049 +			while (iter != m_Libs.end())
 37.1050 +			{
 37.1051 +				if (--id == 0)
 37.1052 +				{
 37.1053 +					pExt = (*iter);
 37.1054 +					break;
 37.1055 +				}
 37.1056 +				iter++;
 37.1057 +			}
 37.1058 +			/* This should never happen */
 37.1059 +			if (!pExt)
 37.1060 +			{
 37.1061 +				rootmenu->ConsolePrint("[SM] No extension was found with id %d.", id);
 37.1062 +				return;
 37.1063 +			}
 37.1064 +
 37.1065 +			if (!pExt->IsLoaded())
 37.1066 +			{
 37.1067 +				rootmenu->ConsolePrint(" File: %s", pExt->GetFilename());
 37.1068 +				rootmenu->ConsolePrint(" Loaded: No (%s)", pExt->m_Error.c_str());
 37.1069 +			}
 37.1070 +			else
 37.1071 +			{
 37.1072 +				char error[255];
 37.1073 +				if (!pExt->IsRunning(error, sizeof(error)))
 37.1074 +				{
 37.1075 +					rootmenu->ConsolePrint(" File: %s", pExt->GetFilename());
 37.1076 +					rootmenu->ConsolePrint(" Loaded: Yes");
 37.1077 +					rootmenu->ConsolePrint(" Running: No (%s)", error);
 37.1078 +				}
 37.1079 +				else
 37.1080 +				{
 37.1081 +					IExtensionInterface *pAPI = pExt->GetAPI();
 37.1082 +					rootmenu->ConsolePrint(" File: %s", pExt->GetFilename());
 37.1083 +					rootmenu->ConsolePrint(" Loaded: Yes (version %s)", pAPI->GetExtensionVerString());
 37.1084 +					rootmenu->ConsolePrint(" Name: %s (%s)", pAPI->GetExtensionName(), pAPI->GetExtensionDescription());
 37.1085 +					rootmenu->ConsolePrint(" Author: %s (%s)", pAPI->GetExtensionAuthor(), pAPI->GetExtensionURL());
 37.1086 +					rootmenu->ConsolePrint(" Binary info: API version %d (compiled %s)", pAPI->GetExtensionVersion(), pAPI->GetExtensionDateString());
 37.1087 +
 37.1088 +					if (pExt->IsExternal())
 37.1089 +					{
 37.1090 +						rootmenu->ConsolePrint(" Method: Loaded by Metamod:Source, attached to SourceMod");
 37.1091 +					}
 37.1092 +					else if (pAPI->IsMetamodExtension())
 37.1093 +					{
 37.1094 +						rootmenu->ConsolePrint(" Method: Loaded by SourceMod, attached to Metamod:Source");
 37.1095 +					}
 37.1096 +					else
 37.1097 +					{
 37.1098 +						rootmenu->ConsolePrint(" Method: Loaded by SourceMod");
 37.1099 +					}
 37.1100 +				}
 37.1101 +			}
 37.1102 +			return;
 37.1103 +		}
 37.1104 +		else if (strcmp(cmd, "unload") == 0)
 37.1105 +		{
 37.1106 +			if (argcount < 4)
 37.1107 +			{
 37.1108 +				rootmenu->ConsolePrint("[SM] Usage: sm exts unload <#> [code]");
 37.1109 +				return;
 37.1110 +			}
 37.1111 +
 37.1112 +			const char *arg = smcore.Arg(command, 3);
 37.1113 +			unsigned int num = atoi(arg);
 37.1114 +			CExtension *pExt = FindByOrder(num);
 37.1115 +
 37.1116 +			if (!pExt)
 37.1117 +			{
 37.1118 +				rootmenu->ConsolePrint("[SM] Extension number %d was not found.", num);
 37.1119 +				return;
 37.1120 +			}
 37.1121 +
 37.1122 +			if (argcount > 4 && pExt->unload_code)
 37.1123 +			{
 37.1124 +				const char *unload = smcore.Arg(command, 4);
 37.1125 +				if (pExt->unload_code == (unsigned)atoi(unload))
 37.1126 +				{
 37.1127 +					char filename[PLATFORM_MAX_PATH];
 37.1128 +					snprintf(filename, PLATFORM_MAX_PATH, "%s", pExt->GetFilename());
 37.1129 +					UnloadExtension(pExt);
 37.1130 +					rootmenu->ConsolePrint("[SM] Extension %s is now unloaded.", filename);
 37.1131 +				}
 37.1132 +				else
 37.1133 +				{
 37.1134 +					rootmenu->ConsolePrint("[SM] Please try again, the correct unload code is \"%d\"", pExt->unload_code);
 37.1135 +				}
 37.1136 +				return;
 37.1137 +			}
 37.1138 +
 37.1139 +			if (!pExt->IsLoaded() 
 37.1140 +				|| (!pExt->m_ChildDeps.size() && !pExt->m_Dependents.size()))
 37.1141 +			{
 37.1142 +				char filename[PLATFORM_MAX_PATH];
 37.1143 +				snprintf(filename, PLATFORM_MAX_PATH, "%s", pExt->GetFilename());
 37.1144 +				UnloadExtension(pExt);
 37.1145 +				rootmenu->ConsolePrint("[SM] Extension %s is now unloaded.", filename);
 37.1146 +				return;
 37.1147 +			}
 37.1148 +			else
 37.1149 +			{
 37.1150 +				List<CPlugin *> plugins;
 37.1151 +				if (pExt->m_ChildDeps.size())
 37.1152 +				{
 37.1153 +					rootmenu->ConsolePrint("[SM] Unloading %s will unload the following extensions: ", pExt->GetFilename());
 37.1154 +					List<CExtension *>::iterator iter;
 37.1155 +					CExtension *pOther;
 37.1156 +					/* Get list of all extensions */
 37.1157 +					for (iter=m_Libs.begin(); iter!=m_Libs.end(); iter++)
 37.1158 +					{
 37.1159 +						List<IfaceInfo>::iterator i_iter;
 37.1160 +						pOther = (*iter);
 37.1161 +						if (!pOther->IsLoaded() || pOther == pExt)
 37.1162 +						{
 37.1163 +							continue;
 37.1164 +						}
 37.1165 +						/* Get their dependencies */
 37.1166 +						for (i_iter=pOther->m_Deps.begin();
 37.1167 +							 i_iter!=pOther->m_Deps.end();
 37.1168 +							 i_iter++)
 37.1169 +						{
 37.1170 +							/* Is this dependency to us? */
 37.1171 +							if ((*i_iter).owner != pExt)
 37.1172 +							{
 37.1173 +								continue;
 37.1174 +							}
 37.1175 +							/* Will our dependent care? */
 37.1176 +							if (!pExt->GetAPI()->QueryInterfaceDrop((*i_iter).iface))
 37.1177 +							{
 37.1178 +								rootmenu->ConsolePrint(" -> %s", pExt->GetFilename());
 37.1179 +								/* Add to plugin unload list */
 37.1180 +								List<CPlugin *>::iterator p_iter;
 37.1181 +								for (p_iter=pOther->m_Dependents.begin();
 37.1182 +									 p_iter!=pOther->m_Dependents.end();
 37.1183 +									 p_iter++)
 37.1184 +								{
 37.1185 +									if (plugins.find((*p_iter)) == plugins.end())
 37.1186 +									{
 37.1187 +										plugins.push_back((*p_iter));
 37.1188 +									}
 37.1189 +								}
 37.1190 +							}
 37.1191 +						}
 37.1192 +					}
 37.1193 +				}
 37.1194 +				if (pExt->m_Dependents.size())
 37.1195 +				{
 37.1196 +					rootmenu->ConsolePrint("[SM] Unloading %s will unload the following plugins: ", pExt->GetFilename());
 37.1197 +					List<CPlugin *>::iterator iter;
 37.1198 +					CPlugin *pPlugin;
 37.1199 +					for (iter = pExt->m_Dependents.begin(); iter != pExt->m_Dependents.end(); iter++)
 37.1200 +					{
 37.1201 +						pPlugin = (*iter);
 37.1202 +						if (plugins.find(pPlugin) == plugins.end())
 37.1203 +						{
 37.1204 +							plugins.push_back(pPlugin);
 37.1205 +						}
 37.1206 +					}
 37.1207 +					for (iter = plugins.begin(); iter != plugins.end(); iter++)
 37.1208 +					{
 37.1209 +						pPlugin = (*iter);
 37.1210 +						rootmenu->ConsolePrint(" -> %s", pPlugin->GetFilename());
 37.1211 +					}
 37.1212 +				}
 37.1213 +				srand(static_cast<int>(time(NULL)));
 37.1214 +				pExt->unload_code = (rand() % 877) + 123;	//123 to 999
 37.1215 +				rootmenu->ConsolePrint("[SM] To verify unloading %s, please use the following: ", pExt->GetFilename());
 37.1216 +				rootmenu->ConsolePrint("[SM] sm exts unload %d %d", num, pExt->unload_code);
 37.1217 +
 37.1218 +				return;
 37.1219 +			}
 37.1220 +		}
 37.1221 +		else if (strcmp(cmd, "reload") == 0)
 37.1222 +		{
 37.1223 +			if (argcount < 4)
 37.1224 +			{
 37.1225 +				rootmenu->ConsolePrint("[SM] Usage: sm exts reload <#>");
 37.1226 +				return;
 37.1227 +			}
 37.1228 +			
 37.1229 +			const char *arg = smcore.Arg(command, 3);
 37.1230 +			unsigned int num = atoi(arg);
 37.1231 +			CExtension *pExt = FindByOrder(num);
 37.1232 +
 37.1233 +			if (!pExt)
 37.1234 +			{
 37.1235 +				rootmenu->ConsolePrint("[SM] Extension number %d was not found.", num);
 37.1236 +				return;
 37.1237 +			}
 37.1238 +			
 37.1239 +			if (pExt->IsLoaded())
 37.1240 +			{
 37.1241 +				char filename[PLATFORM_MAX_PATH];
 37.1242 +				char error[255];
 37.1243 +				
 37.1244 +				snprintf(filename, PLATFORM_MAX_PATH, "%s", pExt->GetFilename());
 37.1245 +				
 37.1246 +				if (pExt->Reload(error, sizeof(error)))
 37.1247 +				{
 37.1248 +					rootmenu->ConsolePrint("[SM] Extension %s is now reloaded.", filename);
 37.1249 +				}
 37.1250 +				else
 37.1251 +				{
 37.1252 +					rootmenu->ConsolePrint("[SM] Extension %s failed to reload: %s", filename, error);
 37.1253 +				}
 37.1254 +					
 37.1255 +				return;
 37.1256 +			} 
 37.1257 +			else
 37.1258 +			{
 37.1259 +				rootmenu->ConsolePrint("[SM] Extension %s is not loaded.", pExt->GetFilename());
 37.1260 +				
 37.1261 +				return;
 37.1262 +			}
 37.1263 +			
 37.1264 +		}
 37.1265 +	}
 37.1266 +
 37.1267 +	rootmenu->ConsolePrint("SourceMod Extensions Menu:");
 37.1268 +	rootmenu->DrawGenericOption("info", "Extra extension information");
 37.1269 +	rootmenu->DrawGenericOption("list", "List extensions");
 37.1270 +	rootmenu->DrawGenericOption("load", "Load an extension");
 37.1271 +	rootmenu->DrawGenericOption("reload", "Reload an extension");
 37.1272 +	rootmenu->DrawGenericOption("unload", "Unload an extension");
 37.1273 +}
 37.1274 +
 37.1275 +CExtension *CExtensionManager::GetExtensionFromIdent(IdentityToken_t *ptr)
 37.1276 +{
 37.1277 +	if (ptr->type == g_ExtType)
 37.1278 +	{
 37.1279 +		return (CExtension *)(ptr->ptr);
 37.1280 +	}
 37.1281 +
 37.1282 +	return NULL;
 37.1283 +}
 37.1284 +
 37.1285 +CExtensionManager::CExtensionManager()
 37.1286 +{
 37.1287 +}
 37.1288 +
 37.1289 +CExtensionManager::~CExtensionManager()
 37.1290 +{
 37.1291 +}
 37.1292 +
 37.1293 +void CExtensionManager::AddLibrary(IExtension *pSource, const char *library)
 37.1294 +{
 37.1295 +	CExtension *pExt = (CExtension *)pSource;
 37.1296 +	pExt->AddLibrary(library);
 37.1297 +	scripts->OnLibraryAction(library, LibraryAction_Added);
 37.1298 +}
 37.1299 +
 37.1300 +bool CExtensionManager::LibraryExists(const char *library)
 37.1301 +{
 37.1302 +	CExtension *pExt;
 37.1303 +
 37.1304 +	for (List<CExtension *>::iterator iter = m_Libs.begin();
 37.1305 +		 iter != m_Libs.end();
 37.1306 +		 iter++)
 37.1307 +	{
 37.1308 +		pExt = (*iter);
 37.1309 +		for (List<String>::iterator s_iter = pExt->m_Libraries.begin();
 37.1310 +			 s_iter != pExt->m_Libraries.end();
 37.1311 +			 s_iter++)
 37.1312 +		{
 37.1313 +			if ((*s_iter).compare(library) == 0)
 37.1314 +			{
 37.1315 +				return true;
 37.1316 +			}
 37.1317 +		}
 37.1318 +	}
 37.1319 +
 37.1320 +	return false;
 37.1321 +}
 37.1322 +
 37.1323 +IExtension *CExtensionManager::LoadExternal(IExtensionInterface *pInterface,
 37.1324 +											const char *filepath,
 37.1325 +											const char *filename,
 37.1326 +											char *error,
 37.1327 +											size_t maxlength)
 37.1328 +{
 37.1329 +	IExtension *pAlready;
 37.1330 +	if ((pAlready=FindExtensionByFile(filename)) != NULL)
 37.1331 +	{
 37.1332 +		return pAlready;
 37.1333 +	}
 37.1334 +
 37.1335 +	CExtension *pExt = new CRemoteExtension(pInterface, filename, filepath);
 37.1336 +
 37.1337 +	if (!pExt->Load(error, maxlength) || !pExt->IsLoaded())
 37.1338 +	{
 37.1339 +		pExt->Unload();
 37.1340 +		delete pExt;
 37.1341 +		return NULL;
 37.1342 +	}
 37.1343 +
 37.1344 +	m_Libs.push_back(pExt);
 37.1345 +
 37.1346 +	return pExt;
 37.1347 +}
 37.1348 +
 37.1349 +void CExtensionManager::CallOnCoreMapStart(edict_t *pEdictList, int edictCount, int clientMax)
 37.1350 +{
 37.1351 +	IExtensionInterface *pAPI;
 37.1352 +	List<CExtension *>::iterator iter;
 37.1353 +
 37.1354 +	for (iter=m_Libs.begin(); iter!=m_Libs.end(); iter++)
 37.1355 +	{
 37.1356 +		if ((pAPI = (*iter)->GetAPI()) == NULL)
 37.1357 +		{
 37.1358 +			continue;
 37.1359 +		}
 37.1360 +		if (pAPI->GetExtensionVersion() > 3)
 37.1361 +		{
 37.1362 +			pAPI->OnCoreMapStart(pEdictList, edictCount, clientMax);
 37.1363 +		}
 37.1364 +	}
 37.1365 +}
 37.1366 +
 37.1367 +void CExtensionManager::ListExtensions(CVector<IExtension *> *list)
 37.1368 +{
 37.1369 +	for (List<CExtension *>::iterator iter = m_Libs.begin(); iter != m_Libs.end(); iter++)
 37.1370 +	{
 37.1371 +		list->push_back(*iter);
 37.1372 +	}
 37.1373 +}
 37.1374 +
 37.1375 +bool CLocalExtension::IsSameFile(const char *file)
 37.1376 +{
 37.1377 +	/* Only care about the shortened name. */
 37.1378 +	return strcmp(file, m_File.c_str()) == 0;
 37.1379 +}
 37.1380 +
 37.1381 +bool CRemoteExtension::IsSameFile(const char *file)
 37.1382 +{
 37.1383 +	/* :TODO: this could be better, but no one uses this API anyway. */
 37.1384 +	return strcmp(file, m_Path.c_str()) == 0;
 37.1385 +}
 37.1386 +
    38.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    38.2 +++ b/core/logic/ExtensionSys.h	Fri Mar 29 11:37:29 2013 -0700
    38.3 @@ -0,0 +1,194 @@
    38.4 +/**
    38.5 + * vim: set ts=4 :
    38.6 + * =============================================================================
    38.7 + * SourceMod
    38.8 + * Copyright (C) 2004-2008 AlliedModders LLC.  All rights reserved.
    38.9 + * =============================================================================
   38.10 + *
   38.11 + * This program is free software; you can redistribute it and/or modify it under
   38.12 + * the terms of the GNU General Public License, version 3.0, as published by the
   38.13 + * Free Software Foundation.
   38.14 + * 
   38.15 + * This program is distributed in the hope that it will be useful, but WITHOUT
   38.16 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   38.17 + * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
   38.18 + * details.
   38.19 + *
   38.20 + * You should have received a copy of the GNU General Public License along with
   38.21 + * this program.  If not, see <http://www.gnu.org/licenses/>.
   38.22 + *
   38.23 + * As a special exception, AlliedModders LLC gives you permission to link the
   38.24 + * code of this program (as well as its derivative works) to "Half-Life 2," the
   38.25 + * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
   38.26 + * by the Valve Corporation.  You must obey the GNU General Public License in
   38.27 + * all respects for all other code used.  Additionally, AlliedModders LLC grants
   38.28 + * this exception to all derivative works.  AlliedModders LLC defines further
   38.29 + * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
   38.30 + * or <http://www.sourcemod.net/license.php>.
   38.31 + *
   38.32 + * Version: $Id$
   38.33 + */
   38.34 +
   38.35 +#ifndef _INCLUDE_SOURCEMOD_EXTENSION_SYSTEM_H_
   38.36 +#define _INCLUDE_SOURCEMOD_EXTENSION_SYSTEM_H_
   38.37 +
   38.38 +#include <IExtensionSys.h>
   38.39 +#include <ILibrarySys.h>
   38.40 +#include <sh_list.h>
   38.41 +#include <sh_string.h>
   38.42 +#include <sm_trie_tpl.h>
   38.43 +#include "common_logic.h"
   38.44 +#include <IPluginSys.h>
   38.45 +#include <IRootConsoleMenu.h>
   38.46 +#include "NativeOwner.h"
   38.47 +#include "ShareSys.h"
   38.48 +
   38.49 +class CPlayer;
   38.50 +
   38.51 +using namespace SourceMod;
   38.52 +using namespace SourceHook;
   38.53 +
   38.54 +class CExtension;
   38.55 +
   38.56 +struct sm_extnative_t
   38.57 +{
   38.58 +	CExtension *owner;
   38.59 +	const sp_nativeinfo_t *info;
   38.60 +};
   38.61 +
   38.62 +class CExtension : 
   38.63 +	public IExtension,
   38.64 +	public CNativeOwner
   38.65 +{
   38.66 +	friend class CExtensionManager;
   38.67 +public:
   38.68 +	virtual ~CExtension();
   38.69 +public: //IExtension
   38.70 +	IExtensionInterface *GetAPI();
   38.71 +	const char *GetFilename();
   38.72 +	const char *GetPath() const;
   38.73 +	IdentityToken_t *GetIdentity();
   38.74 +	ITERATOR *FindFirstDependency(IExtension **pOwner, SMInterface **pInterface);
   38.75 +	bool FindNextDependency(ITERATOR *iter, IExtension **pOwner, SMInterface **pInterface);
   38.76 +	void FreeDependencyIterator(ITERATOR *iter);
   38.77 +	bool IsRunning(char *error, size_t maxlength);
   38.78 +public:
   38.79 +	void SetError(const char *error);
   38.80 +	void AddDependency(const IfaceInfo *pInfo);
   38.81 +	void AddChildDependent(CExtension *pOther, SMInterface *iface);
   38.82 +	void AddInterface(SMInterface *pInterface);
   38.83 +	void AddPlugin(CPlugin *pPlugin);
   38.84 +	void MarkAllLoaded();
   38.85 +	void AddLibrary(const char *library);
   38.86 +public:
   38.87 +	virtual bool Load(char *error, size_t maxlength);
   38.88 +	virtual bool IsLoaded() =0;
   38.89 +	virtual void Unload() =0;
   38.90 +	virtual bool Reload(char *error, size_t maxlength) =0;
   38.91 +	virtual bool IsSameFile(const char* file) =0;
   38.92 +protected:
   38.93 +	void Initialize(const char *filename, const char *path);
   38.94 +	bool PerformAPICheck(char *error, size_t maxlength);
   38.95 +	void CreateIdentity();
   38.96 +	void DestroyIdentity();
   38.97 +protected:
   38.98 +	IdentityToken_t *m_pIdentToken;
   38.99 +	IExtensionInterface *m_pAPI;
  38.100 +	String m_File;
  38.101 +	String m_RealFile;
  38.102 +	String m_Path;
  38.103 +	String m_Error;
  38.104 +	List<IfaceInfo> m_Deps;			/** Dependencies */
  38.105 +	List<IfaceInfo> m_ChildDeps;	/** Children who might depend on us */
  38.106 +	List<SMInterface *> m_Interfaces;
  38.107 +	List<String> m_Libraries;
  38.108 +	unsigned int unload_code;
  38.109 +	bool m_bFullyLoaded;
  38.110 +};
  38.111 +
  38.112 +class CLocalExtension : public CExtension
  38.113 +{
  38.114 +public:
  38.115 +	CLocalExtension(const char *filename);
  38.116 +public:
  38.117 +	bool Load(char *error, size_t maxlength);
  38.118 +	bool IsLoaded();
  38.119 +	void Unload();
  38.120 +	bool Reload(char *error, size_t maxlength);
  38.121 +	bool IsExternal();
  38.122 +	bool IsSameFile(const char *file);
  38.123 +private:
  38.124 +	int m_PlId;
  38.125 +	ILibrary *m_pLib;
  38.126 +};
  38.127 +
  38.128 +class CRemoteExtension : public CExtension
  38.129 +{
  38.130 +public:
  38.131 +	CRemoteExtension(IExtensionInterface *pAPI, const char *filename, const char *path);
  38.132 +public:
  38.133 +	bool Load(char *error, size_t maxlength);
  38.134 +	bool IsLoaded();
  38.135 +	void Unload();
  38.136 +	bool Reload(char *error, size_t maxlength);
  38.137 +	bool IsExternal();
  38.138 +	bool IsSameFile(const char *file);
  38.139 +};
  38.140 +
  38.141 +class CExtensionManager : 
  38.142 +	public IExtensionSys,
  38.143 +	public SMGlobalClass,
  38.144 +	public IPluginsListener
  38.145 +{
  38.146 +public:
  38.147 +	CExtensionManager();
  38.148 +	~CExtensionManager();
  38.149 +public: //SMGlobalClass
  38.150 +	void OnSourceModAllInitialized();
  38.151 +	void OnSourceModShutdown();
  38.152 +public: //IExtensionManager
  38.153 +	IExtension *LoadExtension(const char *path, 
  38.154 +		char *error,
  38.155 +		size_t maxlength);
  38.156 +	bool UnloadExtension(IExtension *pExt);
  38.157 +	IExtension *FindExtensionByFile(const char *file);
  38.158 +	IExtension *FindExtensionByName(const char *ext);
  38.159 +	IExtension *LoadExternal(IExtensionInterface *pInterface,
  38.160 +		const char *filepath,
  38.161 +		const char *filename,
  38.162 +		char *error,
  38.163 +		size_t maxlength);
  38.164 +public: //IPluginsListener
  38.165 +	void OnPluginDestroyed(IPlugin *plugin);
  38.166 +public: //IRootConsoleCommand
  38.167 +	void OnRootConsoleCommand(const char *cmdname, const CCommand &command);
  38.168 +public:
  38.169 +	IExtension *LoadAutoExtension(const char *path);
  38.170 +	void BindDependency(IExtension *pOwner, IfaceInfo *pInfo);
  38.171 +	void AddInterface(IExtension *pOwner, SMInterface *pInterface);
  38.172 +	void BindChildPlugin(IExtension *pParent, SMPlugin *pPlugin);
  38.173 +	void MarkAllLoaded();
  38.174 +	void AddDependency(IExtension *pSource, const char *file, bool required, bool autoload);
  38.175 +	void TryAutoload();
  38.176 +	void AddLibrary(IExtension *pSource, const char *library);
  38.177 +	bool LibraryExists(const char *library);
  38.178 +	void CallOnCoreMapStart(edict_t *pEdictList, int edictCount, int clientMax);
  38.179 +	void AddRawDependency(IExtension *ext, IdentityToken_t *other, void *iface);
  38.180 +	void ListExtensions(CVector<IExtension *> *list);
  38.181 +public:
  38.182 +	CExtension *GetExtensionFromIdent(IdentityToken_t *ptr);
  38.183 +	void Shutdown();
  38.184 +	CNativeOwner *GetNativeOwner(IExtension *pExt)
  38.185 +	{
  38.186 +		CExtension *p = (CExtension *)pExt;
  38.187 +		return p;
  38.188 +	}
  38.189 +private:
  38.190 +	CExtension *FindByOrder(unsigned int num);
  38.191 +private:
  38.192 +	List<CExtension *> m_Libs;
  38.193 +};
  38.194 +
  38.195 +extern CExtensionManager g_Extensions;
  38.196 +
  38.197 +#endif //_INCLUDE_SOURCEMOD_EXTENSION_SYSTEM_H_
    39.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    39.2 +++ b/core/logic/HandleSys.cpp	Fri Mar 29 11:37:29 2013 -0700
    39.3 @@ -0,0 +1,1125 @@
    39.4 +/**
    39.5 + * vim: set ts=4 :
    39.6 + * =============================================================================
    39.7 + * SourceMod
    39.8 + * Copyright (C) 2004-2008 AlliedModders LLC.  All rights reserved.
    39.9 + * =============================================================================
   39.10 + *
   39.11 + * This program is free software; you can redistribute it and/or modify it under
   39.12 + * the terms of the GNU General Public License, version 3.0, as published by the
   39.13 + * Free Software Foundation.
   39.14 + * 
   39.15 + * This program is distributed in the hope that it will be useful, but WITHOUT
   39.16 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   39.17 + * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
   39.18 + * details.
   39.19 + *
   39.20 + * You should have received a copy of the GNU General Public License along with
   39.21 + * this program.  If not, see <http://www.gnu.org/licenses/>.
   39.22 + *
   39.23 + * As a special exception, AlliedModders LLC gives you permission to link the
   39.24 + * code of this program (as well as its derivative works) to "Half-Life 2," the
   39.25 + * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
   39.26 + * by the Valve Corporation.  You must obey the GNU General Public License in
   39.27 + * all respects for all other code used.  Additionally, AlliedModders LLC grants
   39.28 + * this exception to all derivative works.  AlliedModders LLC defines further
   39.29 + * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
   39.30 + * or <http://www.sourcemod.net/license.php>.
   39.31 + *
   39.32 + * Version: $Id$
   39.33 + */
   39.34 +
   39.35 +#include "HandleSys.h"
   39.36 +#include <assert.h>
   39.37 +#include <string.h>
   39.38 +#include "common_logic.h"
   39.39 +#include "ShareSys.h"
   39.40 +#include "ExtensionSys.h"
   39.41 +
   39.42 +HandleSystem g_HandleSys;
   39.43 +
   39.44 +QHandle *ignore_handle;
   39.45 +
   39.46 +inline HandleType_t TypeParent(HandleType_t type)
   39.47 +{
   39.48 +	return (type & ~HANDLESYS_SUBTYPE_MASK);
   39.49 +}
   39.50 +
   39.51 +inline HandleError IdentityHandle(IdentityToken_t *token, unsigned int *index)
   39.52 +{
   39.53 +	return g_HandleSys.GetHandle(token->ident, g_ShareSys.GetIdentRoot(), &ignore_handle, index);
   39.54 +}
   39.55 +
   39.56 +HandleSystem::HandleSystem()
   39.57 +{
   39.58 +	m_Handles = new QHandle[HANDLESYS_MAX_HANDLES + 1];
   39.59 +	memset(m_Handles, 0, sizeof(QHandle) * (HANDLESYS_MAX_HANDLES + 1));
   39.60 +
   39.61 +	m_Types = new QHandleType[HANDLESYS_TYPEARRAY_SIZE];
   39.62 +	memset(m_Types, 0, sizeof(QHandleType) * HANDLESYS_TYPEARRAY_SIZE);
   39.63 +
   39.64 +	m_strtab = new BaseStringTable(512);
   39.65 +
   39.66 +	m_TypeTail = 0;
   39.67 +}
   39.68 +
   39.69 +HandleSystem::~HandleSystem()
   39.70 +{
   39.71 +	delete [] m_Handles;
   39.72 +	delete [] m_Types;
   39.73 +	delete m_strtab;
   39.74 +}
   39.75 +
   39.76 +
   39.77 +HandleType_t HandleSystem::CreateType(const char *name, 
   39.78 +									  IHandleTypeDispatch *dispatch, 
   39.79 +									  HandleType_t parent, 
   39.80 +									  const TypeAccess *typeAccess, 
   39.81 +									  const HandleAccess *hndlAccess, 
   39.82 +									  IdentityToken_t *ident,
   39.83 +									  HandleError *err)
   39.84 +{
   39.85 +	if (!dispatch)
   39.86 +	{
   39.87 +		if (err)
   39.88 +		{
   39.89 +			*err = HandleError_Parameter;
   39.90 +		}
   39.91 +		return 0;
   39.92 +	}
   39.93 +
   39.94 +	if (typeAccess && typeAccess->hsVersion > SMINTERFACE_HANDLESYSTEM_VERSION)
   39.95 +	{
   39.96 +		if (err)
   39.97 +		{
   39.98 +			*err = HandleError_Version;
   39.99 +		}
  39.100 +		return 0;
  39.101 +	}
  39.102 +
  39.103 +	if (hndlAccess && hndlAccess->hsVersion > SMINTERFACE_HANDLESYSTEM_VERSION)
  39.104 +	{
  39.105 +		if (err)
  39.106 +		{
  39.107 +			*err = HandleError_Version;
  39.108 +		}
  39.109 +		return 0;
  39.110 +	}
  39.111 +
  39.112 +	bool isChild = false;
  39.113 +
  39.114 +	if (parent != 0)
  39.115 +	{
  39.116 +		isChild = true;
  39.117 +		if (parent & HANDLESYS_SUBTYPE_MASK)
  39.118 +		{
  39.119 +			if (err)
  39.120 +			{
  39.121 +				*err = HandleError_NoInherit;
  39.122 +			}
  39.123 +			return 0;
  39.124 +		}
  39.125 +		if (parent >= HANDLESYS_TYPEARRAY_SIZE
  39.126 +			|| m_Types[parent].dispatch == NULL)
  39.127 +		{
  39.128 +			if (err)
  39.129 +			{
  39.130 +				*err = HandleError_Parameter;
  39.131 +			}
  39.132 +			return 0;
  39.133 +		}
  39.134 +		if (m_Types[parent].typeSec.access[HTypeAccess_Inherit] == false
  39.135 +			&& (m_Types[parent].typeSec.ident != ident))
  39.136 +		{
  39.137 +			if (err)
  39.138 +			{
  39.139 +				*err = HandleError_Access;
  39.140 +			}
  39.141 +			return 0;
  39.142 +		}
  39.143 +	}
  39.144 +
  39.145 +	if (name && name[0] != '\0')
  39.146 +	{
  39.147 +		if (m_TypeLookup.retrieve(name))
  39.148 +		{
  39.149 +			if (err)
  39.150 +			{
  39.151 +				*err = HandleError_Parameter;
  39.152 +			}
  39.153 +			return 0;
  39.154 +		}
  39.155 +	}
  39.156 +
  39.157 +	unsigned int index;
  39.158 +
  39.159 +	if (isChild)
  39.160 +	{
  39.161 +		QHandleType *pParent = &m_Types[parent];
  39.162 +		if (pParent->children >= HANDLESYS_MAX_SUBTYPES)
  39.163 +		{
  39.164 +			if (err)
  39.165 +			{
  39.166 +				*err = HandleError_Limit;
  39.167 +			}
  39.168 +			return 0;
  39.169 +		}
  39.170 +		index = 0;
  39.171 +		for (unsigned int i=1; i<=HANDLESYS_MAX_SUBTYPES; i++)
  39.172 +		{
  39.173 +			if (m_Types[parent + i].dispatch == NULL)
  39.174 +			{
  39.175 +				index = parent + i;
  39.176 +				break;
  39.177 +			}
  39.178 +		}
  39.179 +		if (!index)
  39.180 +		{
  39.181 +			if (err)
  39.182 +			{
  39.183 +				*err = HandleError_Limit;
  39.184 +			}
  39.185 +			return 0;
  39.186 +		}
  39.187 +		pParent->children++;
  39.188 +	} else {
  39.189 +		if (m_FreeTypes == 0)
  39.190 +		{
  39.191 +			/* Reserve another index */
  39.192 +			if (m_TypeTail >= HANDLESYS_TYPEARRAY_SIZE)
  39.193 +			{
  39.194 +				if (err)
  39.195 +				{
  39.196 +					*err = HandleError_Limit;
  39.197 +				}
  39.198 +				return 0;
  39.199 +			} else {
  39.200 +				m_TypeTail += (HANDLESYS_MAX_SUBTYPES + 1);
  39.201 +				index = m_TypeTail;
  39.202 +			}
  39.203 +		} else {
  39.204 +			/* The "free array" is compacted into the normal array for easiness */
  39.205 +			index = m_Types[m_FreeTypes--].freeID;
  39.206 +		}
  39.207 +	}
  39.208 +
  39.209 +	QHandleType *pType = &m_Types[index];
  39.210 +	
  39.211 +	pType->dispatch = dispatch;
  39.212 +	if (name && name[0] != '\0')
  39.213 +	{
  39.214 +		pType->nameIdx = m_strtab->AddString(name);
  39.215 +		m_TypeLookup.insert(name, pType);
  39.216 +	} else {
  39.217 +		pType->nameIdx = -1;
  39.218 +	}
  39.219 +
  39.220 +	pType->opened = 0;
  39.221 +
  39.222 +	if (typeAccess)
  39.223 +	{
  39.224 +		pType->typeSec = *typeAccess;
  39.225 +	} else {
  39.226 +		InitAccessDefaults(&pType->typeSec, NULL);
  39.227 +		pType->typeSec.ident = ident;
  39.228 +	}
  39.229 +
  39.230 +	if (hndlAccess)
  39.231 +	{
  39.232 +		pType->hndlSec = *hndlAccess;
  39.233 +	} else {
  39.234 +		InitAccessDefaults(NULL, &pType->hndlSec);
  39.235 +	}
  39.236 +
  39.237 +	if (!isChild)
  39.238 +	{
  39.239 +		pType->children = 0;
  39.240 +	}
  39.241 +
  39.242 +	return index;
  39.243 +}
  39.244 +
  39.245 +bool HandleSystem::FindHandleType(const char *name, HandleType_t *type)
  39.246 +{
  39.247 +	QHandleType **typepp = m_TypeLookup.retrieve(name);
  39.248 +
  39.249 +	if (!typepp)
  39.250 +	{
  39.251 +		return false;
  39.252 +	}
  39.253 +
  39.254 +	unsigned int offset = *typepp - m_Types;
  39.255 +
  39.256 +	if (type)
  39.257 +	{
  39.258 +		*type = offset;
  39.259 +	}
  39.260 +
  39.261 +	return true;
  39.262 +}
  39.263 +
  39.264 +HandleError HandleSystem::TryAllocHandle(unsigned int *handle)
  39.265 +{
  39.266 +	if (m_FreeHandles == 0)
  39.267 +	{
  39.268 +		if (m_HandleTail >= HANDLESYS_MAX_HANDLES)
  39.269 +		{
  39.270 +			return HandleError_Limit;;
  39.271 +		}
  39.272 +		*handle = ++m_HandleTail;
  39.273 +	}
  39.274 +	else
  39.275 +	{
  39.276 +		*handle = m_Handles[m_FreeHandles--].freeID;
  39.277 +	}
  39.278 +
  39.279 +	return HandleError_None;
  39.280 +}
  39.281 +
  39.282 +HandleError HandleSystem::MakePrimHandle(HandleType_t type, 
  39.283 +						   QHandle **in_pHandle, 
  39.284 +						   unsigned int *in_index, 
  39.285 +						   Handle_t *in_handle,
  39.286 +						   IdentityToken_t *owner,
  39.287 +						   bool identity)
  39.288 +{
  39.289 +	HandleError err;
  39.290 +	unsigned int owner_index = 0;
  39.291 +
  39.292 +	if (owner && (IdentityHandle(owner, &owner_index) != HandleError_None))
  39.293 +	{
  39.294 +		return HandleError_Identity;
  39.295 +	}
  39.296 +
  39.297 +	unsigned int handle;
  39.298 +	if ((err = TryAllocHandle(&handle)) != HandleError_None)
  39.299 +	{
  39.300 +		if (!TryAndFreeSomeHandles()
  39.301 +			|| (err = TryAllocHandle(&handle)) != HandleError_None)
  39.302 +		{
  39.303 +			return err;
  39.304 +		}
  39.305 +	}
  39.306 +
  39.307 +	QHandle *pHandle = &m_Handles[handle];
  39.308 +	
  39.309 +	assert(pHandle->set == false);
  39.310 +
  39.311 +	if (++m_HSerial >= HANDLESYS_MAX_SERIALS)
  39.312 +	{
  39.313 +		m_HSerial = 1;
  39.314 +	}
  39.315 +
  39.316 +	/* Set essential information */
  39.317 +	pHandle->set = identity ? HandleSet_Identity : HandleSet_Used;
  39.318 +	pHandle->refcount = 1;
  39.319 +	pHandle->type = type;
  39.320 +	pHandle->serial = m_HSerial;
  39.321 +	pHandle->owner = owner;
  39.322 +	pHandle->ch_next = 0;
  39.323 +	pHandle->access_special = false;
  39.324 +	pHandle->is_destroying = false;
  39.325 +
  39.326 +	/* Create the hash value */
  39.327 +	Handle_t hash = pHandle->serial;
  39.328 +	hash <<= 16;
  39.329 +	hash |= handle;
  39.330 +
  39.331 +	/* Add a reference count to the type */
  39.332 +	m_Types[type].opened++;
  39.333 +
  39.334 +	/* Output */
  39.335 +	*in_pHandle = pHandle;
  39.336 +	*in_index = handle;
  39.337 +	*in_handle = hash;
  39.338 +
  39.339 +	/* Decode the identity token 
  39.340 +	 * For now, we don't allow nested ownership
  39.341 +	 */
  39.342 +	if (owner && !identity)
  39.343 +	{
  39.344 +		QHandle *pIdentity = &m_Handles[owner_index];
  39.345 +		if (pIdentity->ch_prev == 0)
  39.346 +		{
  39.347 +			pIdentity->ch_prev = handle;
  39.348 +			pIdentity->ch_next = handle;
  39.349 +			pHandle->ch_prev = 0;
  39.350 +		}
  39.351 +		else
  39.352 +		{
  39.353 +			/* Link previous node to us (forward) */
  39.354 +			m_Handles[pIdentity->ch_next].ch_next = handle;
  39.355 +			/* Link us to previous node (backwards) */
  39.356 +			pHandle->ch_prev = pIdentity->ch_next;
  39.357 +			/* Set new tail */
  39.358 +			pIdentity->ch_next = handle;
  39.359 +		}
  39.360 +		pIdentity->refcount++;
  39.361 +	}
  39.362 +	else
  39.363 +	{
  39.364 +		pHandle->ch_prev = 0;
  39.365 +	}
  39.366 +
  39.367 +	return HandleError_None;
  39.368 +}
  39.369 +
  39.370 +void HandleSystem::SetTypeSecurityOwner(HandleType_t type, IdentityToken_t *pToken)
  39.371 +{
  39.372 +	if (!type
  39.373 +		|| type >= HANDLESYS_TYPEARRAY_SIZE
  39.374 +		|| m_Types[type].dispatch == NULL)
  39.375 +	{
  39.376 +		return;
  39.377 +	}
  39.378 +
  39.379 +	m_Types[type].typeSec.ident = pToken;
  39.380 +}
  39.381 +
  39.382 +Handle_t HandleSystem::CreateHandleInt(HandleType_t type, 
  39.383 +									   void *object, 
  39.384 +									   const HandleSecurity *pSec,
  39.385 +									   HandleError *err, 
  39.386 +									   const HandleAccess *pAccess,
  39.387 +									   bool identity)
  39.388 +{
  39.389 +	IdentityToken_t *ident;
  39.390 +	IdentityToken_t *owner;
  39.391 +
  39.392 +	if (pSec)
  39.393 +	{
  39.394 +		ident = pSec->pIdentity;
  39.395 +		owner = pSec->pOwner;
  39.396 +	} else {
  39.397 +		ident = NULL;
  39.398 +		owner = NULL;
  39.399 +	}
  39.400 +
  39.401 +	if (!type 
  39.402 +		|| type >= HANDLESYS_TYPEARRAY_SIZE
  39.403 +		|| m_Types[type].dispatch == NULL)
  39.404 +	{
  39.405 +		if (err)
  39.406 +		{
  39.407 +			*err = HandleError_Parameter;
  39.408 +		}
  39.409 +		return 0;
  39.410 +	}
  39.411 +
  39.412 +	/* Check to see if we're allowed to create this handle type */
  39.413 +	QHandleType *pType = &m_Types[type];
  39.414 +	if (!pType->typeSec.access[HTypeAccess_Create]
  39.415 +	&& (!pType->typeSec.ident
  39.416 +		|| pType->typeSec.ident != ident))
  39.417 +	{
  39.418 +		if (err)
  39.419 +		{
  39.420 +			*err = HandleError_Access;
  39.421 +		}
  39.422 +		return 0;
  39.423 +	}
  39.424 +
  39.425 +	unsigned int index;
  39.426 +	Handle_t handle;
  39.427 +	QHandle *pHandle;
  39.428 +	HandleError _err;
  39.429 +
  39.430 +	if ((_err=MakePrimHandle(type, &pHandle, &index, &handle, owner, identity)) != HandleError_None)
  39.431 +	{
  39.432 +		if (err)
  39.433 +		{
  39.434 +			*err = _err;
  39.435 +		}
  39.436 +		return 0;
  39.437 +	}
  39.438 +
  39.439 +	if (pAccess)
  39.440 +	{
  39.441 +		pHandle->access_special = true;
  39.442 +		pHandle->sec = *pAccess;
  39.443 +	}
  39.444 +
  39.445 +	pHandle->object = object;
  39.446 +	pHandle->clone = 0;
  39.447 +
  39.448 +	return handle;
  39.449 +}
  39.450 +
  39.451 +Handle_t HandleSystem::CreateHandleEx(HandleType_t type, void *object, const HandleSecurity *pSec, const HandleAccess *pAccess, HandleError *err)
  39.452 +{
  39.453 +	return CreateHandleInt(type, object, pSec, err, pAccess, false);
  39.454 +}
  39.455 +
  39.456 +Handle_t HandleSystem::CreateHandle(HandleType_t type, void *object, IdentityToken_t *owner, IdentityToken_t *ident, HandleError *err)
  39.457 +{
  39.458 +	HandleSecurity sec;
  39.459 +
  39.460 +	sec.pIdentity = ident;
  39.461 +	sec.pOwner = owner;
  39.462 +
  39.463 +	return CreateHandleEx(type, object, &sec, NULL, err);
  39.464 +}
  39.465 +
  39.466 +bool HandleSystem::TypeCheck(HandleType_t intype, HandleType_t outtype)
  39.467 +{
  39.468 +	/* Check the type inheritance */
  39.469 +	if (intype & HANDLESYS_SUBTYPE_MASK)
  39.470 +	{
  39.471 +		if (intype != outtype
  39.472 +			&& (TypeParent(intype) != TypeParent(outtype)))
  39.473 +		{
  39.474 +			return false;
  39.475 +		}
  39.476 +	} else {
  39.477 +		if (intype != outtype)
  39.478 +		{
  39.479 +			return false;
  39.480 +		}
  39.481 +	}
  39.482 +
  39.483 +	return true;
  39.484 +}
  39.485 +
  39.486 +HandleError HandleSystem::GetHandle(Handle_t handle,
  39.487 +									IdentityToken_t *ident, 
  39.488 +									QHandle **in_pHandle, 
  39.489 +									unsigned int *in_index,
  39.490 +									bool ignoreFree)
  39.491 +{
  39.492 +	unsigned int serial = (handle >> 16);
  39.493 +	unsigned int index = (handle & HANDLESYS_HANDLE_MASK);
  39.494 +
  39.495 +	if (index == 0 || index > m_HandleTail || index > HANDLESYS_MAX_HANDLES)
  39.496 +	{
  39.497 +		return HandleError_Index;
  39.498 +	}
  39.499 +
  39.500 +	QHandle *pHandle = &m_Handles[index];
  39.501 +
  39.502 +	if (!pHandle->set
  39.503 +		|| (pHandle->set == HandleSet_Freed && !ignoreFree))
  39.504 +	{
  39.505 +		return HandleError_Freed;
  39.506 +	} else if (pHandle->set == HandleSet_Identity
  39.507 +			   && ident != g_ShareSys.GetIdentRoot())
  39.508 +	{
  39.509 +		/* Only IdentityHandle() can read this! */
  39.510 +		return HandleError_Identity;
  39.511 +	}
  39.512 +	if (pHandle->serial != serial)
  39.513 +	{
  39.514 +		return HandleError_Changed;
  39.515 +	}
  39.516 +
  39.517 +	*in_pHandle = pHandle;
  39.518 +	*in_index = index;
  39.519 +
  39.520 +	return HandleError_None;
  39.521 +}
  39.522 +
  39.523 +bool HandleSystem::CheckAccess(QHandle *pHandle, HandleAccessRight right, const HandleSecurity *pSecurity)
  39.524 +{
  39.525 +	QHandleType *pType = &m_Types[pHandle->type];
  39.526 +	unsigned int access;
  39.527 +
  39.528 +	if (pHandle->access_special)
  39.529 +	{
  39.530 +		access = pHandle->sec.access[right];
  39.531 +	} else {
  39.532 +		access = pType->hndlSec.access[right];
  39.533 +	}
  39.534 +
  39.535 +	/* Check if the type's identity matches */
  39.536 +	if (access & HANDLE_RESTRICT_IDENTITY)
  39.537 +	{
  39.538 +		IdentityToken_t *owner = pType->typeSec.ident;
  39.539 +		if (!owner
  39.540 +			|| (!pSecurity || pSecurity->pIdentity != owner))
  39.541 +		{
  39.542 +			return false;
  39.543 +		}
  39.544 +	}
  39.545 +
  39.546 +	/* Check if the owner is allowed */
  39.547 +	if (access & HANDLE_RESTRICT_OWNER)
  39.548 +	{
  39.549 +		IdentityToken_t *owner = pHandle->owner;
  39.550 +		if (owner
  39.551 +			&& (!pSecurity || pSecurity->pOwner != owner))
  39.552 +		{
  39.553 +			return false;
  39.554 +		}
  39.555 +	}
  39.556 +
  39.557 +	return true;
  39.558 +}
  39.559 +
  39.560 +HandleError HandleSystem::CloneHandle(QHandle *pHandle, unsigned int index, Handle_t *newhandle, IdentityToken_t *newOwner)
  39.561 +{
  39.562 +	/* Get a new Handle ID */
  39.563 +	unsigned int new_index;
  39.564 +	QHandle *pNewHandle;
  39.565 +	Handle_t new_handle;
  39.566 +	HandleError err;
  39.567 +
  39.568 +	if ((err=MakePrimHandle(pHandle->type, &pNewHandle, &new_index, &new_handle, newOwner)) != HandleError_None)
  39.569 +	{
  39.570 +		return err;
  39.571 +	}
  39.572 +
  39.573 +	/* Assign permissions from parent */
  39.574 +	if (pHandle->access_special)
  39.575 +	{
  39.576 +		pNewHandle->access_special = true;
  39.577 +		pNewHandle->sec = pHandle->sec;
  39.578 +	}
  39.579 +
  39.580 +	pNewHandle->clone = index;
  39.581 +	pNewHandle->object = NULL;
  39.582 +	pHandle->refcount++;
  39.583 +
  39.584 +	*newhandle = new_handle;
  39.585 +
  39.586 +	return HandleError_None;
  39.587 +}
  39.588 +
  39.589 +HandleError HandleSystem::CloneHandle(Handle_t handle, Handle_t *newhandle, IdentityToken_t *newOwner, const HandleSecurity *pSecurity)
  39.590 +{
  39.591 +	HandleError err;
  39.592 +	QHandle *pHandle;
  39.593 +	unsigned int index;
  39.594 +	IdentityToken_t *ident = pSecurity ? pSecurity->pIdentity : NULL;
  39.595 +
  39.596 +	if ((err=GetHandle(handle, ident, &pHandle, &index)) != HandleError_None)
  39.597 +	{
  39.598 +		return err;
  39.599 +	}
  39.600 +
  39.601 +	/* Identities cannot be cloned */
  39.602 +	if (pHandle->set == HandleSet_Identity)
  39.603 +	{
  39.604 +		return HandleError_Identity;
  39.605 +	}
  39.606 +
  39.607 +	/* Check if the handle can be cloned */
  39.608 +	if (!CheckAccess(pHandle, HandleAccess_Clone, pSecurity))
  39.609 +	{
  39.610 +		return HandleError_Access;
  39.611 +	}
  39.612 +
  39.613 +	/* Make sure we're not cloning a clone */
  39.614 +	if (pHandle->clone)
  39.615 +	{
  39.616 +		QHandle *pParent = &m_Handles[pHandle->clone];
  39.617 +		return CloneHandle(pParent, pHandle->clone, newhandle, newOwner);
  39.618 +	}
  39.619 +
  39.620 +	return CloneHandle(pHandle, index, newhandle, newOwner);
  39.621 +}
  39.622 +
  39.623 +Handle_t HandleSystem::FastCloneHandle(QHandle *pHandle, unsigned int index)
  39.624 +{
  39.625 +	if (pHandle->clone)
  39.626 +		return FastCloneHandle(&m_Handles[pHandle->clone], pHandle->clone);
  39.627 +
  39.628 +	Handle_t hndl;
  39.629 +	if (CloneHandle(pHandle, index, &hndl, g_pCoreIdent) != HandleError_None)
  39.630 +		return BAD_HANDLE;
  39.631 +
  39.632 +	return hndl;
  39.633 +}
  39.634 +
  39.635 +Handle_t HandleSystem::FastCloneHandle(Handle_t hndl)
  39.636 +{
  39.637 +	QHandle *pHandle;
  39.638 +	unsigned int index;
  39.639 +
  39.640 +	GetHandleUnchecked(hndl, pHandle, index);
  39.641 +
  39.642 +	return FastCloneHandle(pHandle, index);
  39.643 +}
  39.644 +
  39.645 +void HandleSystem::GetHandleUnchecked(Handle_t hndl, QHandle *& pHandle, unsigned int &index)
  39.646 +{
  39.647 +#ifndef NDEBUG
  39.648 +	unsigned int serial = (hndl >> 16);
  39.649 +#endif
  39.650 +	index = (hndl & HANDLESYS_HANDLE_MASK);
  39.651 +
  39.652 +	assert(index != 0 && index <= m_HandleTail && index < HANDLESYS_MAX_HANDLES);
  39.653 +
  39.654 +	pHandle = &m_Handles[index];
  39.655 +
  39.656 +	assert(pHandle->set && pHandle->set != HandleSet_Freed);
  39.657 +	assert(pHandle->serial == serial);
  39.658 +}
  39.659 +
  39.660 +HandleError HandleSystem::FreeHandle(QHandle *pHandle, unsigned int index)
  39.661 +{
  39.662 +	if (pHandle->is_destroying)
  39.663 +	{
  39.664 +		/* Someone tried to free this recursively.  
  39.665 +		 * We'll just ignore this safely.
  39.666 +		 */
  39.667 +		return HandleError_None;
  39.668 +	}
  39.669 +
  39.670 +	QHandleType *pType = &m_Types[pHandle->type];
  39.671 +
  39.672 +	if (pHandle->clone)
  39.673 +	{
  39.674 +		/* If we're a clone, decrease the parent reference count */
  39.675 +		QHandle *pMaster;
  39.676 +		unsigned int master;
  39.677 +
  39.678 +		/* Note that if we ever have per-handle security, we would need to re-check
  39.679 +		* the access on this Handle. */
  39.680 +		master = pHandle->clone;
  39.681 +		pMaster = &m_Handles[master];
  39.682 +
  39.683 +		/* Release the clone now */
  39.684 +		pHandle->is_destroying = true;
  39.685 +		ReleasePrimHandle(index);
  39.686 +
  39.687 +		/* Decrement the master's reference count */
  39.688 +		if (--pMaster->refcount == 0)
  39.689 +		{
  39.690 +			/* Type should be the same but do this anyway... */
  39.691 +			pType = &m_Types[pMaster->type];
  39.692 +			pMaster->is_destroying = true;
  39.693 +			if (pMaster->object)
  39.694 +			{
  39.695 +				pType->dispatch->OnHandleDestroy(pMaster->type, pMaster->object);
  39.696 +			}
  39.697 +			ReleasePrimHandle(master);
  39.698 +		}
  39.699 +	} else if (pHandle->set == HandleSet_Identity) {
  39.700 +		/* If we're an identity, skip all this stuff!
  39.701 +		 * NOTE: SHARESYS DOES NOT CARE ABOUT THE DESTRUCTOR
  39.702 +		 */
  39.703 +		pHandle->is_destroying = true;
  39.704 +		ReleasePrimHandle(index);
  39.705 +	} else {
  39.706 +		/* Decrement, free if necessary */
  39.707 +		if (--pHandle->refcount == 0)
  39.708 +		{
  39.709 +			pHandle->is_destroying = true;
  39.710 +			if (pHandle->object)
  39.711 +			{
  39.712 +				pType->dispatch->OnHandleDestroy(pHandle->type, pHandle->object);
  39.713 +			}
  39.714 +			ReleasePrimHandle(index);
  39.715 +		} else {
  39.716 +			/* We must be cloned, so mark ourselves as freed */
  39.717 +			pHandle->set = HandleSet_Freed;
  39.718 +			/* Now, unlink us, so we're not being tracked by the owner */
  39.719 +			if (pHandle->owner)
  39.720 +			{
  39.721 +				UnlinkHandleFromOwner(pHandle, index);
  39.722 +			}
  39.723 +		}
  39.724 +	}
  39.725 +
  39.726 +	return HandleError_None;
  39.727 +}
  39.728 +
  39.729 +HandleError HandleSystem::FreeHandle(Handle_t handle, const HandleSecurity *pSecurity)
  39.730 +{
  39.731 +	unsigned int index;
  39.732 +	QHandle *pHandle;
  39.733 +	HandleError err;
  39.734 +	IdentityToken_t *ident = pSecurity ? pSecurity->pIdentity : NULL;
  39.735 +
  39.736 +	if ((err=GetHandle(handle, ident, &pHandle, &index)) != HandleError_None)
  39.737 +	{
  39.738 +		return err;
  39.739 +	}
  39.740 +
  39.741 +	if (!CheckAccess(pHandle, HandleAccess_Delete, pSecurity))
  39.742 +	{
  39.743 +		return HandleError_Access;
  39.744 +	}
  39.745 +
  39.746 +	return FreeHandle(pHandle, index);
  39.747 +}
  39.748 +
  39.749 +HandleError HandleSystem::ReadHandle(Handle_t handle, HandleType_t type, const HandleSecurity *pSecurity, void **object)
  39.750 +{
  39.751 +	unsigned int index;
  39.752 +	QHandle *pHandle;
  39.753 +	HandleError err;
  39.754 +	IdentityToken_t *ident = pSecurity ? pSecurity->pIdentity : NULL;
  39.755 +
  39.756 +	if ((err=GetHandle(handle, ident, &pHandle, &index)) != HandleError_None)
  39.757 +	{
  39.758 +		return err;
  39.759 +	}
  39.760 +
  39.761 +	if (!CheckAccess(pHandle, HandleAccess_Read, pSecurity))
  39.762 +	{
  39.763 +		return HandleError_Access;
  39.764 +	}
  39.765 +
  39.766 +	/* Check the type inheritance */
  39.767 +	if (pHandle->type & HANDLESYS_SUBTYPE_MASK)
  39.768 +	{
  39.769 +		if (pHandle->type != type
  39.770 +			&& (TypeParent(pHandle->type) != TypeParent(type)))
  39.771 +		{
  39.772 +			return HandleError_Type;
  39.773 +		}
  39.774 +	} else if (type) {
  39.775 +		if (pHandle->type != type)
  39.776 +		{
  39.777 +			return HandleError_Type;
  39.778 +		}
  39.779 +	}
  39.780 +
  39.781 +	if (object)
  39.782 +	{
  39.783 +		/* if we're a clone, the rules change - object is ONLY in our reference */
  39.784 +		if (pHandle->clone)
  39.785 +		{
  39.786 +			pHandle = &m_Handles[pHandle->clone];
  39.787 +		}
  39.788 +		*object = pHandle->object;
  39.789 +	}
  39.790 +
  39.791 +	return HandleError_None;
  39.792 +}
  39.793 +
  39.794 +void HandleSystem::UnlinkHandleFromOwner(QHandle *pHandle, unsigned int index)
  39.795 +{
  39.796 +	/* Unlink us if necessary */
  39.797 +	unsigned int ident_index;
  39.798 +	if (IdentityHandle(pHandle->owner, &ident_index) != HandleError_None)
  39.799 +	{
  39.800 +		/* Uh-oh! */
  39.801 +		assert(pHandle->owner == 0);
  39.802 +		return;
  39.803 +	}
  39.804 +
  39.805 +	pHandle->owner = NULL;
  39.806 +
  39.807 +	/* Note that since 0 is an invalid handle, if any of these links are 0,
  39.808 +	* the data can still be set.
  39.809 +	*/
  39.810 +	QHandle *pIdentity = &m_Handles[ident_index];
  39.811 +
  39.812 +	/* Unlink case: We're the head AND tail node */
  39.813 +	if (index == pIdentity->ch_prev && index == pIdentity->ch_next)
  39.814 +	{
  39.815 +		pIdentity->ch_prev = 0;
  39.816 +		pIdentity->ch_next = 0;
  39.817 +	}
  39.818 +	/* Unlink case: We're the head node */
  39.819 +	else if (index == pIdentity->ch_prev) {
  39.820 +		/* Link us to the next in the chain */
  39.821 +		pIdentity->ch_prev = pHandle->ch_next;
  39.822 +		/* Patch up the previous link */
  39.823 +		m_Handles[pHandle->ch_next].ch_prev = 0;
  39.824 +	}
  39.825 +	/* Unlink case: We're the tail node */
  39.826 +	else if (index == pIdentity->ch_next) {
  39.827 +		/* Link us to the previous in the chain */
  39.828 +		pIdentity->ch_next = pHandle->ch_prev;
  39.829 +		/* Patch up the next link */
  39.830 +		m_Handles[pHandle->ch_prev].ch_next = 0;
  39.831 +	}
  39.832 +	/* Unlink case: We're in the middle! */
  39.833 +	else {
  39.834 +		/* Patch the forward reference */
  39.835 +		m_Handles[pHandle->ch_next].ch_prev = pHandle->ch_prev;
  39.836 +		/* Patch the backward reference */
  39.837 +		m_Handles[pHandle->ch_prev].ch_next = pHandle->ch_next;
  39.838 +	}
  39.839 +
  39.840 +	/* Lastly, decrease the reference count */
  39.841 +	pIdentity->refcount--;
  39.842 +}
  39.843 +
  39.844 +void HandleSystem::ReleasePrimHandle(unsigned int index)
  39.845 +{
  39.846 +	QHandle *pHandle = &m_Handles[index];
  39.847 +	HandleSet set = pHandle->set;
  39.848 +
  39.849 +	if (pHandle->owner && (set != HandleSet_Identity))
  39.850 +	{
  39.851 +		UnlinkHandleFromOwner(pHandle, index);
  39.852 +	}
  39.853 +
  39.854 +	/* Were we an identity ourself? */
  39.855 +	QHandle *pLocal;
  39.856 +	if (set == HandleSet_Identity)
  39.857 +	{
  39.858 +		/* Extra work to do.  We need to find everything connected to this identity and release it. */
  39.859 +		unsigned int ch_index;
  39.860 +#if defined _DEBUG
  39.861 +		unsigned int old_index = 0;
  39.862 +#endif
  39.863 +		while ((ch_index = pHandle->ch_next) != 0)
  39.864 +		{
  39.865 +			pLocal = &m_Handles[ch_index];
  39.866 +#if defined _DEBUG
  39.867 +			assert(old_index != ch_index);
  39.868 +			assert(pLocal->set == HandleSet_Used);
  39.869 +			old_index = ch_index;
  39.870 +#endif
  39.871 +			FreeHandle(pLocal, ch_index);
  39.872 +		}
  39.873 +	}
  39.874 +
  39.875 +	pHandle->set = HandleSet_None;
  39.876 +	m_Types[pHandle->type].opened--;
  39.877 +	m_Handles[++m_FreeHandles].freeID = index;
  39.878 +}
  39.879 +
  39.880 +bool HandleSystem::RemoveType(HandleType_t type, IdentityToken_t *ident)
  39.881 +{
  39.882 +	if (type == 0 || type >= HANDLESYS_TYPEARRAY_SIZE)
  39.883 +	{
  39.884 +		return false;
  39.885 +	}
  39.886 +
  39.887 +	QHandleType *pType = &m_Types[type];
  39.888 +
  39.889 +	if (pType->typeSec.ident
  39.890 +		&& pType->typeSec.ident != ident)
  39.891 +	{
  39.892 +		return false;
  39.893 +	}
  39.894 +
  39.895 +	if (pType->dispatch == NULL)
  39.896 +	{
  39.897 +		return false;
  39.898 +	}
  39.899 +
  39.900 +	/* Remove children if we have to */
  39.901 +	if (!(type & HANDLESYS_SUBTYPE_MASK))
  39.902 +	{
  39.903 +		QHandleType *childType;
  39.904 +		for (unsigned int i=1; i<=HANDLESYS_MAX_SUBTYPES; i++)
  39.905 +		{
  39.906 +			childType = &m_Types[type + i];
  39.907 +			if (childType->dispatch)
  39.908 +			{
  39.909 +				RemoveType(type + i, childType->typeSec.ident);
  39.910 +			}
  39.911 +		}
  39.912 +		/* Link us into the free chain */
  39.913 +		m_Types[++m_FreeTypes].freeID = type;
  39.914 +	}
  39.915 +
  39.916 +	/* Invalidate the type now */
  39.917 +	IHandleTypeDispatch *dispatch = pType->dispatch;
  39.918 +	pType->dispatch = NULL;
  39.919 +
  39.920 +	/* Make sure nothing is using this type. */
  39.921 +	if (pType->opened)
  39.922 +	{
  39.923 +		QHandle *pHandle;
  39.924 +		for (unsigned int i=1; i<=m_HandleTail; i++)
  39.925 +		{
  39.926 +			pHandle = &m_Handles[i];
  39.927 +			if (!pHandle->set || pHandle->type != type)
  39.928 +			{
  39.929 +				continue;
  39.930 +			}
  39.931 +
  39.932 +			FreeHandle(pHandle, i);
  39.933 +
  39.934 +			if (pType->opened == 0)
  39.935 +			{
  39.936 +				break;
  39.937 +			}
  39.938 +		}
  39.939 +	}
  39.940 +
  39.941 +	/* Remove it from the type cache. */
  39.942 +	if (pType->nameIdx != -1)
  39.943 +	{
  39.944 +		const char *typeName;
  39.945 +
  39.946 +		typeName = m_strtab->GetString(pType->nameIdx);
  39.947 +		m_TypeLookup.remove(typeName);
  39.948 +	}
  39.949 +
  39.950 +	return true;
  39.951 +}
  39.952 +
  39.953 +bool HandleSystem::InitAccessDefaults(TypeAccess *pTypeAccess, HandleAccess *pHandleAccess)
  39.954 +{
  39.955 +	if (pTypeAccess)
  39.956 +	{
  39.957 +		if (pTypeAccess->hsVersion > SMINTERFACE_HANDLESYSTEM_VERSION)
  39.958 +		{
  39.959 +			return false;
  39.960 +		}
  39.961 +		pTypeAccess->access[HTypeAccess_Create] = false;
  39.962 +		pTypeAccess->access[HTypeAccess_Inherit] = false;
  39.963 +		pTypeAccess->ident = NULL;
  39.964 +	}
  39.965 +
  39.966 +	if (pHandleAccess)
  39.967 +	{
  39.968 +		if (pHandleAccess->hsVersion > SMINTERFACE_HANDLESYSTEM_VERSION)
  39.969 +		{
  39.970 +			return false;
  39.971 +		}
  39.972 +
  39.973 +		pHandleAccess->access[HandleAccess_Clone] = 0;
  39.974 +		pHandleAccess->access[HandleAccess_Delete] = HANDLE_RESTRICT_OWNER;
  39.975 +		pHandleAccess->access[HandleAccess_Read] = HANDLE_RESTRICT_IDENTITY;
  39.976 +	}
  39.977 +
  39.978 +	return true;
  39.979 +}
  39.980 +
  39.981 +#define HANDLE_LOG_VERY_BAD(message, ...) \
  39.982 +	smcore.LogFatal(message, ##__VA_ARGS__); \
  39.983 +	smcore.LogError(message, ##__VA_ARGS__);
  39.984 +
  39.985 +bool HandleSystem::TryAndFreeSomeHandles()
  39.986 +{
  39.987 +	IPluginIterator *pl_iter = scripts->GetPluginIterator();
  39.988 +	IPlugin *highest_owner = NULL;
  39.989 +	unsigned int highest_handle_count = 0;
  39.990 +
  39.991 +	/* Search all plugins */
  39.992 +	while (pl_iter->MorePlugins())
  39.993 +	{
  39.994 +		IPlugin *plugin = pl_iter->GetPlugin();
  39.995 +		IdentityToken_t *identity = plugin->GetIdentity();
  39.996 +		unsigned int handle_count = 0;
  39.997 +
  39.998 +		if (identity == NULL)
  39.999 +		{
 39.1000 +			continue;
 39.1001 +		}
 39.1002 +
 39.1003 +		/* Search all handles */
 39.1004 +		for (unsigned int i = 1; i <= m_HandleTail; i++)
 39.1005 +		{
 39.1006 +			if (m_Handles[i].set != HandleSet_Used)
 39.1007 +			{
 39.1008 +				continue;
 39.1009 +			}
 39.1010 +			if (m_Handles[i].owner == identity)
 39.1011 +			{
 39.1012 +				handle_count++;
 39.1013 +			}
 39.1014 +		}
 39.1015 +
 39.1016 +		if (handle_count > highest_handle_count)
 39.1017 +		{
 39.1018 +			highest_owner = plugin;
 39.1019 +			highest_handle_count = handle_count;
 39.1020 +		}
 39.1021 +
 39.1022 +		pl_iter->NextPlugin();
 39.1023 +	}
 39.1024 +
 39.1025 +	if (highest_owner == NULL || highest_handle_count == 0)
 39.1026 +	{
 39.1027 +		return false;
 39.1028 +	}
 39.1029 +
 39.1030 +	HANDLE_LOG_VERY_BAD("[SM] MEMORY LEAK DETECTED IN PLUGIN (file \"%s\")", highest_owner->GetFilename());
 39.1031 +	HANDLE_LOG_VERY_BAD("[SM] Unloading plugin to free %d handles.", highest_handle_count);
 39.1032 +	HANDLE_LOG_VERY_BAD("[SM] Contact the author(s) of this plugin to correct this error.", highest_handle_count);
 39.1033 +
 39.1034 +	highest_owner->GetBaseContext()->ThrowNativeErrorEx(SP_ERROR_MEMACCESS, "Memory leak");
 39.1035 +
 39.1036 +	return scripts->UnloadPlugin(highest_owner);
 39.1037 +}
 39.1038 +
 39.1039 +void HandleSystem::Dump(HANDLE_REPORTER rep)
 39.1040 +{
 39.1041 +	unsigned int total_size = 0;
 39.1042 +	rep("%-10.10s\t%-20.20s\t%-20.20s\t%-10.10s", "Handle", "Owner", "Type", "Memory");
 39.1043 +	rep("--------------------------------------------------------------------------");
 39.1044 +	for (unsigned int i = 1; i <= m_HandleTail; i++)
 39.1045 +	{
 39.1046 +		if (m_Handles[i].set != HandleSet_Used)
 39.1047 +		{
 39.1048 +			continue;
 39.1049 +		}
 39.1050 +		/* Get the index */
 39.1051 +		unsigned int index = (m_Handles[i].serial << 16) | i;
 39.1052 +		/* Determine the owner */
 39.1053 +		const char *owner = "UNKNOWN";
 39.1054 +		if (m_Handles[i].owner)
 39.1055 +		{
 39.1056 +			IdentityToken_t *pOwner = m_Handles[i].owner;
 39.1057 +			if (pOwner == g_pCoreIdent)
 39.1058 +			{
 39.1059 +				owner = "CORE";
 39.1060 +			}
 39.1061 +			else if (pOwner == scripts->GetIdentity())
 39.1062 +			{
 39.1063 +				owner = "PLUGINSYS";
 39.1064 +			}
 39.1065 +			else
 39.1066 +			{
 39.1067 +				IExtension *ext = g_Extensions.GetExtensionFromIdent(pOwner);
 39.1068 +				if (ext)
 39.1069 +				{
 39.1070 +					owner = ext->GetFilename();
 39.1071 +				}
 39.1072 +				else
 39.1073 +				{
 39.1074 +					SMPlugin *pPlugin = scripts->FindPluginByIdentity(pOwner);
 39.1075 +					if (pPlugin)
 39.1076 +					{
 39.1077 +						owner = pPlugin->GetFilename();
 39.1078 +					}
 39.1079 +				}
 39.1080 +			}
 39.1081 +		}
 39.1082 +		else
 39.1083 +		{
 39.1084 +			owner = "NONE";
 39.1085 +		}
 39.1086 +		const char *type = "ANON";
 39.1087 +		QHandleType *pType = &m_Types[m_Handles[i].type];
 39.1088 +		unsigned int size = 0;
 39.1089 +		unsigned int parentIdx;
 39.1090 +		bool bresult;
 39.1091 +		if (pType->nameIdx != -1)
 39.1092 +		{
 39.1093 +			type = m_strtab->GetString(pType->nameIdx);
 39.1094 +		}
 39.1095 +
 39.1096 +		if ((parentIdx = m_Handles[i].clone) != 0)
 39.1097 +		{
 39.1098 +			if (m_Handles[parentIdx].refcount > 0)
 39.1099 +			{
 39.1100 +				size = 0;
 39.1101 +				bresult = true;
 39.1102 +			}
 39.1103 +			else
 39.1104 +			{
 39.1105 +				bresult = pType->dispatch->GetHandleApproxSize(m_Handles[parentIdx].type, m_Handles[parentIdx].object, &size);
 39.1106 +			}
 39.1107 +		}
 39.1108 +		else
 39.1109 +		{
 39.1110 +			bresult = pType->dispatch->GetHandleApproxSize(m_Handles[i].type, m_Handles[i].object, &size);
 39.1111 +		}
 39.1112 +
 39.1113 +		if (pType->dispatch->GetDispatchVersion() < HANDLESYS_MEMUSAGE_MIN_VERSION
 39.1114 +			|| !bresult)
 39.1115 +		{
 39.1116 +			rep("0x%08x\t%-20.20s\t%-20.20s\t%-10.10s", index, owner, type, "-1");
 39.1117 +		}
 39.1118 +		else
 39.1119 +		{
 39.1120 +			char buffer[32];
 39.1121 +			smcore.Format(buffer, sizeof(buffer), "%d", size);
 39.1122 +			rep("0x%08x\t%-20.20s\t%-20.20s\t%-10.10s", index, owner, type, buffer);
 39.1123 +			total_size += size;
 39.1124 +		}
 39.1125 +	}
 39.1126 +	rep("-- Approximately %d bytes of memory are in use by Handles.\n", total_size);
 39.1127 +}
 39.1128 +
    40.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    40.2 +++ b/core/logic/HandleSys.h	Fri Mar 29 11:37:29 2013 -0700
    40.3 @@ -0,0 +1,253 @@
    40.4 +/**
    40.5 + * vim: set ts=4 :
    40.6 + * =============================================================================
    40.7 + * SourceMod
    40.8 + * Copyright (C) 2004-2008 AlliedModders LLC.  All rights reserved.
    40.9 + * =============================================================================
   40.10 + *
   40.11 + * This program is free software; you can redistribute it and/or modify it under
   40.12 + * the terms of the GNU General Public License, version 3.0, as published by the
   40.13 + * Free Software Foundation.
   40.14 + * 
   40.15 + * This program is distributed in the hope that it will be useful, but WITHOUT
   40.16 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   40.17 + * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
   40.18 + * details.
   40.19 + *
   40.20 + * You should have received a copy of the GNU General Public License along with
   40.21 + * this program.  If not, see <http://www.gnu.org/licenses/>.
   40.22 + *
   40.23 + * As a special exception, AlliedModders LLC gives you permission to link the
   40.24 + * code of this program (as well as its derivative works) to "Half-Life 2," the
   40.25 + * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
   40.26 + * by the Valve Corporation.  You must obey the GNU General Public License in
   40.27 + * all respects for all other code used.  Additionally, AlliedModders LLC grants
   40.28 + * this exception to all derivative works.  AlliedModders LLC defines further
   40.29 + * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
   40.30 + * or <http://www.sourcemod.net/license.php>.
   40.31 + *
   40.32 + * Version: $Id$
   40.33 + */
   40.34 +
   40.35 +#ifndef _INCLUDE_SOURCEMOD_HANDLESYSTEM_H_
   40.36 +#define _INCLUDE_SOURCEMOD_HANDLESYSTEM_H_
   40.37 +
   40.38 +#include <IHandleSys.h>
   40.39 +#include <stdio.h>
   40.40 +#include <sm_trie_tpl.h>
   40.41 +#include "sm_memtable.h"
   40.42 +#include "common_logic.h"
   40.43 +
   40.44 +#define HANDLESYS_MAX_HANDLES		(1<<14)
   40.45 +#define HANDLESYS_MAX_TYPES			(1<<9)
   40.46 +#define HANDLESYS_MAX_SUBTYPES		0xF
   40.47 +#define HANDLESYS_SUBTYPE_MASK		0xF
   40.48 +#define HANDLESYS_TYPEARRAY_SIZE	(HANDLESYS_MAX_TYPES * (HANDLESYS_MAX_SUBTYPES + 1))
   40.49 +#define HANDLESYS_MAX_SERIALS		0xFFFF
   40.50 +#define HANDLESYS_SERIAL_MASK		0xFFFF0000
   40.51 +#define HANDLESYS_HANDLE_MASK		0x0000FFFF
   40.52 +
   40.53 +#define HANDLESYS_MEMUSAGE_MIN_VERSION		3
   40.54 +
   40.55 +/**
   40.56 + *   The QHandle is a nasty structure that compacts the handle system into a big vector.
   40.57 + * The members of the vector each encapsulate one Handle, however, they also act as nodes
   40.58 + * in an inlined linked list and an inlined vector.
   40.59 + *
   40.60 + *   The first of these lists is the 'freeID' list.  Each node from 1 to N (where N
   40.61 + * is the number of free nodes) has a 'freeID' that specifies a free Handle ID.  This
   40.62 + * is a quick hack to get around allocating a second base vector.
   40.63 + *
   40.64 + *   The second vector is the identity linked list.  An identity has its own handle, so
   40.65 + * these handles are used as sentinel nodes for index linking.  They point to the first and last
   40.66 + * index into the handle array.  Each subsequent Handle who is owned by that identity is mapped into
   40.67 + * that list.  This lets owning identities be unloaded in O(n) time.
   40.68 + *
   40.69 + *   Eventually, there may be a third list for type chains.
   40.70 + */
   40.71 +
   40.72 +enum HandleSet
   40.73 +{
   40.74 +	HandleSet_None = 0,
   40.75 +	HandleSet_Used,			/* The Handle is in use */
   40.76 +	HandleSet_Freed,		/* The "master" Handle of a clone chain is freed */
   40.77 +	HandleSet_Identity,		/* The Handle is a special identity */
   40.78 +};
   40.79 +
   40.80 +struct QHandle
   40.81 +{
   40.82 +	HandleType_t type;			/* Handle type */
   40.83 +	void *object;				/* Unmaintained object pointer */
   40.84 +	IdentityToken_t *owner;		/* Identity of object which owns this */
   40.85 +	unsigned int serial;		/* Serial no. for sanity checking */
   40.86 +	unsigned int refcount;		/* Reference count for safe destruction */
   40.87 +	unsigned int clone;			/* If non-zero, this is our cloned parent index */
   40.88 +	HandleSet set;				/* Information about the handle's state */
   40.89 +	bool access_special;		/* Whether or not access rules are special or type-derived */
   40.90 +	bool is_destroying;			/* Whether or not the handle is being destroyed */
   40.91 +	HandleAccess sec;			/* Security rules */
   40.92 +	/* The following variables are unrelated to the Handle array, and used 
   40.93 +	 * as an inlined chain of information */
   40.94 +	unsigned int freeID;		/* ID of a free handle in the free handle chain */
   40.95 +	/* Indexes into the handle array for owner membership.
   40.96 +	 * For identity roots, these are treated as the head/tail. */
   40.97 +	unsigned int ch_prev;		/* chained previous handle */
   40.98 +	unsigned int ch_next;		/* chained next handle */
   40.99 +};
  40.100 +
  40.101 +struct QHandleType
  40.102 +{
  40.103 +	IHandleTypeDispatch *dispatch;
  40.104 +	unsigned int freeID;
  40.105 +	unsigned int children;
  40.106 +	TypeAccess typeSec;
  40.107 +	HandleAccess hndlSec;
  40.108 +	unsigned int opened;
  40.109 +	int nameIdx;
  40.110 +};
  40.111 +
  40.112 +typedef void (HANDLE_REPORTER)(const char *str, ...);
  40.113 +
  40.114 +class HandleSystem : 
  40.115 +	public IHandleSys
  40.116 +{
  40.117 +	friend HandleError IdentityHandle(IdentityToken_t *token, unsigned int *index);
  40.118 +	friend class ShareSystem;
  40.119 +public:
  40.120 +	HandleSystem();
  40.121 +	~HandleSystem();
  40.122 +public: //IHandleSystem
  40.123 +
  40.124 +	HandleType_t CreateType(const char *name,
  40.125 +		IHandleTypeDispatch *dispatch,
  40.126 +		HandleType_t parent,
  40.127 +		const TypeAccess *typeAccess,
  40.128 +		const HandleAccess *hndlAccess,
  40.129 +		IdentityToken_t *ident,
  40.130 +		HandleError *err);
  40.131 +
  40.132 +	bool RemoveType(HandleType_t type, IdentityToken_t *ident);
  40.133 +
  40.134 +	bool FindHandleType(const char *name, HandleType_t *type);
  40.135 +
  40.136 +	Handle_t CreateHandle(HandleType_t type, 
  40.137 +		void *object,
  40.138 +		IdentityToken_t *owner,
  40.139 +		IdentityToken_t *ident,
  40.140 +		HandleError *err);
  40.141 +
  40.142 +	HandleError FreeHandle(Handle_t handle, const HandleSecurity *pSecurity);
  40.143 +
  40.144 +	HandleError CloneHandle(Handle_t handle, 
  40.145 +		Handle_t *newhandle, 
  40.146 +		IdentityToken_t *newOwner,
  40.147 +		const HandleSecurity *pSecurity);
  40.148 +
  40.149 +	HandleError ReadHandle(Handle_t handle, 
  40.150 +		HandleType_t type, 
  40.151 +		const HandleSecurity *pSecurity,
  40.152 +		void **object);
  40.153 +
  40.154 +	bool InitAccessDefaults(TypeAccess *pTypeAccess, HandleAccess *pHandleAccess);
  40.155 +
  40.156 +	bool TypeCheck(HandleType_t intype, HandleType_t outtype);
  40.157 +
  40.158 +	virtual Handle_t CreateHandleEx(HandleType_t type, 
  40.159 +		void *object,
  40.160 +		const HandleSecurity *pSec,
  40.161 +		const HandleAccess *pAccess,
  40.162 +		HandleError *err);
  40.163 +
  40.164 +	void Dump(HANDLE_REPORTER rep);
  40.165 +
  40.166 +	/* Bypasses security checks. */
  40.167 +	Handle_t FastCloneHandle(Handle_t hndl);
  40.168 +protected:
  40.169 +	/**
  40.170 +	 * Decodes a handle with sanity and security checking.
  40.171 +	 */
  40.172 +	HandleError GetHandle(Handle_t handle, 
  40.173 +						  IdentityToken_t *ident, 
  40.174 +						  QHandle **pHandle, 
  40.175 +						  unsigned int *index,
  40.176 +						  bool ignoreFree=false);
  40.177 +
  40.178 +	Handle_t FastCloneHandle(QHandle *pHandle, unsigned int index);
  40.179 +	void GetHandleUnchecked(Handle_t hndl, QHandle *& pHandle, unsigned int &index);
  40.180 +
  40.181 +	/**
  40.182 +	 * Creates a basic handle and sets its reference count to 1.
  40.183 +	 * Does not do any type or security checking.
  40.184 +	 */
  40.185 +	HandleError MakePrimHandle(HandleType_t type, 
  40.186 +							   QHandle **pHandle, 
  40.187 +							   unsigned int *index, 
  40.188 +							   HandleType_t *handle,
  40.189 +							   IdentityToken_t *owner,
  40.190 +							   bool identity=false);
  40.191 +
  40.192 +	/**
  40.193 +	 * Frees a primitive handle.  Does no object freeing, only reference count, bookkeeping, 
  40.194 +	 * and linked list maintenance.
  40.195 +	 * If used on an Identity handle, destroys all Handles under that identity.
  40.196 +	 */
  40.197 +	void ReleasePrimHandle(unsigned int index);
  40.198 +
  40.199 +	/**
  40.200 +	 * Sets the security owner of a type.
  40.201 +	 */
  40.202 +	void SetTypeSecurityOwner(HandleType_t type, IdentityToken_t *pToken);
  40.203 +
  40.204 +	/**
  40.205 +	 * Helper function to check access rights.
  40.206 +	 */
  40.207 +	bool CheckAccess(QHandle *pHandle, HandleAccessRight right, const HandleSecurity *pSecurity);
  40.208 +
  40.209 +	/** 
  40.210 +	 * Some wrappers for internal functions, so we can pass indexes instead of encoded handles.
  40.211 +	 */
  40.212 +	HandleError FreeHandle(QHandle *pHandle, unsigned int index);
  40.213 +	void UnlinkHandleFromOwner(QHandle *pHandle, unsigned int index);
  40.214 +	HandleError CloneHandle(QHandle *pHandle, unsigned int index, Handle_t *newhandle, IdentityToken_t *newOwner);
  40.215 +	Handle_t CreateHandleInt(HandleType_t type, void *object, const HandleSecurity *pSec, HandleError *err, const HandleAccess *pAccess, bool identity);
  40.216 +
  40.217 +	bool TryAndFreeSomeHandles();
  40.218 +	HandleError TryAllocHandle(unsigned int *handle);
  40.219 +private:
  40.220 +	QHandle *m_Handles;
  40.221 +	QHandleType *m_Types;
  40.222 +	KTrie<QHandleType *> m_TypeLookup;
  40.223 +	unsigned int m_TypeTail;
  40.224 +	unsigned int m_FreeTypes;
  40.225 +	unsigned int m_HandleTail;
  40.226 +	unsigned int m_FreeHandles;
  40.227 +	unsigned int m_HSerial;
  40.228 +	BaseStringTable *m_strtab;
  40.229 +};
  40.230 +
  40.231 +extern HandleSystem g_HandleSys;
  40.232 +
  40.233 +struct AutoHandleRooter
  40.234 +{
  40.235 +public:
  40.236 +	AutoHandleRooter(Handle_t hndl)
  40.237 +	{
  40.238 +		if (hndl != BAD_HANDLE)
  40.239 +			this->hndl = g_HandleSys.FastCloneHandle(hndl);
  40.240 +		else
  40.241 +			this->hndl = BAD_HANDLE;
  40.242 +	}
  40.243 +
  40.244 +	~AutoHandleRooter()
  40.245 +	{
  40.246 +		if (hndl != BAD_HANDLE)
  40.247 +		{
  40.248 +			HandleSecurity sec(g_pCoreIdent, g_pCoreIdent);
  40.249 +			g_HandleSys.FreeHandle(hndl, &sec);
  40.250 +		}
  40.251 +	}
  40.252 +private:
  40.253 +	Handle_t hndl;
  40.254 +};
  40.255 +
  40.256 +#endif //_INCLUDE_SOURCEMOD_HANDLESYSTEM_H_
    41.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    41.2 +++ b/core/logic/NativeInvoker.cpp	Fri Mar 29 11:37:29 2013 -0700
    41.3 @@ -0,0 +1,379 @@
    41.4 +/**
    41.5 + * vim: set ts=4 :
    41.6 + * =============================================================================
    41.7 + * SourcePawn
    41.8 + * Copyright (C) 2004-2009 AlliedModders LLC.  All rights reserved.
    41.9 + * =============================================================================
   41.10 + *
   41.11 + * This program is free software; you can redistribute it and/or modify it under
   41.12 + * the terms of the GNU General Public License, version 3.0, as published by the
   41.13 + * Free Software Foundation.
   41.14 + * 
   41.15 + * This program is distributed in the hope that it will be useful, but WITHOUT
   41.16 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   41.17 + * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
   41.18 + * details.
   41.19 + *
   41.20 + * You should have received a copy of the GNU General Public License along with
   41.21 + * this program.  If not, see <http://www.gnu.org/licenses/>.
   41.22 + *
   41.23 + * As a special exception, AlliedModders LLC gives you permission to link the
   41.24 + * code of this program (as well as its derivative works) to "Half-Life 2," the
   41.25 + * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
   41.26 + * by the Valve Corporation.  You must obey the GNU General Public License in
   41.27 + * all respects for all other code used.  Additionally, AlliedModders LLC grants
   41.28 + * this exception to all derivative works.  AlliedModders LLC defines further
   41.29 + * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
   41.30 + * or <http://www.sourcemod.net/license.php>.
   41.31 + *
   41.32 + * Version: $Id$
   41.33 + */
   41.34 +
   41.35 +#include "NativeInvoker.h"
   41.36 +#include "ShareSys.h"
   41.37 +
   41.38 +NativeInterface g_NInvoke;
   41.39 +
   41.40 +NativeInvoker::NativeInvoker()
   41.41 +{
   41.42 +}
   41.43 +
   41.44 +NativeInvoker::~NativeInvoker()
   41.45 +{
   41.46 +}
   41.47 +
   41.48 +const char *NativeInterface::GetInterfaceName()
   41.49 +{
   41.50 +	return SMINTERFACE_NINVOKE_NAME;
   41.51 +}
   41.52 +
   41.53 +unsigned int NativeInterface::GetInterfaceVersion()
   41.54 +{
   41.55 +	return SMINTERFACE_NINVOKE_VERSION;
   41.56 +}
   41.57 +
   41.58 +void NativeInterface::OnSourceModAllInitialized()
   41.59 +{
   41.60 +	sharesys->AddInterface(NULL, &g_NInvoke);
   41.61 +}
   41.62 +
   41.63 +IPluginRuntime *NativeInterface::CreateRuntime(const char *name, size_t bytes)
   41.64 +{
   41.65 +	return g_pSourcePawn2->CreateEmptyRuntime(name, bytes);
   41.66 +}
   41.67 +
   41.68 +INativeInvoker *NativeInterface::CreateInvoker()
   41.69 +{
   41.70 +	return new NativeInvoker();
   41.71 +}
   41.72 +
   41.73 +bool NativeInvoker::Start(IPluginContext *pContext, const char *name)
   41.74 +{
   41.75 +	NativeEntry *entry;
   41.76 +	
   41.77 +	entry = g_ShareSys.FindNative(name);
   41.78 +	if (entry == NULL)
   41.79 +	{
   41.80 +		return false;
   41.81 +	}
   41.82 +
   41.83 +	native = NULL;
   41.84 +	if (entry->replacement.owner != NULL)
   41.85 +	{
   41.86 +		native = entry->replacement.func;
   41.87 +	}
   41.88 +	else if (entry->owner != NULL)
   41.89 +	{
   41.90 +		native = entry->func;
   41.91 +	}
   41.92 +
   41.93 +	if (native == NULL)
   41.94 +	{
   41.95 +		return false;
   41.96 +	}
   41.97 +
   41.98 +	this->pContext = pContext;
   41.99 +
  41.100 +	m_curparam = 0;
  41.101 +	m_errorstate = SP_ERROR_NONE;
  41.102 +
  41.103 +	return true;
  41.104 +}
  41.105 +
  41.106 +cell_t NativeInvoker::PushCell(cell_t cell)
  41.107 +{
  41.108 +	if (m_curparam >= SP_MAX_EXEC_PARAMS)
  41.109 +	{
  41.110 +		return SetError(SP_ERROR_PARAMS_MAX);
  41.111 +	}
  41.112 +
  41.113 +	m_info[m_curparam].marked = false;
  41.114 +	m_params[m_curparam] = cell;
  41.115 +	m_curparam++;
  41.116 +
  41.117 +	return SP_ERROR_NONE;
  41.118 +}
  41.119 +
  41.120 +int NativeInvoker::PushCellByRef(cell_t *cell, int flags)
  41.121 +{
  41.122 +	return PushArray(cell, 1, flags);
  41.123 +}
  41.124 +
  41.125 +int NativeInvoker::PushFloat(float number)
  41.126 +{
  41.127 +	cell_t val = *(cell_t *)&number;
  41.128 +
  41.129 +	return PushCell(val);
  41.130 +}
  41.131 +
  41.132 +int NativeInvoker::PushFloatByRef(float *number, int flags)
  41.133 +{
  41.134 +	return PushCellByRef((cell_t *)number, flags);
  41.135 +}
  41.136 +
  41.137 +int NativeInvoker::PushArray(cell_t *inarray, unsigned int cells, int copyback)
  41.138 +{
  41.139 +	if (m_curparam >= SP_MAX_EXEC_PARAMS)
  41.140 +	{
  41.141 +		return SetError(SP_ERROR_PARAMS_MAX);
  41.142 +	}
  41.143 +
  41.144 +	ParamInfo *info = &m_info[m_curparam];
  41.145 +
  41.146 +	info->flags = inarray ? copyback : 0;
  41.147 +	info->marked = true;
  41.148 +	info->size = cells;
  41.149 +	info->str.is_sz = false;
  41.150 +	info->orig_addr = inarray;
  41.151 +
  41.152 +	m_curparam++;
  41.153 +
  41.154 +	return SP_ERROR_NONE;
  41.155 +}
  41.156 +
  41.157 +int NativeInvoker::PushString(const char *string)
  41.158 +{
  41.159 +	return _PushString(string, SM_PARAM_STRING_COPY, 0, strlen(string)+1);
  41.160 +}
  41.161 +
  41.162 +int NativeInvoker::PushStringEx(char *buffer, size_t length, int sz_flags, int cp_flags)
  41.163 +{
  41.164 +	return _PushString(buffer, sz_flags, cp_flags, length);
  41.165 +}
  41.166 +
  41.167 +int NativeInvoker::_PushString(const char *string, int sz_flags, int cp_flags, size_t len)
  41.168 +{
  41.169 +	if (m_curparam >= SP_MAX_EXEC_PARAMS)
  41.170 +	{
  41.171 +		return SetError(SP_ERROR_PARAMS_MAX);
  41.172 +	}
  41.173 +
  41.174 +	ParamInfo *info = &m_info[m_curparam];
  41.175 +
  41.176 +	info->marked = true;
  41.177 +	info->orig_addr = (cell_t *)string;
  41.178 +	info->flags = cp_flags;
  41.179 +	info->size = len;
  41.180 +	info->str.sz_flags = sz_flags;
  41.181 +	info->str.is_sz = true;
  41.182 +
  41.183 +	m_curparam++;
  41.184 +
  41.185 +	return SP_ERROR_NONE;
  41.186 +}
  41.187 +
  41.188 +void NativeInvoker::Cancel()
  41.189 +{
  41.190 +	if (pContext == NULL)
  41.191 +	{
  41.192 +		return;
  41.193 +	}
  41.194 +
  41.195 +	m_errorstate = SP_ERROR_NONE;
  41.196 +	m_curparam = 0;
  41.197 +	pContext = NULL;
  41.198 +	native = NULL;
  41.199 +}
  41.200 +
  41.201 +int NativeInvoker::SetError(int err)
  41.202 +{
  41.203 +	m_errorstate = err;
  41.204 +	return err;
  41.205 +}
  41.206 +
  41.207 +int NativeInvoker::Invoke(cell_t *result)
  41.208 +{
  41.209 +	int err = SP_ERROR_NONE;
  41.210 +
  41.211 +	if (pContext == NULL)
  41.212 +	{
  41.213 +		return SP_ERROR_INVALID_NATIVE;
  41.214 +	}
  41.215 +
  41.216 +	if (m_errorstate != SP_ERROR_NONE)
  41.217 +	{
  41.218 +		err = m_errorstate;
  41.219 +		Cancel();
  41.220 +		return err;
  41.221 +	}
  41.222 +
  41.223 +	cell_t tresult;
  41.224 +
  41.225 +	if (result == NULL)
  41.226 +	{
  41.227 +		result = &tresult;
  41.228 +	}
  41.229 +
  41.230 +	//This is for re-entrancy!
  41.231 +	IPluginContext *ctx = pContext;
  41.232 +	cell_t _temp_params[SP_MAX_EXEC_PARAMS + 1];
  41.233 +	cell_t *temp_params = &_temp_params[1];
  41.234 +	ParamInfo temp_info[SP_MAX_EXEC_PARAMS];
  41.235 +	unsigned int numparams = m_curparam;
  41.236 +	unsigned int i;
  41.237 +	bool docopies = true;
  41.238 +
  41.239 +	if (numparams)
  41.240 +	{
  41.241 +		//Save the info locally, then reset it for re-entrant calls.
  41.242 +		memcpy(temp_info, m_info, numparams * sizeof(ParamInfo));
  41.243 +	}
  41.244 +	m_curparam = 0;
  41.245 +	pContext = NULL;
  41.246 +
  41.247 +	/* Initialize 0th parameter */
  41.248 +	_temp_params[0] = numparams;
  41.249 +
  41.250 +	/* Browse the parameters and build arrays */
  41.251 +	for (i = 0; i < numparams; i++)
  41.252 +	{
  41.253 +		/* Is this marked as an array? */
  41.254 +		if (temp_info[i].marked)
  41.255 +		{
  41.256 +			if (!temp_info[i].str.is_sz)
  41.257 +			{
  41.258 +				/* Allocate a normal/generic array */
  41.259 +				if ((err = ctx->HeapAlloc(temp_info[i].size, 
  41.260 +										  &temp_info[i].local_addr,
  41.261 +										  &temp_info[i].phys_addr))
  41.262 +					!= SP_ERROR_NONE)
  41.263 +				{
  41.264 +					break;
  41.265 +				}
  41.266 +				if (temp_info[i].orig_addr)
  41.267 +				{
  41.268 +					memcpy(temp_info[i].phys_addr, temp_info[i].orig_addr, sizeof(cell_t) * temp_info[i].size);
  41.269 +				}
  41.270 +			}
  41.271 +			else
  41.272 +			{
  41.273 +				/* Calculate cells required for the string */
  41.274 +				size_t cells = (temp_info[i].size + sizeof(cell_t) - 1) / sizeof(cell_t);
  41.275 +
  41.276 +				/* Allocate the buffer */
  41.277 +				if ((err = ctx->HeapAlloc(cells,
  41.278 +										  &temp_info[i].local_addr,
  41.279 +										  &temp_info[i].phys_addr))
  41.280 +					!= SP_ERROR_NONE)
  41.281 +				{
  41.282 +					break;
  41.283 +				}
  41.284 +				/* Copy original string if necessary */
  41.285 +				if ((temp_info[i].str.sz_flags & SM_PARAM_STRING_COPY) && (temp_info[i].orig_addr != NULL))
  41.286 +				{
  41.287 +					/* Cut off UTF-8 properly */
  41.288 +					if (temp_info[i].str.sz_flags & SM_PARAM_STRING_UTF8)
  41.289 +					{
  41.290 +						if ((err = ctx->StringToLocalUTF8(temp_info[i].local_addr, 
  41.291 +														  temp_info[i].size, 
  41.292 +														  (const char *)temp_info[i].orig_addr,
  41.293 +														  NULL))
  41.294 +							!= SP_ERROR_NONE)
  41.295 +						{
  41.296 +							break;
  41.297 +						}
  41.298 +					}
  41.299 +					/* Copy a binary blob */
  41.300 +					else if (temp_info[i].str.sz_flags & SM_PARAM_STRING_BINARY)
  41.301 +					{
  41.302 +						memmove(temp_info[i].phys_addr, temp_info[i].orig_addr, temp_info[i].size);
  41.303 +					}
  41.304 +					/* Copy ASCII characters */
  41.305 +					else
  41.306 +					{
  41.307 +						if ((err = ctx->StringToLocal(temp_info[i].local_addr,
  41.308 +													  temp_info[i].size,
  41.309 +													  (const char *)temp_info[i].orig_addr))
  41.310 +							!= SP_ERROR_NONE)
  41.311 +						{
  41.312 +							break;
  41.313 +						}
  41.314 +					}
  41.315 +				}
  41.316 +			} /* End array/string calculation */
  41.317 +			/* Update the pushed parameter with the byref local address */
  41.318 +			temp_params[i] = temp_info[i].local_addr;
  41.319 +		}
  41.320 +		else
  41.321 +		{
  41.322 +			/* Just copy the value normally */
  41.323 +			temp_params[i] = m_params[i];
  41.324 +		}
  41.325 +	}
  41.326 +
  41.327 +	/* Make the call if we can */
  41.328 +	if (err == SP_ERROR_NONE)
  41.329 +	{
  41.330 +		*result = native(ctx, _temp_params);
  41.331 +		if (ctx->GetLastNativeError() != SP_ERROR_NONE)
  41.332 +		{
  41.333 +			docopies = false;
  41.334 +			ctx->ClearLastNativeError();
  41.335 +		}
  41.336 +	}
  41.337 +	else
  41.338 +	{
  41.339 +		docopies = false;
  41.340 +	}
  41.341 +
  41.342 +	/* i should be equal to the last valid parameter + 1 */
  41.343 +	while (i--)
  41.344 +	{
  41.345 +		if (!temp_info[i].marked)
  41.346 +		{
  41.347 +			continue;
  41.348 +		}
  41.349 +
  41.350 +		if (docopies && (temp_info[i].flags & SM_PARAM_COPYBACK))
  41.351 +		{
  41.352 +			if (temp_info[i].orig_addr)
  41.353 +			{
  41.354 +				if (temp_info[i].str.is_sz)
  41.355 +				{
  41.356 +					memcpy(temp_info[i].orig_addr, temp_info[i].phys_addr, temp_info[i].size);
  41.357 +
  41.358 +				}
  41.359 +				else
  41.360 +				{
  41.361 +					if (temp_info[i].size == 1)
  41.362 +					{
  41.363 +						*temp_info[i].orig_addr = *(temp_info[i].phys_addr);
  41.364 +					}
  41.365 +					else
  41.366 +					{
  41.367 +						memcpy(temp_info[i].orig_addr, 
  41.368 +							temp_info[i].phys_addr, 
  41.369 +							temp_info[i].size * sizeof(cell_t));
  41.370 +					}
  41.371 +				}
  41.372 +			}
  41.373 +		}
  41.374 +
  41.375 +		if ((err = ctx->HeapPop(temp_info[i].local_addr)) != SP_ERROR_NONE)
  41.376 +		{
  41.377 +			return err;
  41.378 +		}
  41.379 +	}
  41.380 +
  41.381 +	return err;
  41.382 +}
    42.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    42.2 +++ b/core/logic/NativeInvoker.h	Fri Mar 29 11:37:29 2013 -0700
    42.3 @@ -0,0 +1,102 @@
    42.4 +/**
    42.5 + * vim: set ts=4 :
    42.6 + * =============================================================================
    42.7 + * SourceMod
    42.8 + * Copyright (C) 2004-2009 AlliedModders LLC.  All rights reserved.
    42.9 + * =============================================================================
   42.10 + *
   42.11 + * This program is free software; you can redistribute it and/or modify it under
   42.12 + * the terms of the GNU General Public License, version 3.0, as published by the
   42.13 + * Free Software Foundation.
   42.14 + * 
   42.15 + * This program is distributed in the hope that it will be useful, but WITHOUT
   42.16 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   42.17 + * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
   42.18 + * details.
   42.19 + *
   42.20 + * You should have received a copy of the GNU General Public License along with
   42.21 + * this program.  If not, see <http://www.gnu.org/licenses/>.
   42.22 + *
   42.23 + * As a special exception, AlliedModders LLC gives you permission to link the
   42.24 + * code of this program (as well as its derivative works) to "Half-Life 2," the
   42.25 + * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
   42.26 + * by the Valve Corporation.  You must obey the GNU General Public License in
   42.27 + * all respects for all other code used.  Additionally, AlliedModders LLC grants
   42.28 + * this exception to all derivative works.  AlliedModders LLC defines further
   42.29 + * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
   42.30 + * or <http://www.sourcemod.net/license.php>.
   42.31 + *
   42.32 + * Version: $Id$
   42.33 + */
   42.34 +
   42.35 +#ifndef _INCLUDE_SOURCEMOD_NATIVE_INVOKER_H_
   42.36 +#define _INCLUDE_SOURCEMOD_NATIVE_INVOKER_H_
   42.37 +
   42.38 +#include <sp_vm_api.h>
   42.39 +#include <INativeInvoker.h>
   42.40 +#include "common_logic.h"
   42.41 +
   42.42 +using namespace SourceMod;
   42.43 +using namespace SourcePawn;
   42.44 +
   42.45 +struct ParamInfo
   42.46 +{
   42.47 +	int flags;			/* Copy-back flags */
   42.48 +	bool marked;		/* Whether this is marked as being used */
   42.49 +	cell_t local_addr;	/* Local address to free */
   42.50 +	cell_t *phys_addr;	/* Physical address of our copy */
   42.51 +	cell_t *orig_addr;	/* Original address to copy back to */
   42.52 +	ucell_t size;		/* Size of array in bytes */
   42.53 +	struct
   42.54 +	{
   42.55 +		bool is_sz;		/* is a string */
   42.56 +		int sz_flags;	/* has sz flags */
   42.57 +	} str;
   42.58 +};
   42.59 +
   42.60 +class NativeInvoker : public INativeInvoker
   42.61 +{
   42.62 +public:
   42.63 +	NativeInvoker();
   42.64 +	~NativeInvoker();
   42.65 +public: /* ICallable */
   42.66 +	int PushCell(cell_t cell);
   42.67 +	int PushCellByRef(cell_t *cell, int flags=SM_PARAM_COPYBACK);
   42.68 +	int PushFloat(float number);
   42.69 +	int PushFloatByRef(float *number, int flags=SM_PARAM_COPYBACK);
   42.70 +	int PushArray(cell_t *inarray, unsigned int cells, int flags=0);
   42.71 +	int PushString(const char *string);
   42.72 +	int PushStringEx(char *buffer, size_t length, int sz_flags, int cp_flags);
   42.73 +	void Cancel();
   42.74 +public: /* INativeInvoker */
   42.75 +	bool Start(IPluginContext *pContext, const char *name);
   42.76 +	int Invoke(cell_t *result);
   42.77 +private:
   42.78 +	int _PushString(const char *string, int sz_flags, int cp_flags, size_t len);
   42.79 +	int SetError(int err);
   42.80 +private:
   42.81 +	IPluginContext *pContext;
   42.82 +	SPVM_NATIVE_FUNC native;
   42.83 +	cell_t m_params[SP_MAX_EXEC_PARAMS];
   42.84 +	ParamInfo m_info[SP_MAX_EXEC_PARAMS];
   42.85 +	unsigned int m_curparam;
   42.86 +	int m_errorstate;
   42.87 +};
   42.88 +
   42.89 +class NativeInterface : 
   42.90 +	public INativeInterface,
   42.91 +	public SMGlobalClass
   42.92 +{
   42.93 +public: /* SMGlobalClass */
   42.94 +	void OnSourceModAllInitialized();
   42.95 +public: /* SMInterface */
   42.96 +	unsigned int GetInterfaceVersion();
   42.97 +	const char *GetInterfaceName();
   42.98 +public: /* INativeInvoker */
   42.99 +	IPluginRuntime *CreateRuntime(const char *name, size_t bytes);
  42.100 +	INativeInvoker *CreateInvoker();
  42.101 +};
  42.102 +
  42.103 +extern NativeInterface g_NInvoke;
  42.104 +
  42.105 +#endif /* _INCLUDE_SOURCEMOD_NATIVE_INVOKER_H_ */
    43.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    43.2 +++ b/core/logic/NativeOwner.cpp	Fri Mar 29 11:37:29 2013 -0700
    43.3 @@ -0,0 +1,174 @@
    43.4 +/**
    43.5 + * vim: set ts=4 :
    43.6 + * =============================================================================
    43.7 + * SourcePawn
    43.8 + * Copyright (C) 2004-2009 AlliedModders LLC.  All rights reserved.
    43.9 + * =============================================================================
   43.10 + *
   43.11 + * This program is free software; you can redistribute it and/or modify it under
   43.12 + * the terms of the GNU General Public License, version 3.0, as published by the
   43.13 + * Free Software Foundation.
   43.14 + * 
   43.15 + * This program is distributed in the hope that it will be useful, but WITHOUT
   43.16 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   43.17 + * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
   43.18 + * details.
   43.19 + *
   43.20 + * You should have received a copy of the GNU General Public License along with
   43.21 + * this program.  If not, see <http://www.gnu.org/licenses/>.
   43.22 + *
   43.23 + * As a special exception, AlliedModders LLC gives you permission to link the
   43.24 + * code of this program (as well as its derivative works) to "Half-Life 2," the
   43.25 + * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
   43.26 + * by the Valve Corporation.  You must obey the GNU General Public License in
   43.27 + * all respects for all other code used.  Additionally, AlliedModders LLC grants
   43.28 + * this exception to all derivative works.  AlliedModders LLC defines further
   43.29 + * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
   43.30 + * or <http://www.sourcemod.net/license.php>.
   43.31 + *
   43.32 + * Version: $Id$
   43.33 + */
   43.34 +#include "NativeOwner.h"
   43.35 +#include "ShareSys.h"
   43.36 +#include "PluginSys.h"
   43.37 +
   43.38 +CNativeOwner::CNativeOwner() : m_nMarkSerial(0)
   43.39 +{
   43.40 +}
   43.41 +
   43.42 +void CNativeOwner::SetMarkSerial(unsigned int serial)
   43.43 +{
   43.44 +	m_nMarkSerial = serial;
   43.45 +}
   43.46 +
   43.47 +unsigned int CNativeOwner::GetMarkSerial()
   43.48 +{
   43.49 +	return m_nMarkSerial;
   43.50 +}
   43.51 +
   43.52 +void CNativeOwner::AddDependent(CPlugin *pPlugin)
   43.53 +{
   43.54 +	m_Dependents.push_back(pPlugin);
   43.55 +}
   43.56 +
   43.57 +void CNativeOwner::AddWeakRef(const WeakNative & ref)
   43.58 +{
   43.59 +	m_WeakRefs.push_back(ref);
   43.60 +}
   43.61 +
   43.62 +void CNativeOwner::AddNatives(const sp_nativeinfo_t *natives)
   43.63 +{
   43.64 +	NativeEntry *pEntry;
   43.65 +
   43.66 +	for (unsigned int i = 0; natives[i].func != NULL && natives[i].name != NULL; i++)
   43.67 +	{
   43.68 +		if ((pEntry = g_ShareSys.AddNativeToCache(this, &natives[i])) == NULL)
   43.69 +		{
   43.70 +			continue;
   43.71 +		}
   43.72 +
   43.73 +		m_Natives.push_back(pEntry);
   43.74 +	}
   43.75 +}
   43.76 +
   43.77 +void CNativeOwner::PropagateMarkSerial(unsigned int serial)
   43.78 +{
   43.79 +	CNativeOwner *pOwner;
   43.80 +	List<CPlugin *>::iterator iter;
   43.81 +
   43.82 +	for (iter = m_Dependents.begin();
   43.83 +		 iter != m_Dependents.end();
   43.84 +		 iter++)
   43.85 +	{
   43.86 +		pOwner = (*iter);
   43.87 +		pOwner->SetMarkSerial(serial);
   43.88 +	}
   43.89 +}
   43.90 +
   43.91 +void CNativeOwner::UnbindWeakRef(const WeakNative & ref)
   43.92 +{
   43.93 +	sp_native_t *native;
   43.94 +	IPluginContext *pContext;
   43.95 +
   43.96 +	pContext = ref.pl->GetBaseContext();
   43.97 +	if ((pContext->GetNativeByIndex(ref.idx, &native)) == SP_ERROR_NONE)
   43.98 +	{
   43.99 +		/* If there is no reference, the native must be unbound */
  43.100 +		if (ref.entry == NULL)
  43.101 +		{
  43.102 +			native->status = SP_NATIVE_UNBOUND;
  43.103 +			native->pfn = NULL;
  43.104 +		}
  43.105 +		/* If we've cached a reference, it's a core native we can 
  43.106 +		 * rebind back to its original (this was a replacement).
  43.107 +		 */
  43.108 +		else
  43.109 +		{
  43.110 +			native->pfn = ref.entry->func;
  43.111 +		}
  43.112 +	}
  43.113 +}
  43.114 +
  43.115 +void CNativeOwner::DropEverything()
  43.116 +{
  43.117 +	NativeEntry *pEntry;
  43.118 +	List<WeakNative>::iterator iter;
  43.119 +	List<NativeEntry *>::iterator ntv_iter;
  43.120 +
  43.121 +	/* Unbind and remove all weak references to us */
  43.122 +	iter = m_WeakRefs.begin();
  43.123 +	while (iter != m_WeakRefs.end())
  43.124 +	{
  43.125 +		UnbindWeakRef((*iter));
  43.126 +		iter = m_WeakRefs.erase(iter);
  43.127 +	}
  43.128 +
  43.129 +	/* Unmark our replacement natives */
  43.130 +	ntv_iter = m_ReplacedNatives.begin();
  43.131 +	while (ntv_iter != m_ReplacedNatives.end())
  43.132 +	{
  43.133 +		pEntry = (*ntv_iter);
  43.134 +		pEntry->replacement.func = NULL;
  43.135 +		pEntry->replacement.owner = NULL;
  43.136 +		ntv_iter = m_ReplacedNatives.erase(ntv_iter);
  43.137 +	}
  43.138 +
  43.139 +	/* Strip all of our natives from the cache */
  43.140 +	ntv_iter = m_Natives.begin();
  43.141 +	while (ntv_iter != m_Natives.end())
  43.142 +	{
  43.143 +		g_ShareSys.ClearNativeFromCache(this, (*ntv_iter)->name);
  43.144 +		ntv_iter = m_Natives.erase(ntv_iter);
  43.145 +	}
  43.146 +}
  43.147 +
  43.148 +void CNativeOwner::DropWeakRefsTo(CPlugin *pPlugin)
  43.149 +{
  43.150 +	List<WeakNative>::iterator iter;
  43.151 +
  43.152 +	iter = m_WeakRefs.begin();
  43.153 +	while (iter != m_WeakRefs.end())
  43.154 +	{
  43.155 +		WeakNative & ref = (*iter);
  43.156 +
  43.157 +		if (ref.pl == pPlugin)
  43.158 +		{
  43.159 +			iter = m_WeakRefs.erase(iter);
  43.160 +		}
  43.161 +		else
  43.162 +		{
  43.163 +			iter++;
  43.164 +		}
  43.165 +	}
  43.166 +}
  43.167 +
  43.168 +void CNativeOwner::DropRefsTo(CPlugin *pPlugin)
  43.169 +{
  43.170 +	m_Dependents.remove(pPlugin);
  43.171 +	DropWeakRefsTo(pPlugin);
  43.172 +}
  43.173 +
  43.174 +void CNativeOwner::AddReplacedNative(NativeEntry *pEntry)
  43.175 +{
  43.176 +	m_ReplacedNatives.push_back(pEntry);
  43.177 +}
    44.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    44.2 +++ b/core/logic/NativeOwner.h	Fri Mar 29 11:37:29 2013 -0700
    44.3 @@ -0,0 +1,64 @@
    44.4 +#ifndef _INCLUDE_SOURCEMOD_NATIVE_OWNER_H_
    44.5 +#define _INCLUDE_SOURCEMOD_NATIVE_OWNER_H_
    44.6 +
    44.7 +#include <sp_vm_types.h>
    44.8 +#include <sh_list.h>
    44.9 +#include "common_logic.h"
   44.10 +
   44.11 +struct NativeEntry;
   44.12 +class CPlugin;
   44.13 +
   44.14 +using namespace SourceMod;
   44.15 +
   44.16 +struct WeakNative
   44.17 +{
   44.18 +	WeakNative(IPlugin *plugin, uint32_t index) : 
   44.19 +		pl(plugin), idx(index), entry(NULL)
   44.20 +	{
   44.21 +		pl = plugin;
   44.22 +		idx = index;
   44.23 +	}
   44.24 +	WeakNative(IPlugin *plugin, uint32_t index, NativeEntry *pEntry) : 
   44.25 +		pl(plugin), idx(index), entry(pEntry)
   44.26 +	{
   44.27 +		pl = plugin;
   44.28 +		idx = index;
   44.29 +	}
   44.30 +	IPlugin *pl;
   44.31 +	uint32_t idx;
   44.32 +	NativeEntry *entry;
   44.33 +};
   44.34 +
   44.35 +using namespace SourceHook;
   44.36 +
   44.37 +class CNativeOwner
   44.38 +{
   44.39 +public:
   44.40 +	CNativeOwner();
   44.41 +public:
   44.42 +	virtual void DropEverything();
   44.43 +public:
   44.44 +	void AddNatives(const sp_nativeinfo_t *info);
   44.45 +public:
   44.46 +	void SetMarkSerial(unsigned int serial);
   44.47 +	unsigned int GetMarkSerial();
   44.48 +	void PropagateMarkSerial(unsigned int serial);
   44.49 +public:
   44.50 +	void AddDependent(CPlugin *pPlugin);
   44.51 +	void AddWeakRef(const WeakNative & ref);
   44.52 +	void DropRefsTo(CPlugin *pPlugin);
   44.53 +	void AddReplacedNative(NativeEntry *pEntry);
   44.54 +private:
   44.55 +	void DropWeakRefsTo(CPlugin *pPlugin);
   44.56 +	void UnbindWeakRef(const WeakNative & ref);
   44.57 +protected:
   44.58 +	List<CPlugin *> m_Dependents;
   44.59 +	unsigned int m_nMarkSerial;
   44.60 +	List<WeakNative> m_WeakRefs;
   44.61 +	List<NativeEntry *> m_Natives;
   44.62 +	List<NativeEntry *> m_ReplacedNatives;
   44.63 +};
   44.64 +
   44.65 +extern CNativeOwner g_CoreNatives;
   44.66 +
   44.67 +#endif //_INCLUDE_SOURCEMOD_NATIVE_OWNER_H_
    45.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    45.2 +++ b/core/logic/PluginSys.cpp	Fri Mar 29 11:37:29 2013 -0700
    45.3 @@ -0,0 +1,2693 @@
    45.4 +/**
    45.5 + * vim: set ts=4 :
    45.6 + * =============================================================================
    45.7 + * SourceMod
    45.8 + * Copyright (C) 2004-2008 AlliedModders LLC.  All rights reserved.
    45.9 + * =============================================================================
   45.10 + *
   45.11 + * This program is free software; you can redistribute it and/or modify it under
   45.12 + * the terms of the GNU General Public License, version 3.0, as published by the
   45.13 + * Free Software Foundation.
   45.14 + * 
   45.15 + * This program is distributed in the hope that it will be useful, but WITHOUT
   45.16 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   45.17 + * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
   45.18 + * details.
   45.19 + *
   45.20 + * You should have received a copy of the GNU General Public License along with
   45.21 + * this program.  If not, see <http://www.gnu.org/licenses/>.
   45.22 + *
   45.23 + * As a special exception, AlliedModders LLC gives you permission to link the
   45.24 + * code of this program (as well as its derivative works) to "Half-Life 2," the
   45.25 + * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
   45.26 + * by the Valve Corporation.  You must obey the GNU General Public License in
   45.27 + * all respects for all other code used.  Additionally, AlliedModders LLC grants
   45.28 + * this exception to all derivative works.  AlliedModders LLC defines further
   45.29 + * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
   45.30 + * or <http://www.sourcemod.net/license.php>.
   45.31 + *
   45.32 + * Version: $Id$
   45.33 + */
   45.34 +
   45.35 +#include <stdio.h>
   45.36 +#include "PluginSys.h"
   45.37 +#include "ShareSys.h"
   45.38 +#include <ILibrarySys.h>
   45.39 +#include <ISourceMod.h>
   45.40 +#include <IHandleSys.h>
   45.41 +#include <IForwardSys.h>
   45.42 +#include <IPlayerHelpers.h>
   45.43 +#include "ExtensionSys.h"
   45.44 +#include "GameConfigs.h"
   45.45 +#include "common_logic.h"
   45.46 +#include "Translator.h"
   45.47 +
   45.48 +CPluginManager g_PluginSys;
   45.49 +HandleType_t g_PluginType = 0;
   45.50 +IdentityType_t g_PluginIdent = 0;
   45.51 +
   45.52 +CPlugin::CPlugin(const char *file)
   45.53 +{
   45.54 +	static int MySerial = 0;
   45.55 +
   45.56 +	m_type = PluginType_Private;
   45.57 +	m_status = Plugin_Uncompiled;
   45.58 +	m_bSilentlyFailed = false;
   45.59 +	m_serial = ++MySerial;
   45.60 +	m_pRuntime = NULL;
   45.61 +	m_errormsg[sizeof(m_errormsg) - 1] = '\0';
   45.62 +	smcore.Format(m_filename, sizeof(m_filename), "%s", file);
   45.63 +	m_handle = 0;
   45.64 +	m_ident = NULL;
   45.65 +	m_FakeNativesMissing = false;
   45.66 +	m_LibraryMissing = false;
   45.67 +	m_bGotAllLoaded = false;
   45.68 +	m_pPhrases = g_Translator.CreatePhraseCollection();
   45.69 +	m_MaxClientsVar = NULL;
   45.70 +}
   45.71 +
   45.72 +CPlugin::~CPlugin()
   45.73 +{
   45.74 +	if (m_handle)
   45.75 +	{
   45.76 +		HandleSecurity sec;
   45.77 +		sec.pOwner = g_PluginSys.GetIdentity();
   45.78 +		sec.pIdentity = sec.pOwner;
   45.79 +
   45.80 +		handlesys->FreeHandle(m_handle, &sec);
   45.81 +		g_ShareSys.DestroyIdentity(m_ident);
   45.82 +	}
   45.83 +
   45.84 +	if (m_pRuntime != NULL)
   45.85 +	{
   45.86 +		delete m_pRuntime;
   45.87 +		m_pRuntime = NULL;
   45.88 +	}
   45.89 +
   45.90 +	for (size_t i=0; i<m_configs.size(); i++)
   45.91 +	{
   45.92 +		delete m_configs[i];
   45.93 +	}
   45.94 +	m_configs.clear();
   45.95 +	if (m_pPhrases != NULL)
   45.96 +	{
   45.97 +		m_pPhrases->Destroy();
   45.98 +		m_pPhrases = NULL;
   45.99 +	}
  45.100 +}
  45.101 +
  45.102 +void CPlugin::InitIdentity()
  45.103 +{
  45.104 +	if (!m_handle)
  45.105 +	{
  45.106 +		m_ident = g_ShareSys.CreateIdentity(g_PluginIdent, this);
  45.107 +		m_handle = handlesys->CreateHandle(g_PluginType, this, g_PluginSys.GetIdentity(), g_PluginSys.GetIdentity(), NULL);
  45.108 +		m_pRuntime->GetDefaultContext()->SetKey(1, m_ident);
  45.109 +		m_pRuntime->GetDefaultContext()->SetKey(2, (IPlugin *)this);
  45.110 +	}
  45.111 +}
  45.112 +
  45.113 +unsigned int CPlugin::CalcMemUsage()
  45.114 +{
  45.115 +	unsigned int base_size = 
  45.116 +		sizeof(CPlugin) 
  45.117 +		+ sizeof(IdentityToken_t)
  45.118 +		+ (m_configs.size() * (sizeof(AutoConfig *) + sizeof(AutoConfig)))
  45.119 +		+ m_pProps.mem_usage();
  45.120 +
  45.121 +	for (unsigned int i = 0; i < m_configs.size(); i++)
  45.122 +	{
  45.123 +		base_size += m_configs[i]->autocfg.size();
  45.124 +		base_size += m_configs[i]->folder.size();
  45.125 +	}
  45.126 +
  45.127 +	for (List<String>::iterator i = m_Libraries.begin();
  45.128 +		 i != m_Libraries.end();
  45.129 +		 i++)
  45.130 +	{
  45.131 +		base_size += (*i).size();
  45.132 +	}
  45.133 +
  45.134 +	for (List<String>::iterator i = m_RequiredLibs.begin();
  45.135 +		 i != m_RequiredLibs.end();
  45.136 +		 i++)
  45.137 +	{
  45.138 +		base_size += (*i).size();
  45.139 +	}
  45.140 +
  45.141 +	return base_size;
  45.142 +}
  45.143 +
  45.144 +Handle_t CPlugin::GetMyHandle()
  45.145 +{
  45.146 +	return m_handle;
  45.147 +}
  45.148 +
  45.149 +CPlugin *CPlugin::CreatePlugin(const char *file, char *error, size_t maxlength)
  45.150 +{
  45.151 +	char fullpath[PLATFORM_MAX_PATH];
  45.152 +	g_pSM->BuildPath(Path_SM, fullpath, sizeof(fullpath), "plugins/%s", file);
  45.153 +	FILE *fp = fopen(fullpath, "rb");
  45.154 +
  45.155 +	CPlugin *pPlugin = new CPlugin(file);
  45.156 +
  45.157 +	if (!fp)
  45.158 +	{
  45.159 +		if (error)
  45.160 +		{
  45.161 +			smcore.Format(error, maxlength, "Unable to open file");
  45.162 +		}
  45.163 +		pPlugin->m_status = Plugin_BadLoad;
  45.164 +		return pPlugin;
  45.165 +	}
  45.166 +
  45.167 +	fclose(fp);
  45.168 +
  45.169 +	return pPlugin;
  45.170 +}
  45.171 +
  45.172 +bool CPlugin::GetProperty(const char *prop, void **ptr, bool remove/* =false */)
  45.173 +{
  45.174 +	void **ptrpp = m_pProps.retrieve(prop);
  45.175 +	bool exists = !!ptrpp;
  45.176 +
  45.177 +	if (exists)
  45.178 +	{
  45.179 +		*ptr = *ptrpp;
  45.180 +		if (remove)
  45.181 +			m_pProps.remove(prop);
  45.182 +	}
  45.183 +
  45.184 +	return exists;
  45.185 +}
  45.186 +
  45.187 +bool CPlugin::SetProperty(const char *prop, void *ptr)
  45.188 +{
  45.189 +	 return m_pProps.insert(prop, ptr);
  45.190 +}
  45.191 +
  45.192 +IPluginRuntime *CPlugin::GetRuntime()
  45.193 +{
  45.194 +	return m_pRuntime;
  45.195 +}
  45.196 +
  45.197 +void CPlugin::SetErrorState(PluginStatus status, const char *error_fmt, ...)
  45.198 +{
  45.199 +	PluginStatus old_status = m_status;
  45.200 +	m_status = status;
  45.201 +
  45.202 +	if (old_status == Plugin_Running)
  45.203 +	{
  45.204 +		/* Tell everyone we're now paused */
  45.205 +		g_PluginSys._SetPauseState(this, true);
  45.206 +	}
  45.207 +
  45.208 +	va_list ap;
  45.209 +	va_start(ap, error_fmt);
  45.210 +	smcore.FormatArgs(m_errormsg, sizeof(m_errormsg), error_fmt, ap);
  45.211 +	va_end(ap);
  45.212 +
  45.213 +	if (m_pRuntime != NULL)
  45.214 +	{
  45.215 +		m_pRuntime->SetPauseState(true);
  45.216 +	}
  45.217 +}
  45.218 +
  45.219 +bool CPlugin::UpdateInfo()
  45.220 +{
  45.221 +	/* Now grab the info */
  45.222 +	uint32_t idx;
  45.223 +	IPluginContext *base = GetBaseContext();
  45.224 +	int err = base->FindPubvarByName("myinfo", &idx);
  45.225 +
  45.226 +	memset(&m_info, 0, sizeof(m_info));
  45.227 +
  45.228 +	if (err == SP_ERROR_NONE)
  45.229 +	{
  45.230 +		struct sm_plugininfo_c_t
  45.231 +		{
  45.232 +			cell_t name;
  45.233 +			cell_t description;
  45.234 +			cell_t author;
  45.235 +			cell_t version;
  45.236 +			cell_t url;
  45.237 +		};
  45.238 +		sm_plugininfo_c_t *cinfo;
  45.239 +		cell_t local_addr;
  45.240 +
  45.241 +		base->GetPubvarAddrs(idx, &local_addr, (cell_t **)&cinfo);
  45.242 +		base->LocalToString(cinfo->name, (char **)&m_info.name);
  45.243 +		base->LocalToString(cinfo->description, (char **)&m_info.description);
  45.244 +		base->LocalToString(cinfo->author, (char **)&m_info.author);
  45.245 +		base->LocalToString(cinfo->url, (char **)&m_info.url);
  45.246 +		base->LocalToString(cinfo->version, (char **)&m_info.version);
  45.247 +	}
  45.248 +
  45.249 +	m_info.author = m_info.author ? m_info.author : "";
  45.250 +	m_info.description = m_info.description ? m_info.description : "";
  45.251 +	m_info.name = m_info.name ? m_info.name : "";
  45.252 +	m_info.url = m_info.url ? m_info.url : "";
  45.253 +	m_info.version = m_info.version ? m_info.version : "";
  45.254 +
  45.255 +	if ((err = base->FindPubvarByName("__version", &idx)) == SP_ERROR_NONE)
  45.256 +	{
  45.257 +		struct __version_info
  45.258 +		{
  45.259 +			cell_t version;
  45.260 +			cell_t filevers;
  45.261 +			cell_t date;
  45.262 +			cell_t time;
  45.263 +		};
  45.264 +		__version_info *info;
  45.265 +		cell_t local_addr;
  45.266 +		const char *pDate, *pTime, *pFileVers;
  45.267 +
  45.268 +		pDate = "";
  45.269 +		pTime = "";
  45.270 +
  45.271 +		base->GetPubvarAddrs(idx, &local_addr, (cell_t **)&info);
  45.272 +		m_FileVersion = info->version;
  45.273 +		if (m_FileVersion >= 4)
  45.274 +		{
  45.275 +			base->LocalToString(info->date, (char **)&pDate);
  45.276 +			base->LocalToString(info->time, (char **)&pTime);
  45.277 +			smcore.Format(m_DateTime, sizeof(m_DateTime), "%s %s", pDate, pTime);
  45.278 +		}
  45.279 +		if (m_FileVersion > 5)
  45.280 +		{
  45.281 +			base->LocalToString(info->filevers, (char **)&pFileVers);
  45.282 +			SetErrorState(Plugin_Failed, "Newer SourceMod required (%s or higher)", pFileVers);
  45.283 +			return false;
  45.284 +		}
  45.285 +	}
  45.286 +	else
  45.287 +	{
  45.288 +		m_FileVersion = 0;
  45.289 +	}
  45.290 +
  45.291 +	if ((err = base->FindPubvarByName("MaxClients", &idx)) == SP_ERROR_NONE)
  45.292 +	{
  45.293 +		base->GetPubvarByIndex(idx, &m_MaxClientsVar);
  45.294 +	}
  45.295 +
  45.296 +	return true;
  45.297 +}
  45.298 +
  45.299 +void CPlugin::SyncMaxClients(int max_clients)
  45.300 +{
  45.301 +	if (m_MaxClientsVar == NULL)
  45.302 +	{
  45.303 +		return;
  45.304 +	}
  45.305 +
  45.306 +	*m_MaxClientsVar->offs = max_clients;
  45.307 +}
  45.308 +
  45.309 +void CPlugin::Call_OnPluginStart()
  45.310 +{
  45.311 +	if (m_status != Plugin_Loaded)
  45.312 +	{
  45.313 +		return;
  45.314 +	}
  45.315 +
  45.316 +	m_status = Plugin_Running;
  45.317 +
  45.318 +	SyncMaxClients(playerhelpers->GetMaxClients());
  45.319 +
  45.320 +	cell_t result;
  45.321 +	IPluginFunction *pFunction = m_pRuntime->GetFunctionByName("OnPluginStart");
  45.322 +	if (!pFunction)
  45.323 +	{
  45.324 +		return;
  45.325 +	}
  45.326 +
  45.327 +	int err;
  45.328 +	if ((err=pFunction->Execute(&result)) != SP_ERROR_NONE)
  45.329 +	{
  45.330 +		SetErrorState(Plugin_Error, "Error detected in plugin startup (see error logs)");
  45.331 +	}
  45.332 +}
  45.333 +
  45.334 +void CPlugin::Call_OnPluginEnd()
  45.335 +{
  45.336 +	if (m_status > Plugin_Paused)
  45.337 +	{
  45.338 +		return;
  45.339 +	}
  45.340 +
  45.341 +	cell_t result;
  45.342 +	IPluginFunction *pFunction = m_pRuntime->GetFunctionByName("OnPluginEnd");
  45.343 +	if (!pFunction)
  45.344 +	{
  45.345 +		return;
  45.346 +	}
  45.347 +
  45.348 +	pFunction->Execute(&result);
  45.349 +}
  45.350 +
  45.351 +void CPlugin::Call_OnAllPluginsLoaded()
  45.352 +{
  45.353 +	if (m_status > Plugin_Paused)
  45.354 +	{
  45.355 +		return;
  45.356 +	}
  45.357 +
  45.358 +	if (m_bGotAllLoaded)
  45.359 +	{
  45.360 +		return;
  45.361 +	}
  45.362 +
  45.363 +	m_bGotAllLoaded = true;
  45.364 +
  45.365 +	cell_t result;
  45.366 +	IPluginFunction *pFunction = m_pRuntime->GetFunctionByName("OnAllPluginsLoaded");
  45.367 +	if (pFunction != NULL)
  45.368 +	{
  45.369 +		pFunction->Execute(&result);
  45.370 +	}
  45.371 +
  45.372 +	if (smcore.IsMapRunning())
  45.373 +	{
  45.374 +		if ((pFunction = m_pRuntime->GetFunctionByName("OnMapStart")) != NULL)
  45.375 +		{
  45.376 +			pFunction->Execute(NULL);
  45.377 +		}
  45.378 +	}
  45.379 +
  45.380 +	if (smcore.AreConfigsExecuted())
  45.381 +	{
  45.382 +		smcore.ExecuteConfigs(GetBaseContext());
  45.383 +	}
  45.384 +}
  45.385 +
  45.386 +APLRes CPlugin::Call_AskPluginLoad(char *error, size_t maxlength)
  45.387 +{
  45.388 +	if (m_status != Plugin_Created)
  45.389 +	{
  45.390 +		return APLRes_Failure;
  45.391 +	}
  45.392 +
  45.393 +	m_status = Plugin_Loaded;
  45.394 +
  45.395 +	int err;
  45.396 +	cell_t result;
  45.397 +	bool haveNewAPL = false;
  45.398 +	IPluginFunction *pFunction = m_pRuntime->GetFunctionByName("AskPluginLoad2");
  45.399 +
  45.400 +	if (pFunction) 
  45.401 +	{
  45.402 +		haveNewAPL = true;
  45.403 +	}
  45.404 +	else if (!(pFunction = m_pRuntime->GetFunctionByName("AskPluginLoad")))
  45.405 +	{
  45.406 +		return APLRes_Success;
  45.407 +	}
  45.408 +
  45.409 +	pFunction->PushCell(m_handle);
  45.410 +	pFunction->PushCell(g_PluginSys.IsLateLoadTime() ? 1 : 0);
  45.411 +	pFunction->PushStringEx(error, maxlength, 0, SM_PARAM_COPYBACK);
  45.412 +	pFunction->PushCell(maxlength);
  45.413 +	if ((err=pFunction->Execute(&result)) != SP_ERROR_NONE)
  45.414 +	{
  45.415 +		return APLRes_Failure;
  45.416 +	}
  45.417 +
  45.418 +	if (haveNewAPL) 
  45.419 +	{
  45.420 +		return (APLRes)result;
  45.421 +	}
  45.422 +	else if (result)
  45.423 +	{
  45.424 +		return APLRes_Success;
  45.425 +	}
  45.426 +	else
  45.427 +	{
  45.428 +		return APLRes_Failure;
  45.429 +	}
  45.430 +}
  45.431 +
  45.432 +void *CPlugin::GetPluginStructure()
  45.433 +{
  45.434 +	return NULL;
  45.435 +}
  45.436 +
  45.437 +IPluginContext *CPlugin::GetBaseContext()
  45.438 +{
  45.439 +	if (m_pRuntime == NULL)
  45.440 +	{
  45.441 +		return NULL;
  45.442 +	}
  45.443 +
  45.444 +	return m_pRuntime->GetDefaultContext();
  45.445 +}
  45.446 +
  45.447 +sp_context_t *CPlugin::GetContext()
  45.448 +{
  45.449 +	return NULL;
  45.450 +}
  45.451 +
  45.452 +const char *CPlugin::GetFilename()
  45.453 +{
  45.454 +	return m_filename;
  45.455 +}
  45.456 +
  45.457 +PluginType CPlugin::GetType()
  45.458 +{
  45.459 +	return m_type;
  45.460 +}
  45.461 +
  45.462 +const sm_plugininfo_t *CPlugin::GetPublicInfo()
  45.463 +{
  45.464 +	if (GetStatus() >= Plugin_Created)
  45.465 +	{
  45.466 +		return NULL;
  45.467 +	}
  45.468 +	return &m_info;
  45.469 +}
  45.470 +
  45.471 +unsigned int CPlugin::GetSerial()
  45.472 +{
  45.473 +	return m_serial;
  45.474 +}
  45.475 +
  45.476 +PluginStatus CPlugin::GetStatus()
  45.477 +{
  45.478 +	return m_status;
  45.479 +}
  45.480 +
  45.481 +bool CPlugin::IsSilentlyFailed()
  45.482 +{
  45.483 +	return m_bSilentlyFailed;
  45.484 +}
  45.485 +
  45.486 +bool CPlugin::IsDebugging()
  45.487 +{
  45.488 +	if (m_pRuntime == NULL)
  45.489 +	{
  45.490 +		return false;
  45.491 +	}
  45.492 +
  45.493 +	return true;
  45.494 +}
  45.495 +
  45.496 +void CPlugin::SetSilentlyFailed(bool sf)
  45.497 +{
  45.498 +	m_bSilentlyFailed = sf;
  45.499 +}
  45.500 +
  45.501 +void CPlugin::LibraryActions(LibraryAction action)
  45.502 +{
  45.503 +	List<String>::iterator iter;
  45.504 +	for (iter = m_Libraries.begin();
  45.505 +		iter != m_Libraries.end();
  45.506 +		iter++)
  45.507 +	{
  45.508 +		g_PluginSys.OnLibraryAction((*iter).c_str(), action);
  45.509 +	}
  45.510 +}
  45.511 +
  45.512 +bool CPlugin::SetPauseState(bool paused)
  45.513 +{
  45.514 +	if (paused && GetStatus() != Plugin_Running)
  45.515 +	{
  45.516 +		return false;
  45.517 +	} else if (!paused && GetStatus() != Plugin_Paused) {
  45.518 +		return false;
  45.519 +	}
  45.520 +
  45.521 +	if (paused)
  45.522 +	{
  45.523 +		LibraryActions(LibraryAction_Removed);
  45.524 +	}
  45.525 +
  45.526 +	IPluginFunction *pFunction = m_pRuntime->GetFunctionByName("OnPluginPauseChange");
  45.527 +	if (pFunction)
  45.528 +	{
  45.529 +		cell_t result;
  45.530 +		pFunction->PushCell(paused ? 1 : 0);
  45.531 +		pFunction->Execute(&result);
  45.532 +	}
  45.533 +
  45.534 +	if (paused)
  45.535 +	{
  45.536 +		m_status = Plugin_Paused;
  45.537 +		m_pRuntime->SetPauseState(true);
  45.538 +	} else {
  45.539 +		m_status = Plugin_Running;
  45.540 +		m_pRuntime->SetPauseState(false);
  45.541 +	}
  45.542 +
  45.543 +	g_PluginSys._SetPauseState(this, paused);
  45.544 +
  45.545 +	if (!paused)
  45.546 +	{
  45.547 +		LibraryActions(LibraryAction_Added);
  45.548 +	}
  45.549 +
  45.550 +	return true;
  45.551 +}
  45.552 +
  45.553 +IdentityToken_t *CPlugin::GetIdentity()
  45.554 +{
  45.555 +	return m_ident;
  45.556 +}
  45.557 +
  45.558 +bool CPlugin::IsRunnable()
  45.559 +{
  45.560 +	return (m_status <= Plugin_Paused) ? true : false;
  45.561 +}
  45.562 +
  45.563 +time_t CPlugin::GetFileTimeStamp()
  45.564 +{
  45.565 +	char path[PLATFORM_MAX_PATH];
  45.566 +	g_pSM->BuildPath(Path_SM, path, sizeof(path), "plugins/%s", m_filename);
  45.567 +#ifdef PLATFORM_WINDOWS
  45.568 +	struct _stat s;
  45.569 +	if (_stat(path, &s) != 0)
  45.570 +#elif defined PLATFORM_POSIX
  45.571 +	struct stat s;
  45.572 +	if (stat(path, &s) != 0)
  45.573 +#endif
  45.574 +	{
  45.575 +		return 0;
  45.576 +	}
  45.577 +	else
  45.578 +	{
  45.579 +		return s.st_mtime;
  45.580 +	}
  45.581 +}
  45.582 +
  45.583 +time_t CPlugin::GetTimeStamp()
  45.584 +{
  45.585 +	return m_LastAccess;
  45.586 +}
  45.587 +
  45.588 +void CPlugin::SetTimeStamp(time_t t)
  45.589 +{
  45.590 +	m_LastAccess = t;
  45.591 +}
  45.592 +
  45.593 +IPhraseCollection *CPlugin::GetPhrases()
  45.594 +{
  45.595 +	return m_pPhrases;
  45.596 +}
  45.597 +
  45.598 +void CPlugin::DependencyDropped(CPlugin *pOwner)
  45.599 +{
  45.600 +	if (!m_pRuntime)
  45.601 +	{
  45.602 +		return;
  45.603 +	}
  45.604 +
  45.605 +	List<String>::iterator reqlib_iter;
  45.606 +	List<String>::iterator lib_iter;
  45.607 +	for (lib_iter=pOwner->m_Libraries.begin(); lib_iter!=pOwner->m_Libraries.end(); lib_iter++)
  45.608 +	{
  45.609 +		for (reqlib_iter=m_RequiredLibs.begin(); reqlib_iter!=m_RequiredLibs.end(); reqlib_iter++)
  45.610 +		{
  45.611 +			if ((*reqlib_iter) == (*lib_iter))
  45.612 +			{
  45.613 +				m_LibraryMissing = true;
  45.614 +			}
  45.615 +		}	
  45.616 +	}
  45.617 +
  45.618 +	List<NativeEntry *>::iterator iter;
  45.619 +	NativeEntry *pNative;
  45.620 +	sp_native_t *native;
  45.621 +	uint32_t idx;
  45.622 +	unsigned int unbound = 0;
  45.623 +
  45.624 +	for (iter = pOwner->m_Natives.begin();
  45.625 +		 iter != pOwner->m_Natives.end();
  45.626 +		 iter++)
  45.627 +	{
  45.628 +		pNative = (*iter);
  45.629 +		/* Find this native! */
  45.630 +		if (m_pRuntime->FindNativeByName(pNative->name, &idx) != SP_ERROR_NONE)
  45.631 +		{
  45.632 +			continue;
  45.633 +		}
  45.634 +		/* Unbind it */
  45.635 +		m_pRuntime->GetNativeByIndex(idx, &native);
  45.636 +		native->pfn = NULL;
  45.637 +		native->status = SP_NATIVE_UNBOUND;
  45.638 +		unbound++;
  45.639 +	}
  45.640 +
  45.641 +	if (unbound)
  45.642 +	{
  45.643 +		m_FakeNativesMissing = true;
  45.644 +	}
  45.645 +
  45.646 +	/* :IDEA: in the future, add native trapping? */
  45.647 +	if (m_FakeNativesMissing || m_LibraryMissing)
  45.648 +	{
  45.649 +		SetErrorState(Plugin_Error, "Depends on plugin: %s", pOwner->GetFilename());
  45.650 +	}
  45.651 +}
  45.652 +
  45.653 +unsigned int CPlugin::GetConfigCount()
  45.654 +{
  45.655 +	return (unsigned int)m_configs.size();
  45.656 +}
  45.657 +
  45.658 +AutoConfig *CPlugin::GetConfig(unsigned int i)
  45.659 +{
  45.660 +	if (i >= GetConfigCount())
  45.661 +	{
  45.662 +		return NULL;
  45.663 +	}
  45.664 +
  45.665 +	return m_configs[i];
  45.666 +}
  45.667 +
  45.668 +void CPlugin::AddConfig(bool autoCreate, const char *cfg, const char *folder)
  45.669 +{
  45.670 +	/* Do a check for duplicates to prevent double-execution */
  45.671 +	for (size_t i = 0; i < m_configs.size(); i++)
  45.672 +	{
  45.673 +		if (m_configs[i]->autocfg.compare(cfg) == 0
  45.674 +			&& m_configs[i]->folder.compare(folder) == 0
  45.675 +			&& m_configs[i]->create == autoCreate)
  45.676 +		{
  45.677 +			return;
  45.678 +		}
  45.679 +	}
  45.680 +
  45.681 +	AutoConfig *c = new AutoConfig;
  45.682 +
  45.683 +	c->autocfg = cfg;
  45.684 +	c->folder = folder;
  45.685 +	c->create = autoCreate;
  45.686 +
  45.687 +	m_configs.push_back(c);
  45.688 +}
  45.689 +
  45.690 +void CPlugin::DropEverything()
  45.691 +{
  45.692 +	CPlugin *pOther;
  45.693 +	List<WeakNative>::iterator wk_iter;
  45.694 +
  45.695 +	/* Tell everyone that depends on us that we're about to drop */
  45.696 +	for (List<CPlugin *>::iterator iter = m_Dependents.begin();
  45.697 +		 iter != m_Dependents.end(); 
  45.698 +		 iter++)
  45.699 +	{
  45.700 +		pOther = static_cast<CPlugin *>(*iter);
  45.701 +		pOther->DependencyDropped(this);
  45.702 +	}
  45.703 +
  45.704 +	/* Note: we don't care about things we depend on. 
  45.705 +	 * The reason is that extensions have their own cleanup 
  45.706 +	 * code for plugins.  Although the "right" design would be 
  45.707 +	 * to centralize that here, i'm omitting it for now.  Thus, 
  45.708 +	 * the code below to walk the plugins list will suffice.
  45.709 +	 */
  45.710 +	
  45.711 +	/* Other plugins could be holding weak references that were 
  45.712 +	 * added by us.  We need to clean all of those up now.
  45.713 +	 */
  45.714 +	for (List<CPlugin *>::iterator iter = g_PluginSys.m_plugins.begin();
  45.715 +		 iter != g_PluginSys.m_plugins.end();
  45.716 +		 iter++)
  45.717 +	{
  45.718 +		(*iter)->ToNativeOwner()->DropRefsTo(this);
  45.719 +	}
  45.720 +
  45.721 +	/* Proceed with the rest of the necessities. */
  45.722 +	CNativeOwner::DropEverything();
  45.723 +}
  45.724 +
  45.725 +bool CPlugin::AddFakeNative(IPluginFunction *pFunc, const char *name, SPVM_FAKENATIVE_FUNC func)
  45.726 +{
  45.727 +	NativeEntry *pEntry;
  45.728 +
  45.729 +	if ((pEntry = g_ShareSys.AddFakeNative(pFunc, name, func)) == NULL)
  45.730 +	{
  45.731 +		return false;
  45.732 +	}
  45.733 +
  45.734 +	m_Natives.push_back(pEntry);
  45.735 +
  45.736 +	return true;
  45.737 +}
  45.738 +
  45.739 +/*******************
  45.740 + * PLUGIN ITERATOR *
  45.741 + *******************/
  45.742 +
  45.743 +CPluginManager::CPluginIterator::CPluginIterator(List<CPlugin *> *_mylist)
  45.744 +{
  45.745 +	mylist = _mylist;
  45.746 +	Reset();
  45.747 +}
  45.748 +
  45.749 +IPlugin *CPluginManager::CPluginIterator::GetPlugin()
  45.750 +{
  45.751 +	return (*current);
  45.752 +}
  45.753 +
  45.754 +bool CPluginManager::CPluginIterator::MorePlugins()
  45.755 +{
  45.756 +	return (current != mylist->end());
  45.757 +}
  45.758 +
  45.759 +void CPluginManager::CPluginIterator::NextPlugin()
  45.760 +{
  45.761 +	current++;
  45.762 +}
  45.763 +
  45.764 +void CPluginManager::CPluginIterator::Release()
  45.765 +{
  45.766 +	g_PluginSys.ReleaseIterator(this);
  45.767 +}
  45.768 +
  45.769 +CPluginManager::CPluginIterator::~CPluginIterator()
  45.770 +{
  45.771 +}
  45.772 +
  45.773 +void CPluginManager::CPluginIterator::Reset()
  45.774 +{
  45.775 +	current = mylist->begin();
  45.776 +}
  45.777 +
  45.778 +/******************
  45.779 + * PLUGIN MANAGER *
  45.780 + ******************/
  45.781 +
  45.782 +CPluginManager::CPluginManager()
  45.783 +{
  45.784 +	m_AllPluginsLoaded = false;
  45.785 +	m_MyIdent = NULL;
  45.786 +	m_LoadingLocked = false;
  45.787 +	
  45.788 +	m_bBlockBadPlugins = true;
  45.789 +}
  45.790 +
  45.791 +CPluginManager::~CPluginManager()
  45.792 +{
  45.793 +	CStack<CPluginManager::CPluginIterator *>::iterator iter;
  45.794 +	for (iter=m_iters.begin(); iter!=m_iters.end(); iter++)
  45.795 +	{
  45.796 +		delete (*iter);
  45.797 +	}
  45.798 +	m_iters.popall();
  45.799 +}
  45.800 +
  45.801 +void CPluginManager::Shutdown()
  45.802 +{
  45.803 +	List<CPlugin *>::iterator iter;
  45.804 +
  45.805 +	while ((iter = m_plugins.begin()) != m_plugins.end())
  45.806 +	{
  45.807 +		UnloadPlugin(*iter);
  45.808 +	}
  45.809 +}
  45.810 +
  45.811 +void CPluginManager::LoadAll(const char *config_path, const char *plugins_path)
  45.812 +{
  45.813 +	LoadAll_FirstPass(config_path, plugins_path);
  45.814 +	g_Extensions.MarkAllLoaded();
  45.815 +	LoadAll_SecondPass();
  45.816 +	g_Extensions.MarkAllLoaded();
  45.817 +	AllPluginsLoaded();
  45.818 +}
  45.819 +
  45.820 +void CPluginManager::LoadAll_FirstPass(const char *config, const char *basedir)
  45.821 +{
  45.822 +	/* First read in the database of plugin settings */
  45.823 +	m_AllPluginsLoaded = false;
  45.824 +	LoadPluginsFromDir(basedir, NULL);
  45.825 +}
  45.826 +
  45.827 +void CPluginManager::LoadPluginsFromDir(const char *basedir, const char *localpath)
  45.828 +{
  45.829 +	char base_path[PLATFORM_MAX_PATH];
  45.830 +
  45.831 +	/* Form the current path to start reading from */
  45.832 +	if (localpath == NULL)
  45.833 +	{
  45.834 +		libsys->PathFormat(base_path, sizeof(base_path), "%s", basedir);
  45.835 +	} else {
  45.836 +		libsys->PathFormat(base_path, sizeof(base_path), "%s/%s", basedir, localpath);
  45.837 +	}
  45.838 +
  45.839 +	IDirectory *dir = libsys->OpenDirectory(base_path);
  45.840 +
  45.841 +	if (!dir)
  45.842 +	{
  45.843 +		char error[256];
  45.844 +		libsys->GetPlatformError(error, sizeof(error));
  45.845 +		smcore.LogError("[SM] Failure reading from plugins path: %s", localpath);
  45.846 +		smcore.LogError("[SM] Platform returned error: %s", error);
  45.847 +		return;
  45.848 +	}
  45.849 +
  45.850 +	while (dir->MoreFiles())
  45.851 +	{
  45.852 +		if (dir->IsEntryDirectory() 
  45.853 +			&& (strcmp(dir->GetEntryName(), ".") != 0)
  45.854 +			&& (strcmp(dir->GetEntryName(), "..") != 0)
  45.855 +			&& (strcmp(dir->GetEntryName(), "disabled") != 0)
  45.856 +			&& (strcmp(dir->GetEntryName(), "optional") != 0))
  45.857 +		{
  45.858 +			char new_local[PLATFORM_MAX_PATH];
  45.859 +			if (localpath == NULL)
  45.860 +			{
  45.861 +				/* If no path yet, don't add a former slash */
  45.862 +				smcore.Format(new_local, sizeof(new_local), "%s", dir->GetEntryName());
  45.863 +			} else {
  45.864 +				libsys->PathFormat(new_local, sizeof(new_local), "%s/%s", localpath, dir->GetEntryName());
  45.865 +			}
  45.866 +			LoadPluginsFromDir(basedir, new_local);
  45.867 +		} else if (dir->IsEntryFile()) {
  45.868 +			const char *name = dir->GetEntryName();
  45.869 +			size_t len = strlen(name);
  45.870 +			if (len >= 4
  45.871 +				&& strcmp(&name[len-4], ".smx") == 0)
  45.872 +			{
  45.873 +				/* If the filename matches, load the plugin */
  45.874 +				char plugin[PLATFORM_MAX_PATH];
  45.875 +				if (localpath == NULL)
  45.876 +				{
  45.877 +					smcore.Format(plugin, sizeof(plugin), "%s", name);
  45.878 +				} else {
  45.879 +					libsys->PathFormat(plugin, sizeof(plugin), "%s/%s", localpath, name);
  45.880 +				}
  45.881 +				LoadAutoPlugin(plugin);
  45.882 +			}
  45.883 +		}
  45.884 +		dir->NextEntry();
  45.885 +	}
  45.886 +	libsys->CloseDirectory(dir);
  45.887 +}
  45.888 +
  45.889 +LoadRes CPluginManager::_LoadPlugin(CPlugin **_plugin, const char *path, bool debug, PluginType type, char error[], size_t maxlength)
  45.890 +{
  45.891 +	if (m_LoadingLocked)
  45.892 +	{
  45.893 +		return LoadRes_NeverLoad;
  45.894 +	}
  45.895 +
  45.896 +	int err;
  45.897 +
  45.898 +	/**
  45.899 +	 * Does this plugin already exist?
  45.900 +	 */
  45.901 +	CPlugin **pluginpp = m_LoadLookup.retrieve(path);
  45.902 +	if (pluginpp && *pluginpp)
  45.903 +	{
  45.904 +		CPlugin *pPlugin = *pluginpp;
  45.905 +		/* Check to see if we should try reloading it */
  45.906 +		if (pPlugin->GetStatus() == Plugin_BadLoad
  45.907 +			|| pPlugin->GetStatus() == Plugin_Error
  45.908 +			|| pPlugin->GetStatus() == Plugin_Failed)
  45.909 +		{
  45.910 +			UnloadPlugin(pPlugin);
  45.911 +		}
  45.912 +		else
  45.913 +		{
  45.914 +			if (_plugin)
  45.915 +			{
  45.916 +				*_plugin = pPlugin;
  45.917 +			}
  45.918 +			return LoadRes_AlreadyLoaded;
  45.919 +		}
  45.920 +	}
  45.921 +
  45.922 +	CPlugin *pPlugin = CPlugin::CreatePlugin(path, error, maxlength);
  45.923 +
  45.924 +	assert(pPlugin != NULL);
  45.925 +
  45.926 +	pPlugin->m_type = PluginType_MapUpdated;
  45.927 +
  45.928 +	ICompilation *co = NULL;
  45.929 +
  45.930 +	if (pPlugin->m_status == Plugin_Uncompiled)
  45.931 +	{
  45.932 +		co = g_pSourcePawn2->StartCompilation();
  45.933 +	}
  45.934 +
  45.935 +	/* Do the actual compiling */
  45.936 +	if (co != NULL)
  45.937 +	{
  45.938 +		char fullpath[PLATFORM_MAX_PATH];
  45.939 +		g_pSM->BuildPath(Path_SM, fullpath, sizeof(fullpath), "plugins/%s", pPlugin->m_filename);
  45.940 +
  45.941 +		pPlugin->m_pRuntime = g_pSourcePawn2->LoadPlugin(co, fullpath, &err);
  45.942 +		if (pPlugin->m_pRuntime == NULL)
  45.943 +		{
  45.944 +			if (error)
  45.945 +			{
  45.946 +				smcore.Format(error, 
  45.947 +					maxlength, 
  45.948 +					"Unable to load plugin (error %d: %s)", 
  45.949 +					err, 
  45.950 +					g_pSourcePawn2->GetErrorString(err));
  45.951 +			}
  45.952 +			pPlugin->m_status = Plugin_BadLoad;
  45.953 +		}
  45.954 +		else
  45.955 +		{
  45.956 +			if (pPlugin->UpdateInfo())
  45.957 +			{
  45.958 +				pPlugin->m_status = Plugin_Created;
  45.959 +			}
  45.960 +			else
  45.961 +			{
  45.962 +				if (error)
  45.963 +				{
  45.964 +					smcore.Format(error, maxlength, "%s", pPlugin->m_errormsg);
  45.965 +				}
  45.966 +			}
  45.967 +		}
  45.968 +	}
  45.969 +	
  45.970 +	if (pPlugin->GetStatus() == Plugin_Created)
  45.971 +	{
  45.972 +		unsigned char *pCodeHash = pPlugin->m_pRuntime->GetCodeHash();
  45.973 +		
  45.974 +		char codeHashBuf[40];
  45.975 +		smcore.Format(codeHashBuf, 40, "plugin_");
  45.976 +		for (int i = 0; i < 16; i++)
  45.977 +			smcore.Format(codeHashBuf + 7 + (i * 2), 3, "%02x", pCodeHash[i]);
  45.978 +		
  45.979 +		const char *bulletinUrl = g_pGameConf->GetKeyValue(codeHashBuf);
  45.980 +		if (bulletinUrl != NULL)
  45.981 +		{
  45.982 +			if (m_bBlockBadPlugins)
  45.983 +			{
  45.984 +				if (error)
  45.985 +				{
  45.986 +					if (bulletinUrl[0] != '\0')
  45.987 +					{
  45.988 +						smcore.Format(error, maxlength, "Known malware detected and blocked. See %s for more info", bulletinUrl);
  45.989 +					} else {
  45.990 +						smcore.Format(error, maxlength, "Possible malware or illegal plugin detected and blocked");
  45.991 +					}
  45.992 +				}
  45.993 +				pPlugin->m_status = Plugin_BadLoad;
  45.994 +			} else {
  45.995 +				if (bulletinUrl[0] != '\0')
  45.996 +				{
  45.997 +					smcore.Log("%s: Known malware detected. See %s for more info, blocking disabled in core.cfg", pPlugin->GetFilename(), bulletinUrl);
  45.998 +				} else {
  45.999 +					smcore.Log("%s: Possible malware or illegal plugin detected, blocking disabled in core.cfg", pPlugin->GetFilename());
 45.1000 +				}
 45.1001 +			}
 45.1002 +		}
 45.1003 +	}
 45.1004 +
 45.1005 +	LoadRes loadFailure = LoadRes_Failure;
 45.1006 +	/* Get the status */
 45.1007 +	if (pPlugin->GetStatus() == Plugin_Created)
 45.1008 +	{
 45.1009 +		/* First native pass - add anything from Core */
 45.1010 +		g_ShareSys.BindNativesToPlugin(pPlugin, true);
 45.1011 +		pPlugin->InitIdentity();
 45.1012 +		APLRes result = pPlugin->Call_AskPluginLoad(error, maxlength);  
 45.1013 +		switch (result)
 45.1014 +		{
 45.1015 +		case APLRes_Success:
 45.1016 +			/* Autoload any modules */
 45.1017 +			LoadOrRequireExtensions(pPlugin, 1, error, maxlength);
 45.1018 +			break;
 45.1019 +		case APLRes_Failure:
 45.1020 +			pPlugin->SetErrorState(Plugin_Failed, "%s", error);
 45.1021 +			loadFailure = LoadRes_Failure;
 45.1022 +			break;
 45.1023 +		case APLRes_SilentFailure:
 45.1024 +			pPlugin->SetErrorState(Plugin_Failed, "%s", error);
 45.1025 +			loadFailure = LoadRes_SilentFailure;
 45.1026 +			pPlugin->SetSilentlyFailed(true);
 45.1027 +			break;
 45.1028 +		default:
 45.1029 +			assert(false);
 45.1030 +		}
 45.1031 +	}
 45.1032 +
 45.1033 +	/* Save the time stamp */
 45.1034 +	time_t t = pPlugin->GetFileTimeStamp();
 45.1035 +	pPlugin->SetTimeStamp(t);
 45.1036 +
 45.1037 +	if (_plugin)
 45.1038 +	{
 45.1039 +		*_plugin = pPlugin;
 45.1040 +	}
 45.1041 +
 45.1042 +	return (pPlugin->GetStatus() == Plugin_Loaded) ? LoadRes_Successful : loadFailure;
 45.1043 +}
 45.1044 +
 45.1045 +IPlugin *CPluginManager::LoadPlugin(const char *path, bool debug, PluginType type, char error[], size_t maxlength, bool *wasloaded)
 45.1046 +{
 45.1047 +	CPlugin *pl;
 45.1048 +	LoadRes res;
 45.1049 +
 45.1050 +	*wasloaded = false;
 45.1051 +	if ((res=_LoadPlugin(&pl, path, true, type, error, maxlength)) == LoadRes_Failure)
 45.1052 +	{
 45.1053 +		delete pl;
 45.1054 +		return NULL;
 45.1055 +	}
 45.1056 +
 45.1057 +	if (res == LoadRes_AlreadyLoaded)
 45.1058 +	{
 45.1059 +		*wasloaded = true;
 45.1060 +		return pl;
 45.1061 +	}
 45.1062 +
 45.1063 +	if (res == LoadRes_NeverLoad)
 45.1064 +	{
 45.1065 +		if (error)
 45.1066 +		{
 45.1067 +			if (m_LoadingLocked)
 45.1068 +			{
 45.1069 +				smcore.Format(error, maxlength, "There is a global plugin loading lock in effect");
 45.1070 +			}
 45.1071 +			else
 45.1072 +			{
 45.1073 +				smcore.Format(error, maxlength, "This plugin is blocked from loading (see plugin_settings.cfg)");
 45.1074 +			}
 45.1075 +		}
 45.1076 +		return NULL;
 45.1077 +	}
 45.1078 +
 45.1079 +	AddPlugin(pl);
 45.1080 +
 45.1081 +	/* Run second pass if we need to */
 45.1082 +	if (IsLateLoadTime() && pl->GetStatus() == Plugin_Loaded)
 45.1083 +	{
 45.1084 +		if (!RunSecondPass(pl, error, maxlength))
 45.1085 +		{
 45.1086 +			UnloadPlugin(pl);
 45.1087 +			return NULL;
 45.1088 +		}
 45.1089 +		pl->Call_OnAllPluginsLoaded();
 45.1090 +	}
 45.1091 +
 45.1092 +	return pl;
 45.1093 +}
 45.1094 +
 45.1095 +void CPluginManager::LoadAutoPlugin(const char *plugin)
 45.1096 +{
 45.1097 +	CPlugin *pl = NULL;
 45.1098 +	LoadRes res;
 45.1099 +	char error[255] = "Unknown error";
 45.1100 +
 45.1101 +	if ((res=_LoadPlugin(&pl, plugin, false, PluginType_MapUpdated, error, sizeof(error))) == LoadRes_Failure)
 45.1102 +	{
 45.1103 +		smcore.LogError("[SM] Failed to load plugin \"%s\": %s.", plugin, error);
 45.1104 +		pl->SetErrorState(
 45.1105 +			pl->GetStatus() <= Plugin_Created ? Plugin_BadLoad : pl->GetStatus(), 
 45.1106 +			"%s",
 45.1107 +			error);
 45.1108 +	}
 45.1109 +
 45.1110 +	if (res == LoadRes_Successful || res == LoadRes_Failure || res == LoadRes_SilentFailure)
 45.1111 +	{
 45.1112 +		AddPlugin(pl);
 45.1113 +	}
 45.1114 +}
 45.1115 +
 45.1116 +void CPluginManager::AddPlugin(CPlugin *pPlugin)
 45.1117 +{
 45.1118 +	List<IPluginsListener *>::iterator iter;
 45.1119 +	IPluginsListener *pListener;
 45.1120 +
 45.1121 +	for (iter=m_listeners.begin(); iter!=m_listeners.end(); iter++)
 45.1122 +	{
 45.1123 +		pListener = (*iter);
 45.1124 +		pListener->OnPluginCreated(pPlugin);
 45.1125 +	}
 45.1126 +
 45.1127 +	m_plugins.push_back(pPlugin);
 45.1128 +	m_LoadLookup.insert(pPlugin->m_filename, pPlugin);
 45.1129 +}
 45.1130 +
 45.1131 +void CPluginManager::LoadAll_SecondPass()
 45.1132 +{
 45.1133 +	List<CPlugin *>::iterator iter;
 45.1134 +	CPlugin *pPlugin;
 45.1135 +
 45.1136 +	char error[256];
 45.1137 +	for (iter=m_plugins.begin(); iter!=m_plugins.end(); iter++)
 45.1138 +	{
 45.1139 +		pPlugin = (*iter);
 45.1140 +		if (pPlugin->GetStatus() == Plugin_Loaded)
 45.1141 +		{
 45.1142 +			error[0] = '\0';
 45.1143 +			if (!RunSecondPass(pPlugin, error, sizeof(error)))
 45.1144 +			{
 45.1145 +				smcore.LogError("[SM] Unable to load plugin \"%s\": %s", pPlugin->GetFilename(), error);
 45.1146 +				pPlugin->SetErrorState(Plugin_Failed, "%s", error);
 45.1147 +			}
 45.1148 +		}
 45.1149 +	}
 45.1150 +
 45.1151 +	m_AllPluginsLoaded = true;
 45.1152 +}
 45.1153 +
 45.1154 +bool CPluginManager::FindOrRequirePluginDeps(CPlugin *pPlugin, char *error, size_t maxlength)
 45.1155 +{
 45.1156 +	struct _pl
 45.1157 +	{
 45.1158 +		cell_t name;
 45.1159 +		cell_t file;
 45.1160 +		cell_t required;
 45.1161 +	} *pl;
 45.1162 +
 45.1163 +	IPluginContext *pBase = pPlugin->GetBaseContext();
 45.1164 +	uint32_t num = pBase->GetPubVarsNum();
 45.1165 +	sp_pubvar_t *pubvar;
 45.1166 +	char *name, *file;
 45.1167 +	char pathfile[PLATFORM_MAX_PATH];
 45.1168 +
 45.1169 +	for (uint32_t i=0; i<num; i++)
 45.1170 +	{
 45.1171 +		if (pBase->GetPubvarByIndex(i, &pubvar) != SP_ERROR_NONE)
 45.1172 +		{
 45.1173 +			continue;
 45.1174 +		}
 45.1175 +		if (strncmp(pubvar->name, "__pl_", 5) == 0)
 45.1176 +		{
 45.1177 +			pl = (_pl *)pubvar->offs;
 45.1178 +			if (pBase->LocalToString(pl->file, &file) != SP_ERROR_NONE)
 45.1179 +			{
 45.1180 +				continue;
 45.1181 +			}
 45.1182 +			if (pBase->LocalToString(pl->name, &name) != SP_ERROR_NONE)
 45.1183 +			{
 45.1184 +				continue;
 45.1185 +			}
 45.1186 +			libsys->GetFileFromPath(pathfile, sizeof(pathfile), pPlugin->GetFilename());
 45.1187 +			if (strcmp(pathfile, file) == 0)
 45.1188 +			{
 45.1189 +				continue;
 45.1190 +			}
 45.1191 +			if (pl->required == false)
 45.1192 +			{
 45.1193 +				IPluginFunction *pFunc;
 45.1194 +				char buffer[64];
 45.1195 +				smcore.Format(buffer, sizeof(buffer), "__pl_%s_SetNTVOptional", &pubvar->name[5]);
 45.1196 +				if ((pFunc=pBase->GetFunctionByName(buffer)))
 45.1197 +				{
 45.1198 +					cell_t res;
 45.1199 +					pFunc->Execute(&res);
 45.1200 +					if (pPlugin->GetBaseContext()->GetLastNativeError() != SP_ERROR_NONE)
 45.1201 +					{
 45.1202 +						if (error)
 45.1203 +						{
 45.1204 +							smcore.Format(error, maxlength, "Fatal error during initializing plugin load");
 45.1205 +						}
 45.1206 +						return false;
 45.1207 +					}
 45.1208 +				}
 45.1209 +			}
 45.1210 +			else
 45.1211 +			{
 45.1212 +				/* Check that we aren't registering the same library twice */
 45.1213 +				if (pPlugin->m_RequiredLibs.find(name) == pPlugin->m_RequiredLibs.end())
 45.1214 +				{
 45.1215 +					pPlugin->m_RequiredLibs.push_back(name);
 45.1216 +				}
 45.1217 +				else
 45.1218 +				{
 45.1219 +					continue;
 45.1220 +				}
 45.1221 +				List<CPlugin *>::iterator iter;
 45.1222 +				CPlugin *pl;
 45.1223 +				bool found = false;
 45.1224 +				for (iter=m_plugins.begin(); iter!=m_plugins.end(); iter++)
 45.1225 +				{
 45.1226 +					pl = (*iter);
 45.1227 +					if (pl->m_Libraries.find(name) != pl->m_Libraries.end())
 45.1228 +					{
 45.1229 +						found = true;
 45.1230 +						break;
 45.1231 +					}
 45.1232 +				}
 45.1233 +				if (!found)
 45.1234 +				{
 45.1235 +					if (error)
 45.1236 +					{
 45.1237 +						smcore.Format(error, maxlength, "Could not find required plugin \"%s\"", name);
 45.1238 +					}
 45.1239 +					return false;
 45.1240 +				}
 45.1241 +			}
 45.1242 +		}
 45.1243 +	}
 45.1244 +
 45.1245 +	return true;
 45.1246 +}
 45.1247 +
 45.1248 +bool CPluginManager::LoadOrRequireExtensions(CPlugin *pPlugin, unsigned int pass, char *error, size_t maxlength)
 45.1249 +{
 45.1250 +	/* Find any extensions this plugin needs */
 45.1251 +	struct _ext
 45.1252 +	{
 45.1253 +		cell_t name;
 45.1254 +		cell_t file;
 45.1255 +		cell_t autoload;
 45.1256 +		cell_t required;
 45.1257 +	} *ext;
 45.1258 +
 45.1259 +	IPluginContext *pBase = pPlugin->GetBaseContext();
 45.1260 +	uint32_t num = pBase->GetPubVarsNum();
 45.1261 +	sp_pubvar_t *pubvar;
 45.1262 +	IExtension *pExt;
 45.1263 +	char path[PLATFORM_MAX_PATH];
 45.1264 +	char *file, *name;
 45.1265 +	for (uint32_t i=0; i<num; i++)
 45.1266 +	{
 45.1267 +		if (pBase->GetPubvarByIndex(i, &pubvar) != SP_ERROR_NONE)
 45.1268 +		{
 45.1269 +			continue;
 45.1270 +		}
 45.1271 +		if (strncmp(pubvar->name, "__ext_", 6) == 0)
 45.1272 +		{
 45.1273 +			ext = (_ext *)pubvar->offs;
 45.1274 +			if (pBase->LocalToString(ext->file, &file) != SP_ERROR_NONE)
 45.1275 +			{
 45.1276 +				continue;
 45.1277 +			}
 45.1278 +			if (pBase->LocalToString(ext->name, &name) != SP_ERROR_NONE)
 45.1279 +			{
 45.1280 +				continue;
 45.1281 +			}
 45.1282 +			if (pass == 1)
 45.1283 +			{
 45.1284 +				/* Attempt to auto-load if necessary */
 45.1285 +				if (ext->autoload)
 45.1286 +				{
 45.1287 +					libsys->PathFormat(path, PLATFORM_MAX_PATH, "%s", file);
 45.1288 +					bool bErrorOnMissing = ext->required ? true : false;
 45.1289 +					g_Extensions.LoadAutoExtension(path);
 45.1290 +				}
 45.1291 +			}
 45.1292 +			else if (pass == 2)
 45.1293 +			{
 45.1294 +				/* Is this required? */
 45.1295 +				if (ext->required)
 45.1296 +				{
 45.1297 +					libsys->PathFormat(path, PLATFORM_MAX_PATH, "%s", file);
 45.1298 +					if ((pExt = g_Extensions.FindExtensionByFile(path)) == NULL)
 45.1299 +					{
 45.1300 +						pExt = g_Extensions.FindExtensionByName(name);
 45.1301 +					}
 45.1302 +					/* :TODO: should we bind to unloaded extensions?
 45.1303 +					 * Currently the extension manager will ignore this.
 45.1304 +					 */
 45.1305 +					if (!pExt || !pExt->IsRunning(NULL, 0))
 45.1306 +					{
 45.1307 +						if (error)
 45.1308 +						{
 45.1309 +							smcore.Format(error, maxlength, "Required extension \"%s\" file(\"%s\") not running", name, file);
 45.1310 +						}
 45.1311 +						return false;
 45.1312 +					}
 45.1313 +					else
 45.1314 +					{
 45.1315 +						g_Extensions.BindChildPlugin(pExt, pPlugin);
 45.1316 +					}
 45.1317 +				}
 45.1318 +				else
 45.1319 +				{
 45.1320 +					IPluginFunction *pFunc;
 45.1321 +					char buffer[64];
 45.1322 +					smcore.Format(buffer, sizeof(buffer), "__ext_%s_SetNTVOptional", &pubvar->name[6]);
 45.1323 +
 45.1324 +					if ((pFunc = pBase->GetFunctionByName(buffer)) != NULL)
 45.1325 +					{
 45.1326 +						cell_t res;
 45.1327 +						pFunc->Execute(&res);
 45.1328 +						if (pPlugin->GetBaseContext()->GetLastNativeError() != SP_ERROR_NONE)
 45.1329 +						{
 45.1330 +							if (error)
 45.1331 +							{
 45.1332 +								smcore.Format(error, maxlength, "Fatal error during plugin initialization (ext req)");
 45.1333 +							}
 45.1334 +							return false;
 45.1335 +						}
 45.1336 +					}
 45.1337 +				}
 45.1338 +			}
 45.1339 +		}
 45.1340 +	}
 45.1341 +
 45.1342 +	return true;
 45.1343 +}
 45.1344 +
 45.1345 +bool CPluginManager::RunSecondPass(CPlugin *pPlugin, char *error, size_t maxlength)
 45.1346 +{
 45.1347 +	/* Second pass for extension requirements */
 45.1348 +	if (!LoadOrRequireExtensions(pPlugin, 2, error, maxlength))
 45.1349 +	{
 45.1350 +		return false;
 45.1351 +	}
 45.1352 +
 45.1353 +	if (!FindOrRequirePluginDeps(pPlugin, error, maxlength))
 45.1354 +	{
 45.1355 +		return false;
 45.1356 +	}
 45.1357 +
 45.1358 +	/* Run another binding pass */
 45.1359 +	g_ShareSys.BindNativesToPlugin(pPlugin, false);
 45.1360 +
 45.1361 +	/* Find any unbound natives. Right now, these are not allowed. */
 45.1362 +	IPluginContext *pContext = pPlugin->GetBaseContext();
 45.1363 +	uint32_t num = pContext->GetNativesNum();
 45.1364 +	sp_native_t *native;
 45.1365 +	for (unsigned int i=0; i<num; i++)
 45.1366 +	{
 45.1367 +		if (pContext->GetNativeByIndex(i, &native) != SP_ERROR_NONE)
 45.1368 +		{
 45.1369 +			break;
 45.1370 +		}
 45.1371 +		if (native->status == SP_NATIVE_UNBOUND
 45.1372 +			&& native->name[0] != '@'
 45.1373 +			&& !(native->flags & SP_NTVFLAG_OPTIONAL))
 45.1374 +		{
 45.1375 +			if (error)
 45.1376 +			{
 45.1377 +				smcore.Format(error, maxlength, "Native \"%s\" was not found", native->name);
 45.1378 +			}
 45.1379 +			return false;
 45.1380 +		}
 45.1381 +	}
 45.1382 +
 45.1383 +	/* Finish by telling all listeners */
 45.1384 +	List<IPluginsListener *>::iterator iter;
 45.1385 +	IPluginsListener *pListener;
 45.1386 +	for (iter=m_listeners.begin(); iter!=m_listeners.end(); iter++)
 45.1387 +	{
 45.1388 +		pListener = (*iter);
 45.1389 +		pListener->OnPluginLoaded(pPlugin);
 45.1390 +	}
 45.1391 +	
 45.1392 +	/* Tell this plugin to finish initializing itself */
 45.1393 +	pPlugin->Call_OnPluginStart();
 45.1394 +
 45.1395 +	/* Now, if we have fake natives, go through all plugins that might need rebinding */
 45.1396 +	if (pPlugin->GetStatus() <= Plugin_Paused && pPlugin->m_Natives.size())
 45.1397 +	{
 45.1398 +		List<CPlugin *>::iterator pl_iter;
 45.1399 +		CPlugin *pOther;
 45.1400 +		for (pl_iter = m_plugins.begin();
 45.1401 +			 pl_iter != m_plugins.end();
 45.1402 +			 pl_iter++)
 45.1403 +		{
 45.1404 +			pOther = (*pl_iter);
 45.1405 +			if ((pOther->GetStatus() == Plugin_Error
 45.1406 +				&& (pOther->m_FakeNativesMissing || pOther->m_LibraryMissing))
 45.1407 +				|| pOther->m_FakeNativesMissing)
 45.1408 +			{
 45.1409 +				TryRefreshDependencies(pOther);
 45.1410 +			}
 45.1411 +			else if ((pOther->GetStatus() == Plugin_Running
 45.1412 +					  || pOther->GetStatus() == Plugin_Paused)
 45.1413 +					 && pOther != pPlugin)
 45.1414 +			{
 45.1415 +				List<NativeEntry *>::iterator nv_iter;
 45.1416 +				for (nv_iter = pPlugin->m_Natives.begin();
 45.1417 +					 nv_iter != pPlugin->m_Natives.end();
 45.1418 +					 nv_iter++)
 45.1419 +				{
 45.1420 +					g_ShareSys.BindNativeToPlugin(pOther, (*nv_iter));
 45.1421 +				}
 45.1422 +			}
 45.1423 +		}
 45.1424 +	}
 45.1425 +
 45.1426 +	/* Go through our libraries and tell other plugins they're added */
 45.1427 +	List<String>::iterator s_iter;
 45.1428 +	for (s_iter = pPlugin->m_Libraries.begin();
 45.1429 +		s_iter != pPlugin->m_Libraries.end();
 45.1430 +		s_iter++)
 45.1431 +	{
 45.1432 +		OnLibraryAction((*s_iter).c_str(), LibraryAction_Added);
 45.1433 +	}
 45.1434 +
 45.1435 +	/* :TODO: optimize? does this even matter? */
 45.1436 +	pPlugin->GetPhrases()->AddPhraseFile("core.phrases");
 45.1437 +
 45.1438 +	return true;
 45.1439 +}
 45.1440 +
 45.1441 +void CPluginManager::TryRefreshDependencies(CPlugin *pPlugin)
 45.1442 +{
 45.1443 +	assert(pPlugin->GetBaseContext() != NULL);
 45.1444 +
 45.1445 +	g_ShareSys.BindNativesToPlugin(pPlugin, false);
 45.1446 +
 45.1447 +	List<String>::iterator lib_iter;
 45.1448 +	List<String>::iterator req_iter;
 45.1449 +	List<CPlugin *>::iterator pl_iter;
 45.1450 +	CPlugin *pl;
 45.1451 +	for (req_iter=pPlugin->m_RequiredLibs.begin(); req_iter!=pPlugin->m_RequiredLibs.end(); req_iter++)
 45.1452 +	{
 45.1453 +		bool found = false;
 45.1454 +		for (pl_iter=m_plugins.begin(); pl_iter!=m_plugins.end(); pl_iter++)
 45.1455 +		{
 45.1456 +			pl = (*pl_iter);
 45.1457 +			for (lib_iter=pl->m_Libraries.begin(); lib_iter!=pl->m_Libraries.end(); lib_iter++)
 45.1458 +			{
 45.1459 +				if ((*req_iter) == (*lib_iter))
 45.1460 +				{
 45.1461 +					found = true;
 45.1462 +				}
 45.1463 +			}
 45.1464 +		}
 45.1465 +		if (!found)
 45.1466 +		{
 45.1467 +			pPlugin->SetErrorState(Plugin_Error, "Library not found: %s", (*req_iter).c_str());
 45.1468 +			return;
 45.1469 +		}
 45.1470 +	}
 45.1471 +
 45.1472 +	/* Find any unbound natives
 45.1473 +	 * Right now, these are not allowed
 45.1474 +	 */
 45.1475 +	IPluginContext *pContext = pPlugin->GetBaseContext();
 45.1476 +	uint32_t num = pContext->GetNativesNum();
 45.1477 +	sp_native_t *native;
 45.1478 +	for (unsigned int i=0; i<num; i++)
 45.1479 +	{
 45.1480 +		if (pContext->GetNativeByIndex(i, &native) != SP_ERROR_NONE)
 45.1481 +		{
 45.1482 +			break;
 45.1483 +		}
 45.1484 +		if (native->status == SP_NATIVE_UNBOUND
 45.1485 +			&& native->name[0] != '@'
 45.1486 +			&& !(native->flags & SP_NTVFLAG_OPTIONAL))
 45.1487 +		{
 45.1488 +			pPlugin->SetErrorState(Plugin_Error, "Native not found: %s", native->name);
 45.1489 +			return;
 45.1490 +		}
 45.1491 +	}
 45.1492 +
 45.1493 +	if (pPlugin->GetStatus() == Plugin_Error)
 45.1494 +	{
 45.1495 +		/* If we got here, all natives are okay again! */
 45.1496 +		pPlugin->m_status = Plugin_Running;
 45.1497 +		if (pPlugin->m_pRuntime->IsPaused())
 45.1498 +		{
 45.1499 +			pPlugin->m_pRuntime->SetPauseState(false);
 45.1500 +			_SetPauseState(pPlugin, false);
 45.1501 +		}
 45.1502 +	}
 45.1503 +}
 45.1504 +
 45.1505 +bool CPluginManager::UnloadPlugin(IPlugin *plugin)
 45.1506 +{
 45.1507 +	CPlugin *pPlugin = (CPlugin *)plugin;
 45.1508 +
 45.1509 +	/* This prevents removal during insertion or anything else weird */
 45.1510 +	if (m_plugins.find(pPlugin) == m_plugins.end())
 45.1511 +	{
 45.1512 +		return false;
 45.1513 +	}
 45.1514 +
 45.1515 +	IPluginContext *pContext = plugin->GetBaseContext();
 45.1516 +	if (pContext != NULL && pContext->IsInExec())
 45.1517 +	{
 45.1518 +		char buffer[255];
 45.1519 +		smcore.Format(buffer, sizeof(buffer), "sm plugins unload %s\n", plugin->GetFilename());
 45.1520 +		engine->ServerCommand(buffer);
 45.1521 +		return false;
 45.1522 +	}
 45.1523 +
 45.1524 +	/* Remove us from the lookup table and linked list */
 45.1525 +	m_plugins.remove(pPlugin);
 45.1526 +	m_LoadLookup.remove(pPlugin->m_filename);
 45.1527 +
 45.1528 +	/* Go through our libraries and tell other plugins they're gone */
 45.1529 +	List<String>::iterator s_iter;
 45.1530 +	for (s_iter = pPlugin->m_Libraries.begin();
 45.1531 +		 s_iter != pPlugin->m_Libraries.end();
 45.1532 +		 s_iter++)
 45.1533 +	{
 45.1534 +		OnLibraryAction((*s_iter).c_str(), LibraryAction_Removed);
 45.1535 +	}
 45.1536 +
 45.1537 +	List<IPluginsListener *>::iterator iter;
 45.1538 +	IPluginsListener *pListener;
 45.1539 +
 45.1540 +	if (pPlugin->GetStatus() <= Plugin_Error)
 45.1541 +	{
 45.1542 +		/* Notify plugin */
 45.1543 +		pPlugin->Call_OnPluginEnd();
 45.1544 +
 45.1545 +		/* Notify listeners of unloading */
 45.1546 +		for (iter=m_listeners.begin(); iter!=m_listeners.end(); iter++)
 45.1547 +		{
 45.1548 +			pListener = (*iter);
 45.1549 +			pListener->OnPluginUnloaded(pPlugin);
 45.1550 +		}
 45.1551 +	}
 45.1552 +
 45.1553 +	pPlugin->DropEverything();
 45.1554 +
 45.1555 +	for (iter=m_listeners.begin(); iter!=m_listeners.end(); iter++)
 45.1556 +	{
 45.1557 +		/* Notify listeners of destruction */
 45.1558 +		pListener = (*iter);
 45.1559 +		pListener->OnPluginDestroyed(pPlugin);
 45.1560 +	}
 45.1561 +	
 45.1562 +	/* Tell the plugin to delete itself */
 45.1563 +	delete pPlugin;
 45.1564 +
 45.1565 +	return true;
 45.1566 +}
 45.1567 +
 45.1568 +IPlugin *CPluginManager::FindPluginByContext(const sp_context_t *ctx)
 45.1569 +{
 45.1570 +	IPlugin *pPlugin;
 45.1571 +	IPluginContext *pContext;
 45.1572 +
 45.1573 +	pContext = reinterpret_cast<IPluginContext *>(const_cast<sp_context_t *>(ctx));
 45.1574 +
 45.1575 +	if (pContext->GetKey(2, (void **)&pPlugin))
 45.1576 +	{
 45.1577 +		return pPlugin;
 45.1578 +	}
 45.1579 +
 45.1580 +	return NULL;
 45.1581 +}
 45.1582 +
 45.1583 +CPlugin *CPluginManager::GetPluginByCtx(const sp_context_t *ctx)
 45.1584 +{
 45.1585 +	return (CPlugin *)FindPluginByContext(ctx);
 45.1586 +}
 45.1587 +
 45.1588 +unsigned int CPluginManager::GetPluginCount()
 45.1589 +{
 45.1590 +	return m_plugins.size();
 45.1591 +}
 45.1592 +
 45.1593 +void CPluginManager::AddPluginsListener(IPluginsListener *listener)
 45.1594 +{
 45.1595 +	m_listeners.push_back(listener);
 45.1596 +}
 45.1597 +
 45.1598 +void CPluginManager::RemovePluginsListener(IPluginsListener *listener)
 45.1599 +{
 45.1600 +	m_listeners.remove(listener);
 45.1601 +}
 45.1602 +
 45.1603 +IPluginIterator *CPluginManager::GetPluginIterator()
 45.1604 +{
 45.1605 +	if (m_iters.empty())
 45.1606 +	{
 45.1607 +		return new CPluginIterator(&m_plugins);
 45.1608 +	} else {
 45.1609 +		CPluginIterator *iter = m_iters.front();
 45.1610 +		m_iters.pop();
 45.1611 +		iter->Reset();
 45.1612 +		return iter;
 45.1613 +	}
 45.1614 +}
 45.1615 +
 45.1616 +void CPluginManager::ReleaseIterator(CPluginIterator *iter)
 45.1617 +{
 45.1618 +	m_iters.push(iter);
 45.1619 +}
 45.1620 +
 45.1621 +bool CPluginManager::TestAliasMatch(const char *alias, const char *localpath)
 45.1622 +{
 45.1623 +	/* As an optimization, we do not call strlen, but compute the length in the first pass */
 45.1624 +	size_t alias_len = 0;
 45.1625 +	size_t local_len = 0;
 45.1626 +
 45.1627 +	const char *ptr = alias;
 45.1628 +	unsigned int alias_explicit_paths = 0;
 45.1629 +	unsigned int alias_path_end = 0;
 45.1630 +	while (*ptr != '\0')
 45.1631 +	{
 45.1632 +		if (*ptr == '\\' || *ptr == '/')
 45.1633 +		{
 45.1634 +			alias_explicit_paths++;
 45.1635 +			alias_path_end = alias_len;
 45.1636 +		}
 45.1637 +		alias_len++;
 45.1638 +		ptr++;
 45.1639 +	}
 45.1640 +
 45.1641 +	if (alias_explicit_paths && alias_path_end == alias_len - 1)
 45.1642 +	{
 45.1643 +		/* Trailing slash is totally invalid here */
 45.1644 +		return false;
 45.1645 +	}
 45.1646 +
 45.1647 +	ptr = localpath;
 45.1648 +	unsigned int local_explicit_paths = 0;
 45.1649 +	unsigned int local_path_end = 0;
 45.1650 +	while (*ptr != '\0')
 45.1651 +	{
 45.1652 +		if (*ptr == '\\' || *ptr == '/')
 45.1653 +		{
 45.1654 +			local_explicit_paths++;
 45.1655 +			local_path_end = local_len;
 45.1656 +		}
 45.1657 +		local_len++;
 45.1658 +		ptr++;
 45.1659 +	}
 45.1660 +
 45.1661 +	/* If the alias has more explicit paths than the real path,
 45.1662 +	 * no match will be possible.
 45.1663 +	 */
 45.1664 +	if (alias_explicit_paths > local_explicit_paths)
 45.1665 +	{
 45.1666 +		return false;
 45.1667 +	}
 45.1668 +
 45.1669 +	if (alias_explicit_paths)
 45.1670 +	{
 45.1671 +		/* We need to find if the paths match now.  For example, these should all match:
 45.1672 +		 * csdm     csdm
 45.1673 +		 * csdm     optional/csdm
 45.1674 +		 * csdm/ban optional/crab/csdm/ban
 45.1675 +		*/
 45.1676 +		const char *aliasptr = alias;
 45.1677 +		const char *localptr = localpath;
 45.1678 +		bool match = true;
 45.1679 +		do
 45.1680 +		{
 45.1681 +			if (*aliasptr != *localptr)
 45.1682 +			{
 45.1683 +				/* We have to knock one path off */
 45.1684 +				local_explicit_paths--;
 45.1685 +				if (alias_explicit_paths > local_explicit_paths)
 45.1686 +				{
 45.1687 +					/* Skip out if we're gonna have an impossible match */
 45.1688 +					return false;
 45.1689 +				}
 45.1690 +				/* Eat up localptr tokens until we get a result */
 45.1691 +				while (((localptr - localpath) < (int)local_path_end)
 45.1692 +					&& *localptr != '/'
 45.1693 +					&& *localptr != '\\')
 45.1694 +				{
 45.1695 +					localptr++;
 45.1696 +				}
 45.1697 +				/* Check if we hit the end of our searchable area.
 45.1698 +				 * This probably isn't possible because of the path 
 45.1699 +				 * count check, but it's a good idea anyway.
 45.1700 +				 */
 45.1701 +				if ((localptr - localpath) >= (int)local_path_end)
 45.1702 +				{
 45.1703 +					return false;
 45.1704 +				} else {
 45.1705 +					/* Consume the slash token */
 45.1706 +					localptr++;
 45.1707 +				}
 45.1708 +				/* Reset the alias pointer so we can continue consuming */
 45.1709 +				aliasptr = alias;
 45.1710 +				match = false;
 45.1711 +				continue;
 45.1712 +			}
 45.1713 +			/* Note:
 45.1714 +			 * This is safe because if localptr terminates early, aliasptr will too
 45.1715 +			 */
 45.1716 +			do
 45.1717 +			{
 45.1718 +				/* We should never reach the end of the string because of this check. */
 45.1719 +				bool aliasend = (aliasptr - alias) > (int)alias_path_end;
 45.1720 +				bool localend = (localptr - localpath) > (int)local_path_end;
 45.1721 +				if (aliasend || localend)
 45.1722 +				{
 45.1723 +					if (aliasend && localend)
 45.1724 +					{
 45.1725 +						/* we matched, and we can break out now */
 45.1726 +						match = true;
 45.1727 +						break;
 45.1728 +					}
 45.1729 +					/* Otherwise, we've hit the end somehow and rest won't match up.  Break out. */
 45.1730 +					match = false;
 45.1731 +					break;
 45.1732 +				}
 45.1733 +
 45.1734 +				/* If we got here, it's safe to compare the next two tokens */
 45.1735 +				if (*localptr != *aliasptr)
 45.1736 +				{
 45.1737 +					match = false;
 45.1738 +					break;
 45.1739 +				}
 45.1740 +				localptr++;
 45.1741 +				aliasptr++;
 45.1742 +			} while (true);
 45.1743 +		} while (!match);
 45.1744 +	}
 45.1745 +
 45.1746 +	/* If we got here, it's time to compare filenames */
 45.1747 +	const char *aliasptr = alias;
 45.1748 +	const char *localptr = localpath;
 45.1749 +
 45.1750 +	if (alias_explicit_paths)
 45.1751 +	{
 45.1752 +		aliasptr = &alias[alias_path_end + 1];
 45.1753 +	}
 45.1754 +
 45.1755 +	if (local_explicit_paths)
 45.1756 +	{
 45.1757 +		localptr = &localpath[local_path_end + 1];
 45.1758 +	}
 45.1759 +
 45.1760 +	while (true)
 45.1761 +	{
 45.1762 +		if (*aliasptr == '*')
 45.1763 +		{
 45.1764 +			/* First, see if this is the last character */
 45.1765 +			if ((unsigned)(aliasptr - alias) == alias_len - 1)
 45.1766 +			{
 45.1767 +				/* If so, there's no need to match anything else */
 45.1768 +				return true;
 45.1769 +			}
 45.1770 +			/* Otherwise, we need to search for an appropriate matching sequence in local.
 45.1771 +			 * Note that we only need to search up to the next asterisk.
 45.1772 +			 */
 45.1773 +			aliasptr++;
 45.1774 +			bool match = true;
 45.1775 +			const char *local_orig = localptr;
 45.1776 +			do
 45.1777 +			{
 45.1778 +				match = true;
 45.1779 +				while (*aliasptr != '\0' && *aliasptr != '*')
 45.1780 +				{
 45.1781 +					/* Since aliasptr is never '\0', localptr hitting the end will fail */
 45.1782 +					if (*aliasptr != *localptr)
 45.1783 +					{
 45.1784 +						match = false;
 45.1785 +						break;
 45.1786 +					}
 45.1787 +					aliasptr++;
 45.1788 +					localptr++;
 45.1789 +				}
 45.1790 +				if (!match)
 45.1791 +				{
 45.1792 +					/* If we didn't get a match, we need to advance the search stream.
 45.1793 +					 * This will let us skip tokens while still searching for another match.
 45.1794 +					 */
 45.1795 +					localptr = ++local_orig;
 45.1796 +					/* Make sure we don't go out of bounds */
 45.1797 +					if (*localptr == '\0')
 45.1798 +					{
 45.1799 +						break;
 45.1800 +					}
 45.1801 +				}
 45.1802 +			} while (!match);
 45.1803 +
 45.1804 +			if (!match)
 45.1805 +			{
 45.1806 +				return false;
 45.1807 +			} else {
 45.1808 +				/* If we got a match, move on to the next token */
 45.1809 +				continue;
 45.1810 +			}
 45.1811 +		} else if (*aliasptr == '\0') {
 45.1812 +			if (*localptr == '\0'
 45.1813 +				||
 45.1814 +				strcmp(localptr, ".smx") == 0)
 45.1815 +			{
 45.1816 +				return true;
 45.1817 +			} else {
 45.1818 +				return false;
 45.1819 +			}
 45.1820 +		} else if (*aliasptr != *localptr) {
 45.1821 +			return false;
 45.1822 +		}
 45.1823 +		aliasptr++;
 45.1824 +		localptr++;
 45.1825 +	}
 45.1826 +
 45.1827 +	return true;
 45.1828 +}
 45.1829 +
 45.1830 +bool CPluginManager::IsLateLoadTime() const
 45.1831 +{
 45.1832 +	return (m_AllPluginsLoaded || !smcore.IsMapLoading());
 45.1833 +}
 45.1834 +
 45.1835 +void CPluginManager::OnSourceModAllInitialized()
 45.1836 +{
 45.1837 +	m_MyIdent = g_ShareSys.CreateCoreIdentity();
 45.1838 +
 45.1839 +	HandleAccess sec;
 45.1840 +	handlesys->InitAccessDefaults(NULL, &sec);
 45.1841 +
 45.1842 +	sec.access[HandleAccess_Delete] = HANDLE_RESTRICT_IDENTITY;
 45.1843 +	sec.access[HandleAccess_Clone] = HANDLE_RESTRICT_IDENTITY;
 45.1844 +
 45.1845 +	g_PluginType = handlesys->CreateType("Plugin", this, 0, NULL, &sec, m_MyIdent, NULL);
 45.1846 +	g_PluginIdent = g_ShareSys.CreateIdentType("PLUGIN");
 45.1847 +
 45.1848 +	rootmenu->AddRootConsoleCommand("plugins", "Manage Plugins", this);
 45.1849 +
 45.1850 +	g_ShareSys.AddInterface(NULL, GetOldAPI());
 45.1851 +	
 45.1852 +	m_pOnLibraryAdded = forwardsys->CreateForward("OnLibraryAdded", ET_Ignore, 1, NULL, Param_String);
 45.1853 +	m_pOnLibraryRemoved = forwardsys->CreateForward("OnLibraryRemoved", ET_Ignore, 1, NULL, Param_String);
 45.1854 +}
 45.1855 +
 45.1856 +void CPluginManager::OnSourceModShutdown()
 45.1857 +{
 45.1858 +	rootmenu->RemoveRootConsoleCommand("plugins", this);
 45.1859 +
 45.1860 +	UnloadAll();
 45.1861 +
 45.1862 +	handlesys->RemoveType(g_PluginType, m_MyIdent);
 45.1863 +	g_ShareSys.DestroyIdentType(g_PluginIdent);
 45.1864 +	g_ShareSys.DestroyIdentity(m_MyIdent);
 45.1865 +	
 45.1866 +	forwardsys->ReleaseForward(m_pOnLibraryAdded);
 45.1867 +	forwardsys->ReleaseForward(m_pOnLibraryRemoved);
 45.1868 +}
 45.1869 +
 45.1870 +ConfigResult CPluginManager::OnSourceModConfigChanged(const char *key, 
 45.1871 +												 const char *value, 
 45.1872 +												 ConfigSource source, 
 45.1873 +												 char *error, 
 45.1874 +												 size_t maxlength)
 45.1875 +{
 45.1876 +	if (strcmp(key, "BlockBadPlugins") == 0) {
 45.1877 +		if (strcasecmp(value, "yes") == 0)
 45.1878 +		{
 45.1879 +			m_bBlockBadPlugins = true;
 45.1880 +		} else if (strcasecmp(value, "no") == 0) {
 45.1881 +			m_bBlockBadPlugins = false;
 45.1882 +		} else {
 45.1883 +			smcore.Format(error, maxlength, "Invalid value: must be \"yes\" or \"no\"");
 45.1884 +			return ConfigResult_Reject;
 45.1885 +		}
 45.1886 +		return ConfigResult_Accept;
 45.1887 +	}
 45.1888 +	return ConfigResult_Ignore;
 45.1889 +}
 45.1890 +
 45.1891 +void CPluginManager::OnHandleDestroy(HandleType_t type, void *object)
 45.1892 +{
 45.1893 +	/* We don't care about the internal object, actually */
 45.1894 +}
 45.1895 +
 45.1896 +bool CPluginManager::GetHandleApproxSize(HandleType_t type, void *object, unsigned int *pSize)
 45.1897 +{
 45.1898 +	*pSize = ((CPlugin *)object)->CalcMemUsage();
 45.1899 +	return true;
 45.1900 +}
 45.1901 +
 45.1902 +IPlugin *CPluginManager::PluginFromHandle(Handle_t handle, HandleError *err)
 45.1903 +{
 45.1904 +	IPlugin *pPlugin;
 45.1905 +	HandleError _err;
 45.1906 +
 45.1907 +	HandleSecurity sec;
 45.1908 +
 45.1909 +	sec.pOwner = NULL;
 45.1910 +	sec.pIdentity = m_MyIdent;
 45.1911 +
 45.1912 +	if ((_err=handlesys->ReadHandle(handle, g_PluginType, &sec, (void **)&pPlugin)) != HandleError_None)
 45.1913 +	{
 45.1914 +		pPlugin = NULL;
 45.1915 +	}
 45.1916 +
 45.1917 +	if (err)
 45.1918 +	{
 45.1919 +		*err = _err;
 45.1920 +	}
 45.1921 +
 45.1922 +	return pPlugin;
 45.1923 +}
 45.1924 +
 45.1925 +CPlugin *CPluginManager::GetPluginByOrder(int num)
 45.1926 +{
 45.1927 +	if (num < 1 || num > (int)GetPluginCount())
 45.1928 +	{
 45.1929 +		return NULL;
 45.1930 +	}
 45.1931 +
 45.1932 +	CPlugin *pl;
 45.1933 +	int id = 1;
 45.1934 +
 45.1935 +	SourceHook::List<CPlugin *>::iterator iter;
 45.1936 +	for (iter = m_plugins.begin(); iter != m_plugins.end() && id < num; iter++, id++) {}
 45.1937 +
 45.1938 +	pl = *iter;
 45.1939 +
 45.1940 +	return pl;
 45.1941 +}
 45.1942 +
 45.1943 +const char *CPluginManager::GetStatusText(PluginStatus st)
 45.1944 +{
 45.1945 +	switch (st)
 45.1946 +	{
 45.1947 +	case Plugin_Running:
 45.1948 +		return "Running";
 45.1949 +	case Plugin_Paused:
 45.1950 +		return "Paused";
 45.1951 +	case Plugin_Error:
 45.1952 +		return "Error";
 45.1953 +	case Plugin_Uncompiled:
 45.1954 +		return "Uncompiled";
 45.1955 +	case Plugin_BadLoad:
 45.1956 +		return "Bad Load";
 45.1957 +	case Plugin_Failed:
 45.1958 +		return "Failed";
 45.1959 +	default:
 45.1960 +		assert(false);
 45.1961 +		return "-";
 45.1962 +	}
 45.1963 +}
 45.1964 +
 45.1965 +static inline bool IS_STR_FILLED(const char *text)
 45.1966 +{
 45.1967 +	return text[0] != '\0';
 45.1968 +}
 45.1969 +
 45.1970 +void CPluginManager::OnRootConsoleCommand(const char *cmdname, const CCommand &command)
 45.1971 +{
 45.1972 +	int argcount = smcore.Argc(command);
 45.1973 +	if (argcount >= 3)
 45.1974 +	{
 45.1975 +		const char *cmd = smcore.Arg(command, 2);
 45.1976 +		if (strcmp(cmd, "list") == 0)
 45.1977 +		{
 45.1978 +			char buffer[256];
 45.1979 +			unsigned int id = 1;
 45.1980 +			int plnum = GetPluginCount();
 45.1981 +
 45.1982 +			if (!plnum)
 45.1983 +			{
 45.1984 +				rootmenu->ConsolePrint("[SM] No plugins loaded");
 45.1985 +				return;
 45.1986 +			}
 45.1987 +			else
 45.1988 +			{
 45.1989 +				rootmenu->ConsolePrint("[SM] Listing %d plugin%s:", GetPluginCount(), (plnum > 1) ? "s" : "");
 45.1990 +			}
 45.1991 +
 45.1992 +			CPlugin *pl;
 45.1993 +			SourceHook::List<CPlugin *>::iterator iter;
 45.1994 +			SourceHook::List<CPlugin *> m_FailList;
 45.1995 +
 45.1996 +			for (iter = m_plugins.begin(); iter != m_plugins.end(); iter++, id++)
 45.1997 +			{
 45.1998 +				pl = (*iter);
 45.1999 +				assert(pl->GetStatus() != Plugin_Created);
 45.2000 +				int len = 0;
 45.2001 +				const sm_plugininfo_t *info = pl->GetPublicInfo();
 45.2002 +				if (pl->GetStatus() != Plugin_Running && !pl->IsSilentlyFailed())
 45.2003 +				{
 45.2004 +					len += smcore.Format(buffer, sizeof(buffer), "  %02d <%s>", id, GetStatusText(pl->GetStatus()));
 45.2005 +
 45.2006 +					if (pl->GetStatus() <= Plugin_Error)
 45.2007 +					{
 45.2008 +						/* Plugin has failed to load. */
 45.2009 +						m_FailList.push_back(pl);
 45.2010 +					}
 45.2011 +				}
 45.2012 +				else
 45.2013 +				{
 45.2014 +					len += smcore.Format(buffer, sizeof(buffer), "  %02d", id);
 45.2015 +				}
 45.2016 +				if (pl->GetStatus() < Plugin_Created)
 45.2017 +				{
 45.2018 +					if (pl->IsSilentlyFailed())
 45.2019 +						len += smcore.Format(&buffer[len], sizeof(buffer)-len, " Disabled:");
 45.2020 +					len += smcore.Format(&buffer[len], sizeof(buffer)-len, " \"%s\"", (IS_STR_FILLED(info->name)) ? info->name : pl->GetFilename());
 45.2021 +					if (IS_STR_FILLED(info->version))
 45.2022 +					{
 45.2023 +						len += smcore.Format(&buffer[len], sizeof(buffer)-len, " (%s)", info->version);
 45.2024 +					}
 45.2025 +					if (IS_STR_FILLED(info->author))
 45.2026 +					{
 45.2027 +						smcore.Format(&buffer[len], sizeof(buffer)-len, " by %s", info->author);
 45.2028 +					}
 45.2029 +				}
 45.2030 +				else
 45.2031 +				{
 45.2032 +					smcore.Format(&buffer[len], sizeof(buffer)-len, " %s", pl->m_filename);
 45.2033 +				}
 45.2034 +				rootmenu->ConsolePrint("%s", buffer);
 45.2035 +			}
 45.2036 +
 45.2037 +			if (!m_FailList.empty())
 45.2038 +			{
 45.2039 +				rootmenu->ConsolePrint("Load Errors:");
 45.2040 +
 45.2041 +				SourceHook::List<CPlugin *>::iterator _iter;
 45.2042 +
 45.2043 +				CPlugin *pl;
 45.2044 +
 45.2045 +				for (_iter=m_FailList.begin(); _iter!=m_FailList.end(); _iter++)
 45.2046 +				{
 45.2047 +					pl = (CPlugin *)*_iter;
 45.2048 +					rootmenu->ConsolePrint("%s: %s",(IS_STR_FILLED(pl->GetPublicInfo()->name)) ? pl->GetPublicInfo()->name : pl->GetFilename(), pl->m_errormsg);
 45.2049 +				}
 45.2050 +			}
 45.2051 +
 45.2052 +			return;
 45.2053 +		}
 45.2054 +		else if (strcmp(cmd, "load") == 0)
 45.2055 +		{
 45.2056 +			if (argcount < 4)
 45.2057 +			{
 45.2058 +				rootmenu->ConsolePrint("[SM] Usage: sm plugins load <file>");
 45.2059 +				return;
 45.2060 +			}
 45.2061 +
 45.2062 +			char error[128];
 45.2063 +			bool wasloaded;
 45.2064 +			const char *filename = smcore.Arg(command, 3);
 45.2065 +
 45.2066 +			char pluginfile[256];
 45.2067 +			const char *ext = libsys->GetFileExtension(filename) ? "" : ".smx";
 45.2068 +			g_pSM->BuildPath(Path_None, pluginfile, sizeof(pluginfile), "%s%s", filename, ext);
 45.2069 +
 45.2070 +			IPlugin *pl = LoadPlugin(pluginfile, false, PluginType_MapUpdated, error, sizeof(error), &wasloaded);
 45.2071 +
 45.2072 +			if (wasloaded)
 45.2073 +			{
 45.2074 +				rootmenu->ConsolePrint("[SM] Plugin %s is already loaded.", pluginfile);
 45.2075 +				return;
 45.2076 +			}
 45.2077 +
 45.2078 +			if (pl)
 45.2079 +			{
 45.2080 +				rootmenu->ConsolePrint("[SM] Loaded plugin %s successfully.", pluginfile);
 45.2081 +			}
 45.2082 +			else
 45.2083 +			{
 45.2084 +				rootmenu->ConsolePrint("[SM] Plugin %s failed to load: %s.", pluginfile, error);
 45.2085 +			}
 45.2086 +
 45.2087 +			return;
 45.2088 +		}
 45.2089 +		else if (strcmp(cmd, "unload") == 0)
 45.2090 +		{
 45.2091 +			if (argcount < 4)
 45.2092 +			{
 45.2093 +				rootmenu->ConsolePrint("[SM] Usage: sm plugins unload <#|file>");
 45.2094 +				return;
 45.2095 +			}
 45.2096 +
 45.2097 +			CPlugin *pl;
 45.2098 +			char *end;
 45.2099 +			const char *arg = smcore.Arg(command, 3);
 45.2100 +			int id = strtol(arg, &end, 10);
 45.2101 +
 45.2102 +			if (*end == '\0')
 45.2103 +			{
 45.2104 +				pl = GetPluginByOrder(id);
 45.2105 +				if (!pl)
 45.2106 +				{
 45.2107 +					rootmenu->ConsolePrint("[SM] Plugin index %d not found.", id);
 45.2108 +					return;
 45.2109 +				}
 45.2110 +			}
 45.2111 +			else
 45.2112 +			{
 45.2113 +				char pluginfile[256];
 45.2114 +				const char *ext = libsys->GetFileExtension(arg) ? "" : ".smx";
 45.2115 +				g_pSM->BuildPath(Path_None, pluginfile, sizeof(pluginfile), "%s%s", arg, ext);
 45.2116 +
 45.2117 +				CPlugin **pluginpp = m_LoadLookup.retrieve(pluginfile);
 45.2118 +				if (!pluginpp || !*pluginpp)
 45.2119 +				{
 45.2120 +					rootmenu->ConsolePrint("[SM] Plugin %s is not loaded.", pluginfile);
 45.2121 +					return;
 45.2122 +				}
 45.2123 +				pl = *pluginpp;
 45.2124 +			}
 45.2125 +
 45.2126 +			char name[PLATFORM_MAX_PATH];
 45.2127 +
 45.2128 +			if (pl->GetStatus() < Plugin_Created)
 45.2129 +			{
 45.2130 +				const sm_plugininfo_t *info = pl->GetPublicInfo();
 45.2131 +				smcore.Format(name, sizeof(name), (IS_STR_FILLED(info->name)) ? info->name : pl->GetFilename());
 45.2132 +			}
 45.2133 +			else
 45.2134 +			{
 45.2135 +				smcore.Format(name, sizeof(name), "%s", pl->GetFilename());
 45.2136 +			}
 45.2137 +
 45.2138 +			if (UnloadPlugin(pl))
 45.2139 +			{
 45.2140 +				rootmenu->ConsolePrint("[SM] Plugin %s unloaded successfully.", name);
 45.2141 +			}
 45.2142 +			else
 45.2143 +			{
 45.2144 +				rootmenu->ConsolePrint("[SM] Failed to unload plugin %s.", name);
 45.2145 +			}
 45.2146 +
 45.2147 +			return;
 45.2148 +		}
 45.2149 +		else if (strcmp(cmd, "unload_all") == 0)
 45.2150 +		{
 45.2151 +			g_PluginSys.UnloadAll();
 45.2152 +			rootmenu->ConsolePrint("[SM] All plugins have been unloaded.");
 45.2153 +			return;
 45.2154 +		}
 45.2155 +		else if (strcmp(cmd, "load_lock") == 0)
 45.2156 +		{
 45.2157 +			if (m_LoadingLocked)
 45.2158 +			{
 45.2159 +				rootmenu->ConsolePrint("[SM] There is already a loading lock in effect.");
 45.2160 +			}
 45.2161 +			else
 45.2162 +			{
 45.2163 +				m_LoadingLocked = true;
 45.2164 +				rootmenu->ConsolePrint("[SM] Loading is now locked; no plugins will be loaded or re-loaded.");
 45.2165 +			}
 45.2166 +			return;
 45.2167 +		}
 45.2168 +		else if (strcmp(cmd, "load_unlock") == 0)
 45.2169 +		{
 45.2170 +			if (m_LoadingLocked)
 45.2171 +			{
 45.2172 +				m_LoadingLocked = false;
 45.2173 +				rootmenu->ConsolePrint("[SM] The loading lock is no longer in effect.");
 45.2174 +			}
 45.2175 +			else
 45.2176 +			{
 45.2177 +				rootmenu->ConsolePrint("[SM] There was no loading lock in effect.");
 45.2178 +			}
 45.2179 +			return;
 45.2180 +		}
 45.2181 +		else if (strcmp(cmd, "info") == 0)
 45.2182 +		{
 45.2183 +			if (argcount < 4)
 45.2184 +			{
 45.2185 +				rootmenu->ConsolePrint("[SM] Usage: sm plugins info <#>");
 45.2186 +				return;
 45.2187 +			}
 45.2188 +
 45.2189 +			CPlugin *pl;
 45.2190 +			char *end;
 45.2191 +			const char *arg = smcore.Arg(command, 3);
 45.2192 +			int id = strtol(arg, &end, 10);
 45.2193 +
 45.2194 +			if (*end == '\0')
 45.2195 +			{
 45.2196 +				pl = GetPluginByOrder(id);
 45.2197 +				if (!pl)
 45.2198 +				{
 45.2199 +					rootmenu->ConsolePrint("[SM] Plugin index %d not found.", id);
 45.2200 +					return;
 45.2201 +				}
 45.2202 +			}
 45.2203 +			else
 45.2204 +			{
 45.2205 +				char pluginfile[256];
 45.2206 +				const char *ext = libsys->GetFileExtension(arg) ? "" : ".smx";
 45.2207 +				g_pSM->BuildPath(Path_None, pluginfile, sizeof(pluginfile), "%s%s", arg, ext);
 45.2208 +
 45.2209 +				CPlugin **pluginpp = m_LoadLookup.retrieve(pluginfile);
 45.2210 +				if (!pluginpp || !*pluginpp)
 45.2211 +				{
 45.2212 +					rootmenu->ConsolePrint("[SM] Plugin %s is not loaded.", pluginfile);
 45.2213 +					return;
 45.2214 +				}
 45.2215 +				pl = *pluginpp;
 45.2216 +			}
 45.2217 +
 45.2218 +			const sm_plugininfo_t *info = pl->GetPublicInfo();
 45.2219 +
 45.2220 +			rootmenu->ConsolePrint("  Filename: %s", pl->GetFilename());
 45.2221 +			if (pl->GetStatus() <= Plugin_Error)
 45.2222 +			{
 45.2223 +				if (IS_STR_FILLED(info->name))
 45.2224 +				{
 45.2225 +					if (IS_STR_FILLED(info->description))
 45.2226 +					{
 45.2227 +						rootmenu->ConsolePrint("  Title: %s (%s)", info->name, info->description);
 45.2228 +					} else {
 45.2229 +						rootmenu->ConsolePrint("  Title: %s", info->name);
 45.2230 +					}
 45.2231 +				}
 45.2232 +				if (IS_STR_FILLED(info->author))
 45.2233 +				{
 45.2234 +					rootmenu->ConsolePrint("  Author: %s", info->author);
 45.2235 +				}
 45.2236 +				if (IS_STR_FILLED(info->version))
 45.2237 +				{
 45.2238 +					rootmenu->ConsolePrint("  Version: %s", info->version);
 45.2239 +				}
 45.2240 +				if (IS_STR_FILLED(info->url))
 45.2241 +				{
 45.2242 +					rootmenu->ConsolePrint("  URL: %s", info->url);
 45.2243 +				}
 45.2244 +				if (pl->GetStatus() == Plugin_Error)
 45.2245 +				{
 45.2246 +					rootmenu->ConsolePrint("  Error: %s", pl->m_errormsg);
 45.2247 +				}
 45.2248 +				else
 45.2249 +				{
 45.2250 +					if (pl->GetStatus() == Plugin_Running)
 45.2251 +					{
 45.2252 +						rootmenu->ConsolePrint("  Status: running");
 45.2253 +					}
 45.2254 +					else
 45.2255 +					{
 45.2256 +						rootmenu->ConsolePrint("  Status: not running");
 45.2257 +					}
 45.2258 +
 45.2259 +					const char *typestr = "";
 45.2260 +					switch (pl->GetType())
 45.2261 +					{
 45.2262 +					case PluginType_MapUpdated:
 45.2263 +						typestr = "Map Change if Updated";
 45.2264 +						break;
 45.2265 +					case PluginType_MapOnly:
 45.2266 +						typestr = "Map Change";
 45.2267 +						break;
 45.2268 +					case PluginType_Private:
 45.2269 +					case PluginType_Global:
 45.2270 +						typestr = "Never";
 45.2271 +						break;
 45.2272 +					}
 45.2273 +
 45.2274 +					rootmenu->ConsolePrint("  Reloads: %s", typestr);
 45.2275 +				}
 45.2276 +				if (pl->m_FileVersion >= 3)
 45.2277 +				{
 45.2278 +					rootmenu->ConsolePrint("  Timestamp: %s", pl->m_DateTime);
 45.2279 +				}
 45.2280 +				
 45.2281 +				unsigned char *pCodeHash = pl->m_pRuntime->GetCodeHash();
 45.2282 +				unsigned char *pDataHash = pl->m_pRuntime->GetDataHash();
 45.2283 +				
 45.2284 +				char combinedHash[33];
 45.2285 +				for (int i = 0; i < 16; i++)
 45.2286 +					smcore.Format(combinedHash + (i * 2), 3, "%02x", pCodeHash[i] ^ pDataHash[i]);
 45.2287 +				
 45.2288 +				rootmenu->ConsolePrint("  Hash: %s", combinedHash);
 45.2289 +			}
 45.2290 +			else
 45.2291 +			{
 45.2292 +				rootmenu->ConsolePrint("  Load error: %s", pl->m_errormsg);
 45.2293 +				if (pl->GetStatus() < Plugin_Created)
 45.2294 +				{
 45.2295 +					rootmenu->ConsolePrint("  File info: (title \"%s\") (version \"%s\")", 
 45.2296 +											info->name ? info->name : "<none>",
 45.2297 +											info->version ? info->version : "<none>");
 45.2298 +					if (IS_STR_FILLED(info->url))
 45.2299 +					{
 45.2300 +						rootmenu->ConsolePrint("  File URL: %s", info->url);
 45.2301 +					}
 45.2302 +				}
 45.2303 +			}
 45.2304 +
 45.2305 +			return;
 45.2306 +		}
 45.2307 +		else if (strcmp(cmd, "refresh") == 0)
 45.2308 +		{
 45.2309 +			smcore.DoGlobalPluginLoads();
 45.2310 +			rootmenu->ConsolePrint("[SM] The plugin list has been refreshed and reloaded.");
 45.2311 +			return;
 45.2312 +		}
 45.2313 +		else if (strcmp(cmd, "reload") == 0)
 45.2314 +		{
 45.2315 +			if (argcount < 4)
 45.2316 +			{
 45.2317 +				rootmenu->ConsolePrint("[SM] Usage: sm plugins reload <#|file>");
 45.2318 +				return;
 45.2319 +			}
 45.2320 +
 45.2321 +			CPlugin *pl;
 45.2322 +			char *end;
 45.2323 +			const char *arg = smcore.Arg(command, 3);
 45.2324 +			int id = strtol(arg, &end, 10);
 45.2325 +
 45.2326 +			if (*end == '\0')
 45.2327 +			{
 45.2328 +				pl = GetPluginByOrder(id);
 45.2329 +				if (!pl)
 45.2330 +				{
 45.2331 +					rootmenu->ConsolePrint("[SM] Plugin index %d not found.", id);
 45.2332 +					return;
 45.2333 +				}
 45.2334 +			}
 45.2335 +			else
 45.2336 +			{
 45.2337 +				char pluginfile[256];
 45.2338 +				const char *ext = libsys->GetFileExtension(arg) ? "" : ".smx";
 45.2339 +				g_pSM->BuildPath(Path_None, pluginfile, sizeof(pluginfile), "%s%s", arg, ext);
 45.2340 +
 45.2341 +				CPlugin **pluginpp = m_LoadLookup.retrieve(pluginfile);
 45.2342 +				if (!pluginpp || !*pluginpp)
 45.2343 +				{
 45.2344 +					rootmenu->ConsolePrint("[SM] Plugin %s is not loaded.", pluginfile);
 45.2345 +					return;
 45.2346 +				}
 45.2347 +				pl = *pluginpp;
 45.2348 +			}
 45.2349 +
 45.2350 +			char name[PLATFORM_MAX_PATH];
 45.2351 +			const sm_plugininfo_t *info = pl->GetPublicInfo();
 45.2352 +			if (pl->GetStatus() <= Plugin_Paused) 
 45.2353 +				strcpy(name, (IS_STR_FILLED(info->name)) ? info->name : pl->GetFilename());
 45.2354 +			else
 45.2355 +				strcpy(name, pl->GetFilename());
 45.2356 +
 45.2357 +			if (ReloadPlugin(pl))
 45.2358 +			{
 45.2359 +				rootmenu->ConsolePrint("[SM] Plugin %s reloaded successfully.", name);
 45.2360 +			}
 45.2361 +			else
 45.2362 +			{
 45.2363 +				rootmenu->ConsolePrint("[SM] Failed to reload plugin %s.", name);
 45.2364 +			}
 45.2365 +
 45.2366 +			return;
 45.2367 +		}
 45.2368 +	}
 45.2369 +
 45.2370 +	/* Draw the main menu */
 45.2371 +	rootmenu->ConsolePrint("SourceMod Plugins Menu:");
 45.2372 +	rootmenu->DrawGenericOption("info", "Information about a plugin");
 45.2373 +	rootmenu->DrawGenericOption("list", "Show loaded plugins");
 45.2374 +	rootmenu->DrawGenericOption("load", "Load a plugin");
 45.2375 +	rootmenu->DrawGenericOption("load_lock", "Prevents any more plugins from being loaded");
 45.2376 +	rootmenu->DrawGenericOption("load_unlock", "Re-enables plugin loading");
 45.2377 +	rootmenu->DrawGenericOption("refresh", "Reloads/refreshes all plugins in the plugins folder");
 45.2378 +	rootmenu->DrawGenericOption("reload", "Reloads a plugin");
 45.2379 +	rootmenu->DrawGenericOption("unload", "Unload a plugin");
 45.2380 +	rootmenu->DrawGenericOption("unload_all", "Unloads all plugins");
 45.2381 +}
 45.2382 +
 45.2383 +bool CPluginManager::ReloadPlugin(CPlugin *pl)
 45.2384 +{
 45.2385 +	List<CPlugin *>::iterator iter;
 45.2386 +	char filename[PLATFORM_MAX_PATH];
 45.2387 +	bool wasloaded;
 45.2388 +	PluginType ptype;
 45.2389 +	IPlugin *newpl;
 45.2390 +	int id = 1;
 45.2391 +
 45.2392 +	strcpy(filename, pl->m_filename);
 45.2393 +	ptype = pl->GetType();
 45.2394 +
 45.2395 +	for (iter=m_plugins.begin(); iter!=m_plugins.end(); iter++, id++)
 45.2396 +	{
 45.2397 +		if ((*iter) == pl)
 45.2398 +		{
 45.2399 +			break;
 45.2400 +		}
 45.2401 +	}
 45.2402 +
 45.2403 +	if (!UnloadPlugin(pl))
 45.2404 +	{
 45.2405 +		return false;
 45.2406 +	}
 45.2407 +	if (!(newpl=LoadPlugin(filename, true, ptype, NULL, 0, &wasloaded)))
 45.2408 +	{
 45.2409 +		return false;
 45.2410 +	}
 45.2411 +
 45.2412 +	for (iter=m_plugins.begin(); iter!=m_plugins.end(); iter++)
 45.2413 +	{
 45.2414 +		if ((*iter) == (CPlugin *)newpl)
 45.2415 +		{
 45.2416 +			m_plugins.erase(iter);
 45.2417 +			break;
 45.2418 +		}
 45.2419 +	}
 45.2420 +
 45.2421 +	int i;
 45.2422 +	for (i=1, iter=m_plugins.begin(); iter!=m_plugins.end() && i<id; iter++, i++)
 45.2423 +	{
 45.2424 +	}
 45.2425 +	m_plugins.insert(iter, (CPlugin *)newpl);
 45.2426 +
 45.2427 +	return true;
 45.2428 +}
 45.2429 +
 45.2430 +void CPluginManager::RefreshAll()
 45.2431 +{
 45.2432 +	/* If we're in a load lock, just skip this whole bit. */
 45.2433 +	if (m_LoadingLocked)
 45.2434 +	{
 45.2435 +		return;
 45.2436 +	}
 45.2437 +
 45.2438 +	List<CPlugin *>::iterator iter;
 45.2439 +	List<CPlugin *> tmp_list = m_plugins;
 45.2440 +	CPlugin *pl;
 45.2441 +	time_t t;
 45.2442 +
 45.2443 +	for (iter=tmp_list.begin(); iter!=tmp_list.end(); iter++)
 45.2444 +	{
 45.2445 +		pl = (*iter);
 45.2446 +		if (pl->GetType() ==  PluginType_MapOnly)
 45.2447 +		{
 45.2448 +			UnloadPlugin((IPlugin *)pl);
 45.2449 +		}
 45.2450 +		else if (pl->GetType() == PluginType_MapUpdated)
 45.2451 +		{
 45.2452 +			t = pl->GetFileTimeStamp();
 45.2453 +			if (!t || t > pl->GetTimeStamp())
 45.2454 +			{
 45.2455 +				pl->SetTimeStamp(t);
 45.2456 +				UnloadPlugin((IPlugin *)pl);
 45.2457 +			}
 45.2458 +		}
 45.2459 +	}
 45.2460 +}
 45.2461 +
 45.2462 +void CPluginManager::_SetPauseState(CPlugin *pl, bool paused)
 45.2463 +{
 45.2464 +	List<IPluginsListener *>::iterator iter;
 45.2465 +	IPluginsListener *pListener;
 45.2466 +	for (iter=m_listeners.begin(); iter!=m_listeners.end(); iter++)
 45.2467 +	{
 45.2468 +		pListener = (*iter);
 45.2469 +		pListener->OnPluginPauseChange(pl, paused);
 45.2470 +	}	
 45.2471 +}
 45.2472 +
 45.2473 +void CPluginManager::AddFunctionsToForward(const char *name, IChangeableForward *pForward)
 45.2474 +{
 45.2475 +	List<CPlugin *>::iterator iter;
 45.2476 +	CPlugin *pPlugin;
 45.2477 +	IPluginFunction *pFunction;
 45.2478 +
 45.2479 +	for (iter = m_plugins.begin(); iter != m_plugins.end(); iter++)
 45.2480 +	{
 45.2481 +		pPlugin = (*iter);
 45.2482 +
 45.2483 +		if (pPlugin->GetStatus() <= Plugin_Paused)
 45.2484 +		{
 45.2485 +			pFunction = pPlugin->GetBaseContext()->GetFunctionByName(name);
 45.2486 +
 45.2487 +			if (pFunction)
 45.2488 +			{
 45.2489 +				pForward->AddFunction(pFunction);
 45.2490 +			}
 45.2491 +		}
 45.2492 +	}
 45.2493 +}
 45.2494 +
 45.2495 +CPlugin *CPluginManager::GetPluginFromIdentity(IdentityToken_t *pToken)
 45.2496 +{
 45.2497 +	if (pToken->type != g_PluginIdent)
 45.2498 +	{
 45.2499 +		return NULL;
 45.2500 +	}
 45.2501 +
 45.2502 +	return (CPlugin *)(pToken->ptr);
 45.2503 +}
 45.2504 +
 45.2505 +void CPluginManager::OnLibraryAction(const char *lib, LibraryAction action)
 45.2506 +{
 45.2507 +	switch (action)
 45.2508 +	{
 45.2509 +	case LibraryAction_Removed:
 45.2510 +		m_pOnLibraryRemoved->PushString(lib);
 45.2511 +		m_pOnLibraryRemoved->Execute(NULL);
 45.2512 +		break;
 45.2513 +	case LibraryAction_Added:
 45.2514 +		m_pOnLibraryAdded->PushString(lib);
 45.2515 +		m_pOnLibraryAdded->Execute(NULL);
 45.2516 +		break;
 45.2517 +	}
 45.2518 +}
 45.2519 +
 45.2520 +bool CPluginManager::LibraryExists(const char *lib)
 45.2521 +{
 45.2522 +	List<CPlugin *>::iterator iter;
 45.2523 +
 45.2524 +	for (iter=m_plugins.begin();
 45.2525 +		 iter!=m_plugins.end();
 45.2526 +		 iter++)
 45.2527 +	{
 45.2528 +		CPlugin *pl = (*iter);
 45.2529 +		if (pl->GetStatus() != Plugin_Running)
 45.2530 +		{
 45.2531 +			continue;
 45.2532 +		}
 45.2533 +		List<String>::iterator s_iter;
 45.2534 +		for (s_iter = pl->m_Libraries.begin();
 45.2535 +			 s_iter != pl->m_Libraries.end();
 45.2536 +			 s_iter++)
 45.2537 +		{
 45.2538 +			if ((*s_iter).compare(lib) == 0)
 45.2539 +			{
 45.2540 +				return true;
 45.2541 +			}
 45.2542 +		}
 45.2543 +	}
 45.2544 +
 45.2545 +	return false;
 45.2546 +}
 45.2547 +
 45.2548 +void CPluginManager::AllPluginsLoaded()
 45.2549 +{
 45.2550 +	List<CPlugin *>::iterator iter;
 45.2551 +	CPlugin *pl;
 45.2552 +
 45.2553 +	for (iter=m_plugins.begin(); iter!=m_plugins.end(); iter++)
 45.2554 +	{
 45.2555 +		pl = (*iter);
 45.2556 +		pl->Call_OnAllPluginsLoaded();
 45.2557 +	}
 45.2558 +}
 45.2559 +
 45.2560 +void CPluginManager::UnloadAll()
 45.2561 +{
 45.2562 +	List<CPlugin *>::iterator iter;
 45.2563 +	while ( (iter = m_plugins.begin()) != m_plugins.end() )
 45.2564 +	{
 45.2565 +		UnloadPlugin((*iter));
 45.2566 +	}
 45.2567 +}
 45.2568 +
 45.2569 +int CPluginManager::GetOrderOfPlugin(IPlugin *pl)
 45.2570 +{
 45.2571 +	int id = 1;
 45.2572 +	List<CPlugin *>::iterator iter;
 45.2573 +
 45.2574 +	for (iter = m_plugins.begin(); iter != m_plugins.end(); iter++, id++)
 45.2575 +	{
 45.2576 +		if ((*iter) == pl)
 45.2577 +		{
 45.2578 +			return id;
 45.2579 +		}
 45.2580 +	}
 45.2581 +
 45.2582 +	return -1;
 45.2583 +}
 45.2584 +
 45.2585 +SMPlugin *CPluginManager::FindPluginByConsoleArg(const char *arg)
 45.2586 +{
 45.2587 +	int id;
 45.2588 +	char *end;
 45.2589 +	CPlugin *pl;
 45.2590 +	
 45.2591 +	id = strtol(arg, &end, 10);
 45.2592 +
 45.2593 +	if (*end == '\0')
 45.2594 +	{
 45.2595 +		pl = GetPluginByOrder(id);
 45.2596 +		if (!pl)
 45.2597 +		{
 45.2598 +			return NULL;
 45.2599 +		}
 45.2600 +	}
 45.2601 +	else
 45.2602 +	{
 45.2603 +		char pluginfile[256];
 45.2604 +		const char *ext = libsys->GetFileExtension(arg) ? "" : ".smx";
 45.2605 +		smcore.Format(pluginfile, sizeof(pluginfile), "%s%s", arg, ext);
 45.2606 +
 45.2607 +		CPlugin **pluginpp = m_LoadLookup.retrieve(pluginfile);
 45.2608 +		if (!pluginpp || !*pluginpp)
 45.2609 +		{
 45.2610 +			return NULL;
 45.2611 +		}
 45.2612 +	}
 45.2613 +
 45.2614 +	return pl;
 45.2615 +}
 45.2616 +
 45.2617 +void CPluginManager::OnSourceModMaxPlayersChanged(int newvalue)
 45.2618 +{
 45.2619 +	SyncMaxClients(newvalue);
 45.2620 +}
 45.2621 +
 45.2622 +void CPluginManager::SyncMaxClients(int max_clients)
 45.2623 +{
 45.2624 +	List<CPlugin *>::iterator iter;
 45.2625 +
 45.2626 +	for (iter = m_plugins.begin(); iter != m_plugins.end(); iter++)
 45.2627 +	{
 45.2628 +		(*iter)->SyncMaxClients(max_clients);
 45.2629 +	}
 45.2630 +}
 45.2631 +
 45.2632 +void CPluginManager::ListPlugins(CVector<SMPlugin *> *list)
 45.2633 +{
 45.2634 +	List<CPlugin *>::iterator iter;
 45.2635 +
 45.2636 +	for (iter = m_plugins.begin(); iter != m_plugins.end(); iter++)
 45.2637 +	{
 45.2638 +		list->push_back((*iter));
 45.2639 +	}
 45.2640 +}
 45.2641 +
 45.2642 +class OldPluginAPI : public IPluginManager
 45.2643 +{
 45.2644 +public:
 45.2645 +	IPlugin *LoadPlugin(const char *path, 
 45.2646 +						bool debug,
 45.2647 +						PluginType type,
 45.2648 +						char error[],
 45.2649 +						size_t maxlength,
 45.2650 +						bool *wasloaded)
 45.2651 +	{
 45.2652 +		return g_PluginSys.LoadPlugin(path, debug, type, error, maxlength, wasloaded);
 45.2653 +	}
 45.2654 +
 45.2655 +	bool UnloadPlugin(IPlugin *plugin)
 45.2656 +	{
 45.2657 +		return g_PluginSys.UnloadPlugin(plugin);
 45.2658 +	}
 45.2659 +
 45.2660 +	IPlugin *FindPluginByContext(const sp_context_t *ctx)
 45.2661 +	{
 45.2662 +		return g_PluginSys.FindPluginByContext(ctx);
 45.2663 +	}
 45.2664 +
 45.2665 +	unsigned int GetPluginCount()
 45.2666 +	{
 45.2667 +		return g_PluginSys.GetPluginCount();
 45.2668 +	}
 45.2669 +
 45.2670 +	IPluginIterator *GetPluginIterator()
 45.2671 +	{
 45.2672 +		return g_PluginSys.GetPluginIterator();
 45.2673 +	}
 45.2674 +
 45.2675 +	void AddPluginsListener(IPluginsListener *listener)
 45.2676 +	{
 45.2677 +		g_PluginSys.AddPluginsListener(listener);
 45.2678 +	}
 45.2679 +
 45.2680 +	void RemovePluginsListener(IPluginsListener *listener)
 45.2681 +	{
 45.2682 +		g_PluginSys.RemovePluginsListener(listener);
 45.2683 +	}
 45.2684 +
 45.2685 +	IPlugin *PluginFromHandle(Handle_t handle, HandleError *err)
 45.2686 +	{
 45.2687 +		return g_PluginSys.PluginFromHandle(handle, err);
 45.2688 +	}
 45.2689 +};
 45.2690 +
 45.2691 +static OldPluginAPI sOldPluginAPI;
 45.2692 +
 45.2693 +IPluginManager *CPluginManager::GetOldAPI()
 45.2694 +{
 45.2695 +	return &sOldPluginAPI;
 45.2696 +}
    46.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    46.2 +++ b/core/logic/PluginSys.h	Fri Mar 29 11:37:29 2013 -0700
    46.3 @@ -0,0 +1,482 @@
    46.4 +/**
    46.5 + * vim: set ts=4 :
    46.6 + * =============================================================================
    46.7 + * SourceMod
    46.8 + * Copyright (C) 2004-2010 AlliedModders LLC.  All rights reserved.
    46.9 + * =============================================================================
   46.10 + *
   46.11 + * This program is free software; you can redistribute it and/or modify it under
   46.12 + * the terms of the GNU General Public License, version 3.0, as published by the
   46.13 + * Free Software Foundation.
   46.14 + * 
   46.15 + * This program is distributed in the hope that it will be useful, but WITHOUT
   46.16 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   46.17 + * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
   46.18 + * details.
   46.19 + *
   46.20 + * You should have received a copy of the GNU General Public License along with
   46.21 + * this program.  If not, see <http://www.gnu.org/licenses/>.
   46.22 + *
   46.23 + * As a special exception, AlliedModders LLC gives you permission to link the
   46.24 + * code of this program (as well as its derivative works) to "Half-Life 2," the
   46.25 + * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
   46.26 + * by the Valve Corporation.  You must obey the GNU General Public License in
   46.27 + * all respects for all other code used.  Additionally, AlliedModders LLC grants
   46.28 + * this exception to all derivative works.  AlliedModders LLC defines further
   46.29 + * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
   46.30 + * or <http://www.sourcemod.net/license.php>.
   46.31 + *
   46.32 + * Version: $Id$
   46.33 + */
   46.34 +
   46.35 +#ifndef _INCLUDE_SOURCEMOD_PLUGINSYSTEM_H_
   46.36 +#define _INCLUDE_SOURCEMOD_PLUGINSYSTEM_H_
   46.37 +
   46.38 +#include <time.h>
   46.39 +#include <errno.h>
   46.40 +#include <sys/stat.h>
   46.41 +#include <IPluginSys.h>
   46.42 +#include <IHandleSys.h>
   46.43 +#include <IForwardSys.h>
   46.44 +#include <sh_list.h>
   46.45 +#include <sh_stack.h>
   46.46 +#include <sh_vector.h>
   46.47 +#include <sh_string.h>
   46.48 +#include "common_logic.h"
   46.49 +#include <sm_trie_tpl.h>
   46.50 +#include <IRootConsoleMenu.h>
   46.51 +#include "ITranslator.h"
   46.52 +#include "IGameConfigs.h"
   46.53 +#include "NativeOwner.h"
   46.54 +#include "ShareSys.h"
   46.55 +
   46.56 +class CPlayer;
   46.57 +
   46.58 +using namespace SourceHook;
   46.59 +
   46.60 +/**
   46.61 + * NOTES:
   46.62 + *
   46.63 + * UPDATE 2008-03-11: These comments are horribly out of date.  They paint a good overall 
   46.64 + * picture of how PluginSys works, but things like dependencies and fake natives have 
   46.65 + * complicated things quite a bit.
   46.66 + *
   46.67 + *  Currently this system needs a lot of work but it's good skeletally.  Plugin creation 
   46.68 + * is done without actually compiling anything.  This is done by Load functions in the 
   46.69 + * manager.  This will need a rewrite when we add context switching.
   46.70 + *
   46.71 + *  The plugin object itself has a few things to note.  The most important is that it stores
   46.72 + * a table of function objects.  The manager marshals allocation and freeing of these objects.
   46.73 + * The plugin object can be in erroneous states, they are:
   46.74 + *   Plugin_Error   --> Some error occurred any time during or after compilation.
   46.75 + *						This error can be cleared since the plugin itself is valid.
   46.76 + *						However, the state itself being set prevents any runtime action.
   46.77 + *   Plugin_BadLoad	--> The plugin failed to load entirely and nothing can be done to save it.
   46.78 + *
   46.79 + *  If a plugin fails to load externally, it is never added to the internal tracker.  However, 
   46.80 + * plugins that failed to load from the internal loading mechanism are always tracked.  This 
   46.81 + * allows users to see which automatically loaded plugins failed, and makes the interface a bit
   46.82 + * more flexible.
   46.83 + *
   46.84 + *  Once a plugin is compiled, it sets its own state to Plugin_Created.  This state is still invalid
   46.85 + * for execution.  SourceMod is a two pass system, and even though the second pass is not implemented
   46.86 + * yet, it is structured so Plugin_Created must be switched to Plugin_Running in the second pass.  When
   46.87 + * implemented, a Created plugin will be switched to Error in the second pass if it not loadable.
   46.88 + *
   46.89 + *  The two pass loading mechanism is described below.  Modules/natives are not implemented yet.
   46.90 + * PASS ONE: All loadable plugins are found and have the following steps performed:
   46.91 + *			 1.  Loading and compilation is attempted.
   46.92 + *			 2.  If successful, all natives from Core are added.
   46.93 + *			 3.  OnPluginLoad() is called.
   46.94 + *			 4.  If failed, any user natives are scrapped and the process halts here.
   46.95 + *			 5.  If successful, the plugin is ready for Pass 2.
   46.96 + * INTERMEDIATE:
   46.97 + *			 1.  All forced modules are loaded.
   46.98 + * PASS TWO: All loaded plugins are found and have these steps performed:
   46.99 + *			 1. Any modules referenced in the plugin that are not already loaded, are loaded.
  46.100 + *			 2. If any module fails to load and the plugin requires it, load fails and jump to step 6.
  46.101 + *			 3. If any natives are unresolved, check if they are found in the user-natives pool.
  46.102 + *			 4. If yes, load succeeds.  If not, natives are passed through a native acceptance filter.
  46.103 + *			 5. If the filter fails, the plugin is marked as failed.
  46.104 + *			 6. If the plugin has failed to load at this point, any dynamic natives it has added are scrapped.
  46.105 + *			    Furthermore, any plugin that referenced these natives must now have pass 2 re-ran.
  46.106 + * PASS THREE (not a real pass):
  46.107 + *			 7. Once all plugins are deemed to be loaded, OnPluginStart() is called
  46.108 + */
  46.109 +
  46.110 +enum LoadRes
  46.111 +{
  46.112 +	LoadRes_Successful,
  46.113 +	LoadRes_AlreadyLoaded,
  46.114 +	LoadRes_Failure,
  46.115 +	LoadRes_SilentFailure,
  46.116 +	LoadRes_NeverLoad
  46.117 +};
  46.118 +
  46.119 +enum APLRes
  46.120 +{
  46.121 +	APLRes_Success,
  46.122 +	APLRes_Failure,
  46.123 +	APLRes_SilentFailure
  46.124 +};
  46.125 +
  46.126 +class CPlugin : 
  46.127 +	public SMPlugin,
  46.128 +	public CNativeOwner
  46.129 +{
  46.130 +	friend class CPluginManager;
  46.131 +	friend class CFunction;
  46.132 +public:
  46.133 +	CPlugin(const char *file);
  46.134 +	~CPlugin();
  46.135 +public:
  46.136 +	PluginType GetType();
  46.137 +	SourcePawn::IPluginContext *GetBaseContext();
  46.138 +	sp_context_t *GetContext();
  46.139 +	void *GetPluginStructure();
  46.140 +	const char *GetFilename();
  46.141 +	bool IsDebugging();
  46.142 +	PluginStatus GetStatus();
  46.143 +	bool IsSilentlyFailed();
  46.144 +	void SetSilentlyFailed(bool sf);
  46.145 +	const sm_plugininfo_t *GetPublicInfo();
  46.146 +	bool SetPauseState(bool paused);
  46.147 +	unsigned int GetSerial();
  46.148 +	IdentityToken_t *GetIdentity();
  46.149 +	unsigned int CalcMemUsage();
  46.150 +	bool SetProperty(const char *prop, void *ptr);
  46.151 +	bool GetProperty(const char *prop, void **ptr, bool remove=false);
  46.152 +	void DropEverything();
  46.153 +	SourcePawn::IPluginRuntime *GetRuntime();
  46.154 +	CNativeOwner *ToNativeOwner() {
  46.155 +		return this;
  46.156 +	}
  46.157 +public:
  46.158 +	/**
  46.159 +	 * Creates a plugin object with default values.
  46.160 +	 *   If an error buffer is specified, and an error occurs, the error will be copied to the buffer
  46.161 +	 * and NULL will be returned.
  46.162 +	 *   If an error buffer is not specified, the error will be copied to an internal buffer and 
  46.163 +	 * a valid (but error-stated) CPlugin will be returned.
  46.164 +	 */
  46.165 +	static CPlugin *CreatePlugin(const char *file, char *error, size_t maxlength);
  46.166 +public:
  46.167 +
  46.168 +	/**
  46.169 +	 * Sets an error state on the plugin
  46.170 +	 */
  46.171 +	void SetErrorState(PluginStatus status, const char *error_fmt, ...);
  46.172 +
  46.173 +	/**
  46.174 +	 * Initializes the plugin's identity information
  46.175 +	 */
  46.176 +	void InitIdentity();
  46.177 +
  46.178 +	/**
  46.179 +	 * Calls the OnPluginLoad function, and sets any failed states if necessary.
  46.180 +	 * NOTE: Valid pre-states are: Plugin_Created
  46.181 +	 * NOTE: If validated, plugin state is changed to Plugin_Loaded
  46.182 +	 *
  46.183 +	 * If the error buffer is NULL, the error message is cached locally.
  46.184 +	 */
  46.185 +	APLRes Call_AskPluginLoad(char *error, size_t maxlength);
  46.186 +
  46.187 +	/**
  46.188 +	 * Calls the OnPluginStart function.
  46.189 +	 * NOTE: Valid pre-states are: Plugin_Created
  46.190 +	 * NOTE: Post-state will be Plugin_Running
  46.191 +	 */
  46.192 +	void Call_OnPluginStart();
  46.193 +
  46.194 +	/**
  46.195 +	 * Calls the OnPluginEnd function.
  46.196 +	 */
  46.197 +	void Call_OnPluginEnd();
  46.198 +
  46.199 +	/**
  46.200 +	 * Calls the OnAllPluginsLoaded function.
  46.201 +	 */
  46.202 +	void Call_OnAllPluginsLoaded();
  46.203 +
  46.204 +	/**
  46.205 +	 * Returns true if a plugin is usable.
  46.206 +	 */
  46.207 +	bool IsRunnable();
  46.208 +
  46.209 +	/**
  46.210 +	 * Get languages info.
  46.211 +	 */
  46.212 +	IPhraseCollection *GetPhrases();
  46.213 +public:
  46.214 +	/**
  46.215 +	 * Returns the modification time during last plugin load.
  46.216 +	 */
  46.217 +	time_t GetTimeStamp();
  46.218 +
  46.219 +	/**
  46.220 +	 * Returns the current modification time of the plugin file.
  46.221 +	 */
  46.222 +	time_t GetFileTimeStamp();
  46.223 +
  46.224 +	/** 
  46.225 +	 * Returns true if the plugin was running, but is now invalid.
  46.226 +	 */
  46.227 +	bool WasRunning();
  46.228 +
  46.229 +	Handle_t GetMyHandle();
  46.230 +
  46.231 +	bool AddFakeNative(IPluginFunction *pFunc, const char *name, SPVM_FAKENATIVE_FUNC func);
  46.232 +	void AddConfig(bool autoCreate, const char *cfg, const char *folder);
  46.233 +	unsigned int GetConfigCount();
  46.234 +	AutoConfig *GetConfig(unsigned int i);
  46.235 +	inline void AddLibrary(const char *name)
  46.236 +	{
  46.237 +		m_Libraries.push_back(name);
  46.238 +	}
  46.239 +	void LibraryActions(LibraryAction action);
  46.240 +	void SyncMaxClients(int max_clients);
  46.241 +protected:
  46.242 +	bool UpdateInfo();
  46.243 +	void SetTimeStamp(time_t t);
  46.244 +	void DependencyDropped(CPlugin *pOwner);
  46.245 +private:
  46.246 +	PluginType m_type;
  46.247 +	char m_filename[PLATFORM_MAX_PATH];
  46.248 +	PluginStatus m_status;
  46.249 +	bool m_bSilentlyFailed;
  46.250 +	unsigned int m_serial;
  46.251 +	sm_plugininfo_t m_info;
  46.252 +	char m_errormsg[256];
  46.253 +	time_t m_LastAccess;
  46.254 +	IdentityToken_t *m_ident;
  46.255 +	Handle_t m_handle;
  46.256 +	bool m_WasRunning;
  46.257 +	IPhraseCollection *m_pPhrases;
  46.258 +	List<String> m_RequiredLibs;
  46.259 +	List<String> m_Libraries;
  46.260 +	KTrie<void *> m_pProps;
  46.261 +	bool m_FakeNativesMissing;
  46.262 +	bool m_LibraryMissing;
  46.263 +	CVector<AutoConfig *> m_configs;
  46.264 +	bool m_bGotAllLoaded;
  46.265 +	int m_FileVersion;
  46.266 +	char m_DateTime[256];
  46.267 +	IPluginRuntime *m_pRuntime;
  46.268 +	IPluginContext *m_pContext;
  46.269 +	sp_pubvar_t *m_MaxClientsVar;
  46.270 +};
  46.271 +
  46.272 +class CPluginManager : 
  46.273 +	public IScriptManager,
  46.274 +	public SMGlobalClass,
  46.275 +	public IHandleTypeDispatch,
  46.276 +	public IRootConsoleCommand
  46.277 +{
  46.278 +	friend class CPlugin;
  46.279 +public:
  46.280 +	CPluginManager();
  46.281 +	~CPluginManager();
  46.282 +public:
  46.283 +	/* Implements iterator class */
  46.284 +	class CPluginIterator : public IPluginIterator
  46.285 +	{
  46.286 +	public:
  46.287 +		CPluginIterator(List<CPlugin *> *mylist);
  46.288 +		virtual ~CPluginIterator();
  46.289 +		virtual bool MorePlugins();
  46.290 +		virtual IPlugin *GetPlugin();
  46.291 +		virtual void NextPlugin();
  46.292 +		void Release();
  46.293 +	public:
  46.294 +		void Reset();
  46.295 +	private:
  46.296 +		List<CPlugin *> *mylist;
  46.297 +		List<CPlugin *>::iterator current;
  46.298 +	};
  46.299 +	friend class CPluginManager::CPluginIterator;
  46.300 +public: //IScriptManager
  46.301 +	IPlugin *LoadPlugin(const char *path, 
  46.302 +								bool debug,
  46.303 +								PluginType type,
  46.304 +								char error[],
  46.305 +								size_t maxlength,
  46.306 +								bool *wasloaded);
  46.307 +	bool UnloadPlugin(IPlugin *plugin);
  46.308 +	IPlugin *FindPluginByContext(const sp_context_t *ctx);
  46.309 +	unsigned int GetPluginCount();
  46.310 +	IPluginIterator *GetPluginIterator();
  46.311 +	void AddPluginsListener(IPluginsListener *listener);
  46.312 +	void RemovePluginsListener(IPluginsListener *listener);
  46.313 +	void LoadAll(const char *config_path, const char *plugins_path);
  46.314 +	void RefreshAll();
  46.315 +	SMPlugin *FindPluginByOrder(unsigned num) {
  46.316 +		return GetPluginByOrder(num);
  46.317 +	}
  46.318 +	SMPlugin *FindPluginByIdentity(IdentityToken_t *ident) {
  46.319 +		return GetPluginFromIdentity(ident);
  46.320 +	}
  46.321 +	SMPlugin *FindPluginByContext(IPluginContext *ctx) {
  46.322 +		return GetPluginByCtx(ctx->GetContext());
  46.323 +	}
  46.324 +	SMPlugin *FindPluginByContext(sp_context_t *ctx) {
  46.325 +		return GetPluginByCtx(ctx);
  46.326 +	}
  46.327 +	SMPlugin *FindPluginByConsoleArg(const char *text);
  46.328 +	SMPlugin *FindPluginByHandle(Handle_t hndl, HandleError *errp) {
  46.329 +		return static_cast<SMPlugin *>(PluginFromHandle(hndl, errp));
  46.330 +	}
  46.331 +	void ListPlugins(CVector<SMPlugin *> *plugins);
  46.332 +public: //SMGlobalClass
  46.333 +	void OnSourceModAllInitialized();
  46.334 +	void OnSourceModShutdown();
  46.335 +	ConfigResult OnSourceModConfigChanged(const char *key, const char *value, ConfigSource source, char *error, size_t maxlength);
  46.336 +	void OnSourceModMaxPlayersChanged(int newvalue);
  46.337 +public: //IHandleTypeDispatch
  46.338 +	void OnHandleDestroy(HandleType_t type, void *object);
  46.339 +	bool GetHandleApproxSize(HandleType_t type, void *object, unsigned int *pSize);
  46.340 +public: //IRootConsoleCommand
  46.341 +	void OnRootConsoleCommand(const char *cmdname, const CCommand &command);
  46.342 +public:
  46.343 +	/**
  46.344 +	 * Loads all plugins not yet loaded
  46.345 +	 */
  46.346 +	void LoadAll_FirstPass(const char *config, const char *basedir);
  46.347 +
  46.348 +	/**
  46.349 +	 * Runs the second loading pass for all plugins
  46.350 +	 */
  46.351 +	void LoadAll_SecondPass();
  46.352 +
  46.353 +	/**
  46.354 +	 * Tests a plugin file mask against a local folder.
  46.355 +	 * The alias is searched backwards from localdir - i.e., given this input:
  46.356 +	 *   csdm/ban        csdm/ban
  46.357 +	 *   ban             csdm/ban
  46.358 +	 *   csdm/ban        optional/csdm/ban
  46.359 +	 * All of these will return true for an alias match.  
  46.360 +	 * Wildcards are allowed in the filename.
  46.361 +	 */
  46.362 +	bool TestAliasMatch(const char *alias, const char *localdir);
  46.363 +
  46.364 +	/** 
  46.365 +	 * Returns whether anything loaded will be a late load.
  46.366 +	 */
  46.367 +	bool IsLateLoadTime() const;
  46.368 +
  46.369 +	/**
  46.370 +	 * Converts a Handle to an IPlugin if possible.
  46.371 +	 */
  46.372 +	IPlugin *PluginFromHandle(Handle_t handle, HandleError *err);
  46.373 +
  46.374 +	/**
  46.375 +	 * Finds a plugin based on its index. (starts on index 1)
  46.376 +	 */
  46.377 +	CPlugin *GetPluginByOrder(int num);
  46.378 +
  46.379 +	int GetOrderOfPlugin(IPlugin *pl);
  46.380 +
  46.381 +	/** 
  46.382 +	 * Internal version of FindPluginByContext()
  46.383 +	 */
  46.384 +	CPlugin *GetPluginByCtx(const sp_context_t *ctx);
  46.385 +
  46.386 +	/**
  46.387 +	 * Gets status text for a status code 
  46.388 +	 */
  46.389 +	const char *GetStatusText(PluginStatus status);
  46.390 +
  46.391 +	/**
  46.392 +	 * Add public functions from all running or paused
  46.393 +	 * plugins to the specified forward if the names match.
  46.394 +	 */
  46.395 +	void AddFunctionsToForward(const char *name, IChangeableForward *pForward);
  46.396 +
  46.397 +	/**
  46.398 +	 * Iterates through plugins to call OnAllPluginsLoaded.
  46.399 +	 */
  46.400 +	void AllPluginsLoaded();
  46.401 +
  46.402 +	CPlugin *GetPluginFromIdentity(IdentityToken_t *pToken);
  46.403 +
  46.404 +	void Shutdown();
  46.405 +
  46.406 +	void OnLibraryAction(const char *lib, LibraryAction action);
  46.407 +
  46.408 +	bool LibraryExists(const char *lib);
  46.409 +
  46.410 +	bool ReloadPlugin(CPlugin *pl);
  46.411 +
  46.412 +	void UnloadAll();
  46.413 +
  46.414 +	void SyncMaxClients(int max_clients);
  46.415 +
  46.416 +	void ListPluginsToClient(CPlayer *player, const CCommand &args);
  46.417 +private:
  46.418 +	LoadRes _LoadPlugin(CPlugin **pPlugin, const char *path, bool debug, PluginType type, char error[], size_t maxlength);
  46.419 +
  46.420 +	void LoadAutoPlugin(const char *plugin);
  46.421 +
  46.422 +	/**
  46.423 +	 * Recursively loads all plugins in the given directory.
  46.424 +	 */
  46.425 +	void LoadPluginsFromDir(const char *basedir, const char *localdir);
  46.426 +
  46.427 +	/**
  46.428 +	 * Adds a plugin object.  This is wrapped by LoadPlugin functions.
  46.429 +	 */
  46.430 +	void AddPlugin(CPlugin *pPlugin);
  46.431 +
  46.432 +	/**
  46.433 +	 * Runs the second loading pass on a plugin.
  46.434 +	 */
  46.435 +	bool RunSecondPass(CPlugin *pPlugin, char *error, size_t maxlength);
  46.436 +
  46.437 +	/**
  46.438 +	 * Runs an extension pass on a plugin.
  46.439 +	 */
  46.440 +	bool LoadOrRequireExtensions(CPlugin *pPlugin, unsigned int pass, char *error, size_t maxlength);
  46.441 +
  46.442 +	/**
  46.443 +	* Manages required natives.
  46.444 +	*/
  46.445 +	bool FindOrRequirePluginDeps(CPlugin *pPlugin, char *error, size_t maxlength);
  46.446 +
  46.447 +	void _SetPauseState(CPlugin *pPlugin, bool pause);
  46.448 +protected:
  46.449 +	/**
  46.450 +	 * Caching internal objects
  46.451 +	 */
  46.452 +	void ReleaseIterator(CPluginIterator *iter);
  46.453 +public:
  46.454 +	inline IdentityToken_t *GetIdentity()
  46.455 +	{
  46.456 +		return m_MyIdent;
  46.457 +	}
  46.458 +	IPluginManager *GetOldAPI();
  46.459 +private:
  46.460 +	void TryRefreshDependencies(CPlugin *pOther);
  46.461 +private:
  46.462 +	List<IPluginsListener *> m_listeners;
  46.463 +	List<CPlugin *> m_plugins;
  46.464 +	CStack<CPluginManager::CPluginIterator *> m_iters;
  46.465 +	KTrie<CPlugin *> m_LoadLookup;
  46.466 +	bool m_AllPluginsLoaded;
  46.467 +	IdentityToken_t *m_MyIdent;
  46.468 +
  46.469 +	/* Dynamic native stuff */
  46.470 +	List<FakeNative *> m_Natives;
  46.471 +
  46.472 +	bool m_LoadingLocked;
  46.473 +	
  46.474 +	// Config
  46.475 +	bool m_bBlockBadPlugins;
  46.476 +	
  46.477 +	// Forwards
  46.478 +	IForward *m_pOnLibraryAdded;
  46.479 +	IForward *m_pOnLibraryRemoved;
  46.480 +};
  46.481 +
  46.482 +extern CPluginManager g_PluginSys;
  46.483 +
  46.484 +#endif //_INCLUDE_SOURCEMOD_PLUGINSYSTEM_H_
  46.485 +
    47.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    47.2 +++ b/core/logic/ShareSys.cpp	Fri Mar 29 11:37:29 2013 -0700
    47.3 @@ -0,0 +1,611 @@
    47.4 +/**
    47.5 + * vim: set ts=4 :
    47.6 + * =============================================================================
    47.7 + * SourceMod
    47.8 + * Copyright (C) 2004-2008 AlliedModders LLC.  All rights reserved.
    47.9 + * =============================================================================
   47.10 + *
   47.11 + * This program is free software; you can redistribute it and/or modify it under
   47.12 + * the terms of the GNU General Public License, version 3.0, as published by the
   47.13 + * Free Software Foundation.
   47.14 + * 
   47.15 + * This program is distributed in the hope that it will be useful, but WITHOUT
   47.16 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   47.17 + * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
   47.18 + * details.
   47.19 + *
   47.20 + * You should have received a copy of the GNU General Public License along with
   47.21 + * this program.  If not, see <http://www.gnu.org/licenses/>.
   47.22 + *
   47.23 + * As a special exception, AlliedModders LLC gives you permission to link the
   47.24 + * code of this program (as well as its derivative works) to "Half-Life 2," the
   47.25 + * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
   47.26 + * by the Valve Corporation.  You must obey the GNU General Public License in
   47.27 + * all respects for all other code used.  Additionally, AlliedModders LLC grants
   47.28 + * this exception to all derivative works.  AlliedModders LLC defines further
   47.29 + * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
   47.30 + * or <http://www.sourcemod.net/license.php>.
   47.31 + *
   47.32 + * Version: $Id$
   47.33 + */
   47.34 +
   47.35 +#include "ShareSys.h"
   47.36 +#include "ExtensionSys.h"
   47.37 +#include <ILibrarySys.h>
   47.38 +#include "common_logic.h"
   47.39 +#include "PluginSys.h"
   47.40 +#include "HandleSys.h"
   47.41 +
   47.42 +ShareSystem g_ShareSys;
   47.43 +static unsigned int g_mark_serial = 0;
   47.44 +
   47.45 +ShareSystem::ShareSystem()
   47.46 +{
   47.47 +	m_IdentRoot.ident = 0;
   47.48 +	m_TypeRoot = 0;
   47.49 +	m_IfaceType = 0;
   47.50 +	m_CoreType = 0;
   47.51 +}
   47.52 +
   47.53 +IdentityToken_t *ShareSystem::CreateCoreIdentity()
   47.54 +{
   47.55 +	if (!m_CoreType)
   47.56 +	{
   47.57 +		m_CoreType = CreateIdentType("CORE");
   47.58 +	}
   47.59 +
   47.60 +	return CreateIdentity(m_CoreType, this);
   47.61 +}
   47.62 +
   47.63 +void ShareSystem::Initialize()
   47.64 +{
   47.65 +	TypeAccess sec;
   47.66 +
   47.67 +	handlesys->InitAccessDefaults(&sec, NULL);
   47.68 +	sec.ident = GetIdentRoot();
   47.69 +
   47.70 +	m_TypeRoot = handlesys->CreateType("Identity", this, 0, &sec, NULL, NULL, NULL);
   47.71 +	m_IfaceType = handlesys->CreateType("Interface", this, 0, NULL, NULL, GetIdentRoot(), NULL);
   47.72 +
   47.73 +	/* Initialize our static identity handle */
   47.74 +	m_IdentRoot.ident = handlesys->CreateHandle(m_TypeRoot, NULL, NULL, GetIdentRoot(), NULL);
   47.75 +
   47.76 +	/* Add the Handle System and others... they are too innocent and pure to do it themselves */
   47.77 +	AddInterface(NULL, handlesys);
   47.78 +	AddInterface(NULL, libsys);
   47.79 +}
   47.80 +
   47.81 +void ShareSystem::OnSourceModShutdown()
   47.82 +{
   47.83 +	if (m_CoreType)
   47.84 +	{
   47.85 +		handlesys->RemoveType(m_CoreType, GetIdentRoot());
   47.86 +	}
   47.87 +
   47.88 +	handlesys->RemoveType(m_IfaceType, GetIdentRoot());
   47.89 +	handlesys->RemoveType(m_TypeRoot, GetIdentRoot());
   47.90 +}
   47.91 +
   47.92 +IdentityType_t ShareSystem::FindIdentType(const char *name)
   47.93 +{
   47.94 +	HandleType_t type;
   47.95 +
   47.96 +	if (handlesys->FindHandleType(name, &type))
   47.97 +	{
   47.98 +		if (g_HandleSys.TypeCheck(type, m_TypeRoot))
   47.99 +		{
  47.100 +			return type;
  47.101 +		}
  47.102 +	}
  47.103 +
  47.104 +	return 0;
  47.105 +}
  47.106 +
  47.107 +IdentityType_t ShareSystem::CreateIdentType(const char *name)
  47.108 +{
  47.109 +	if (!m_TypeRoot)
  47.110 +	{
  47.111 +		return 0;
  47.112 +	}
  47.113 +
  47.114 +	return handlesys->CreateType(name, this, m_TypeRoot, NULL, NULL, GetIdentRoot(), NULL);
  47.115 +}
  47.116 +
  47.117 +void ShareSystem::OnHandleDestroy(HandleType_t type, void *object)
  47.118 +{
  47.119 +	/* THIS WILL NEVER BE CALLED FOR ANYTHING WITH THE IDENTITY TYPE */
  47.120 +}
  47.121 +
  47.122 +IdentityToken_t *ShareSystem::CreateIdentity(IdentityType_t type, void *ptr)
  47.123 +{
  47.124 +	if (!m_TypeRoot)
  47.125 +	{
  47.126 +		return 0;
  47.127 +	}
  47.128 +
  47.129 +	/* :TODO: Cache? */
  47.130 +	IdentityToken_t *pToken = new IdentityToken_t;
  47.131 +
  47.132 +	HandleSecurity sec;
  47.133 +	sec.pOwner = sec.pIdentity = GetIdentRoot();
  47.134 +
  47.135 +	pToken->ident = g_HandleSys.CreateHandleInt(type, NULL, &sec, NULL, NULL, true);
  47.136 +	pToken->ptr = ptr;
  47.137 +	pToken->type = type;
  47.138 +
  47.139 +	return pToken;
  47.140 +}
  47.141 +
  47.142 +bool ShareSystem::AddInterface(IExtension *myself, SMInterface *iface)
  47.143 +{
  47.144 +	if (!iface)
  47.145 +	{
  47.146 +		return false;
  47.147 +	}
  47.148 +
  47.149 +	IfaceInfo info;
  47.150 +
  47.151 +	info.owner = myself;
  47.152 +	info.iface = iface;
  47.153 +	
  47.154 +	m_Interfaces.push_back(info);
  47.155 +
  47.156 +	return true;
  47.157 +}
  47.158 +
  47.159 +bool ShareSystem::RequestInterface(const char *iface_name, 
  47.160 +								   unsigned int iface_vers, 
  47.161 +								   IExtension *myself, 
  47.162 +								   SMInterface **pIface)
  47.163 +{
  47.164 +	/* See if the interface exists */
  47.165 +	List<IfaceInfo>::iterator iter;
  47.166 +	SMInterface *iface;
  47.167 +	IExtension *iface_owner;
  47.168 +	bool found = false;
  47.169 +	for (iter=m_Interfaces.begin(); iter!=m_Interfaces.end(); iter++)
  47.170 +	{
  47.171 +		IfaceInfo &info = (*iter);
  47.172 +		iface = info.iface;
  47.173 +		if (strcmp(iface->GetInterfaceName(), iface_name) == 0)
  47.174 +		{
  47.175 +			if (iface->GetInterfaceVersion() == iface_vers
  47.176 +				|| iface->IsVersionCompatible(iface_vers))
  47.177 +			{
  47.178 +				iface_owner = info.owner;
  47.179 +				found = true;
  47.180 +				break;
  47.181 +			}
  47.182 +		}
  47.183 +	}
  47.184 +
  47.185 +	if (!found)
  47.186 +	{
  47.187 +		return false;
  47.188 +	}
  47.189 +
  47.190 +	/* Add a dependency node */
  47.191 +	if (iface_owner)
  47.192 +	{
  47.193 +		IfaceInfo info;
  47.194 +		info.iface = iface;
  47.195 +		info.owner = iface_owner;
  47.196 +		g_Extensions.BindDependency(myself, &info);
  47.197 +	}
  47.198 +
  47.199 +	if (pIface)
  47.200 +	{
  47.201 +		*pIface = iface;
  47.202 +	}
  47.203 +
  47.204 +	return true;
  47.205 +}
  47.206 +
  47.207 +void ShareSystem::AddNatives(IExtension *myself, const sp_nativeinfo_t *natives)
  47.208 +{
  47.209 +	CNativeOwner *pOwner;
  47.210 +
  47.211 +	pOwner = g_Extensions.GetNativeOwner(myself);
  47.212 +
  47.213 +	pOwner->AddNatives(natives);
  47.214 +}
  47.215 +
  47.216 +void ShareSystem::DestroyIdentity(IdentityToken_t *identity)
  47.217 +{
  47.218 +	HandleSecurity sec;
  47.219 +
  47.220 +	sec.pOwner = GetIdentRoot();
  47.221 +	sec.pIdentity = GetIdentRoot();
  47.222 +
  47.223 +	handlesys->FreeHandle(identity->ident, &sec);
  47.224 +	delete identity;
  47.225 +}
  47.226 +
  47.227 +void ShareSystem::DestroyIdentType(IdentityType_t type)
  47.228 +{
  47.229 +	handlesys->RemoveType(type, GetIdentRoot());
  47.230 +}
  47.231 +
  47.232 +void ShareSystem::RemoveInterfaces(IExtension *pExtension)
  47.233 +{
  47.234 +	List<IfaceInfo>::iterator iter = m_Interfaces.begin();
  47.235 +
  47.236 +	while (iter != m_Interfaces.end())
  47.237 +	{
  47.238 +		if ((*iter).owner == pExtension)
  47.239 +		{
  47.240 +			iter = m_Interfaces.erase(iter);
  47.241 +		}
  47.242 +		else
  47.243 +		{
  47.244 +			iter++;
  47.245 +		}
  47.246 +	}
  47.247 +}
  47.248 +
  47.249 +void ShareSystem::AddDependency(IExtension *myself, const char *filename, bool require, bool autoload)
  47.250 +{
  47.251 +	g_Extensions.AddDependency(myself, filename, require, autoload);
  47.252 +}
  47.253 +
  47.254 +void ShareSystem::RegisterLibrary(IExtension *myself, const char *name)
  47.255 +{
  47.256 +	g_Extensions.AddLibrary(myself, name);
  47.257 +}
  47.258 +
  47.259 +void ShareSystem::OverrideNatives(IExtension *myself, const sp_nativeinfo_t *natives)
  47.260 +{
  47.261 +	unsigned int i;
  47.262 +	NativeEntry *pEntry;
  47.263 +	CNativeOwner *pOwner;
  47.264 +
  47.265 +	pOwner = g_Extensions.GetNativeOwner(myself);
  47.266 +
  47.267 +	for (i = 0; natives[i].func != NULL && natives[i].name != NULL; i++)
  47.268 +	{
  47.269 +		if ((pEntry = FindNative(natives[i].name)) == NULL)
  47.270 +		{
  47.271 +			continue;
  47.272 +		}
  47.273 +
  47.274 +		if (pEntry->owner != &g_CoreNatives)
  47.275 +		{
  47.276 +			continue;
  47.277 +		}
  47.278 +
  47.279 +		if (pEntry->replacement.owner != NULL)
  47.280 +		{
  47.281 +			continue;
  47.282 +		}
  47.283 +
  47.284 +		/* Now it's safe to add the override */
  47.285 +		pEntry->replacement.func = natives[i].func;
  47.286 +		pEntry->replacement.owner = pOwner;
  47.287 +		pOwner->AddReplacedNative(pEntry);
  47.288 +	}
  47.289 +}
  47.290 +
  47.291 +NativeEntry *ShareSystem::FindNative(const char *name)
  47.292 +{
  47.293 +	NativeEntry **ppEntry;
  47.294 +
  47.295 +	if ((ppEntry = m_NtvCache.retrieve(name)) == NULL)
  47.296 +	{
  47.297 +		return NULL;
  47.298 +	}
  47.299 +
  47.300 +	return *ppEntry;
  47.301 +}
  47.302 +
  47.303 +void ShareSystem::BindNativesToPlugin(CPlugin *pPlugin, bool bCoreOnly)
  47.304 +{
  47.305 +	NativeEntry *pEntry;
  47.306 +	sp_native_t *native;
  47.307 +	uint32_t i, native_count;
  47.308 +	IPluginContext *pContext;
  47.309 +
  47.310 +	pContext = pPlugin->GetBaseContext();
  47.311 +
  47.312 +	/* Generate a new serial ID, mark our dependencies with it. */
  47.313 +	g_mark_serial++;
  47.314 +	pPlugin->PropagateMarkSerial(g_mark_serial);
  47.315 +
  47.316 +	native_count = pContext->GetNativesNum();
  47.317 +	for (i = 0; i < native_count; i++)
  47.318 +	{
  47.319 +		if (pContext->GetNativeByIndex(i, &native) != SP_ERROR_NONE)
  47.320 +		{
  47.321 +			continue;
  47.322 +		}
  47.323 +
  47.324 +		/* If we're bound, check if there is a replacement available.  
  47.325 +		 * If not, this native is totally finalized.
  47.326 +		 */
  47.327 +		if (native->status == SP_NATIVE_BOUND)
  47.328 +		{
  47.329 +			pEntry = (NativeEntry *)native->user;
  47.330 +			assert(pEntry != NULL);
  47.331 +			if (pEntry->replacement.owner == NULL
  47.332 +				|| (pEntry->replacement.owner != NULL 
  47.333 +				&&  pEntry->replacement.func == native->pfn))
  47.334 +			{
  47.335 +				continue;
  47.336 +			}
  47.337 +		}
  47.338 +		/* Otherwise, the native must be in our cache. */
  47.339 +		else if ((pEntry = FindNative(native->name)) == NULL)
  47.340 +		{
  47.341 +			continue;
  47.342 +		}
  47.343 +
  47.344 +		if (bCoreOnly && pEntry->owner != &g_CoreNatives)
  47.345 +		{
  47.346 +			continue;
  47.347 +		}
  47.348 +
  47.349 +		BindNativeToPlugin(pPlugin, native, i, pEntry);
  47.350 +	}
  47.351 +}
  47.352 +
  47.353 +void ShareSystem::BindNativeToPlugin(CPlugin *pPlugin, NativeEntry *pEntry)
  47.354 +{
  47.355 +	uint32_t i;
  47.356 +	sp_native_t *native;
  47.357 +	IPluginContext *pContext;
  47.358 +
  47.359 +	pContext = pPlugin->GetBaseContext();
  47.360 +
  47.361 +	if (pContext->FindNativeByName(pEntry->name, &i) != SP_ERROR_NONE)
  47.362 +	{
  47.363 +		return;
  47.364 +	}
  47.365 +	if (pContext->GetNativeByIndex(i, &native) != SP_ERROR_NONE)
  47.366 +	{
  47.367 +		return;
  47.368 +	}
  47.369 +
  47.370 +	if (native->status == SP_NATIVE_BOUND)
  47.371 +	{
  47.372 +		return;
  47.373 +	}
  47.374 +
  47.375 +	BindNativeToPlugin(pPlugin, native, i, pEntry);
  47.376 +}
  47.377 +
  47.378 +void ShareSystem::BindNativeToPlugin(CPlugin *pPlugin, 
  47.379 +									 sp_native_t *native,
  47.380 +									 uint32_t index,
  47.381 +									 NativeEntry *pEntry)
  47.382 +{
  47.383 +	/* Mark as bound... we do the rest next. */
  47.384 +	native->status = SP_NATIVE_BOUND;
  47.385 +	native->user = pEntry;
  47.386 +
  47.387 +	/* See if a replacement is available. */
  47.388 +	if (pEntry->replacement.owner != NULL)
  47.389 +	{
  47.390 +		/* Perform a replacement bind. */
  47.391 +		native->pfn = pEntry->replacement.func;
  47.392 +		pEntry->replacement.owner->AddWeakRef(WeakNative(pPlugin, index, pEntry));
  47.393 +	}
  47.394 +	else
  47.395 +	{
  47.396 +		/* Perform a normal bind. */
  47.397 +		native->pfn = pEntry->func;
  47.398 +
  47.399 +		/* We don't bother with dependency crap if the owner is Core. */
  47.400 +		if (pEntry->owner != &g_CoreNatives)
  47.401 +		{
  47.402 +			/* The native is optional, this is a special case */
  47.403 +			if ((native->flags & SP_NTVFLAG_OPTIONAL) == SP_NTVFLAG_OPTIONAL)
  47.404 +			{
  47.405 +				/* Only add if there is a valid owner. */
  47.406 +				if (pEntry->owner != NULL)
  47.407 +				{
  47.408 +					pEntry->owner->AddWeakRef(WeakNative(pPlugin, index));
  47.409 +				}
  47.410 +				else
  47.411 +				{
  47.412 +					native->status = SP_NATIVE_UNBOUND;
  47.413 +				}
  47.414 +			}
  47.415 +			/* Otherwise, we're a strong dependent and not a weak one */
  47.416 +			else
  47.417 +			{
  47.418 +				/* See if this has already been marked as a dependent.
  47.419 +				 * If it has, it means this relationship has already occurred, 
  47.420 +				 * and there is no reason to do it again.
  47.421 +				 */
  47.422 +				if (pEntry->owner != pPlugin->ToNativeOwner() 
  47.423 +					&& pEntry->owner->GetMarkSerial() != g_mark_serial)
  47.424 +				{
  47.425 +					/* This has not been marked as a dependency yet */
  47.426 +					//pPlugin->AddDependency(pEntry->owner);
  47.427 +					pEntry->owner->AddDependent(pPlugin);
  47.428 +					pEntry->owner->SetMarkSerial(g_mark_serial);
  47.429 +				}
  47.430 +			}
  47.431 +		}
  47.432 +	}
  47.433 +}
  47.434 +
  47.435 +NativeEntry *ShareSystem::AddNativeToCache(CNativeOwner *pOwner, const sp_nativeinfo_t *ntv)
  47.436 +{
  47.437 +	NativeEntry *pEntry;
  47.438 +
  47.439 +	if ((pEntry = FindNative(ntv->name)) == NULL)
  47.440 +	{
  47.441 +		pEntry = new NativeEntry;
  47.442 +
  47.443 +		pEntry->owner = pOwner;
  47.444 +		pEntry->name = ntv->name;
  47.445 +		pEntry->func = ntv->func;
  47.446 +		pEntry->replacement.func = NULL;
  47.447 +		pEntry->replacement.owner = NULL;
  47.448 +		pEntry->fake = NULL;
  47.449 +
  47.450 +		m_NtvCache.insert(ntv->name, pEntry);
  47.451 +
  47.452 +		return pEntry;
  47.453 +	}
  47.454 +
  47.455 +	if (pEntry->owner != NULL)
  47.456 +	{
  47.457 +		return NULL;
  47.458 +	}
  47.459 +
  47.460 +	pEntry->owner = pOwner;
  47.461 +	pEntry->func = ntv->func;
  47.462 +	pEntry->name = ntv->name;
  47.463 +
  47.464 +	return pEntry;
  47.465 +}
  47.466 +
  47.467 +void ShareSystem::ClearNativeFromCache(CNativeOwner *pOwner, const char *name)
  47.468 +{
  47.469 +	NativeEntry *pEntry;
  47.470 +
  47.471 +	if ((pEntry = FindNative(name)) == NULL)
  47.472 +	{
  47.473 +		return;
  47.474 +	}
  47.475 +
  47.476 +	if (pEntry->owner != pOwner)
  47.477 +	{
  47.478 +		return;
  47.479 +	}
  47.480 +
  47.481 +	if (pEntry->fake != NULL)
  47.482 +	{
  47.483 +		g_pSourcePawn2->DestroyFakeNative(pEntry->func);
  47.484 +		delete pEntry->fake;
  47.485 +		pEntry->fake = NULL;
  47.486 +	}
  47.487 +
  47.488 +	pEntry->func = NULL;
  47.489 +	pEntry->name = NULL;
  47.490 +	pEntry->owner = NULL;
  47.491 +	pEntry->replacement.func = NULL;
  47.492 +	pEntry->replacement.owner = NULL;
  47.493 +}
  47.494 +
  47.495 +NativeEntry *ShareSystem::AddFakeNative(IPluginFunction *pFunc, const char *name, SPVM_FAKENATIVE_FUNC func)
  47.496 +{
  47.497 +	FakeNative *pFake;
  47.498 +	NativeEntry *pEntry;
  47.499 +	SPVM_NATIVE_FUNC gate;
  47.500 +
  47.501 +	if ((pEntry = FindNative(name)) != NULL && pEntry->owner != NULL)
  47.502 +	{
  47.503 +		return NULL;
  47.504 +	}
  47.505 +
  47.506 +	pFake = new FakeNative;
  47.507 +
  47.508 +	if ((gate = g_pSourcePawn2->CreateFakeNative(func, pFake)) == NULL)
  47.509 +	{
  47.510 +		delete pFake;
  47.511 +		return NULL;
  47.512 +	}
  47.513 +
  47.514 +	if (pEntry == NULL)
  47.515 +	{
  47.516 +		pEntry = new NativeEntry;
  47.517 +		m_NtvCache.insert(name, pEntry);
  47.518 +	}
  47.519 +
  47.520 +	pFake->call = pFunc;
  47.521 +	pFake->ctx = pFunc->GetParentContext();
  47.522 +	smcore.strncopy(pFake->name, name, sizeof(pFake->name));
  47.523 +	
  47.524 +	pEntry->fake = pFake;
  47.525 +	pEntry->func = gate;
  47.526 +	pEntry->name = pFake->name;
  47.527 +	pEntry->owner = g_PluginSys.GetPluginByCtx(pFake->ctx->GetContext());
  47.528 +	pEntry->replacement.func = NULL;
  47.529 +	pEntry->replacement.owner = NULL;
  47.530 +
  47.531 +	return pEntry;
  47.532 +}
  47.533 +
  47.534 +void ShareSystem::AddCapabilityProvider(IExtension *myself, IFeatureProvider *provider,
  47.535 +		                                const char *name)
  47.536 +{
  47.537 +	if (m_caps.retrieve(name) != NULL)
  47.538 +		return;
  47.539 +
  47.540 +	Capability cap;
  47.541 +	cap.ext = myself;
  47.542 +	cap.provider = provider;
  47.543 +
  47.544 +	m_caps.insert(name, cap);
  47.545 +}
  47.546 +
  47.547 +void ShareSystem::DropCapabilityProvider(IExtension *myself, IFeatureProvider *provider,
  47.548 +		                                 const char *name)
  47.549 +{
  47.550 +	Capability *pCap = m_caps.retrieve(name);
  47.551 +	if (pCap == NULL)
  47.552 +		return;
  47.553 +
  47.554 +	if (pCap->ext != myself || pCap->provider != provider)
  47.555 +		return;
  47.556 +
  47.557 +	m_caps.remove(name);
  47.558 +}
  47.559 +
  47.560 +FeatureStatus ShareSystem::TestFeature(IPluginRuntime *pRuntime, FeatureType feature, 
  47.561 +                                       const char *name)
  47.562 +{
  47.563 +	switch (feature)
  47.564 +	{
  47.565 +	case FeatureType_Native:
  47.566 +		return TestNative(pRuntime, name);
  47.567 +	case FeatureType_Capability:
  47.568 +		return TestCap(name);
  47.569 +	default:
  47.570 +		break;
  47.571 +	}
  47.572 +
  47.573 +	return FeatureStatus_Unknown;
  47.574 +}
  47.575 +
  47.576 +FeatureStatus ShareSystem::TestNative(IPluginRuntime *pRuntime, const char *name)
  47.577 +{
  47.578 +	uint32_t index;
  47.579 +
  47.580 +	if (pRuntime->FindNativeByName(name, &index) == SP_ERROR_NONE)
  47.581 +	{
  47.582 +		sp_native_t *native;
  47.583 +		if (pRuntime->GetNativeByIndex(index, &native) == SP_ERROR_NONE)
  47.584 +		{
  47.585 +			if (native->status == SP_NATIVE_BOUND)
  47.586 +				return FeatureStatus_Available;
  47.587 +			else
  47.588 +				return FeatureStatus_Unknown;
  47.589 +		}
  47.590 +	}
  47.591 +
  47.592 +	NativeEntry *entry = FindNative(name);
  47.593 +	if (entry == NULL)
  47.594 +		return FeatureStatus_Unknown;
  47.595 +
  47.596 +	if ((entry->replacement.owner != NULL || entry->owner != NULL) &&
  47.597 +		(entry->replacement.func != NULL || entry->func != NULL))
  47.598 +	{
  47.599 +		return FeatureStatus_Available;
  47.600 +	}
  47.601 +	else
  47.602 +	{
  47.603 +		return FeatureStatus_Unavailable;
  47.604 +	}
  47.605 +}
  47.606 +
  47.607 +FeatureStatus ShareSystem::TestCap(const char *name)
  47.608 +{
  47.609 +	Capability *cap = m_caps.retrieve(name);
  47.610 +	if (cap == NULL)
  47.611 +		return FeatureStatus_Unknown;
  47.612 +
  47.613 +	return cap->provider->GetFeatureStatus(FeatureType_Capability, name);
  47.614 +}
    48.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    48.2 +++ b/core/logic/ShareSys.h	Fri Mar 29 11:37:29 2013 -0700
    48.3 @@ -0,0 +1,163 @@
    48.4 +/**
    48.5 + * vim: set ts=4 :
    48.6 + * =============================================================================
    48.7 + * SourceMod
    48.8 + * Copyright (C) 2004-2008 AlliedModders LLC.  All rights reserved.
    48.9 + * =============================================================================
   48.10 + *
   48.11 + * This program is free software; you can redistribute it and/or modify it under
   48.12 + * the terms of the GNU General Public License, version 3.0, as published by the
   48.13 + * Free Software Foundation.
   48.14 + * 
   48.15 + * This program is distributed in the hope that it will be useful, but WITHOUT
   48.16 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   48.17 + * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
   48.18 + * details.
   48.19 + *
   48.20 + * You should have received a copy of the GNU General Public License along with
   48.21 + * this program.  If not, see <http://www.gnu.org/licenses/>.
   48.22 + *
   48.23 + * As a special exception, AlliedModders LLC gives you permission to link the
   48.24 + * code of this program (as well as its derivative works) to "Half-Life 2," the
   48.25 + * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
   48.26 + * by the Valve Corporation.  You must obey the GNU General Public License in
   48.27 + * all respects for all other code used.  Additionally, AlliedModders LLC grants
   48.28 + * this exception to all derivative works.  AlliedModders LLC defines further
   48.29 + * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
   48.30 + * or <http://www.sourcemod.net/license.php>.
   48.31 + *
   48.32 + * Version: $Id$
   48.33 + */
   48.34 +
   48.35 +#ifndef _INCLUDE_SOURCEMOD_SHARESYSTEM_H_
   48.36 +#define _INCLUDE_SOURCEMOD_SHARESYSTEM_H_
   48.37 +
   48.38 +#include <IShareSys.h>
   48.39 +#include <IHandleSys.h>
   48.40 +#include <sh_list.h>
   48.41 +#include <sm_trie_tpl.h>
   48.42 +#include "common_logic.h"
   48.43 +
   48.44 +using namespace SourceHook;
   48.45 +
   48.46 +namespace SourceMod
   48.47 +{
   48.48 +	struct IdentityToken_t
   48.49 +	{
   48.50 +		Handle_t ident;
   48.51 +		void *ptr;
   48.52 +		IdentityType_t type;
   48.53 +	};
   48.54 +};
   48.55 +
   48.56 +struct IfaceInfo
   48.57 +{
   48.58 +	bool operator ==(const IfaceInfo &info)
   48.59 +	{
   48.60 +		return (info.iface == iface && info.owner == owner);
   48.61 +	}
   48.62 +	SMInterface *iface;
   48.63 +	IExtension *owner;
   48.64 +};
   48.65 +
   48.66 +class CNativeOwner;
   48.67 +struct NativeEntry;
   48.68 +class CPlugin;
   48.69 +
   48.70 +struct ReplaceNative
   48.71 +{
   48.72 +	CNativeOwner *owner;
   48.73 +	SPVM_NATIVE_FUNC func;
   48.74 +};
   48.75 +
   48.76 +struct FakeNative
   48.77 +{
   48.78 +	char name[64];
   48.79 +	IPluginContext *ctx;
   48.80 +	IPluginFunction *call;
   48.81 +};
   48.82 +
   48.83 +struct NativeEntry
   48.84 +{
   48.85 +	CNativeOwner *owner;
   48.86 +	SPVM_NATIVE_FUNC func;
   48.87 +	const char *name;
   48.88 +	ReplaceNative replacement;
   48.89 +	FakeNative *fake;
   48.90 +};
   48.91 +
   48.92 +struct Capability
   48.93 +{
   48.94 +	IExtension *ext;
   48.95 +	IFeatureProvider *provider;
   48.96 +};
   48.97 +
   48.98 +class ShareSystem :
   48.99 +	public IShareSys,
  48.100 +	public SMGlobalClass,
  48.101 +	public IHandleTypeDispatch
  48.102 +{
  48.103 +	friend class CNativeOwner;
  48.104 +public:
  48.105 +	ShareSystem();
  48.106 +public: //IShareSys
  48.107 +	bool AddInterface(IExtension *myself, SMInterface *pIface);
  48.108 +	bool RequestInterface(const char *iface_name, 
  48.109 +		unsigned int iface_vers,
  48.110 +		IExtension *myself,
  48.111 +		SMInterface **pIface);
  48.112 +	void AddNatives(IExtension *myself, const sp_nativeinfo_t *natives);
  48.113 +	IdentityType_t CreateIdentType(const char *name);
  48.114 +	IdentityType_t FindIdentType(const char *name);
  48.115 +	IdentityToken_t *CreateIdentity(IdentityType_t type, void *ptr);
  48.116 +	void DestroyIdentType(IdentityType_t type);
  48.117 +	void DestroyIdentity(IdentityToken_t *identity);
  48.118 +	void AddDependency(IExtension *myself, const char *filename, bool require, bool autoload);
  48.119 +	void RegisterLibrary(IExtension *myself, const char *name);
  48.120 +	void OverrideNatives(IExtension *myself, const sp_nativeinfo_t *natives);
  48.121 +	void AddCapabilityProvider(IExtension *myself, IFeatureProvider *provider,
  48.122 +		                       const char *name);
  48.123 +	void DropCapabilityProvider(IExtension *myself, IFeatureProvider *provider,
  48.124 +		                        const char *name);
  48.125 +public: //SMGlobalClass
  48.126 +	/* Pre-empt in case anything tries to register idents early */
  48.127 +	void Initialize();
  48.128 +	void OnSourceModShutdown();
  48.129 +public: //IHandleTypeDispatch
  48.130 +	void OnHandleDestroy(HandleType_t type, void *object);
  48.131 +public:
  48.132 +	IdentityToken_t *CreateCoreIdentity();
  48.133 +	void RemoveInterfaces(IExtension *pExtension);
  48.134 +	FeatureStatus TestFeature(IPluginRuntime *pRuntime, FeatureType feature, const char *name);
  48.135 +	FeatureStatus TestNative(IPluginRuntime *pRuntime, const char *name);
  48.136 +	FeatureStatus TestCap(const char *name);
  48.137 +public:
  48.138 +	inline IdentityToken_t *GetIdentRoot()
  48.139 +	{
  48.140 +		return &m_IdentRoot;
  48.141 +	}
  48.142 +public:
  48.143 +	void BindNativesToPlugin(CPlugin *pPlugin, bool bCoreOnly);
  48.144 +	void BindNativeToPlugin(CPlugin *pPlugin, NativeEntry *pEntry);
  48.145 +	NativeEntry *AddFakeNative(IPluginFunction *pFunc, const char *name, SPVM_FAKENATIVE_FUNC func);
  48.146 +	NativeEntry *FindNative(const char *name);
  48.147 +private:
  48.148 +	NativeEntry *AddNativeToCache(CNativeOwner *pOwner, const sp_nativeinfo_t *ntv);
  48.149 +	void ClearNativeFromCache(CNativeOwner *pOwner, const char *name);
  48.150 +	void BindNativeToPlugin(CPlugin *pPlugin, 
  48.151 +		sp_native_t *ntv, 
  48.152 +		uint32_t index, 
  48.153 +		NativeEntry *pEntry);
  48.154 +private:
  48.155 +	List<IfaceInfo> m_Interfaces;
  48.156 +	HandleType_t m_TypeRoot;
  48.157 +	IdentityToken_t m_IdentRoot;
  48.158 +	HandleType_t m_IfaceType;
  48.159 +	IdentityType_t m_CoreType;
  48.160 +	KTrie<NativeEntry *> m_NtvCache;
  48.161 +	KTrie<Capability> m_caps;
  48.162 +};
  48.163 +
  48.164 +extern ShareSystem g_ShareSys;
  48.165 +
  48.166 +#endif //_INCLUDE_SOURCEMOD_SHARESYSTEM_H_
    49.1 --- a/core/logic/common_logic.cpp	Fri Mar 29 12:28:02 2013 -0400
    49.2 +++ b/core/logic/common_logic.cpp	Fri Mar 29 11:37:29 2013 -0700
    49.3 @@ -43,18 +43,23 @@
    49.4  #include "Translator.h"
    49.5  #include "GameConfigs.h"
    49.6  #include "DebugReporter.h"
    49.7 +#include "PluginSys.h"
    49.8 +#include "ShareSys.h"
    49.9 +#include "NativeOwner.h"
   49.10 +#include "HandleSys.h"
   49.11 +#include "ExtensionSys.h"
   49.12  
   49.13  sm_core_t smcore;
   49.14 -IHandleSys *handlesys;
   49.15 +IHandleSys *handlesys = &g_HandleSys;
   49.16  IdentityToken_t *g_pCoreIdent;
   49.17  SMGlobalClass *SMGlobalClass::head = NULL;
   49.18  ISourceMod *g_pSM;
   49.19  ILibrarySys *libsys;
   49.20  ITextParsers *textparser = &g_TextParser;
   49.21  IVEngineServer *engine;
   49.22 -IShareSys *sharesys;
   49.23 +IShareSys *sharesys = &g_ShareSys;
   49.24  IRootConsole *rootmenu;
   49.25 -IPluginManager *pluginsys;
   49.26 +IPluginManager *pluginsys = g_PluginSys.GetOldAPI();
   49.27  IForwardManager *forwardsys;
   49.28  ITimerSystem *timersys;
   49.29  ServerGlobals serverGlobals;
   49.30 @@ -63,6 +68,8 @@
   49.31  IGameHelpers *gamehelpers;
   49.32  ISourcePawnEngine *g_pSourcePawn;
   49.33  ISourcePawnEngine2 *g_pSourcePawn2;
   49.34 +CNativeOwner g_CoreNatives;
   49.35 +IScriptManager *scripts = &g_PluginSys;
   49.36  
   49.37  static void AddCorePhraseFile(const char *filename)
   49.38  {
   49.39 @@ -85,6 +92,16 @@
   49.40  	va_end(ap);
   49.41  }
   49.42  
   49.43 +static void AddNatives(sp_nativeinfo_t *natives)
   49.44 +{
   49.45 +	g_CoreNatives.AddNatives(natives);
   49.46 +}
   49.47 +
   49.48 +static void DumpHandles(void (*dumpfn)(const char *fmt, ...))
   49.49 +{
   49.50 +	g_HandleSys.Dump(dumpfn);
   49.51 +}
   49.52 +
   49.53  static sm_logic_t logic =
   49.54  {
   49.55  	NULL,
   49.56 @@ -100,7 +117,15 @@
   49.57  	GetCoreGameConfig,
   49.58  	OnLogPrint,
   49.59  	&g_DbgReporter,
   49.60 -	GenerateError
   49.61 +	GenerateError,
   49.62 +	AddNatives,
   49.63 +	DumpHandles,
   49.64 +	&g_PluginSys,
   49.65 +	&g_ShareSys,
   49.66 +	&g_Extensions,
   49.67 +	&g_HandleSys,
   49.68 +	NULL,
   49.69 +	-1.0f
   49.70  };
   49.71  
   49.72  static void logic_init(const sm_core_t* core, sm_logic_t* _logic)
   49.73 @@ -111,14 +136,10 @@
   49.74  	memcpy(_logic, &logic, sizeof(sm_logic_t));
   49.75  	memcpy(&serverGlobals, core->serverGlobals, sizeof(ServerGlobals));
   49.76  
   49.77 -	handlesys = core->handlesys;
   49.78  	libsys = core->libsys;
   49.79  	engine = core->engine;
   49.80 -	g_pCoreIdent = core->core_ident;
   49.81  	g_pSM = core->sm;
   49.82 -	sharesys = core->sharesys;
   49.83  	rootmenu = core->rootmenu;
   49.84 -	pluginsys = core->pluginsys;
   49.85  	forwardsys = core->forwardsys;
   49.86  	timersys = core->timersys;
   49.87  	playerhelpers = core->playerhelpers;
   49.88 @@ -126,6 +147,11 @@
   49.89  	gamehelpers = core->gamehelpers;
   49.90  	g_pSourcePawn = *core->spe1;
   49.91  	g_pSourcePawn2 = *core->spe2;
   49.92 +
   49.93 +	g_ShareSys.Initialize();
   49.94 +	g_pCoreIdent = g_ShareSys.CreateCoreIdentity();
   49.95 +	
   49.96 +	_logic->core_ident = g_pCoreIdent;
   49.97  }
   49.98  
   49.99  PLATFORM_EXTERN_C ITextParsers *get_textparsers()
  49.100 @@ -145,7 +171,7 @@
  49.101  
  49.102  void CoreNativesToAdd::OnSourceModAllInitialized()
  49.103  {
  49.104 -	smcore.AddNatives(m_NativeList);
  49.105 +	g_CoreNatives.AddNatives(m_NativeList);
  49.106  }
  49.107  
  49.108  /* Overload a few things to prevent libstdc++ linking */
    50.1 --- a/core/logic/common_logic.h	Fri Mar 29 12:28:02 2013 -0400
    50.2 +++ b/core/logic/common_logic.h	Fri Mar 29 11:37:29 2013 -0700
    50.3 @@ -52,6 +52,7 @@
    50.4  extern IPlayerManager *playerhelpers;
    50.5  extern IAdminSystem *adminsys;
    50.6  extern IGameHelpers *gamehelpers;
    50.7 +extern IScriptManager *scripts;
    50.8  
    50.9  #endif /* _INCLUDE_SOURCEMOD_COMMON_LOGIC_H_ */
   50.10  
    51.1 --- a/core/logic/intercom.h	Fri Mar 29 12:28:02 2013 -0400
    51.2 +++ b/core/logic/intercom.h	Fri Mar 29 11:37:29 2013 -0700
    51.3 @@ -29,20 +29,27 @@
    51.4   * Version: $Id$
    51.5   */
    51.6  
    51.7 +#ifndef _INCLUDE_SOURCEMOD_INTERCOM_H_
    51.8 +#define _INCLUDE_SOURCEMOD_INTERCOM_H_
    51.9 +
   51.10  #include <sp_vm_api.h>
   51.11  #include <IHandleSys.h>
   51.12  #include <IShareSys.h>
   51.13 -
   51.14 -#ifndef _INCLUDE_SOURCEMOD_INTERCOM_H_
   51.15 -#define _INCLUDE_SOURCEMOD_INTERCOM_H_
   51.16 +#include <IPluginSys.h>
   51.17 +#include <sh_string.h>
   51.18 +#include <sp_vm_api.h>
   51.19 +#include <sh_vector.h>
   51.20 +#include <IExtensionSys.h>
   51.21  
   51.22  using namespace SourceMod;
   51.23 +using namespace SourcePawn;
   51.24 +using namespace SourceHook;
   51.25  
   51.26  /**
   51.27   * Add 1 to the RHS of this expression to bump the intercom file
   51.28   * This is to prevent mismatching core/logic binaries
   51.29   */
   51.30 -#define SM_LOGIC_MAGIC		(0x0F47C0DE - 18)
   51.31 +#define SM_LOGIC_MAGIC		(0x0F47C0DE - 19)
   51.32  
   51.33  #if defined SM_LOGIC
   51.34  class IVEngineServer
   51.35 @@ -75,6 +82,12 @@
   51.36  
   51.37  class IVEngineServer;
   51.38  class ConVar;
   51.39 +class SMGlobalClass;
   51.40 +
   51.41 +namespace SourceMod
   51.42 +{
   51.43 +	class IChangeableForward;
   51.44 +}
   51.45  
   51.46  struct ServerGlobals
   51.47  {
   51.48 @@ -83,17 +96,79 @@
   51.49  	float *frametime;
   51.50  };
   51.51  
   51.52 +struct AutoConfig
   51.53 +{
   51.54 +	SourceHook::String autocfg;
   51.55 +	SourceHook::String folder;
   51.56 +	bool create;
   51.57 +};
   51.58 +
   51.59 +enum LibraryAction
   51.60 +{
   51.61 +	LibraryAction_Removed,
   51.62 +	LibraryAction_Added
   51.63 +};
   51.64 +
   51.65 +class CNativeOwner;
   51.66 +
   51.67 +class SMPlugin : public IPlugin
   51.68 +{
   51.69 +public:
   51.70 +	virtual size_t GetConfigCount() = 0;
   51.71 +	virtual AutoConfig *GetConfig(size_t i) = 0;
   51.72 +	virtual void AddLibrary(const char *name) = 0;
   51.73 +	virtual void AddConfig(bool create, const char *cfg, const char *folder) = 0;
   51.74 +	virtual void SetErrorState(PluginStatus status, const char *fmt, ...) = 0;
   51.75 +};
   51.76 +
   51.77 +class IScriptManager
   51.78 +{
   51.79 +public:
   51.80 +	virtual void LoadAll(const char *config_path, const char *plugins_path) = 0;
   51.81 +	virtual void RefreshAll() = 0;
   51.82 +	virtual void Shutdown() = 0;
   51.83 +	virtual IdentityToken_t *GetIdentity() = 0;
   51.84 +	virtual void SyncMaxClients(int maxClients) = 0;
   51.85 +	virtual void AddPluginsListener(IPluginsListener *listener) = 0;
   51.86 +	virtual void RemovePluginsListener(IPluginsListener *listener) = 0;
   51.87 +	virtual IPluginIterator *GetPluginIterator() = 0;
   51.88 +	virtual void OnLibraryAction(const char *name, LibraryAction action) = 0;
   51.89 +	virtual bool LibraryExists(const char *name) = 0;
   51.90 +	virtual SMPlugin *FindPluginByOrder(unsigned num) = 0;
   51.91 +	virtual SMPlugin *FindPluginByIdentity(IdentityToken_t *ident) = 0;
   51.92 +	virtual SMPlugin *FindPluginByContext(IPluginContext *ctx) = 0;
   51.93 +	virtual SMPlugin *FindPluginByContext(sp_context_t *ctx) = 0;
   51.94 +	virtual SMPlugin *FindPluginByConsoleArg(const char *text) = 0;
   51.95 +	virtual SMPlugin *FindPluginByHandle(Handle_t hndl, HandleError *errp) = 0;
   51.96 +	virtual bool UnloadPlugin(IPlugin *plugin) = 0;
   51.97 +	virtual void ListPlugins(CVector<SMPlugin *> *plugins) = 0;
   51.98 +	virtual void AddFunctionsToForward(const char *name, IChangeableForward *fwd) = 0;
   51.99 +};
  51.100 +
  51.101 +class IExtensionSys : public IExtensionManager
  51.102 +{
  51.103 +public:
  51.104 +	virtual IExtension *LoadAutoExtension(const char *name) = 0;
  51.105 +	virtual void TryAutoload() = 0;
  51.106 +	virtual void Shutdown() = 0;
  51.107 +	virtual IExtension *FindExtensionByFile(const char *name) = 0;
  51.108 +	virtual bool LibraryExists(const char *name) = 0;
  51.109 +	virtual void CallOnCoreMapStart(edict_t *edictList, int edictCount, int maxClients) = 0;
  51.110 +	virtual IExtension *GetExtensionFromIdent(IdentityToken_t *token) = 0;
  51.111 +	virtual void BindChildPlugin(IExtension *ext, SMPlugin *plugin) = 0;
  51.112 +	virtual void AddRawDependency(IExtension *myself, IdentityToken_t *token, void *iface) = 0;
  51.113 +	virtual void ListExtensions(CVector<IExtension *> *list) = 0;
  51.114 +};
  51.115 +
  51.116 +class CCommand;
  51.117 +
  51.118  struct sm_core_t
  51.119  {
  51.120  	/* Objects */
  51.121 -	IHandleSys 		*handlesys;
  51.122 -	IdentityToken_t *core_ident;
  51.123  	ISourceMod		*sm;
  51.124  	ILibrarySys		*libsys;
  51.125  	IVEngineServer	*engine;
  51.126 -	IShareSys		*sharesys;
  51.127  	IRootConsole	*rootmenu;
  51.128 -	IPluginManager	*pluginsys;
  51.129  	IForwardManager	*forwardsys;
  51.130  	ITimerSystem    *timersys;
  51.131  	IPlayerManager  *playerhelpers;
  51.132 @@ -102,11 +177,11 @@
  51.133  	ISourcePawnEngine **spe1;
  51.134  	ISourcePawnEngine2 **spe2;
  51.135  	/* Functions */
  51.136 -	void			(*AddNatives)(sp_nativeinfo_t* nlist);
  51.137  	ConVar *		(*FindConVar)(const char*);
  51.138  	unsigned int	(*strncopy)(char*, const char*, size_t);
  51.139  	char *			(*TrimWhitespace)(char *, size_t &);
  51.140  	void			(*LogError)(const char*, ...);
  51.141 +	void			(*LogFatal)(const char*, ...);
  51.142  	void			(*Log)(const char*, ...);
  51.143  	void			(*LogToFile)(FILE *fp, const char*, ...);
  51.144  	void			(*LogToGame)(const char *message);
  51.145 @@ -122,6 +197,15 @@
  51.146  	const char *    (*GetSourceEngineName)();
  51.147  	bool            (*SymbolsAreHidden)();
  51.148  	const char *	(*GetCoreConfigValue)(const char*);
  51.149 +	bool			(*IsMapLoading)();
  51.150 +	bool			(*IsMapRunning)();
  51.151 +	int				(*Argc)(const CCommand &args);
  51.152 +	const char *	(*Arg)(const CCommand &args, int arg);
  51.153 +	int				(*LoadMMSPlugin)(const char *file, bool *ok, char *error, size_t maxlength);
  51.154 +	void			(*UnloadMMSPlugin)(int id);
  51.155 +	void			(*DoGlobalPluginLoads)();
  51.156 +	bool			(*AreConfigsExecuted)();
  51.157 +	void			(*ExecuteConfigs)(IPluginContext *ctx);
  51.158  	/* Data */
  51.159  	ServerGlobals   *serverGlobals;
  51.160  	void *          serverFactory;
  51.161 @@ -145,6 +229,14 @@
  51.162  	bool			(*OnLogPrint)(const char *msg);	// true to supercede
  51.163  	IDebugListener   *debugger;
  51.164  	void			(*GenerateError)(IPluginContext *, cell_t, int, const char *, ...);
  51.165 +	void			(*AddNatives)(sp_nativeinfo_t *natives);
  51.166 +	void			(*DumpHandles)(void (*dumpfn)(const char *fmt, ...));
  51.167 +	IScriptManager	*scripts;
  51.168 +	IShareSys		*sharesys;
  51.169 +	IExtensionSys	*extsys;
  51.170 +	IHandleSys		*handlesys;
  51.171 +	IdentityToken_t *core_ident;
  51.172 +	float			sentinel;
  51.173  };
  51.174  
  51.175  typedef void (*LogicInitFunction)(const sm_core_t *core, sm_logic_t *logic);
  51.176 @@ -152,4 +244,3 @@
  51.177  typedef ITextParsers *(*GetITextParsers)();
  51.178  
  51.179  #endif /* _INCLUDE_SOURCEMOD_INTERCOM_H_ */
  51.180 -
    52.1 --- a/core/logic/msvc10/logic.vcxproj	Fri Mar 29 12:28:02 2013 -0400
    52.2 +++ b/core/logic/msvc10/logic.vcxproj	Fri Mar 29 11:37:29 2013 -0700
    52.3 @@ -113,10 +113,17 @@
    52.4    <ItemGroup>
    52.5      <ClCompile Include="..\common_logic.cpp" />
    52.6      <ClCompile Include="..\DebugReporter.cpp" />
    52.7 +    <ClCompile Include="..\ExtensionSys.cpp" />
    52.8      <ClCompile Include="..\GameConfigs.cpp" />
    52.9 +    <ClCompile Include="..\HandleSys.cpp" />
   52.10      <ClCompile Include="..\MemoryUtils.cpp" />
   52.11 +    <ClCompile Include="..\NativeInvoker.cpp" />
   52.12 +    <ClCompile Include="..\NativeOwner.cpp" />
   52.13      <ClCompile Include="..\PhraseCollection.cpp" />
   52.14 +    <ClCompile Include="..\PluginSys.cpp" />
   52.15      <ClCompile Include="..\Profiler.cpp" />
   52.16 +    <ClCompile Include="..\ShareSys.cpp" />
   52.17 +    <ClCompile Include="..\smn_fakenatives.cpp" />
   52.18      <ClCompile Include="..\smn_filesystem.cpp" />
   52.19      <ClCompile Include="..\sm_crc32.cpp" />
   52.20      <ClCompile Include="..\smn_admin.cpp" />
   52.21 @@ -151,12 +158,17 @@
   52.22      <ClInclude Include="..\AutoHandleRooter.h" />
   52.23      <ClInclude Include="..\CellArray.h" />
   52.24      <ClInclude Include="..\common_logic.h" />
   52.25 +    <ClInclude Include="..\ExtensionSys.h" />
   52.26      <ClInclude Include="..\GameConfigs.h" />
   52.27      <ClInclude Include="..\intercom.h" />
   52.28      <ClInclude Include="..\MemoryUtils.h" />
   52.29      <ClInclude Include="..\MersenneTwister.h" />
   52.30 +    <ClInclude Include="..\NativeInvoker.h" />
   52.31 +    <ClInclude Include="..\NativeOwner.h" />
   52.32      <ClInclude Include="..\PhraseCollection.h" />
   52.33 +    <ClInclude Include="..\PluginSys.h" />
   52.34      <ClInclude Include="..\Profiler.h" />
   52.35 +    <ClInclude Include="..\ShareSys.h" />
   52.36      <ClInclude Include="..\sm_crc32.h" />
   52.37      <ClInclude Include="..\sm_memtable.h" />
   52.38      <ClInclude Include="..\sm_symtable.h" />
   52.39 @@ -168,9 +180,6 @@
   52.40      <ClInclude Include="..\thread\WinThreads.h" />
   52.41      <ClInclude Include="..\Translator.h" />
   52.42    </ItemGroup>
   52.43 -  <ItemGroup>
   52.44 -    <ResourceCompile Include="..\version.rc" />
   52.45 -  </ItemGroup>
   52.46    <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
   52.47    <ImportGroup Label="ExtensionTargets">
   52.48    </ImportGroup>
    53.1 --- a/core/logic/msvc10/logic.vcxproj.filters	Fri Mar 29 12:28:02 2013 -0400
    53.2 +++ b/core/logic/msvc10/logic.vcxproj.filters	Fri Mar 29 11:37:29 2013 -0700
    53.3 @@ -123,6 +123,27 @@
    53.4      <ClCompile Include="..\smn_filesystem.cpp">
    53.5        <Filter>Natives</Filter>
    53.6      </ClCompile>
    53.7 +    <ClCompile Include="..\smn_fakenatives.cpp">
    53.8 +      <Filter>Natives</Filter>
    53.9 +    </ClCompile>
   53.10 +    <ClCompile Include="..\ExtensionSys.cpp">
   53.11 +      <Filter>Source Files</Filter>
   53.12 +    </ClCompile>
   53.13 +    <ClCompile Include="..\ShareSys.cpp">
   53.14 +      <Filter>Source Files</Filter>
   53.15 +    </ClCompile>
   53.16 +    <ClCompile Include="..\PluginSys.cpp">
   53.17 +      <Filter>Source Files</Filter>
   53.18 +    </ClCompile>
   53.19 +    <ClCompile Include="..\NativeInvoker.cpp">
   53.20 +      <Filter>Source Files</Filter>
   53.21 +    </ClCompile>
   53.22 +    <ClCompile Include="..\NativeOwner.cpp">
   53.23 +      <Filter>Source Files</Filter>
   53.24 +    </ClCompile>
   53.25 +    <ClCompile Include="..\HandleSys.cpp">
   53.26 +      <Filter>Source Files</Filter>
   53.27 +    </ClCompile>
   53.28    </ItemGroup>
   53.29    <ItemGroup>
   53.30      <ClInclude Include="..\CellArray.h">
   53.31 @@ -191,10 +212,20 @@
   53.32      <ClInclude Include="..\..\..\public\sm_platform.h">
   53.33        <Filter>Header Files</Filter>
   53.34      </ClInclude>
   53.35 -  </ItemGroup>
   53.36 -  <ItemGroup>
   53.37 -    <ResourceCompile Include="..\version.rc">
   53.38 -      <Filter>Resource Files</Filter>
   53.39 -    </ResourceCompile>
   53.40 +    <ClInclude Include="..\ExtensionSys.h">
   53.41 +      <Filter>Header Files</Filter>
   53.42 +    </ClInclude>
   53.43 +    <ClInclude Include="..\NativeInvoker.h">
   53.44 +      <Filter>Header Files</Filter>
   53.45 +    </ClInclude>
   53.46 +    <ClInclude Include="..\NativeOwner.h">
   53.47 +      <Filter>Header Files</Filter>
   53.48 +    </ClInclude>
   53.49 +    <ClInclude Include="..\PluginSys.h">
   53.50 +      <Filter>Header Files</Filter>
   53.51 +    </ClInclude>
   53.52 +    <ClInclude Include="..\ShareSys.h">
   53.53 +      <Filter>Header Files</Filter>
   53.54 +    </ClInclude>
   53.55    </ItemGroup>
   53.56  </Project>
   53.57 \ No newline at end of file
    54.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    54.2 +++ b/core/logic/smn_fakenatives.cpp	Fri Mar 29 11:37:29 2013 -0700
    54.3 @@ -0,0 +1,453 @@
    54.4 +/**
    54.5 + * vim: set ts=4 :
    54.6 + * =============================================================================
    54.7 + * SourceMod
    54.8 + * Copyright (C) 2004-2008 AlliedModders LLC.  All rights reserved.
    54.9 + * =============================================================================
   54.10 + *
   54.11 + * This program is free software; you can redistribute it and/or modify it under
   54.12 + * the terms of the GNU General Public License, version 3.0, as published by the
   54.13 + * Free Software Foundation.
   54.14 + * 
   54.15 + * This program is distributed in the hope that it will be useful, but WITHOUT
   54.16 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   54.17 + * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
   54.18 + * details.
   54.19 + *
   54.20 + * You should have received a copy of the GNU General Public License along with
   54.21 + * this program.  If not, see <http://www.gnu.org/licenses/>.
   54.22 + *
   54.23 + * As a special exception, AlliedModders LLC gives you permission to link the
   54.24 + * code of this program (as well as its derivative works) to "Half-Life 2," the
   54.25 + * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
   54.26 + * by the Valve Corporation.  You must obey the GNU General Public License in
   54.27 + * all respects for all other code used.  Additionally, AlliedModders LLC grants
   54.28 + * this exception to all derivative works.  AlliedModders LLC defines further
   54.29 + * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
   54.30 + * or <http://www.sourcemod.net/license.php>.
   54.31 + *
   54.32 + * Version: $Id$
   54.33 + */
   54.34 +
   54.35 +#include <sh_list.h>
   54.36 +#include <sh_string.h>
   54.37 +#include <sm_trie_tpl.h>
   54.38 +#include <ISourceMod.h>
   54.39 +#include "common_logic.h"
   54.40 +#include "ShareSys.h"
   54.41 +#include "PluginSys.h"
   54.42 +
   54.43 +using namespace SourceHook;
   54.44 +
   54.45 +static cell_t s_curparams[SP_MAX_EXEC_PARAMS+1];
   54.46 +static FakeNative *s_curnative = NULL;
   54.47 +static IPluginContext *s_curcaller = NULL;
   54.48 +
   54.49 +cell_t FakeNativeRouter(IPluginContext *pContext, const cell_t *params, void *pData)
   54.50 +{
   54.51 +	FakeNative *native = (FakeNative *)pData;
   54.52 +
   54.53 +	/* Check if too many parameters were passed */
   54.54 +	if (params[0] > SP_MAX_EXEC_PARAMS)
   54.55 +	{
   54.56 +		return pContext->ThrowNativeError("Called native with too many parameters (%d>%d)", params[9], SP_MAX_EXEC_PARAMS);
   54.57 +	}
   54.58 +
   54.59 +	/* Check if the native is paused */
   54.60 +	if (native->ctx->GetRuntime()->IsPaused())
   54.61 +	{
   54.62 +		return pContext->ThrowNativeError("Plugin owning this native is currently paused.");
   54.63 +	}
   54.64 +
   54.65 +	CPlugin *pCaller = g_PluginSys.GetPluginByCtx(pContext->GetContext());
   54.66 +
   54.67 +	/* Save any old data on the stack */
   54.68 +	FakeNative *pSaveNative = s_curnative;
   54.69 +	IPluginContext *pSaveCaller = s_curcaller;
   54.70 +	cell_t save_params[SP_MAX_EXEC_PARAMS+1];
   54.71 +	if (pSaveNative != NULL)
   54.72 +	{
   54.73 +		/* Copy all old parameters */
   54.74 +		for (cell_t i=0; i<=s_curparams[0]; i++)
   54.75 +		{
   54.76 +			save_params[i] = s_curparams[i];
   54.77 +		}
   54.78 +	}
   54.79 +
   54.80 +	/* Save the current parameters */
   54.81 +	s_curnative = native;
   54.82 +	s_curcaller = pContext;
   54.83 +	for (cell_t i=0; i<=params[0]; i++)
   54.84 +	{
   54.85 +		s_curparams[i] = params[i];
   54.86 +	}
   54.87 +
   54.88 +	/* Push info and execute. */
   54.89 +	cell_t result = 0;
   54.90 +	native->call->PushCell(pCaller->GetMyHandle());
   54.91 +	native->call->PushCell(params[0]);
   54.92 +	int error;
   54.93 +	if ((error=native->call->Execute(&result)) != SP_ERROR_NONE)
   54.94 +	{
   54.95 +		if (pContext->GetLastNativeError() == SP_ERROR_NONE)
   54.96 +		{
   54.97 +			pContext->ThrowNativeErrorEx(error, "Error encountered while processing a dynamic native");
   54.98 +		}
   54.99 +	}
  54.100 +
  54.101 +	/* Restore everything from the stack if necessary */
  54.102 +	s_curnative = pSaveNative;
  54.103 +	s_curcaller = pSaveCaller;
  54.104 +	if (pSaveNative != NULL)
  54.105 +	{
  54.106 +		for (cell_t i=0; i<=save_params[0]; i++)
  54.107 +		{
  54.108 +			s_curparams[i] = save_params[i];
  54.109 +		}
  54.110 +	}
  54.111 +
  54.112 +	return result;
  54.113 +}
  54.114 +
  54.115 +static cell_t CreateNative(IPluginContext *pContext, const cell_t *params)
  54.116 +{
  54.117 +	char *name;
  54.118 +	CPlugin *pPlugin;
  54.119 +
  54.120 +	pContext->LocalToString(params[1], &name);
  54.121 +
  54.122 +	IPluginFunction *pFunction = pContext->GetFunctionById(params[2]);
  54.123 +	if (!pFunction)
  54.124 +	{
  54.125 +		return pContext->ThrowNativeError("Function %x is not a valid function", params[2]);
  54.126 +	}
  54.127 +
  54.128 +	pPlugin = g_PluginSys.GetPluginByCtx(pContext->GetContext());
  54.129 +
  54.130 +	if (!pPlugin->AddFakeNative(pFunction, name, FakeNativeRouter))
  54.131 +	{
  54.132 +		return pContext->ThrowNativeError("Fatal error creating dynamic native!");
  54.133 +	}
  54.134 +
  54.135 +	return 1;
  54.136 +}
  54.137 +
  54.138 +static cell_t ThrowNativeError(IPluginContext *pContext, const cell_t *params)
  54.139 +{
  54.140 +	if (!s_curnative || (s_curnative->ctx != pContext))
  54.141 +	{
  54.142 +		return pContext->ThrowNativeError("Not called from inside a native function");
  54.143 +	}
  54.144 +
  54.145 +	g_pSM->SetGlobalTarget(SOURCEMOD_SERVER_LANGUAGE);
  54.146 +
  54.147 +	char buffer[512];
  54.148 +	g_pSM->FormatString(buffer, sizeof(buffer), pContext, params, 2);
  54.149 +
  54.150 +	if (pContext->GetLastNativeError() != SP_ERROR_NONE)
  54.151 +	{
  54.152 +		s_curcaller->ThrowNativeError("Error encountered while processing a dynamic native");
  54.153 +	} else {
  54.154 +		s_curcaller->ThrowNativeErrorEx(params[1], "%s", buffer);
  54.155 +	}
  54.156 +
  54.157 +	return 0;
  54.158 +}
  54.159 +
  54.160 +static cell_t GetNativeStringLength(IPluginContext *pContext, const cell_t *params)
  54.161 +{
  54.162 +	if (!s_curnative || (s_curnative->ctx != pContext))
  54.163 +	{
  54.164 +		return pContext->ThrowNativeError("Not called from inside a native function");
  54.165 +	}
  54.166 +
  54.167 +	cell_t param = params[1];
  54.168 +	if (param < 1 || param > s_curparams[0])
  54.169 +	{
  54.170 +		return pContext->ThrowNativeErrorEx(SP_ERROR_PARAM, "Invalid parameter number: %d", param);
  54.171 +	}
  54.172 +
  54.173 +	int err;
  54.174 +	char *str;
  54.175 +	if ((err=s_curcaller->LocalToString(s_curparams[param], &str)) != SP_ERROR_NONE)
  54.176 +	{
  54.177 +		return err;
  54.178 +	}
  54.179 +
  54.180 +	cell_t *addr;
  54.181 +	pContext->LocalToPhysAddr(params[2], &addr);
  54.182 +	*addr = (cell_t)strlen(str);
  54.183 +
  54.184 +	return SP_ERROR_NONE;
  54.185 +}
  54.186 +
  54.187 +static cell_t GetNativeString(IPluginContext *pContext, const cell_t *params)
  54.188 +{
  54.189 +	if (!s_curnative || (s_curnative->ctx != pContext))
  54.190 +	{
  54.191 +		return pContext->ThrowNativeError("Not called from inside a native function");
  54.192 +	}
  54.193 +
  54.194 +	cell_t param = params[1];
  54.195 +	if (param < 1 || param > s_curparams[0])
  54.196 +	{
  54.197 +		return pContext->ThrowNativeErrorEx(SP_ERROR_PARAM, "Invalid parameter number: %d", param);
  54.198 +	}
  54.199 +
  54.200 +	int err;
  54.201 +	char *str;
  54.202 +	if ((err=s_curcaller->LocalToString(s_curparams[param], &str)) != SP_ERROR_NONE)
  54.203 +	{
  54.204 +		return err;
  54.205 +	}
  54.206 +
  54.207 +	size_t bytes = 0;
  54.208 +	pContext->StringToLocalUTF8(params[2], params[3], str, &bytes);
  54.209 +
  54.210 +	cell_t *addr;
  54.211 +	pContext->LocalToPhysAddr(params[4], &addr);
  54.212 +	*addr = (cell_t)bytes;
  54.213 +
  54.214 +	return SP_ERROR_NONE;
  54.215 +}
  54.216 +
  54.217 +static cell_t SetNativeString(IPluginContext *pContext, const cell_t *params)
  54.218 +{
  54.219 +	if (!s_curnative || (s_curnative->ctx != pContext))
  54.220 +	{
  54.221 +		return pContext->ThrowNativeError("Not called from inside a native function");
  54.222 +	}
  54.223 +
  54.224 +	cell_t param = params[1];
  54.225 +	if (param < 1 || param > s_curparams[0])
  54.226 +	{
  54.227 +		return pContext->ThrowNativeErrorEx(SP_ERROR_PARAM, "Invalid parameter number: %d", param);
  54.228 +	}
  54.229 +
  54.230 +	char *str;
  54.231 +	pContext->LocalToString(params[2], &str);
  54.232 +
  54.233 +	int err;
  54.234 +	size_t bytes = 0;
  54.235 +	if (params[4])
  54.236 +	{
  54.237 +		err = s_curcaller->StringToLocalUTF8(s_curparams[param], params[3], str, &bytes);
  54.238 +	} else {
  54.239 +		err = s_curcaller->StringToLocal(s_curparams[param], params[3], str);
  54.240 +		/* Eww */
  54.241 +		bytes = strlen(str);
  54.242 +		if (bytes >= (size_t)params[3])
  54.243 +		{
  54.244 +			bytes = params[3] - 1;
  54.245 +		}
  54.246 +	}
  54.247 +
  54.248 +	if (err != SP_ERROR_NONE)
  54.249 +	{
  54.250 +		return err;
  54.251 +	}
  54.252 +
  54.253 +	cell_t *addr;
  54.254 +	pContext->LocalToPhysAddr(params[5], &addr);
  54.255 +	*addr = (cell_t)bytes;
  54.256 +
  54.257 +	return SP_ERROR_NONE;
  54.258 +}
  54.259 +
  54.260 +static cell_t GetNativeCell(IPluginContext *pContext, const cell_t *params)
  54.261 +{
  54.262 +	if (!s_curnative || (s_curnative->ctx != pContext))
  54.263 +	{
  54.264 +		return pContext->ThrowNativeError("Not called from inside a native function");
  54.265 +	}
  54.266 +
  54.267 +	cell_t param = params[1];
  54.268 +	if (param < 1 || param > s_curparams[0])
  54.269 +	{
  54.270 +		return pContext->ThrowNativeErrorEx(SP_ERROR_PARAM, "Invalid parameter number: %d", param);
  54.271 +	}
  54.272 +
  54.273 +	return s_curparams[param];
  54.274 +}
  54.275 +
  54.276 +static cell_t GetNativeCellRef(IPluginContext *pContext, const cell_t *params)
  54.277 +{
  54.278 +	if (!s_curnative || (s_curnative->ctx != pContext))
  54.279 +	{
  54.280 +		return pContext->ThrowNativeError("Not called from inside a native function");
  54.281 +	}
  54.282 +
  54.283 +	cell_t param = params[1];
  54.284 +	if (param < 1 || param > s_curparams[0])
  54.285 +	{
  54.286 +		return pContext->ThrowNativeErrorEx(SP_ERROR_PARAM, "Invalid parameter number: %d", param);
  54.287 +	}
  54.288 +
  54.289 +	cell_t *addr;
  54.290 +	if (s_curcaller->LocalToPhysAddr(s_curparams[param], &addr) != SP_ERROR_NONE)
  54.291 +	{
  54.292 +		return s_curcaller->ThrowNativeErrorEx(SP_ERROR_INVALID_ADDRESS, "Invalid address value");
  54.293 +	}
  54.294 +
  54.295 +	return *addr;
  54.296 +}
  54.297 +
  54.298 +static cell_t SetNativeCellRef(IPluginContext *pContext, const cell_t *params)
  54.299 +{
  54.300 +	if (!s_curnative || (s_curnative->ctx != pContext))
  54.301 +	{
  54.302 +		return pContext->ThrowNativeError("Not called from inside a native function");
  54.303 +	}
  54.304 +
  54.305 +	cell_t param = params[1];
  54.306 +	if (param < 1 || param > s_curparams[0])
  54.307 +	{
  54.308 +		return pContext->ThrowNativeErrorEx(SP_ERROR_PARAM, "Invalid parameter number: %d", param);
  54.309 +	}
  54.310 +
  54.311 +	cell_t *addr;
  54.312 +	if (s_curcaller->LocalToPhysAddr(s_curparams[param], &addr) != SP_ERROR_NONE)
  54.313 +	{
  54.314 +		return s_curcaller->ThrowNativeErrorEx(SP_ERROR_INVALID_ADDRESS, "Invalid address value");
  54.315 +	}
  54.316 +
  54.317 +	*addr = params[2];
  54.318 +
  54.319 +	return 1;
  54.320 +}
  54.321 +
  54.322 +static cell_t GetNativeArray(IPluginContext *pContext, const cell_t *params)
  54.323 +{
  54.324 +	if (!s_curnative || (s_curnative->ctx != pContext))
  54.325 +	{
  54.326 +		return pContext->ThrowNativeError("Not called from inside a native function");
  54.327 +	}
  54.328 +
  54.329 +	cell_t param = params[1];
  54.330 +	if (param < 1 || param > s_curparams[0])
  54.331 +	{
  54.332 +		return pContext->ThrowNativeErrorEx(SP_ERROR_PARAM, "Invalid parameter number: %d", param);
  54.333 +	}
  54.334 +
  54.335 +	int err;
  54.336 +	cell_t *addr;
  54.337 +	if ((err=s_curcaller->LocalToPhysAddr(s_curparams[param], &addr)) != SP_ERROR_NONE)
  54.338 +	{
  54.339 +		return err;
  54.340 +	}
  54.341 +
  54.342 +	cell_t *src;
  54.343 +	pContext->LocalToPhysAddr(params[2], &src);
  54.344 +
  54.345 +	memcpy(src, addr, sizeof(cell_t) * params[3]);
  54.346 +
  54.347 +	return SP_ERROR_NONE;
  54.348 +}
  54.349 +
  54.350 +static cell_t SetNativeArray(IPluginContext *pContext, const cell_t *params)
  54.351 +{
  54.352 +	if (!s_curnative || (s_curnative->ctx != pContext))
  54.353 +	{
  54.354 +		return pContext->ThrowNativeError("Not called from inside a native function");
  54.355 +	}
  54.356 +
  54.357 +	cell_t param = params[1];
  54.358 +	if (param < 1 || param > s_curparams[0])
  54.359 +	{
  54.360 +		return pContext->ThrowNativeErrorEx(SP_ERROR_PARAM, "Invalid parameter number: %d", param);
  54.361 +	}
  54.362 +
  54.363 +	int err;
  54.364 +	cell_t *addr;
  54.365 +	if ((err=s_curcaller->LocalToPhysAddr(s_curparams[param], &addr)) != SP_ERROR_NONE)
  54.366 +	{
  54.367 +		return err;
  54.368 +	}
  54.369 +
  54.370 +	cell_t *src;
  54.371 +	pContext->LocalToPhysAddr(params[2], &src);
  54.372 +
  54.373 +	memcpy(addr, src, sizeof(cell_t) * params[3]);
  54.374 +
  54.375 +	return SP_ERROR_NONE;
  54.376 +}
  54.377 +
  54.378 +static cell_t FormatNativeString(IPluginContext *pContext, const cell_t *params)
  54.379 +{
  54.380 +	if (!s_curnative || (s_curnative->ctx != pContext))
  54.381 +	{
  54.382 +		return pContext->ThrowNativeError("Not called from inside a native function");
  54.383 +	}
  54.384 +
  54.385 +	int out_param = params[1];
  54.386 +	int fmt_param = params[2];
  54.387 +	int var_param = params[3];
  54.388 +
  54.389 +	/* Validate input */
  54.390 +	if (out_param && (out_param < 1 || out_param > s_curparams[0]))
  54.391 +	{
  54.392 +		return pContext->ThrowNativeErrorEx(SP_ERROR_PARAM, "Invalid parameter number: %d", out_param);
  54.393 +	}
  54.394 +	if (fmt_param && (fmt_param < 1 || fmt_param > s_curparams[0]))
  54.395 +	{
  54.396 +		return pContext->ThrowNativeErrorEx(SP_ERROR_PARAM, "Invalid parameter number: %d", fmt_param);
  54.397 +	}
  54.398 +	if (var_param && (var_param < 1 || var_param > s_curparams[0] + 1))
  54.399 +	{
  54.400 +		return pContext->ThrowNativeErrorEx(SP_ERROR_PARAM, "Invalid parameter number: %d", fmt_param);
  54.401 +	}
  54.402 +
  54.403 +	/* Get buffer information */
  54.404 +	int err;
  54.405 +	char *output_buffer;
  54.406 +	char *format_buffer;
  54.407 +
  54.408 +	if (out_param)
  54.409 +	{
  54.410 +		if ((err=s_curcaller->LocalToString(s_curparams[out_param], &output_buffer)) != SP_ERROR_NONE)
  54.411 +		{
  54.412 +			return err;
  54.413 +		}
  54.414 +	} else {
  54.415 +		pContext->LocalToString(params[6], &output_buffer);
  54.416 +	}
  54.417 +
  54.418 +	if (fmt_param)
  54.419 +	{
  54.420 +		if ((err=s_curcaller->LocalToString(s_curparams[fmt_param], &format_buffer)) != SP_ERROR_NONE)
  54.421 +		{
  54.422 +			return err;
  54.423 +		}
  54.424 +	} else {
  54.425 +		pContext->LocalToString(params[7], &format_buffer);
  54.426 +	}
  54.427 +
  54.428 +	/* Get maximum length */
  54.429 +	size_t maxlen = (size_t)params[4];
  54.430 +
  54.431 +	/* Do the format */
  54.432 +	size_t written = smcore.atcprintf(output_buffer, maxlen, format_buffer, s_curcaller, s_curparams, &var_param);
  54.433 +
  54.434 +	cell_t *addr;
  54.435 +	pContext->LocalToPhysAddr(params[5], &addr);
  54.436 +	*addr = (cell_t)written;
  54.437 +
  54.438 +	return s_curcaller->GetLastNativeError();
  54.439 +}
  54.440 +
  54.441 +//tee hee
  54.442 +REGISTER_NATIVES(nativeNatives)
  54.443 +{
  54.444 +	{"CreateNative",			CreateNative},
  54.445 +	{"GetNativeArray",			GetNativeArray},
  54.446 +	{"GetNativeCell",			GetNativeCell},
  54.447 +	{"GetNativeCellRef",		GetNativeCellRef},
  54.448 +	{"GetNativeString",			GetNativeString},
  54.449 +	{"GetNativeStringLength",	GetNativeStringLength},
  54.450 +	{"FormatNativeString",		FormatNativeString},
  54.451 +	{"ThrowNativeError",		ThrowNativeError},
  54.452 +	{"SetNativeArray",			SetNativeArray},
  54.453 +	{"SetNativeCellRef",		SetNativeCellRef},
  54.454 +	{"SetNativeString",			SetNativeString},
  54.455 +	{NULL,						NULL},
  54.456 +};
    55.1 --- a/core/logic/smn_players.cpp	Fri Mar 29 12:28:02 2013 -0400
    55.2 +++ b/core/logic/smn_players.cpp	Fri Mar 29 11:37:29 2013 -0700
    55.3 @@ -34,8 +34,8 @@
    55.4  #include <IPlayerHelpers.h>
    55.5  #include <sh_string.h>
    55.6  #include <sh_list.h>
    55.7 +#include "CellArray.h"
    55.8  #include "AutoHandleRooter.h"
    55.9 -#include "CellArray.h"
   55.10  
   55.11  using namespace SourceHook;
   55.12  using namespace SourceMod;
    56.1 --- a/core/logic_bridge.cpp	Fri Mar 29 12:28:02 2013 -0400
    56.2 +++ b/core/logic_bridge.cpp	Fri Mar 29 11:37:29 2013 -0700
    56.3 @@ -33,14 +33,11 @@
    56.4  #include "sourcemod.h"
    56.5  #include "sourcemm_api.h"
    56.6  #include "sm_globals.h"
    56.7 -#include "NativeOwner.h"
    56.8  #include "sm_autonatives.h"
    56.9  #include "logic/intercom.h"
   56.10  #include "LibrarySys.h"
   56.11 -#include "HandleSys.h"
   56.12  #include "sm_stringutil.h"
   56.13  #include "Logger.h"
   56.14 -#include "ShareSys.h"
   56.15  #include "sm_srvcmds.h"
   56.16  #include "ForwardSys.h"
   56.17  #include "TimerSys.h"
   56.18 @@ -49,6 +46,15 @@
   56.19  #include "AdminCache.h"
   56.20  #include "HalfLife2.h"
   56.21  #include "CoreConfig.h"
   56.22 +#if SOURCE_ENGINE >= SE_ALIENSWARM
   56.23 +#include "convar_sm_swarm.h"
   56.24 +#elif SOURCE_ENGINE >= SE_LEFT4DEAD
   56.25 +#include "convar_sm_l4d.h"
   56.26 +#elif SOURCE_ENGINE >= SE_ORANGEBOX
   56.27 +#include "convar_sm_ob.h"
   56.28 +#else
   56.29 +#include "convar_sm.h"
   56.30 +#endif
   56.31  
   56.32  #if defined _WIN32
   56.33  	#define MATCHMAKINGDS_SUFFIX	""
   56.34 @@ -72,13 +78,17 @@
   56.35  ITextParsers *textparsers;
   56.36  sm_logic_t logicore;
   56.37  ITranslator *translator;
   56.38 +IScriptManager *scripts;
   56.39 +IShareSys *sharesys;
   56.40 +IExtensionSys *extsys;
   56.41 +IHandleSys *handlesys;
   56.42  
   56.43  class VEngineServer_Logic : public IVEngineServer_Logic
   56.44  {
   56.45  public:
   56.46  	virtual bool IsMapValid(const char *map)
   56.47  	{
   56.48 -		return engine->IsMapValid(map);
   56.49 +		return !!engine->IsMapValid(map);
   56.50  	}
   56.51  
   56.52  	virtual void ServerCommand(const char *cmd)
   56.53 @@ -89,11 +99,6 @@
   56.54  
   56.55  static VEngineServer_Logic logic_engine;
   56.56  
   56.57 -static void add_natives(sp_nativeinfo_t *natives)
   56.58 -{
   56.59 -	g_pCoreNatives->AddNatives(natives);
   56.60 -}
   56.61 -
   56.62  static ConVar *find_convar(const char *name)
   56.63  {
   56.64  	return icvar->FindVar(name);
   56.65 @@ -108,6 +113,15 @@
   56.66  	va_end(ap);
   56.67  }
   56.68  
   56.69 +static void log_fatal(const char *fmt, ...)
   56.70 +{
   56.71 +	va_list ap;
   56.72 +
   56.73 +	va_start(ap, fmt);
   56.74 +	g_Logger.LogFatalEx(fmt, ap);
   56.75 +	va_end(ap);
   56.76 +}
   56.77 +
   56.78  static void log_message(const char *fmt, ...)
   56.79  {
   56.80  	va_list ap;
   56.81 @@ -206,21 +220,78 @@
   56.82  static const char* get_core_config_value(const char* key)
   56.83  {
   56.84  	return g_CoreConfig.GetCoreConfigValue(key);
   56.85 -}	
   56.86 +}
   56.87 +
   56.88 +static bool is_map_loading()
   56.89 +{
   56.90 +	return g_SourceMod.IsMapLoading();
   56.91 +}
   56.92 +
   56.93 +static bool is_map_running()
   56.94 +{
   56.95 +	return g_SourceMod.IsMapRunning();
   56.96 +}
   56.97 +
   56.98 +int read_cmd_argc(const CCommand &args)
   56.99 +{
  56.100 +	return args.ArgC();
  56.101 +}
  56.102 +
  56.103 +static const char *read_cmd_arg(const CCommand &args, int arg)
  56.104 +{
  56.105 +	return args.Arg(arg);
  56.106 +}
  56.107 +
  56.108 +static int load_mms_plugin(const char *file, bool *ok, char *error, size_t maxlength)
  56.109 +{
  56.110 +	bool ignore_already;
  56.111 +	PluginId id = g_pMMPlugins->Load(file, g_PLID, ignore_already, error, maxlength);
  56.112 +
  56.113 +	Pl_Status status;
  56.114 +
  56.115 +#ifndef METAMOD_PLAPI_VERSION
  56.116 +	const char *file;
  56.117 +	PluginId source;
  56.118 +#endif
  56.119 +
  56.120 +	if (!id || (
  56.121 +#ifndef METAMOD_PLAPI_VERSION
  56.122 +		g_pMMPlugins->Query(id, file, status, source)
  56.123 +#else
  56.124 +		g_pMMPlugins->Query(id, NULL, &status, NULL)
  56.125 +#endif
  56.126 +		&& status < Pl_Paused))
  56.127 +	{
  56.128 +		*ok = false;
  56.129 +	}
  56.130 +	else
  56.131 +	{
  56.132 +		*ok = true;
  56.133 +	}
  56.134 +
  56.135 +	return id;
  56.136 +}
  56.137 +
  56.138 +static void unload_mms_plugin(int id)
  56.139 +{
  56.140 +	char ignore[255];
  56.141 +	g_pMMPlugins->Unload(id, true, ignore, sizeof(ignore));
  56.142 +}
  56.143 +
  56.144 +void do_global_plugin_loads()
  56.145 +{
  56.146 +	g_SourceMod.DoGlobalPluginLoads();
  56.147 +}
  56.148  
  56.149  static ServerGlobals serverGlobals;
  56.150  
  56.151  static sm_core_t core_bridge =
  56.152  {
  56.153  	/* Objects */
  56.154 -	&g_HandleSys,
  56.155 -	NULL,
  56.156  	&g_SourceMod,
  56.157  	&g_LibSys,
  56.158  	reinterpret_cast<IVEngineServer*>(&logic_engine),
  56.159 -	&g_ShareSys,
  56.160  	&g_RootMenu,
  56.161 -	&g_PluginSys,
  56.162  	&g_Forwards,
  56.163  	&g_Timers,
  56.164  	&g_Players,
  56.165 @@ -229,11 +300,11 @@
  56.166  	&g_pSourcePawn,
  56.167  	&g_pSourcePawn2,
  56.168  	/* Functions */
  56.169 -	add_natives,
  56.170  	find_convar,
  56.171  	strncopy,
  56.172  	UTIL_TrimWhitespace,
  56.173  	log_error,
  56.174 +	log_fatal,
  56.175  	log_message,
  56.176  	log_to_file,
  56.177  	log_to_game,
  56.178 @@ -248,6 +319,15 @@
  56.179  	get_source_engine_name,
  56.180  	symbols_are_hidden,
  56.181  	get_core_config_value,
  56.182 +	is_map_loading,
  56.183 +	is_map_running,
  56.184 +	read_cmd_argc,
  56.185 +	read_cmd_arg,
  56.186 +	load_mms_plugin,
  56.187 +	unload_mms_plugin,
  56.188 +	do_global_plugin_loads,
  56.189 +	SM_AreConfigsExecuted,
  56.190 +	SM_ExecuteForPlugin,
  56.191  	&serverGlobals
  56.192  };
  56.193  
  56.194 @@ -257,7 +337,6 @@
  56.195  	serverGlobals.frametime = &gpGlobals->frametime;
  56.196  	serverGlobals.interval_per_tick = &gpGlobals->interval_per_tick;
  56.197  
  56.198 -	core_bridge.core_ident = g_pCoreIdent;
  56.199  	core_bridge.engineFactory = (void *)g_SMAPI->GetEngineFactory(false);
  56.200  	core_bridge.serverFactory = (void *)g_SMAPI->GetServerFactory(false);
  56.201  
  56.202 @@ -286,6 +365,11 @@
  56.203  	g_pThreader = logicore.threader;
  56.204  	g_pSourcePawn2->SetProfiler(logicore.profiler);
  56.205  	translator = logicore.translator;
  56.206 +	scripts = logicore.scripts;
  56.207 +	sharesys = logicore.sharesys;
  56.208 +	extsys = logicore.extsys;
  56.209 +	g_pCoreIdent = logicore.core_ident;
  56.210 +	handlesys = logicore.handlesys;
  56.211  }
  56.212  
  56.213  bool StartLogicBridge(char *error, size_t maxlength)
    57.1 --- a/core/logic_bridge.h	Fri Mar 29 12:28:02 2013 -0400
    57.2 +++ b/core/logic_bridge.h	Fri Mar 29 11:37:29 2013 -0700
    57.3 @@ -42,6 +42,9 @@
    57.4  extern sm_logic_t logicore;
    57.5  extern ITranslator *translator;
    57.6  extern IGameConfig *g_pGameConf;
    57.7 +extern IScriptManager *scripts;
    57.8 +extern IShareSys *sharesys;
    57.9 +extern IExtensionSys *extsys;
   57.10 +extern IHandleSys *handlesys;
   57.11  
   57.12  #endif /* _INCLUDE_SOURCEMOD_LOGIC_BRIDGE_H_ */
   57.13 -
    58.1 --- a/core/msvc10/sourcemod_mm.vcxproj	Fri Mar 29 12:28:02 2013 -0400
    58.2 +++ b/core/msvc10/sourcemod_mm.vcxproj	Fri Mar 29 11:37:29 2013 -0700
    58.3 @@ -2098,11 +2098,9 @@
    58.4      </ClCompile>
    58.5      <ClCompile Include="..\Database.cpp" />
    58.6      <ClCompile Include="..\EventManager.cpp" />
    58.7 -    <ClCompile Include="..\ExtensionSys.cpp" />
    58.8      <ClCompile Include="..\ForwardSys.cpp" />
    58.9      <ClCompile Include="..\frame_hooks.cpp" />
   58.10      <ClCompile Include="..\HalfLife2.cpp" />
   58.11 -    <ClCompile Include="..\HandleSys.cpp" />
   58.12      <ClCompile Include="..\LibrarySys.cpp" />
   58.13      <ClCompile Include="..\Logger.cpp" />
   58.14      <ClCompile Include="..\logic_bridge.cpp" />
   58.15 @@ -2111,12 +2109,8 @@
   58.16      <ClCompile Include="..\MenuStyle_Radio.cpp" />
   58.17      <ClCompile Include="..\MenuStyle_Valve.cpp" />
   58.18      <ClCompile Include="..\MenuVoting.cpp" />
   58.19 -    <ClCompile Include="..\NativeInvoker.cpp" />
   58.20 -    <ClCompile Include="..\NativeOwner.cpp" />
   58.21      <ClCompile Include="..\NextMap.cpp" />
   58.22      <ClCompile Include="..\PlayerManager.cpp" />
   58.23 -    <ClCompile Include="..\PluginSys.cpp" />
   58.24 -    <ClCompile Include="..\ShareSys.cpp" />
   58.25      <ClCompile Include="..\smn_protobuf.cpp">
   58.26        <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Alien Swarm|Win32'">true</ExcludedFromBuild>
   58.27        <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Bloody Good Time|Win32'">true</ExcludedFromBuild>
   58.28 @@ -2170,7 +2164,6 @@
   58.29      <ClCompile Include="..\smn_database.cpp" />
   58.30      <ClCompile Include="..\smn_entities.cpp" />
   58.31      <ClCompile Include="..\smn_events.cpp" />
   58.32 -    <ClCompile Include="..\smn_fakenatives.cpp" />
   58.33      <ClCompile Include="..\smn_halflife.cpp" />
   58.34      <ClCompile Include="..\smn_hudtext.cpp" />
   58.35      <ClCompile Include="..\smn_keyvalues.cpp" />
   58.36 @@ -2308,11 +2301,9 @@
   58.37      <ClInclude Include="..\CoreConfig.h" />
   58.38      <ClInclude Include="..\Database.h" />
   58.39      <ClInclude Include="..\EventManager.h" />
   58.40 -    <ClInclude Include="..\ExtensionSys.h" />
   58.41      <ClInclude Include="..\ForwardSys.h" />
   58.42      <ClInclude Include="..\frame_hooks.h" />
   58.43      <ClInclude Include="..\HalfLife2.h" />
   58.44 -    <ClInclude Include="..\HandleSys.h" />
   58.45      <ClInclude Include="..\LibrarySys.h" />
   58.46      <ClInclude Include="..\Logger.h" />
   58.47      <ClInclude Include="..\logic_bridge.h" />
   58.48 @@ -2321,12 +2312,8 @@
   58.49      <ClInclude Include="..\MenuStyle_Radio.h" />
   58.50      <ClInclude Include="..\MenuStyle_Valve.h" />
   58.51      <ClInclude Include="..\MenuVoting.h" />
   58.52 -    <ClInclude Include="..\NativeInvoker.h" />
   58.53 -    <ClInclude Include="..\NativeOwner.h" />
   58.54      <ClInclude Include="..\NextMap.h" />
   58.55      <ClInclude Include="..\PlayerManager.h" />
   58.56 -    <ClInclude Include="..\PluginSys.h" />
   58.57 -    <ClInclude Include="..\ShareSys.h" />
   58.58      <ClInclude Include="..\sm_autonatives.h" />
   58.59      <ClInclude Include="..\sm_fastlink.h" />
   58.60      <ClInclude Include="..\sm_globals.h" />
    59.1 --- a/core/msvc10/sourcemod_mm.vcxproj.filters	Fri Mar 29 12:28:02 2013 -0400
    59.2 +++ b/core/msvc10/sourcemod_mm.vcxproj.filters	Fri Mar 29 11:37:29 2013 -0700
    59.3 @@ -69,9 +69,6 @@
    59.4      <ClCompile Include="..\EventManager.cpp">
    59.5        <Filter>Source Files</Filter>
    59.6      </ClCompile>
    59.7 -    <ClCompile Include="..\ExtensionSys.cpp">
    59.8 -      <Filter>Source Files</Filter>
    59.9 -    </ClCompile>
   59.10      <ClCompile Include="..\ForwardSys.cpp">
   59.11        <Filter>Source Files</Filter>
   59.12      </ClCompile>
   59.13 @@ -81,9 +78,6 @@
   59.14      <ClCompile Include="..\HalfLife2.cpp">
   59.15        <Filter>Source Files</Filter>
   59.16      </ClCompile>
   59.17 -    <ClCompile Include="..\HandleSys.cpp">
   59.18 -      <Filter>Source Files</Filter>
   59.19 -    </ClCompile>
   59.20      <ClCompile Include="..\LibrarySys.cpp">
   59.21        <Filter>Source Files</Filter>
   59.22      </ClCompile>
   59.23 @@ -108,24 +102,12 @@
   59.24      <ClCompile Include="..\MenuVoting.cpp">
   59.25        <Filter>Source Files</Filter>
   59.26      </ClCompile>
   59.27 -    <ClCompile Include="..\NativeInvoker.cpp">
   59.28 -      <Filter>Source Files</Filter>
   59.29 -    </ClCompile>
   59.30 -    <ClCompile Include="..\NativeOwner.cpp">
   59.31 -      <Filter>Source Files</Filter>
   59.32 -    </ClCompile>
   59.33      <ClCompile Include="..\NextMap.cpp">
   59.34        <Filter>Source Files</Filter>
   59.35      </ClCompile>
   59.36      <ClCompile Include="..\PlayerManager.cpp">
   59.37        <Filter>Source Files</Filter>
   59.38      </ClCompile>
   59.39 -    <ClCompile Include="..\PluginSys.cpp">
   59.40 -      <Filter>Source Files</Filter>
   59.41 -    </ClCompile>
   59.42 -    <ClCompile Include="..\ShareSys.cpp">
   59.43 -      <Filter>Source Files</Filter>
   59.44 -    </ClCompile>
   59.45      <ClCompile Include="..\sm_autonatives.cpp">
   59.46        <Filter>Source Files</Filter>
   59.47      </ClCompile>
   59.48 @@ -168,9 +150,6 @@
   59.49      <ClCompile Include="..\smn_events.cpp">
   59.50        <Filter>Natives</Filter>
   59.51      </ClCompile>
   59.52 -    <ClCompile Include="..\smn_fakenatives.cpp">
   59.53 -      <Filter>Natives</Filter>
   59.54 -    </ClCompile>
   59.55      <ClCompile Include="..\smn_halflife.cpp">
   59.56        <Filter>Natives</Filter>
   59.57      </ClCompile>
   59.58 @@ -251,9 +230,6 @@
   59.59      <ClInclude Include="..\EventManager.h">
   59.60        <Filter>Header Files</Filter>
   59.61      </ClInclude>
   59.62 -    <ClInclude Include="..\ExtensionSys.h">
   59.63 -      <Filter>Header Files</Filter>
   59.64 -    </ClInclude>
   59.65      <ClInclude Include="..\ForwardSys.h">
   59.66        <Filter>Header Files</Filter>
   59.67      </ClInclude>
   59.68 @@ -263,9 +239,6 @@
   59.69      <ClInclude Include="..\HalfLife2.h">
   59.70        <Filter>Header Files</Filter>
   59.71      </ClInclude>
   59.72 -    <ClInclude Include="..\HandleSys.h">
   59.73 -      <Filter>Header Files</Filter>
   59.74 -    </ClInclude>
   59.75      <ClInclude Include="..\LibrarySys.h">
   59.76        <Filter>Header Files</Filter>
   59.77      </ClInclude>
   59.78 @@ -290,24 +263,12 @@
   59.79      <ClInclude Include="..\MenuVoting.h">
   59.80        <Filter>Header Files</Filter>
   59.81      </ClInclude>
   59.82 -    <ClInclude Include="..\NativeInvoker.h">
   59.83 -      <Filter>Header Files</Filter>
   59.84 -    </ClInclude>
   59.85 -    <ClInclude Include="..\NativeOwner.h">
   59.86 -      <Filter>Header Files</Filter>
   59.87 -    </ClInclude>
   59.88      <ClInclude Include="..\NextMap.h">
   59.89        <Filter>Header Files</Filter>
   59.90      </ClInclude>
   59.91      <ClInclude Include="..\PlayerManager.h">
   59.92        <Filter>Header Files</Filter>
   59.93      </ClInclude>
   59.94 -    <ClInclude Include="..\PluginSys.h">
   59.95 -      <Filter>Header Files</Filter>
   59.96 -    </ClInclude>
   59.97 -    <ClInclude Include="..\ShareSys.h">
   59.98 -      <Filter>Header Files</Filter>
   59.99 -    </ClInclude>
  59.100      <ClInclude Include="..\sm_autonatives.h">
  59.101        <Filter>Header Files</Filter>
  59.102      </ClInclude>
    60.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    60.2 +++ b/core/msvc11/sourcemod_mm.sln	Fri Mar 29 11:37:29 2013 -0700
    60.3 @@ -0,0 +1,95 @@
    60.4 +
    60.5 +Microsoft Visual Studio Solution File, Format Version 11.00
    60.6 +# Visual Studio 2010
    60.7 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sourcemod_mm", "sourcemod_mm.vcxproj", "{E39527CD-7CAB-4420-97CC-DA1B93B260BC}"
    60.8 +EndProject
    60.9 +Global
   60.10 +	GlobalSection(SolutionConfigurationPlatforms) = preSolution
   60.11 +		CrazyDebug - Alien Swarm|Win32 = CrazyDebug - Alien Swarm|Win32
   60.12 +		CrazyDebug - CS GO|Win32 = CrazyDebug - CS GO|Win32
   60.13 +		CrazyDebug - Dark Messiah|Win32 = CrazyDebug - Dark Messiah|Win32
   60.14 +		CrazyDebug - Episode 1|Win32 = CrazyDebug - Episode 1|Win32
   60.15 +		CrazyDebug - Left 4 Dead 2|Win32 = CrazyDebug - Left 4 Dead 2|Win32
   60.16 +		CrazyDebug - Left 4 Dead|Win32 = CrazyDebug - Left 4 Dead|Win32
   60.17 +		CrazyDebug - Old Metamod|Win32 = CrazyDebug - Old Metamod|Win32
   60.18 +		CrazyDebug - Orange Box Valve|Win32 = CrazyDebug - Orange Box Valve|Win32
   60.19 +		CrazyDebug - Orange Box|Win32 = CrazyDebug - Orange Box|Win32
   60.20 +		Debug - Alien Swarm|Win32 = Debug - Alien Swarm|Win32
   60.21 +		Debug - CS GO|Win32 = Debug - CS GO|Win32
   60.22 +		Debug - Dark Messiah|Win32 = Debug - Dark Messiah|Win32
   60.23 +		Debug - Episode 1|Win32 = Debug - Episode 1|Win32
   60.24 +		Debug - Left 4 Dead 2|Win32 = Debug - Left 4 Dead 2|Win32
   60.25 +		Debug - Left 4 Dead|Win32 = Debug - Left 4 Dead|Win32
   60.26 +		Debug - Old Metamod|Win32 = Debug - Old Metamod|Win32
   60.27 +		Debug - Orange Box Valve|Win32 = Debug - Orange Box Valve|Win32
   60.28 +		Debug - Orange Box|Win32 = Debug - Orange Box|Win32
   60.29 +		Release - Alien Swarm|Win32 = Release - Alien Swarm|Win32
   60.30 +		Release - CS GO|Win32 = Release - CS GO|Win32
   60.31 +		Release - Dark Messiah|Win32 = Release - Dark Messiah|Win32
   60.32 +		Release - Episode 1|Win32 = Release - Episode 1|Win32
   60.33 +		Release - Left 4 Dead 2|Win32 = Release - Left 4 Dead 2|Win32
   60.34 +		Release - Left 4 Dead|Win32 = Release - Left 4 Dead|Win32
   60.35 +		Release - Old Metamod|Win32 = Release - Old Metamod|Win32
   60.36 +		Release - Orange Box Valve|Win32 = Release - Orange Box Valve|Win32
   60.37 +		Release - Orange Box|Win32 = Release - Orange Box|Win32
   60.38 +	EndGlobalSection
   60.39 +	GlobalSection(ProjectConfigurationPlatforms) = postSolution
   60.40 +		{E39527CD-7CAB-4420-97CC-DA1B93B260BC}.CrazyDebug - Alien Swarm|Win32.ActiveCfg = CrazyDebug - Alien Swarm|Win32
   60.41 +		{E39527CD-7CAB-4420-97CC-DA1B93B260BC}.CrazyDebug - Alien Swarm|Win32.Build.0 = CrazyDebug - Alien Swarm|Win32
   60.42 +		{E39527CD-7CAB-4420-97CC-DA1B93B260BC}.CrazyDebug - CS GO|Win32.ActiveCfg = CrazyDebug - CS GO|Win32
   60.43 +		{E39527CD-7CAB-4420-97CC-DA1B93B260BC}.CrazyDebug - CS GO|Win32.Build.0 = CrazyDebug - CS GO|Win32
   60.44 +		{E39527CD-7CAB-4420-97CC-DA1B93B260BC}.CrazyDebug - Dark Messiah|Win32.ActiveCfg = CrazyDebug - Dark Messiah|Win32
   60.45 +		{E39527CD-7CAB-4420-97CC-DA1B93B260BC}.CrazyDebug - Dark Messiah|Win32.Build.0 = CrazyDebug - Dark Messiah|Win32
   60.46 +		{E39527CD-7CAB-4420-97CC-DA1B93B260BC}.CrazyDebug - Episode 1|Win32.ActiveCfg = CrazyDebug - Episode 1|Win32
   60.47 +		{E39527CD-7CAB-4420-97CC-DA1B93B260BC}.CrazyDebug - Episode 1|Win32.Build.0 = CrazyDebug - Episode 1|Win32
   60.48 +		{E39527CD-7CAB-4420-97CC-DA1B93B260BC}.CrazyDebug - Left 4 Dead 2|Win32.ActiveCfg = CrazyDebug - Left 4 Dead 2|Win32
   60.49 +		{E39527CD-7CAB-4420-97CC-DA1B93B260BC}.CrazyDebug - Left 4 Dead 2|Win32.Build.0 = CrazyDebug - Left 4 Dead 2|Win32
   60.50 +		{E39527CD-7CAB-4420-97CC-DA1B93B260BC}.CrazyDebug - Left 4 Dead|Win32.ActiveCfg = CrazyDebug - Left 4 Dead|Win32
   60.51 +		{E39527CD-7CAB-4420-97CC-DA1B93B260BC}.CrazyDebug - Left 4 Dead|Win32.Build.0 = CrazyDebug - Left 4 Dead|Win32
   60.52 +		{E39527CD-7CAB-4420-97CC-DA1B93B260BC}.CrazyDebug - Old Metamod|Win32.ActiveCfg = CrazyDebug - Old Metamod|Win32
   60.53 +		{E39527CD-7CAB-4420-97CC-DA1B93B260BC}.CrazyDebug - Old Metamod|Win32.Build.0 = CrazyDebug - Old Metamod|Win32
   60.54 +		{E39527CD-7CAB-4420-97CC-DA1B93B260BC}.CrazyDebug - Orange Box Valve|Win32.ActiveCfg = CrazyDebug - Orange Box Valve|Win32
   60.55 +		{E39527CD-7CAB-4420-97CC-DA1B93B260BC}.CrazyDebug - Orange Box Valve|Win32.Build.0 = CrazyDebug - Orange Box Valve|Win32
   60.56 +		{E39527CD-7CAB-4420-97CC-DA1B93B260BC}.CrazyDebug - Orange Box|Win32.ActiveCfg = CrazyDebug - Orange Box|Win32
   60.57 +		{E39527CD-7CAB-4420-97CC-DA1B93B260BC}.CrazyDebug - Orange Box|Win32.Build.0 = CrazyDebug - Orange Box|Win32
   60.58 +		{E39527CD-7CAB-4420-97CC-DA1B93B260BC}.Debug - Alien Swarm|Win32.ActiveCfg = Debug - Alien Swarm|Win32
   60.59 +		{E39527CD-7CAB-4420-97CC-DA1B93B260BC}.Debug - Alien Swarm|Win32.Build.0 = Debug - Alien Swarm|Win32
   60.60 +		{E39527CD-7CAB-4420-97CC-DA1B93B260BC}.Debug - CS GO|Win32.ActiveCfg = Debug - CS GO|Win32
   60.61 +		{E39527CD-7CAB-4420-97CC-DA1B93B260BC}.Debug - CS GO|Win32.Build.0 = Debug - CS GO|Win32
   60.62 +		{E39527CD-7CAB-4420-97CC-DA1B93B260BC}.Debug - Dark Messiah|Win32.ActiveCfg = Debug - Dark Messiah|Win32
   60.63 +		{E39527CD-7CAB-4420-97CC-DA1B93B260BC}.Debug - Dark Messiah|Win32.Build.0 = Debug - Dark Messiah|Win32
   60.64 +		{E39527CD-7CAB-4420-97CC-DA1B93B260BC}.Debug - Episode 1|Win32.ActiveCfg = Debug - Episode 1|Win32
   60.65 +		{E39527CD-7CAB-4420-97CC-DA1B93B260BC}.Debug - Episode 1|Win32.Build.0 = Debug - Episode 1|Win32
   60.66 +		{E39527CD-7CAB-4420-97CC-DA1B93B260BC}.Debug - Left 4 Dead 2|Win32.ActiveCfg = Debug - Left 4 Dead 2|Win32
   60.67 +		{E39527CD-7CAB-4420-97CC-DA1B93B260BC}.Debug - Left 4 Dead 2|Win32.Build.0 = Debug - Left 4 Dead 2|Win32
   60.68 +		{E39527CD-7CAB-4420-97CC-DA1B93B260BC}.Debug - Left 4 Dead|Win32.ActiveCfg = Debug - Left 4 Dead|Win32
   60.69 +		{E39527CD-7CAB-4420-97CC-DA1B93B260BC}.Debug - Left 4 Dead|Win32.Build.0 = Debug - Left 4 Dead|Win32
   60.70 +		{E39527CD-7CAB-4420-97CC-DA1B93B260BC}.Debug - Old Metamod|Win32.ActiveCfg = Debug - Old Metamod|Win32
   60.71 +		{E39527CD-7CAB-4420-97CC-DA1B93B260BC}.Debug - Old Metamod|Win32.Build.0 = Debug - Old Metamod|Win32
   60.72 +		{E39527CD-7CAB-4420-97CC-DA1B93B260BC}.Debug - Orange Box Valve|Win32.ActiveCfg = Debug - Orange Box Valve|Win32
   60.73 +		{E39527CD-7CAB-4420-97CC-DA1B93B260BC}.Debug - Orange Box Valve|Win32.Build.0 = Debug - Orange Box Valve|Win32
   60.74 +		{E39527CD-7CAB-4420-97CC-DA1B93B260BC}.Debug - Orange Box|Win32.ActiveCfg = Debug - Orange Box|Win32
   60.75 +		{E39527CD-7CAB-4420-97CC-DA1B93B260BC}.Debug - Orange Box|Win32.Build.0 = Debug - Orange Box|Win32
   60.76 +		{E39527CD-7CAB-4420-97CC-DA1B93B260BC}.Release - Alien Swarm|Win32.ActiveCfg = Release - Alien Swarm|Win32
   60.77 +		{E39527CD-7CAB-4420-97CC-DA1B93B260BC}.Release - Alien Swarm|Win32.Build.0 = Release - Alien Swarm|Win32
   60.78 +		{E39527CD-7CAB-4420-97CC-DA1B93B260BC}.Release - CS GO|Win32.ActiveCfg = Release - CS GO|Win32
   60.79 +		{E39527CD-7CAB-4420-97CC-DA1B93B260BC}.Release - CS GO|Win32.Build.0 = Release - CS GO|Win32
   60.80 +		{E39527CD-7CAB-4420-97CC-DA1B93B260BC}.Release - Dark Messiah|Win32.ActiveCfg = Release - Dark Messiah|Win32
   60.81 +		{E39527CD-7CAB-4420-97CC-DA1B93B260BC}.Release - Dark Messiah|Win32.Build.0 = Release - Dark Messiah|Win32
   60.82 +		{E39527CD-7CAB-4420-97CC-DA1B93B260BC}.Release - Episode 1|Win32.ActiveCfg = Release - Episode 1|Win32
   60.83 +		{E39527CD-7CAB-4420-97CC-DA1B93B260BC}.Release - Episode 1|Win32.Build.0 = Release - Episode 1|Win32
   60.84 +		{E39527CD-7CAB-4420-97CC-DA1B93B260BC}.Release - Left 4 Dead 2|Win32.ActiveCfg = Release - Left 4 Dead 2|Win32
   60.85 +		{E39527CD-7CAB-4420-97CC-DA1B93B260BC}.Release - Left 4 Dead 2|Win32.Build.0 = Release - Left 4 Dead 2|Win32
   60.86 +		{E39527CD-7CAB-4420-97CC-DA1B93B260BC}.Release - Left 4 Dead|Win32.ActiveCfg = Release - Left 4 Dead|Win32
   60.87 +		{E39527CD-7CAB-4420-97CC-DA1B93B260BC}.Release - Left 4 Dead|Win32.Build.0 = Release - Left 4 Dead|Win32
   60.88 +		{E39527CD-7CAB-4420-97CC-DA1B93B260BC}.Release - Old Metamod|Win32.ActiveCfg = Release - Old Metamod|Win32
   60.89 +		{E39527CD-7CAB-4420-97CC-DA1B93B260BC}.Release - Old Metamod|Win32.Build.0 = Release - Old Metamod|Win32
   60.90 +		{E39527CD-7CAB-4420-97CC-DA1B93B260BC}.Release - Orange Box Valve|Win32.ActiveCfg = Release - Orange Box Valve|Win32
   60.91 +		{E39527CD-7CAB-4420-97CC-DA1B93B260BC}.Release - Orange Box Valve|Win32.Build.0 = Release - Orange Box Valve|Win32
   60.92 +		{E39527CD-7CAB-4420-97CC-DA1B93B260BC}.Release - Orange Box|Win32.ActiveCfg = Release - Orange Box|Win32
   60.93 +		{E39527CD-7CAB-4420-97CC-DA1B93B260BC}.Release - Orange Box|Win32.Build.0 = Release - Orange Box|Win32
   60.94 +	EndGlobalSection
   60.95 +	GlobalSection(SolutionProperties) = preSolution
   60.96 +		HideSolutionNode = FALSE
   60.97 +	EndGlobalSection
   60.98 +EndGlobal
    61.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    61.2 +++ b/core/msvc11/sourcemod_mm.vcxproj	Fri Mar 29 11:37:29 2013 -0700
    61.3 @@ -0,0 +1,2479 @@
    61.4 +<?xml version="1.0" encoding="utf-8"?>
    61.5 +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    61.6 +  <ItemGroup Label="ProjectConfigurations">
    61.7 +    <ProjectConfiguration Include="CrazyDebug - Alien Swarm|Win32">
    61.8 +      <Configuration>CrazyDebug - Alien Swarm</Configuration>
    61.9 +      <Platform>Win32</Platform>
   61.10 +    </ProjectConfiguration>
   61.11 +    <ProjectConfiguration Include="CrazyDebug - Bloody Good Time|Win32">
   61.12 +      <Configuration>CrazyDebug - Bloody Good Time</Configuration>
   61.13 +      <Platform>Win32</Platform>
   61.14 +    </ProjectConfiguration>
   61.15 +    <ProjectConfiguration Include="CrazyDebug - CS GO|Win32">
   61.16 +      <Configuration>CrazyDebug - CS GO</Configuration>
   61.17 +      <Platform>Win32</Platform>
   61.18 +    </ProjectConfiguration>
   61.19 +    <ProjectConfiguration Include="CrazyDebug - CSS|Win32">
   61.20 +      <Configuration>CrazyDebug - CSS</Configuration>
   61.21 +      <Platform>Win32</Platform>
   61.22 +    </ProjectConfiguration>
   61.23 +    <ProjectConfiguration Include="CrazyDebug - Dark Messiah|Win32">
   61.24 +      <Configuration>CrazyDebug - Dark Messiah</Configuration>
   61.25 +      <Platform>Win32</Platform>
   61.26 +    </ProjectConfiguration>
   61.27 +    <ProjectConfiguration Include="CrazyDebug - Episode 1|Win32">
   61.28 +      <Configuration>CrazyDebug - Episode 1</Configuration>
   61.29 +      <Platform>Win32</Platform>
   61.30 +    </ProjectConfiguration>
   61.31 +    <ProjectConfiguration Include="CrazyDebug - EYE|Win32">
   61.32 +      <Configuration>CrazyDebug - EYE</Configuration>
   61.33 +      <Platform>Win32</Platform>
   61.34 +    </ProjectConfiguration>
   61.35 +    <ProjectConfiguration Include="CrazyDebug - Left 4 Dead 2|Win32">
   61.36 +      <Configuration>CrazyDebug - Left 4 Dead 2</Configuration>
   61.37 +      <Platform>Win32</Platform>
   61.38 +    </ProjectConfiguration>
   61.39 +    <ProjectConfiguration Include="CrazyDebug - Left 4 Dead|Win32">
   61.40 +      <Configuration>CrazyDebug - Left 4 Dead</Configuration>
   61.41 +      <Platform>Win32</Platform>
   61.42 +    </ProjectConfiguration>
   61.43 +    <ProjectConfiguration Include="CrazyDebug - Old Metamod|Win32">
   61.44 +      <Configuration>CrazyDebug - Old Metamod</Configuration>
   61.45 +      <Platform>Win32</Platform>
   61.46 +    </ProjectConfiguration>
   61.47 +    <ProjectConfiguration Include="CrazyDebug - Orange Box Valve|Win32">
   61.48 +      <Configuration>CrazyDebug - Orange Box Valve</Configuration>
   61.49 +      <Platform>Win32</Platform>
   61.50 +    </ProjectConfiguration>
   61.51 +    <ProjectConfiguration Include="CrazyDebug - Orange Box|Win32">
   61.52 +      <Configuration>CrazyDebug - Orange Box</Configuration>
   61.53 +      <Platform>Win32</Platform>
   61.54 +    </ProjectConfiguration>
   61.55 +    <ProjectConfiguration Include="Debug - Alien Swarm|Win32">
   61.56 +      <Configuration>Debug - Alien Swarm</Configuration>
   61.57 +      <Platform>Win32</Platform>
   61.58 +    </ProjectConfiguration>
   61.59 +    <ProjectConfiguration Include="Debug - Bloody Good Time|Win32">
   61.60 +      <Configuration>Debug - Bloody Good Time</Configuration>
   61.61 +      <Platform>Win32</Platform>
   61.62 +    </ProjectConfiguration>
   61.63 +    <ProjectConfiguration Include="Debug - CS GO|Win32">
   61.64 +      <Configuration>Debug - CS GO</Configuration>
   61.65 +      <Platform>Win32</Platform>
   61.66 +    </ProjectConfiguration>
   61.67 +    <ProjectConfiguration Include="Debug - CSS|Win32">
   61.68 +      <Configuration>Debug - CSS</Configuration>
   61.69 +      <Platform>Win32</Platform>
   61.70 +    </ProjectConfiguration>
   61.71 +    <ProjectConfiguration Include="Debug - Dark Messiah|Win32">
   61.72 +      <Configuration>Debug - Dark Messiah</Configuration>
   61.73 +      <Platform>Win32</Platform>
   61.74 +    </ProjectConfiguration>
   61.75 +    <ProjectConfiguration Include="Debug - Episode 1|Win32">
   61.76 +      <Configuration>Debug - Episode 1</Configuration>
   61.77 +      <Platform>Win32</Platform>
   61.78 +    </ProjectConfiguration>
   61.79 +    <ProjectConfiguration Include="Debug - EYE|Win32">
   61.80 +      <Configuration>Debug - EYE</Configuration>
   61.81 +      <Platform>Win32</Platform>
   61.82 +    </ProjectConfiguration>
   61.83 +    <ProjectConfiguration Include="Debug - Left 4 Dead 2|Win32">
   61.84 +      <Configuration>Debug - Left 4 Dead 2</Configuration>
   61.85 +      <Platform>Win32</Platform>
   61.86 +    </ProjectConfiguration>
   61.87 +    <ProjectConfiguration Include="Debug - Left 4 Dead|Win32">
   61.88 +      <Configuration>Debug - Left 4 Dead</Configuration>
   61.89 +      <Platform>Win32</Platform>
   61.90 +    </ProjectConfiguration>
   61.91 +    <ProjectConfiguration Include="Debug - Old Metamod|Win32">
   61.92 +      <Configuration>Debug - Old Metamod</Configuration>
   61.93 +      <Platform>Win32</Platform>
   61.94 +    </ProjectConfiguration>
   61.95 +    <ProjectConfiguration Include="Debug - Orange Box Valve|Win32">
   61.96 +      <Configuration>Debug - Orange Box Valve</Configuration>
   61.97 +      <Platform>Win32</Platform>
   61.98 +    </ProjectConfiguration>
   61.99 +    <ProjectConfiguration Include="Debug - Orange Box|Win32">
  61.100 +      <Configuration>Debug - Orange Box</Configuration>
  61.101 +      <Platform>Win32</Platform>
  61.102 +    </ProjectConfiguration>
  61.103 +    <ProjectConfiguration Include="Release - Alien Swarm|Win32">
  61.104 +      <Configuration>Release - Alien Swarm</Configuration>
  61.105 +      <Platform>Win32</Platform>
  61.106 +    </ProjectConfiguration>
  61.107 +    <ProjectConfiguration Include="Release - Bloody Good Time|Win32">
  61.108 +      <Configuration>Release - Bloody Good Time</Configuration>
  61.109 +      <Platform>Win32</Platform>
  61.110 +    </ProjectConfiguration>
  61.111 +    <ProjectConfiguration Include="Release - CS GO|Win32">
  61.112 +      <Configuration>Release - CS GO</Configuration>
  61.113 +      <Platform>Win32</Platform>
  61.114 +    </ProjectConfiguration>
  61.115 +    <ProjectConfiguration Include="Release - CSS|Win32">
  61.116 +      <Configuration>Release - CSS</Configuration>
  61.117 +      <Platform>Win32</Platform>
  61.118 +    </ProjectConfiguration>
  61.119 +    <ProjectConfiguration Include="Release - Dark Messiah|Win32">
  61.120 +      <Configuration>Release - Dark Messiah</Configuration>
  61.121 +      <Platform>Win32</Platform>
  61.122 +    </ProjectConfiguration>
  61.123 +    <ProjectConfiguration Include="Release - Episode 1|Win32">
  61.124 +      <Configuration>Release - Episode 1</Configuration>
  61.125 +      <Platform>Win32</Platform>
  61.126 +    </ProjectConfiguration>
  61.127 +    <ProjectConfiguration Include="Release - EYE|Win32">
  61.128 +      <Configuration>Release - EYE</Configuration>
  61.129 +      <Platform>Win32</Platform>
  61.130 +    </ProjectConfiguration>
  61.131 +    <ProjectConfiguration Include="Release - Left 4 Dead 2|Win32">
  61.132 +      <Configuration>Release - Left 4 Dead 2</Configuration>
  61.133 +      <Platform>Win32</Platform>
  61.134 +    </ProjectConfiguration>
  61.135 +    <ProjectConfiguration Include="Release - Left 4 Dead|Win32">
  61.136 +      <Configuration>Release - Left 4 Dead</Configuration>
  61.137 +      <Platform>Win32</Platform>
  61.138 +    </ProjectConfiguration>
  61.139 +    <ProjectConfiguration Include="Release - Old Metamod|Win32">
  61.140 +      <Configuration>Release - Old Metamod</Configuration>
  61.141 +      <Platform>Win32</Platform>
  61.142 +    </ProjectConfiguration>
  61.143 +    <ProjectConfiguration Include="Release - Orange Box Valve|Win32">
  61.144 +      <Configuration>Release - Orange Box Valve</Configuration>
  61.145 +      <Platform>Win32</Platform>
  61.146 +    </ProjectConfiguration>
  61.147 +    <ProjectConfiguration Include="Release - Orange Box|Win32">
  61.148 +      <Configuration>Release - Orange Box</Configuration>
  61.149 +      <Platform>Win32</Platform>
  61.150 +    </ProjectConfiguration>
  61.151 +  </ItemGroup>
  61.152 +  <PropertyGroup Label="Globals">
  61.153 +    <ProjectGuid>{E39527CD-7CAB-4420-97CC-DA1B93B260BC}</ProjectGuid>
  61.154 +    <RootNamespace>sourcemod_mm</RootNamespace>
  61.155 +    <Keyword>Win32Proj</Keyword>
  61.156 +  </PropertyGroup>
  61.157 +  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
  61.158 +  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release - Alien Swarm|Win32'" Label="Configuration">
  61.159 +    <ConfigurationType>DynamicLibrary</ConfigurationType>
  61.160 +    <CharacterSet>MultiByte</CharacterSet>
  61.161 +    <WholeProgramOptimization>true</WholeProgramOptimization>
  61.162 +    <PlatformToolset>v110</PlatformToolset>
  61.163 +  </PropertyGroup>
  61.164 +  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug - Alien Swarm|Win32'" Label="Configuration">
  61.165 +    <ConfigurationType>DynamicLibrary</ConfigurationType>
  61.166 +    <CharacterSet>MultiByte</CharacterSet>
  61.167 +    <PlatformToolset>v110</PlatformToolset>
  61.168 +  </PropertyGroup>
  61.169 +  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Alien Swarm|Win32'" Label="Configuration">
  61.170 +    <ConfigurationType>DynamicLibrary</ConfigurationType>
  61.171 +    <CharacterSet>MultiByte</CharacterSet>
  61.172 +    <PlatformToolset>v110</PlatformToolset>
  61.173 +  </PropertyGroup>
  61.174 +  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release - CS GO|Win32'" Label="Configuration">
  61.175 +    <ConfigurationType>DynamicLibrary</ConfigurationType>
  61.176 +    <CharacterSet>MultiByte</CharacterSet>
  61.177 +    <WholeProgramOptimization>true</WholeProgramOptimization>
  61.178 +    <PlatformToolset>v110</PlatformToolset>
  61.179 +  </PropertyGroup>
  61.180 +  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug - CS GO|Win32'" Label="Configuration">
  61.181 +    <ConfigurationType>DynamicLibrary</ConfigurationType>
  61.182 +    <CharacterSet>MultiByte</CharacterSet>
  61.183 +    <PlatformToolset>v110</PlatformToolset>
  61.184 +  </PropertyGroup>
  61.185 +  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - CS GO|Win32'" Label="Configuration">
  61.186 +    <ConfigurationType>DynamicLibrary</ConfigurationType>
  61.187 +    <CharacterSet>MultiByte</CharacterSet>
  61.188 +    <PlatformToolset>v110</PlatformToolset>
  61.189 +  </PropertyGroup>
  61.190 +  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release - Left 4 Dead 2|Win32'" Label="Configuration">
  61.191 +    <ConfigurationType>DynamicLibrary</ConfigurationType>
  61.192 +    <CharacterSet>MultiByte</CharacterSet>
  61.193 +    <WholeProgramOptimization>true</WholeProgramOptimization>
  61.194 +    <PlatformToolset>v110</PlatformToolset>
  61.195 +  </PropertyGroup>
  61.196 +  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug - Left 4 Dead 2|Win32'" Label="Configuration">
  61.197 +    <ConfigurationType>DynamicLibrary</ConfigurationType>
  61.198 +    <CharacterSet>MultiByte</CharacterSet>
  61.199 +    <PlatformToolset>v110</PlatformToolset>
  61.200 +  </PropertyGroup>
  61.201 +  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Left 4 Dead 2|Win32'" Label="Configuration">
  61.202 +    <ConfigurationType>DynamicLibrary</ConfigurationType>
  61.203 +    <CharacterSet>MultiByte</CharacterSet>
  61.204 +    <PlatformToolset>v110</PlatformToolset>
  61.205 +  </PropertyGroup>
  61.206 +  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release - Orange Box Valve|Win32'" Label="Configuration">
  61.207 +    <ConfigurationType>DynamicLibrary</ConfigurationType>
  61.208 +    <CharacterSet>MultiByte</CharacterSet>
  61.209 +    <WholeProgramOptimization>true</WholeProgramOptimization>
  61.210 +    <PlatformToolset>v110</PlatformToolset>
  61.211 +  </PropertyGroup>
  61.212 +  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release - CSS|Win32'" Label="Configuration">
  61.213 +    <ConfigurationType>DynamicLibrary</ConfigurationType>
  61.214 +    <CharacterSet>MultiByte</CharacterSet>
  61.215 +    <WholeProgramOptimization>true</WholeProgramOptimization>
  61.216 +    <PlatformToolset>v110</PlatformToolset>
  61.217 +  </PropertyGroup>
  61.218 +  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug - Orange Box Valve|Win32'" Label="Configuration">
  61.219 +    <ConfigurationType>DynamicLibrary</ConfigurationType>
  61.220 +    <CharacterSet>MultiByte</CharacterSet>
  61.221 +    <PlatformToolset>v110</PlatformToolset>
  61.222 +  </PropertyGroup>
  61.223 +  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug - CSS|Win32'" Label="Configuration">
  61.224 +    <ConfigurationType>DynamicLibrary</ConfigurationType>
  61.225 +    <CharacterSet>MultiByte</CharacterSet>
  61.226 +    <PlatformToolset>v110</PlatformToolset>
  61.227 +  </PropertyGroup>
  61.228 +  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Orange Box Valve|Win32'" Label="Configuration">
  61.229 +    <ConfigurationType>DynamicLibrary</ConfigurationType>
  61.230 +    <CharacterSet>MultiByte</CharacterSet>
  61.231 +    <PlatformToolset>v110</PlatformToolset>
  61.232 +  </PropertyGroup>
  61.233 +  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - CSS|Win32'" Label="Configuration">
  61.234 +    <ConfigurationType>DynamicLibrary</ConfigurationType>
  61.235 +    <CharacterSet>MultiByte</CharacterSet>
  61.236 +    <PlatformToolset>v110</PlatformToolset>
  61.237 +  </PropertyGroup>
  61.238 +  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release - Left 4 Dead|Win32'" Label="Configuration">
  61.239 +    <ConfigurationType>DynamicLibrary</ConfigurationType>
  61.240 +    <CharacterSet>MultiByte</CharacterSet>
  61.241 +    <WholeProgramOptimization>true</WholeProgramOptimization>
  61.242 +    <PlatformToolset>v110</PlatformToolset>
  61.243 +  </PropertyGroup>
  61.244 +  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug - Left 4 Dead|Win32'" Label="Configuration">
  61.245 +    <ConfigurationType>DynamicLibrary</ConfigurationType>
  61.246 +    <CharacterSet>MultiByte</CharacterSet>
  61.247 +    <PlatformToolset>v110</PlatformToolset>
  61.248 +  </PropertyGroup>
  61.249 +  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Left 4 Dead|Win32'" Label="Configuration">
  61.250 +    <ConfigurationType>DynamicLibrary</ConfigurationType>
  61.251 +    <CharacterSet>MultiByte</CharacterSet>
  61.252 +    <PlatformToolset>v110</PlatformToolset>
  61.253 +  </PropertyGroup>
  61.254 +  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release - Episode 1|Win32'" Label="Configuration">
  61.255 +    <ConfigurationType>DynamicLibrary</ConfigurationType>
  61.256 +    <CharacterSet>MultiByte</CharacterSet>
  61.257 +    <WholeProgramOptimization>true</WholeProgramOptimization>
  61.258 +    <PlatformToolset>v110</PlatformToolset>
  61.259 +  </PropertyGroup>
  61.260 +  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug - Episode 1|Win32'" Label="Configuration">
  61.261 +    <ConfigurationType>DynamicLibrary</ConfigurationType>
  61.262 +    <CharacterSet>MultiByte</CharacterSet>
  61.263 +    <PlatformToolset>v110</PlatformToolset>
  61.264 +  </PropertyGroup>
  61.265 +  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Episode 1|Win32'" Label="Configuration">
  61.266 +    <ConfigurationType>DynamicLibrary</ConfigurationType>
  61.267 +    <CharacterSet>MultiByte</CharacterSet>
  61.268 +    <PlatformToolset>v110</PlatformToolset>
  61.269 +  </PropertyGroup>
  61.270 +  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release - Orange Box|Win32'" Label="Configuration">
  61.271 +    <ConfigurationType>DynamicLibrary</ConfigurationType>
  61.272 +    <CharacterSet>MultiByte</CharacterSet>
  61.273 +    <WholeProgramOptimization>true</WholeProgramOptimization>
  61.274 +    <PlatformToolset>v110</PlatformToolset>
  61.275 +  </PropertyGroup>
  61.276 +  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug - Orange Box|Win32'" Label="Configuration">
  61.277 +    <ConfigurationType>DynamicLibrary</ConfigurationType>
  61.278 +    <CharacterSet>MultiByte</CharacterSet>
  61.279 +    <PlatformToolset>v110</PlatformToolset>
  61.280 +  </PropertyGroup>
  61.281 +  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Orange Box|Win32'" Label="Configuration">
  61.282 +    <ConfigurationType>DynamicLibrary</ConfigurationType>
  61.283 +    <CharacterSet>MultiByte</CharacterSet>
  61.284 +    <PlatformToolset>v110</PlatformToolset>
  61.285 +  </PropertyGroup>
  61.286 +  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release - Dark Messiah|Win32'" Label="Configuration">
  61.287 +    <ConfigurationType>DynamicLibrary</ConfigurationType>
  61.288 +    <CharacterSet>MultiByte</CharacterSet>
  61.289 +    <WholeProgramOptimization>true</WholeProgramOptimization>
  61.290 +    <PlatformToolset>v110</PlatformToolset>
  61.291 +  </PropertyGroup>
  61.292 +  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug - Dark Messiah|Win32'" Label="Configuration">
  61.293 +    <ConfigurationType>DynamicLibrary</ConfigurationType>
  61.294 +    <CharacterSet>MultiByte</CharacterSet>
  61.295 +    <PlatformToolset>v110</PlatformToolset>
  61.296 +  </PropertyGroup>
  61.297 +  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Dark Messiah|Win32'" Label="Configuration">
  61.298 +    <ConfigurationType>DynamicLibrary</ConfigurationType>
  61.299 +    <CharacterSet>MultiByte</CharacterSet>
  61.300 +    <PlatformToolset>v110</PlatformToolset>
  61.301 +  </PropertyGroup>
  61.302 +  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release - Old Metamod|Win32'" Label="Configuration">
  61.303 +    <ConfigurationType>DynamicLibrary</ConfigurationType>
  61.304 +    <CharacterSet>MultiByte</CharacterSet>
  61.305 +    <WholeProgramOptimization>true</WholeProgramOptimization>
  61.306 +    <PlatformToolset>v110</PlatformToolset>
  61.307 +  </PropertyGroup>
  61.308 +  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug - Old Metamod|Win32'" Label="Configuration">
  61.309 +    <ConfigurationType>DynamicLibrary</ConfigurationType>
  61.310 +    <CharacterSet>MultiByte</CharacterSet>
  61.311 +    <PlatformToolset>v110</PlatformToolset>
  61.312 +  </PropertyGroup>
  61.313 +  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Old Metamod|Win32'" Label="Configuration">
  61.314 +    <ConfigurationType>DynamicLibrary</ConfigurationType>
  61.315 +    <CharacterSet>MultiByte</CharacterSet>
  61.316 +    <PlatformToolset>v110</PlatformToolset>
  61.317 +  </PropertyGroup>
  61.318 +  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release - Bloody Good Time|Win32'" Label="Configuration">
  61.319 +    <ConfigurationType>DynamicLibrary</ConfigurationType>
  61.320 +    <CharacterSet>MultiByte</CharacterSet>
  61.321 +    <WholeProgramOptimization>true</WholeProgramOptimization>
  61.322 +    <PlatformToolset>v110</PlatformToolset>
  61.323 +  </PropertyGroup>
  61.324 +  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug - Bloody Good Time|Win32'" Label="Configuration">
  61.325 +    <ConfigurationType>DynamicLibrary</ConfigurationType>
  61.326 +    <CharacterSet>MultiByte</CharacterSet>
  61.327 +    <PlatformToolset>v110</PlatformToolset>
  61.328 +  </PropertyGroup>
  61.329 +  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Bloody Good Time|Win32'" Label="Configuration">
  61.330 +    <ConfigurationType>DynamicLibrary</ConfigurationType>
  61.331 +    <CharacterSet>MultiByte</CharacterSet>
  61.332 +    <PlatformToolset>v110</PlatformToolset>
  61.333 +  </PropertyGroup>
  61.334 +  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release - EYE|Win32'" Label="Configuration">
  61.335 +    <ConfigurationType>DynamicLibrary</ConfigurationType>
  61.336 +    <CharacterSet>MultiByte</CharacterSet>
  61.337 +    <WholeProgramOptimization>true</WholeProgramOptimization>
  61.338 +    <PlatformToolset>v110</PlatformToolset>
  61.339 +  </PropertyGroup>
  61.340 +  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug - EYE|Win32'" Label="Configuration">
  61.341 +    <ConfigurationType>DynamicLibrary</ConfigurationType>
  61.342 +    <CharacterSet>MultiByte</CharacterSet>
  61.343 +    <PlatformToolset>v110</PlatformToolset>
  61.344 +  </PropertyGroup>
  61.345 +  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - EYE|Win32'" Label="Configuration">
  61.346 +    <ConfigurationType>DynamicLibrary</ConfigurationType>
  61.347 +    <CharacterSet>MultiByte</CharacterSet>
  61.348 +    <PlatformToolset>v110</PlatformToolset>
  61.349 +  </PropertyGroup>
  61.350 +  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
  61.351 +  <ImportGroup Label="ExtensionSettings">
  61.352 +  </ImportGroup>
  61.353 +  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release - Alien Swarm|Win32'" Label="PropertySheets">
  61.354 +    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
  61.355 +  </ImportGroup>
  61.356 +  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug - Alien Swarm|Win32'" Label="PropertySheets">
  61.357 +    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
  61.358 +  </ImportGroup>
  61.359 +  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Alien Swarm|Win32'" Label="PropertySheets">
  61.360 +    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
  61.361 +  </ImportGroup>
  61.362 +  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release - CS GO|Win32'" Label="PropertySheets">
  61.363 +    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
  61.364 +  </ImportGroup>
  61.365 +  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug - CS GO|Win32'" Label="PropertySheets">
  61.366 +    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
  61.367 +  </ImportGroup>
  61.368 +  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - CS GO|Win32'" Label="PropertySheets">
  61.369 +    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
  61.370 +  </ImportGroup>
  61.371 +  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release - Left 4 Dead 2|Win32'" Label="PropertySheets">
  61.372 +    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
  61.373 +  </ImportGroup>
  61.374 +  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug - Left 4 Dead 2|Win32'" Label="PropertySheets">
  61.375 +    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
  61.376 +  </ImportGroup>
  61.377 +  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Left 4 Dead 2|Win32'" Label="PropertySheets">
  61.378 +    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
  61.379 +  </ImportGroup>
  61.380 +  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release - Orange Box Valve|Win32'" Label="PropertySheets">
  61.381 +    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
  61.382 +  </ImportGroup>
  61.383 +  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release - CSS|Win32'" Label="PropertySheets">
  61.384 +    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
  61.385 +  </ImportGroup>
  61.386 +  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug - Orange Box Valve|Win32'" Label="PropertySheets">
  61.387 +    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
  61.388 +  </ImportGroup>
  61.389 +  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug - CSS|Win32'" Label="PropertySheets">
  61.390 +    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
  61.391 +  </ImportGroup>
  61.392 +  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Orange Box Valve|Win32'" Label="PropertySheets">
  61.393 +    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
  61.394 +  </ImportGroup>
  61.395 +  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - CSS|Win32'" Label="PropertySheets">
  61.396 +    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
  61.397 +  </ImportGroup>
  61.398 +  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release - Left 4 Dead|Win32'" Label="PropertySheets">
  61.399 +    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
  61.400 +  </ImportGroup>
  61.401 +  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug - Left 4 Dead|Win32'" Label="PropertySheets">
  61.402 +    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
  61.403 +  </ImportGroup>
  61.404 +  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Left 4 Dead|Win32'" Label="PropertySheets">
  61.405 +    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
  61.406 +  </ImportGroup>
  61.407 +  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release - Episode 1|Win32'" Label="PropertySheets">
  61.408 +    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
  61.409 +  </ImportGroup>
  61.410 +  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug - Episode 1|Win32'" Label="PropertySheets">
  61.411 +    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
  61.412 +  </ImportGroup>
  61.413 +  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Episode 1|Win32'" Label="PropertySheets">
  61.414 +    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
  61.415 +  </ImportGroup>
  61.416 +  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release - Orange Box|Win32'" Label="PropertySheets">
  61.417 +    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
  61.418 +  </ImportGroup>
  61.419 +  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug - Orange Box|Win32'" Label="PropertySheets">
  61.420 +    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
  61.421 +  </ImportGroup>
  61.422 +  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Orange Box|Win32'" Label="PropertySheets">
  61.423 +    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
  61.424 +  </ImportGroup>
  61.425 +  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release - Dark Messiah|Win32'" Label="PropertySheets">
  61.426 +    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
  61.427 +  </ImportGroup>
  61.428 +  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug - Dark Messiah|Win32'" Label="PropertySheets">
  61.429 +    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
  61.430 +  </ImportGroup>
  61.431 +  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Dark Messiah|Win32'" Label="PropertySheets">
  61.432 +    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
  61.433 +  </ImportGroup>
  61.434 +  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release - Bloody Good Time|Win32'" Label="PropertySheets">
  61.435 +    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
  61.436 +  </ImportGroup>
  61.437 +  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug - Bloody Good Time|Win32'" Label="PropertySheets">
  61.438 +    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
  61.439 +  </ImportGroup>
  61.440 +  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Bloody Good Time|Win32'" Label="PropertySheets">
  61.441 +    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
  61.442 +  </ImportGroup>
  61.443 +  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release - EYE|Win32'" Label="PropertySheets">
  61.444 +    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
  61.445 +  </ImportGroup>
  61.446 +  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug - EYE|Win32'" Label="PropertySheets">
  61.447 +    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
  61.448 +  </ImportGroup>
  61.449 +  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - EYE|Win32'" Label="PropertySheets">
  61.450 +    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
  61.451 +  </ImportGroup>
  61.452 +  <PropertyGroup Label="UserMacros" />
  61.453 +  <PropertyGroup>
  61.454 +    <_ProjectFileVersion>10.0.30128.1</_ProjectFileVersion>
  61.455 +    <OutDir Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Old Metamod|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
  61.456 +    <IntDir Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Old Metamod|Win32'">$(Configuration)\</IntDir>
  61.457 +    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Old Metamod|Win32'">true</LinkIncremental>
  61.458 +    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug - Old Metamod|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
  61.459 +    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug - Old Metamod|Win32'">$(Configuration)\</IntDir>
  61.460 +    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug - Old Metamod|Win32'">true</LinkIncremental>
  61.461 +    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release - Old Metamod|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
  61.462 +    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release - Old Metamod|Win32'">$(Configuration)\</IntDir>
  61.463 +    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release - Old Metamod|Win32'">false</LinkIncremental>
  61.464 +    <OutDir Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Dark Messiah|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
  61.465 +    <IntDir Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Dark Messiah|Win32'">$(Configuration)\</IntDir>
  61.466 +    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Dark Messiah|Win32'">true</LinkIncremental>
  61.467 +    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug - Dark Messiah|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
  61.468 +    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug - Dark Messiah|Win32'">$(Configuration)\</IntDir>
  61.469 +    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug - Dark Messiah|Win32'">true</LinkIncremental>
  61.470 +    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release - Dark Messiah|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
  61.471 +    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release - Dark Messiah|Win32'">$(Configuration)\</IntDir>
  61.472 +    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release - Dark Messiah|Win32'">false</LinkIncremental>
  61.473 +    <OutDir Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Orange Box|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
  61.474 +    <IntDir Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Orange Box|Win32'">$(Configuration)\</IntDir>
  61.475 +    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Orange Box|Win32'">true</LinkIncremental>
  61.476 +    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug - Orange Box|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
  61.477 +    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug - Orange Box|Win32'">$(Configuration)\</IntDir>
  61.478 +    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug - Orange Box|Win32'">true</LinkIncremental>
  61.479 +    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release - Orange Box|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
  61.480 +    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release - Orange Box|Win32'">$(Configuration)\</IntDir>
  61.481 +    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release - Orange Box|Win32'">false</LinkIncremental>
  61.482 +    <OutDir Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Episode 1|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
  61.483 +    <IntDir Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Episode 1|Win32'">$(Configuration)\</IntDir>
  61.484 +    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Episode 1|Win32'">true</LinkIncremental>
  61.485 +    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug - Episode 1|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
  61.486 +    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug - Episode 1|Win32'">$(Configuration)\</IntDir>
  61.487 +    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug - Episode 1|Win32'">true</LinkIncremental>
  61.488 +    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release - Episode 1|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
  61.489 +    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release - Episode 1|Win32'">$(Configuration)\</IntDir>
  61.490 +    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release - Episode 1|Win32'">false</LinkIncremental>
  61.491 +    <OutDir Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Left 4 Dead|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
  61.492 +    <IntDir Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Left 4 Dead|Win32'">$(Configuration)\</IntDir>
  61.493 +    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Left 4 Dead|Win32'">true</LinkIncremental>
  61.494 +    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug - Left 4 Dead|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
  61.495 +    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug - Left 4 Dead|Win32'">$(Configuration)\</IntDir>
  61.496 +    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug - Left 4 Dead|Win32'">true</LinkIncremental>
  61.497 +    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release - Left 4 Dead|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
  61.498 +    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release - Left 4 Dead|Win32'">$(Configuration)\</IntDir>
  61.499 +    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release - Left 4 Dead|Win32'">false</LinkIncremental>
  61.500 +    <OutDir Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Orange Box Valve|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
  61.501 +    <OutDir Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - CSS|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
  61.502 +    <IntDir Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Orange Box Valve|Win32'">$(Configuration)\</IntDir>
  61.503 +    <IntDir Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - CSS|Win32'">$(Configuration)\</IntDir>
  61.504 +    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Orange Box Valve|Win32'">true</LinkIncremental>
  61.505 +    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - CSS|Win32'">true</LinkIncremental>
  61.506 +    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug - Orange Box Valve|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
  61.507 +    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug - CSS|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
  61.508 +    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug - Orange Box Valve|Win32'">$(Configuration)\</IntDir>
  61.509 +    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug - CSS|Win32'">$(Configuration)\</IntDir>
  61.510 +    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug - Orange Box Valve|Win32'">true</LinkIncremental>
  61.511 +    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug - CSS|Win32'">true</LinkIncremental>
  61.512 +    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release - Orange Box Valve|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
  61.513 +    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release - CSS|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
  61.514 +    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release - Orange Box Valve|Win32'">$(Configuration)\</IntDir>
  61.515 +    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release - CSS|Win32'">$(Configuration)\</IntDir>
  61.516 +    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release - Orange Box Valve|Win32'">false</LinkIncremental>
  61.517 +    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release - CSS|Win32'">false</LinkIncremental>
  61.518 +    <OutDir Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Alien Swarm|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
  61.519 +    <IntDir Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Alien Swarm|Win32'">$(Configuration)\</IntDir>
  61.520 +    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Alien Swarm|Win32'">true</LinkIncremental>
  61.521 +    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug - Alien Swarm|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
  61.522 +    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug - Alien Swarm|Win32'">$(Configuration)\</IntDir>
  61.523 +    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug - Alien Swarm|Win32'">true</LinkIncremental>
  61.524 +    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release - Alien Swarm|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
  61.525 +    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release - Alien Swarm|Win32'">$(Configuration)\</IntDir>
  61.526 +    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release - Alien Swarm|Win32'">false</LinkIncremental>
  61.527 +    <OutDir Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - CS GO|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
  61.528 +    <IntDir Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - CS GO|Win32'">$(Configuration)\</IntDir>
  61.529 +    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - CS GO|Win32'">true</LinkIncremental>
  61.530 +    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug - CS GO|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
  61.531 +    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug - CS GO|Win32'">$(Configuration)\</IntDir>
  61.532 +    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug - CS GO|Win32'">true</LinkIncremental>
  61.533 +    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release - CS GO|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
  61.534 +    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release - CS GO|Win32'">$(Configuration)\</IntDir>
  61.535 +    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release - CS GO|Win32'">false</LinkIncremental>
  61.536 +    <OutDir Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Left 4 Dead 2|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
  61.537 +    <IntDir Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Left 4 Dead 2|Win32'">$(Configuration)\</IntDir>
  61.538 +    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Left 4 Dead 2|Win32'">true</LinkIncremental>
  61.539 +    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug - Left 4 Dead 2|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
  61.540 +    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug - Left 4 Dead 2|Win32'">$(Configuration)\</IntDir>
  61.541 +    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug - Left 4 Dead 2|Win32'">true</LinkIncremental>
  61.542 +    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release - Left 4 Dead 2|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
  61.543 +    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release - Left 4 Dead 2|Win32'">$(Configuration)\</IntDir>
  61.544 +    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release - Left 4 Dead 2|Win32'">false</LinkIncremental>
  61.545 +    <OutDir Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Bloody Good Time|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
  61.546 +    <IntDir Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Bloody Good Time|Win32'">$(Configuration)\</IntDir>
  61.547 +    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Bloody Good Time|Win32'">true</LinkIncremental>
  61.548 +    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug - Bloody Good Time|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
  61.549 +    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug - Bloody Good Time|Win32'">$(Configuration)\</IntDir>
  61.550 +    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug - Bloody Good Time|Win32'">true</LinkIncremental>
  61.551 +    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release - Bloody Good Time|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
  61.552 +    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release - Bloody Good Time|Win32'">$(Configuration)\</IntDir>
  61.553 +    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release - Bloody Good Time|Win32'">false</LinkIncremental>
  61.554 +    <OutDir Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - EYE|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
  61.555 +    <IntDir Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - EYE|Win32'">$(Configuration)\</IntDir>
  61.556 +    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - EYE|Win32'">true</LinkIncremental>
  61.557 +    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug - EYE|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
  61.558 +    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug - EYE|Win32'">$(Configuration)\</IntDir>
  61.559 +    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug - EYE|Win32'">true</LinkIncremental>
  61.560 +    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release - EYE|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
  61.561 +    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release - EYE|Win32'">$(Configuration)\</IntDir>
  61.562 +    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release - EYE|Win32'">false</LinkIncremental>
  61.563 +    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Dark Messiah|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
  61.564 +    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Dark Messiah|Win32'" />
  61.565 +    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Dark Messiah|Win32'" />
  61.566 +    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Episode 1|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
  61.567 +    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Episode 1|Win32'" />
  61.568 +    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Episode 1|Win32'" />
  61.569 +    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Alien Swarm|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
  61.570 +    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Alien Swarm|Win32'" />
  61.571 +    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Alien Swarm|Win32'" />
  61.572 +    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - CS GO|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
  61.573 +    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - CS GO|Win32'" />
  61.574 +    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - CS GO|Win32'" />
  61.575 +    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Left 4 Dead 2|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
  61.576 +    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Left 4 Dead 2|Win32'" />
  61.577 +    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Left 4 Dead 2|Win32'" />
  61.578 +    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Left 4 Dead|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
  61.579 +    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Left 4 Dead|Win32'" />
  61.580 +    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Left 4 Dead|Win32'" />
  61.581 +    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Old Metamod|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
  61.582 +    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Old Metamod|Win32'" />
  61.583 +    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Old Metamod|Win32'" />
  61.584 +    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Orange Box Valve|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
  61.585 +    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - CSS|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
  61.586 +    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Orange Box Valve|Win32'" />
  61.587 +    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - CSS|Win32'" />
  61.588 +    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Orange Box Valve|Win32'" />
  61.589 +    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - CSS|Win32'" />
  61.590 +    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Orange Box|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
  61.591 +    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Orange Box|Win32'" />
  61.592 +    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Orange Box|Win32'" />
  61.593 +    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Bloody Good Time|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
  61.594 +    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Bloody Good Time|Win32'" />
  61.595 +    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Bloody Good Time|Win32'" />
  61.596 +    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - EYE|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
  61.597 +    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - EYE|Win32'" />
  61.598 +    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - EYE|Win32'" />
  61.599 +    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug - Dark Messiah|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
  61.600 +    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug - Dark Messiah|Win32'" />
  61.601 +    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug - Dark Messiah|Win32'" />
  61.602 +    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug - Episode 1|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
  61.603 +    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug - Episode 1|Win32'" />
  61.604 +    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug - Episode 1|Win32'" />
  61.605 +    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug - Alien Swarm|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
  61.606 +    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug - Alien Swarm|Win32'" />
  61.607 +    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug - Alien Swarm|Win32'" />
  61.608 +    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug - CS GO|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
  61.609 +    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug - CS GO|Win32'" />
  61.610 +    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug - CS GO|Win32'" />
  61.611 +    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug - Left 4 Dead 2|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
  61.612 +    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug - Left 4 Dead 2|Win32'" />
  61.613 +    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug - Left 4 Dead 2|Win32'" />
  61.614 +    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug - Left 4 Dead|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
  61.615 +    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug - Left 4 Dead|Win32'" />
  61.616 +    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug - Left 4 Dead|Win32'" />
  61.617 +    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug - Old Metamod|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
  61.618 +    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug - Old Metamod|Win32'" />
  61.619 +    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug - Old Metamod|Win32'" />
  61.620 +    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug - Orange Box Valve|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
  61.621 +    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug - CSS|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
  61.622 +    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug - Orange Box Valve|Win32'" />
  61.623 +    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug - CSS|Win32'" />
  61.624 +    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug - Orange Box Valve|Win32'" />
  61.625 +    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug - CSS|Win32'" />
  61.626 +    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug - Orange Box|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
  61.627 +    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug - Orange Box|Win32'" />
  61.628 +    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug - Orange Box|Win32'" />
  61.629 +    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug - Bloody Good Time|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
  61.630 +    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug - Bloody Good Time|Win32'" />
  61.631 +    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug - Bloody Good Time|Win32'" />
  61.632 +    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug - EYE|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
  61.633 +    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug - EYE|Win32'" />
  61.634 +    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug - EYE|Win32'" />
  61.635 +    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release - Dark Messiah|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
  61.636 +    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release - Dark Messiah|Win32'" />
  61.637 +    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release - Dark Messiah|Win32'" />
  61.638 +    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release - Episode 1|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
  61.639 +    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release - Episode 1|Win32'" />
  61.640 +    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release - Episode 1|Win32'" />
  61.641 +    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release - Alien Swarm|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
  61.642 +    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release - Alien Swarm|Win32'" />
  61.643 +    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release - Alien Swarm|Win32'" />
  61.644 +    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release - CS GO|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
  61.645 +    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release - CS GO|Win32'" />
  61.646 +    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release - CS GO|Win32'" />
  61.647 +    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release - Left 4 Dead 2|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
  61.648 +    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release - Left 4 Dead 2|Win32'" />
  61.649 +    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release - Left 4 Dead 2|Win32'" />
  61.650 +    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release - Left 4 Dead|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
  61.651 +    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release - Left 4 Dead|Win32'" />
  61.652 +    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release - Left 4 Dead|Win32'" />
  61.653 +    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release - Old Metamod|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
  61.654 +    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release - Old Metamod|Win32'" />
  61.655 +    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release - Old Metamod|Win32'" />
  61.656 +    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release - Orange Box Valve|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
  61.657 +    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release - CSS|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
  61.658 +    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release - Orange Box Valve|Win32'" />
  61.659 +    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release - CSS|Win32'" />
  61.660 +    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release - Orange Box Valve|Win32'" />
  61.661 +    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release - CSS|Win32'" />
  61.662 +    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release - Orange Box|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
  61.663 +    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release - Orange Box|Win32'" />
  61.664 +    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release - Orange Box|Win32'" />
  61.665 +    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release - Bloody Good Time|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
  61.666 +    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release - Bloody Good Time|Win32'" />
  61.667 +    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release - Bloody Good Time|Win32'" />
  61.668 +    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release - EYE|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
  61.669 +    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release - EYE|Win32'" />
  61.670 +    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release - EYE|Win32'" />
  61.671 +    <TargetName Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Alien Swarm|Win32'">sourcemod.2.swarm</TargetName>
  61.672 +    <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug - Alien Swarm|Win32'">sourcemod.2.swarm</TargetName>
  61.673 +    <TargetName Condition="'$(Configuration)|$(Platform)'=='Release - Alien Swarm|Win32'">sourcemod.2.swarm</TargetName>
  61.674 +    <TargetName Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Bloody Good Time|Win32'">sourcemod.2.bgt</TargetName>
  61.675 +    <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug - Bloody Good Time|Win32'">sourcemod.2.bgt</TargetName>
  61.676 +    <TargetName Condition="'$(Configuration)|$(Platform)'=='Release - Bloody Good Time|Win32'">sourcemod.2.bgt</TargetName>
  61.677 +    <TargetName Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - CS GO|Win32'">sourcemod.2.csgo</TargetName>
  61.678 +    <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug - CS GO|Win32'">sourcemod.2.csgo</TargetName>
  61.679 +    <TargetName Condition="'$(Configuration)|$(Platform)'=='Release - CS GO|Win32'">sourcemod.2.csgo</TargetName>
  61.680 +    <TargetName Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Episode 1|Win32'">sourcemod.2.ep1</TargetName>
  61.681 +    <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug - Episode 1|Win32'">sourcemod.2.ep1</TargetName>
  61.682 +    <TargetName Condition="'$(Configuration)|$(Platform)'=='Release - Episode 1|Win32'">sourcemod.2.ep1</TargetName>
  61.683 +    <TargetName Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - EYE|Win32'">sourcemod.2.eye</TargetName>
  61.684 +    <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug - EYE|Win32'">sourcemod.2.eye</TargetName>
  61.685 +    <TargetName Condition="'$(Configuration)|$(Platform)'=='Release - EYE|Win32'">sourcemod.2.eye</TargetName>
  61.686 +    <TargetName Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Left 4 Dead|Win32'">sourcemod.2.l4d</TargetName>
  61.687 +    <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug - Left 4 Dead|Win32'">sourcemod.2.l4d</TargetName>
  61.688 +    <TargetName Condition="'$(Configuration)|$(Platform)'=='Release - Left 4 Dead|Win32'">sourcemod.2.l4d</TargetName>
  61.689 +    <TargetName Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Left 4 Dead 2|Win32'">sourcemod.2.l4d2</TargetName>
  61.690 +    <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug - Left 4 Dead 2|Win32'">sourcemod.2.l4d2</TargetName>
  61.691 +    <TargetName Condition="'$(Configuration)|$(Platform)'=='Release - Left 4 Dead 2|Win32'">sourcemod.2.l4d2</TargetName>
  61.692 +    <TargetName Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Old Metamod|Win32'">sourcemod.1.ep1</TargetName>
  61.693 +    <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug - Old Metamod|Win32'">sourcemod.1.ep1</TargetName>
  61.694 +    <TargetName Condition="'$(Configuration)|$(Platform)'=='Release - Old Metamod|Win32'">sourcemod.1.ep1</TargetName>
  61.695 +    <TargetName Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Orange Box|Win32'">sourcemod.2.ep2</TargetName>
  61.696 +    <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug - Orange Box|Win32'">sourcemod.2.ep2</TargetName>
  61.697 +    <TargetName Condition="'$(Configuration)|$(Platform)'=='Release - Orange Box|Win32'">sourcemod.2.ep2</TargetName>
  61.698 +    <TargetName Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Orange Box Valve|Win32'">sourcemod.2.ep2v</TargetName>
  61.699 +    <TargetName Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - CSS|Win32'">sourcemod.2.css</TargetName>
  61.700 +    <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug - Orange Box Valve|Win32'">sourcemod.2.ep2v</TargetName>
  61.701 +    <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug - CSS|Win32'">sourcemod.2.css</TargetName>
  61.702 +    <TargetName Condition="'$(Configuration)|$(Platform)'=='Release - Orange Box Valve|Win32'">sourcemod.2.ep2v</TargetName>
  61.703 +    <TargetName Condition="'$(Configuration)|$(Platform)'=='Release - CSS|Win32'">sourcemod.2.css</TargetName>
  61.704 +  </PropertyGroup>
  61.705 +  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release - Dark Messiah|Win32'">
  61.706 +    <TargetName>sourcemod.2.darkm</TargetName>
  61.707 +  </PropertyGroup>
  61.708 +  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug - Dark Messiah|Win32'">
  61.709 +    <TargetName>sourcemod.2.darkm</TargetName>
  61.710 +  </PropertyGroup>
  61.711 +  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Dark Messiah|Win32'">
  61.712 +    <TargetName>sourcemod.2.darkm</TargetName>
  61.713 +  </PropertyGroup>
  61.714 +  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Old Metamod|Win32'">
  61.715 +    <ClCompile>
  61.716 +      <AdditionalOptions>/D SE_EPISODEONE=1 /D SE_DARKMESSIAH=2 /D SE_ORANGEBOX=3 /D SE_BLOODYGOODTIME=4 /D SE_EYE=5 /D SE_CSS=6 /D SE_ORANGEBOXVALVE=7 /D SE_LEFT4DEAD=8 /D SE_LEFT4DEAD2=9 /D SE_ALIENSWARM=10 /D SE_PORTAL2=11 /D SE_CSGO=12</AdditionalOptions>
  61.717 +      <Optimization>Disabled</Optimization>
  61.718 +      <AdditionalIncludeDirectories>..\;..\systems;..\..\public;..\..\public\sourcepawn;$(HL2SDK)\public;$(HL2SDK)\public\dlls;$(HL2SDK)\public\engine;$(HL2SDK)\public\mathlib;$(HL2SDK)\public\tier0;$(HL2SDK)\public\tier1;$(HL2SDK)\public\vstdlib;$(MMSOURCE19)\core-legacy;$(MMSOURCE19)\core-legacy\sourcehook;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
  61.719 +      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;SOURCEMOD_MM_EXPORTS;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;SOURCEMOD_BUILD;SM_DEFAULT_THREADER;SOURCE_ENGINE=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
  61.720 +      <MinimalRebuild>true</MinimalRebuild>
  61.721 +      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
  61.722 +      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
  61.723 +      <EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
  61.724 +      <RuntimeTypeInfo>false</RuntimeTypeInfo>
  61.725 +      <PrecompiledHeader>
  61.726 +      </PrecompiledHeader>
  61.727 +      <WarningLevel>Level3</WarningLevel>
  61.728 +      <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
  61.729 +    </ClCompile>
  61.730 +    <ResourceCompile>
  61.731 +      <PreprocessorDefinitions>BINARY_NAME="\"$(TargetFileName)\"";%(PreprocessorDefinitions)</PreprocessorDefinitions>
  61.732 +      <AdditionalIncludeDirectories>..\..\public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
  61.733 +    </ResourceCompile>
  61.734 +    <Link>
  61.735 +      <AdditionalDependencies>$(HL2SDK)\lib\public\tier0.lib;$(HL2SDK)\lib\public\tier1.lib;$(HL2SDK)\lib\public\vstdlib.lib;$(HL2SDK)\lib\public\mathlib.lib;dbghelp.lib;Wsock32.lib;%(AdditionalDependencies)</AdditionalDependencies>
  61.736 +      <OutputFile>$(OutDir)$(TargetFileName)</OutputFile>
  61.737 +      <IgnoreSpecificDefaultLibraries>LIBC;LIBCD;LIBCMT;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
  61.738 +      <GenerateDebugInformation>true</GenerateDebugInformation>
  61.739 +      <SubSystem>Windows</SubSystem>
  61.740 +      <RandomizedBaseAddress>false</RandomizedBaseAddress>
  61.741 +      <DataExecutionPrevention>
  61.742 +      </DataExecutionPrevention>
  61.743 +      <TargetMachine>MachineX86</TargetMachine>
  61.744 +    </Link>
  61.745 +    <PostBuildEvent>
  61.746 +      <Command>IF NOT "%SMOUTDIR%"=="" copy /Y "$(TargetDir)$(TargetFileName)" "%SMOUTDIR%\bin"</Command>
  61.747 +    </PostBuildEvent>
  61.748 +  </ItemDefinitionGroup>
  61.749 +  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug - Old Metamod|Win32'">
  61.750 +    <ClCompile>
  61.751 +      <AdditionalOptions>/D SE_EPISODEONE=1 /D SE_DARKMESSIAH=2 /D SE_ORANGEBOX=3 /D SE_BLOODYGOODTIME=4 /D SE_EYE=5 /D SE_CSS=6 /D SE_ORANGEBOXVALVE=7 /D SE_LEFT4DEAD=8 /D SE_LEFT4DEAD2=9 /D SE_ALIENSWARM=10 /D SE_PORTAL2=11 /D SE_CSGO=12</AdditionalOptions>
  61.752 +      <Optimization>Disabled</Optimization>
  61.753 +      <AdditionalIncludeDirectories>..\;..\systems;..\..\public;..\..\public\sourcepawn;$(HL2SDK)\public;$(HL2SDK)\public\dlls;$(HL2SDK)\public\engine;$(HL2SDK)\public\mathlib;$(HL2SDK)\public\tier0;$(HL2SDK)\public\tier1;$(HL2SDK)\public\vstdlib;$(MMSOURCE19)\core-legacy;$(MMSOURCE19)\core-legacy\sourcehook;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
  61.754 +      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;SOURCEMOD_MM_EXPORTS;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;SOURCEMOD_BUILD;SM_DEFAULT_THREADER;SOURCE_ENGINE=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
  61.755 +      <MinimalRebuild>true</MinimalRebuild>
  61.756 +      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
  61.757 +      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
  61.758 +      <EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
  61.759 +      <RuntimeTypeInfo>false</RuntimeTypeInfo>
  61.760 +      <PrecompiledHeader>
  61.761 +      </PrecompiledHeader>
  61.762 +      <WarningLevel>Level3</WarningLevel>
  61.763 +      <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
  61.764 +    </ClCompile>
  61.765 +    <ResourceCompile>
  61.766 +      <PreprocessorDefinitions>BINARY_NAME="\"$(TargetFileName)\"";%(PreprocessorDefinitions)</PreprocessorDefinitions>
  61.767 +      <AdditionalIncludeDirectories>..\..\public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
  61.768 +    </ResourceCompile>
  61.769 +    <Link>
  61.770 +      <AdditionalDependencies>$(HL2SDK)\lib\public\tier0.lib;$(HL2SDK)\lib\public\tier1.lib;$(HL2SDK)\lib\public\vstdlib.lib;$(HL2SDK)\lib\public\mathlib.lib;Wsock32.lib;%(AdditionalDependencies)</AdditionalDependencies>
  61.771 +      <OutputFile>$(OutDir)$(TargetFileName)</OutputFile>
  61.772 +      <IgnoreSpecificDefaultLibraries>LIBC;LIBCD;LIBCMT;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
  61.773 +      <GenerateDebugInformation>true</GenerateDebugInformation>
  61.774 +      <SubSystem>Windows</SubSystem>
  61.775 +      <RandomizedBaseAddress>false</RandomizedBaseAddress>
  61.776 +      <DataExecutionPrevention>
  61.777 +      </DataExecutionPrevention>
  61.778 +      <TargetMachine>MachineX86</TargetMachine>
  61.779 +    </Link>
  61.780 +    <PostBuildEvent>
  61.781 +      <Command>IF NOT "%SMOUTDIR%"=="" copy /Y "$(TargetDir)$(TargetFileName)" "%SMOUTDIR%\bin"</Command>
  61.782 +    </PostBuildEvent>
  61.783 +  </ItemDefinitionGroup>
  61.784 +  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release - Old Metamod|Win32'">
  61.785 +    <ClCompile>
  61.786 +      <AdditionalOptions>/D SE_EPISODEONE=1 /D SE_DARKMESSIAH=2 /D SE_ORANGEBOX=3 /D SE_BLOODYGOODTIME=4 /D SE_EYE=5 /D SE_CSS=6 /D SE_ORANGEBOXVALVE=7 /D SE_LEFT4DEAD=8 /D SE_LEFT4DEAD2=9 /D SE_ALIENSWARM=10 /D SE_PORTAL2=11 /D SE_CSGO=12</AdditionalOptions>
  61.787 +      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
  61.788 +      <AdditionalIncludeDirectories>..\;..\systems;..\..\public;..\..\public\sourcepawn;$(HL2SDK)\public;$(HL2SDK)\public\dlls;$(HL2SDK)\public\engine;$(HL2SDK)\public\mathlib;$(HL2SDK)\public\tier0;$(HL2SDK)\public\tier1;$(HL2SDK)\public\vstdlib;$(MMSOURCE19)\core-legacy;$(MMSOURCE19)\core-legacy\sourcehook;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
  61.789 +      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;SOURCEMOD_MM_EXPORTS;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;SOURCEMOD_BUILD;SM_DEFAULT_THREADER;SOURCE_ENGINE=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
  61.790 +      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
  61.791 +      <EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
  61.792 +      <RuntimeTypeInfo>false</RuntimeTypeInfo>
  61.793 +      <PrecompiledHeader>
  61.794 +      </PrecompiledHeader>
  61.795 +      <WarningLevel>Level3</WarningLevel>
  61.796 +      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
  61.797 +      <MultiProcessorCompilation>true</MultiProcessorCompilation>
  61.798 +    </ClCompile>
  61.799 +    <ResourceCompile>
  61.800 +      <PreprocessorDefinitions>BINARY_NAME="\"$(TargetFileName)\"";%(PreprocessorDefinitions)</PreprocessorDefinitions>
  61.801 +      <AdditionalIncludeDirectories>..\..\public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
  61.802 +    </ResourceCompile>
  61.803 +    <Link>
  61.804 +      <AdditionalDependencies>$(HL2SDK)\lib\public\tier0.lib;$(HL2SDK)\lib\public\tier1.lib;$(HL2SDK)\lib\public\vstdlib.lib;$(HL2SDK)\lib\public\mathlib.lib;Wsock32.lib;%(AdditionalDependencies)</AdditionalDependencies>
  61.805 +      <OutputFile>$(OutDir)$(TargetFileName)</OutputFile>
  61.806 +      <IgnoreSpecificDefaultLibraries>LIBC;LIBCD;LIBCMTD;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
  61.807 +      <GenerateDebugInformation>true</GenerateDebugInformation>
  61.808 +      <SubSystem>Windows</SubSystem>
  61.809 +      <OptimizeReferences>true</OptimizeReferences>
  61.810 +      <EnableCOMDATFolding>true</EnableCOMDATFolding>
  61.811 +      <RandomizedBaseAddress>false</RandomizedBaseAddress>
  61.812 +      <DataExecutionPrevention>
  61.813 +      </DataExecutionPrevention>
  61.814 +      <TargetMachine>MachineX86</TargetMachine>
  61.815 +    </Link>
  61.816 +    <PostBuildEvent>
  61.817 +      <Command>IF NOT "%SMOUTDIR%"=="" copy /Y "$(TargetDir)$(TargetFileName)" "%SMOUTDIR%\bin"</Command>
  61.818 +    </PostBuildEvent>
  61.819 +  </ItemDefinitionGroup>
  61.820 +  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Dark Messiah|Win32'">
  61.821 +    <ClCompile>
  61.822 +      <AdditionalOptions>/D SE_EPISODEONE=1 /D SE_DARKMESSIAH=2 /D SE_ORANGEBOX=3 /D SE_BLOODYGOODTIME=4 /D SE_EYE=5 /D SE_CSS=6 /D SE_ORANGEBOXVALVE=7 /D SE_LEFT4DEAD=8 /D SE_LEFT4DEAD2=9 /D SE_ALIENSWARM=10 /D SE_PORTAL2=11 /D SE_CSGO=12</AdditionalOptions>
  61.823 +      <Optimization>Disabled</Optimization>
  61.824 +      <AdditionalIncludeDirectories>..\;..\systems;..\..\public;..\..\public\sourcepawn;$(HL2SDK-DARKM)\public;$(HL2SDK-DARKM)\public\dlls;$(HL2SDK-DARKM)\public\engine;$(HL2SDK-DARKM)\public\mathlib;$(HL2SDK-DARKM)\public\tier0;$(HL2SDK-DARKM)\public\tier1;$(HL2SDK-DARKM)\public\vstdlib;$(MMSOURCE19)\core;$(MMSOURCE19)\core\sourcehook;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
  61.825 +      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;SOURCEMOD_MM_EXPORTS;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;SOURCEMOD_BUILD;SM_DEFAULT_THREADER;SOURCE_ENGINE=2;%(PreprocessorDefinitions)</PreprocessorDefinitions>
  61.826 +      <MinimalRebuild>true</MinimalRebuild>
  61.827 +      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
  61.828 +      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
  61.829 +      <EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
  61.830 +      <RuntimeTypeInfo>false</RuntimeTypeInfo>
  61.831 +      <PrecompiledHeader>
  61.832 +      </PrecompiledHeader>
  61.833 +      <WarningLevel>Level3</WarningLevel>
  61.834 +      <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
  61.835 +    </ClCompile>
  61.836 +    <ResourceCompile>
  61.837 +      <PreprocessorDefinitions>BINARY_NAME="\"$(TargetFileName)\"";%(PreprocessorDefinitions)</PreprocessorDefinitions>
  61.838 +      <AdditionalIncludeDirectories>..\..\public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
  61.839 +    </ResourceCompile>
  61.840 +    <Link>
  61.841 +      <AdditionalDependencies>$(HL2SDK-DARKM)\lib\public\tier0.lib;$(HL2SDK-DARKM)\lib\public\tier1.lib;$(HL2SDK-DARKM)\lib\public\vstdlib.lib;$(HL2SDK-DARKM)\lib\public\mathlib.lib;dbghelp.lib;Wsock32.lib;%(AdditionalDependencies)</AdditionalDependencies>
  61.842 +      <OutputFile>$(OutDir)$(TargetFileName)</OutputFile>
  61.843 +      <IgnoreSpecificDefaultLibraries>LIBC;LIBCD;LIBCMT;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
  61.844 +      <GenerateDebugInformation>true</GenerateDebugInformation>
  61.845 +      <SubSystem>Windows</SubSystem>
  61.846 +      <RandomizedBaseAddress>false</RandomizedBaseAddress>
  61.847 +      <DataExecutionPrevention>
  61.848 +      </DataExecutionPrevention>
  61.849 +      <TargetMachine>MachineX86</TargetMachine>
  61.850 +    </Link>
  61.851 +    <PostBuildEvent>
  61.852 +      <Command>IF NOT "%SMOUTDIR%"=="" copy /Y "$(TargetDir)$(TargetFileName)" "%SMOUTDIR%\bin"</Command>
  61.853 +    </PostBuildEvent>
  61.854 +  </ItemDefinitionGroup>
  61.855 +  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug - Dark Messiah|Win32'">
  61.856 +    <ClCompile>
  61.857 +      <AdditionalOptions>/D SE_EPISODEONE=1 /D SE_DARKMESSIAH=2 /D SE_ORANGEBOX=3 /D SE_BLOODYGOODTIME=4 /D SE_EYE=5 /D SE_CSS=6 /D SE_ORANGEBOXVALVE=7 /D SE_LEFT4DEAD=8 /D SE_LEFT4DEAD2=9 /D SE_ALIENSWARM=10 /D SE_PORTAL2=11 /D SE_CSGO=12</AdditionalOptions>
  61.858 +      <Optimization>Disabled</Optimization>
  61.859 +      <AdditionalIncludeDirectories>..\;..\systems;..\..\public;..\..\public\sourcepawn;$(HL2SDK-DARKM)\public;$(HL2SDK-DARKM)\public\dlls;$(HL2SDK-DARKM)\public\engine;$(HL2SDK-DARKM)\public\mathlib;$(HL2SDK-DARKM)\public\tier0;$(HL2SDK-DARKM)\public\tier1;$(HL2SDK-DARKM)\public\vstdlib;$(MMSOURCE19)\core;$(MMSOURCE19)\core\sourcehook;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
  61.860 +      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;SOURCEMOD_MM_EXPORTS;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;SOURCEMOD_BUILD;SM_DEFAULT_THREADER;SOURCE_ENGINE=2;%(PreprocessorDefinitions)</PreprocessorDefinitions>
  61.861 +      <MinimalRebuild>true</MinimalRebuild>
  61.862 +      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
  61.863 +      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
  61.864 +      <EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
  61.865 +      <RuntimeTypeInfo>false</RuntimeTypeInfo>
  61.866 +      <PrecompiledHeader>
  61.867 +      </PrecompiledHeader>
  61.868 +      <WarningLevel>Level3</WarningLevel>
  61.869 +      <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
  61.870 +    </ClCompile>
  61.871 +    <ResourceCompile>
  61.872 +      <PreprocessorDefinitions>BINARY_NAME="\"$(TargetFileName)\"";%(PreprocessorDefinitions)</PreprocessorDefinitions>
  61.873 +      <AdditionalIncludeDirectories>..\..\public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
  61.874 +    </ResourceCompile>
  61.875 +    <Link>
  61.876 +      <AdditionalDependencies>$(HL2SDK-DARKM)\lib\public\tier0.lib;$(HL2SDK-DARKM)\lib\public\tier1.lib;$(HL2SDK-DARKM)\lib\public\vstdlib.lib;$(HL2SDK-DARKM)\lib\public\mathlib.lib;Wsock32.lib;%(AdditionalDependencies)</AdditionalDependencies>
  61.877 +      <OutputFile>$(OutDir)$(TargetFileName)</OutputFile>
  61.878 +      <IgnoreSpecificDefaultLibraries>LIBC;LIBCD;LIBCMT;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
  61.879 +      <GenerateDebugInformation>true</GenerateDebugInformation>
  61.880 +      <SubSystem>Windows</SubSystem>
  61.881 +      <RandomizedBaseAddress>false</RandomizedBaseAddress>
  61.882 +      <DataExecutionPrevention>
  61.883 +      </DataExecutionPrevention>
  61.884 +      <TargetMachine>MachineX86</TargetMachine>
  61.885 +    </Link>
  61.886 +    <PostBuildEvent>
  61.887 +      <Command>IF NOT "%SMOUTDIR%"=="" copy /Y "$(TargetDir)$(TargetFileName)" "%SMOUTDIR%\bin"</Command>
  61.888 +    </PostBuildEvent>
  61.889 +  </ItemDefinitionGroup>
  61.890 +  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release - Dark Messiah|Win32'">
  61.891 +    <ClCompile>
  61.892 +      <AdditionalOptions>/D SE_EPISODEONE=1 /D SE_DARKMESSIAH=2 /D SE_ORANGEBOX=3 /D SE_BLOODYGOODTIME=4 /D SE_EYE=5 /D SE_CSS=6 /D SE_ORANGEBOXVALVE=7 /D SE_LEFT4DEAD=8 /D SE_LEFT4DEAD2=9 /D SE_ALIENSWARM=10 /D SE_PORTAL2=11 /D SE_CSGO=12</AdditionalOptions>
  61.893 +      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
  61.894 +      <AdditionalIncludeDirectories>..\;..\systems;..\..\public;..\..\public\sourcepawn;$(HL2SDK-DARKM)\public;$(HL2SDK-DARKM)\public\dlls;$(HL2SDK-DARKM)\public\engine;$(HL2SDK-DARKM)\public\mathlib;$(HL2SDK-DARKM)\public\tier0;$(HL2SDK-DARKM)\public\tier1;$(HL2SDK-DARKM)\public\vstdlib;$(MMSOURCE19)\core;$(MMSOURCE19)\core\sourcehook;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
  61.895 +      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;SOURCEMOD_MM_EXPORTS;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;SOURCEMOD_BUILD;SM_DEFAULT_THREADER;SOURCE_ENGINE=2;%(PreprocessorDefinitions)</PreprocessorDefinitions>
  61.896 +      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
  61.897 +      <EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
  61.898 +      <RuntimeTypeInfo>false</RuntimeTypeInfo>
  61.899 +      <PrecompiledHeader>
  61.900 +      </PrecompiledHeader>
  61.901 +      <WarningLevel>Level3</WarningLevel>
  61.902 +      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
  61.903 +      <MultiProcessorCompilation>true</MultiProcessorCompilation>
  61.904 +    </ClCompile>
  61.905 +    <ResourceCompile>
  61.906 +      <PreprocessorDefinitions>BINARY_NAME="\"$(TargetFileName)\"";%(PreprocessorDefinitions)</PreprocessorDefinitions>
  61.907 +      <AdditionalIncludeDirectories>..\..\public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
  61.908 +    </ResourceCompile>
  61.909 +    <Link>
  61.910 +      <AdditionalDependencies>$(HL2SDK-DARKM)\lib\public\tier0.lib;$(HL2SDK-DARKM)\lib\public\tier1.lib;$(HL2SDK-DARKM)\lib\public\vstdlib.lib;$(HL2SDK-DARKM)\lib\public\mathlib.lib;Wsock32.lib;%(AdditionalDependencies)</AdditionalDependencies>
  61.911 +      <OutputFile>$(OutDir)$(TargetFileName)</OutputFile>
  61.912 +      <IgnoreSpecificDefaultLibraries>LIBC;LIBCD;LIBCMTD;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
  61.913 +      <GenerateDebugInformation>true</GenerateDebugInformation>
  61.914 +      <SubSystem>Windows</SubSystem>
  61.915 +      <OptimizeReferences>true</OptimizeReferences>
  61.916 +      <EnableCOMDATFolding>true</EnableCOMDATFolding>
  61.917 +      <RandomizedBaseAddress>false</RandomizedBaseAddress>
  61.918 +      <DataExecutionPrevention>
  61.919 +      </DataExecutionPrevention>
  61.920 +      <TargetMachine>MachineX86</TargetMachine>
  61.921 +    </Link>
  61.922 +    <PostBuildEvent>
  61.923 +      <Command>IF NOT "%SMOUTDIR%"=="" copy /Y "$(TargetDir)$(TargetFileName)" "%SMOUTDIR%\bin"</Command>
  61.924 +    </PostBuildEvent>
  61.925 +  </ItemDefinitionGroup>
  61.926 +  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Orange Box|Win32'">
  61.927 +    <ClCompile>
  61.928 +      <AdditionalOptions>/D SE_EPISODEONE=1 /D SE_DARKMESSIAH=2 /D SE_ORANGEBOX=3 /D SE_BLOODYGOODTIME=4 /D SE_EYE=5 /D SE_CSS=6 /D SE_ORANGEBOXVALVE=7 /D SE_LEFT4DEAD=8 /D SE_LEFT4DEAD2=9 /D SE_ALIENSWARM=10 /D SE_PORTAL2=11 /D SE_CSGO=12</AdditionalOptions>
  61.929 +      <Optimization>Disabled</Optimization>
  61.930 +      <AdditionalIncludeDirectories>..\;..\systems;..\..\public;..\..\public\sourcepawn;$(HL2SDKOB)\public;$(HL2SDKOB)\public\engine;$(HL2SDKOB)\public\game\server;$(HL2SDKOB)\public\mathlib;$(HL2SDKOB)\public\tier0;$(HL2SDKOB)\public\tier1;$(HL2SDKOB)\public\vstdlib;$(MMSOURCE19)\core;$(MMSOURCE19)\core\sourcehook;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
  61.931 +      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;SOURCEMOD_MM_EXPORTS;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;SOURCEMOD_BUILD;SM_DEFAULT_THREADER;SOURCE_ENGINE=3;%(PreprocessorDefinitions)</PreprocessorDefinitions>
  61.932 +      <MinimalRebuild>true</MinimalRebuild>
  61.933 +      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
  61.934 +      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
  61.935 +      <EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
  61.936 +      <RuntimeTypeInfo>false</RuntimeTypeInfo>
  61.937 +      <PrecompiledHeader>
  61.938 +      </PrecompiledHeader>
  61.939 +      <WarningLevel>Level3</WarningLevel>
  61.940 +      <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
  61.941 +    </ClCompile>
  61.942 +    <ResourceCompile>
  61.943 +      <PreprocessorDefinitions>BINARY_NAME="\"$(TargetFileName)\"";%(PreprocessorDefinitions)</PreprocessorDefinitions>
  61.944 +      <AdditionalIncludeDirectories>..\..\public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
  61.945 +    </ResourceCompile>
  61.946 +    <Link>
  61.947 +      <AdditionalDependencies>$(HL2SDKOB)\lib\public\tier0.lib;$(HL2SDKOB)\lib\public\tier1.lib;$(HL2SDKOB)\lib\public\vstdlib.lib;$(HL2SDKOB)\lib\public\mathlib.lib;dbghelp.lib;Wsock32.lib;%(AdditionalDependencies)</AdditionalDependencies>
  61.948 +      <OutputFile>$(OutDir)$(TargetFileName)</OutputFile>
  61.949 +      <IgnoreSpecificDefaultLibraries>LIBC;LIBCD;LIBCMT;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
  61.950 +      <GenerateDebugInformation>true</GenerateDebugInformation>
  61.951 +      <SubSystem>Windows</SubSystem>
  61.952 +      <RandomizedBaseAddress>false</RandomizedBaseAddress>
  61.953 +      <DataExecutionPrevention>
  61.954 +      </DataExecutionPrevention>
  61.955 +      <TargetMachine>MachineX86</TargetMachine>
  61.956 +    </Link>
  61.957 +    <PostBuildEvent>
  61.958 +      <Command>IF NOT "%SMOUTDIR%"=="" copy /Y "$(TargetDir)$(TargetFileName)" "%SMOUTDIR%\bin"</Command>
  61.959 +    </PostBuildEvent>
  61.960 +  </ItemDefinitionGroup>
  61.961 +  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug - Orange Box|Win32'">
  61.962 +    <ClCompile>
  61.963 +      <AdditionalOptions>/D SE_EPISODEONE=1 /D SE_DARKMESSIAH=2 /D SE_ORANGEBOX=3 /D SE_BLOODYGOODTIME=4 /D SE_EYE=5 /D SE_CSS=6 /D SE_ORANGEBOXVALVE=7 /D SE_LEFT4DEAD=8 /D SE_LEFT4DEAD2=9 /D SE_ALIENSWARM=10 /D SE_PORTAL2=11 /D SE_CSGO=12</AdditionalOptions>
  61.964 +      <Optimization>Disabled</Optimization>
  61.965 +      <AdditionalIncludeDirectories>..\;..\systems;..\..\public;..\..\public\sourcepawn;$(HL2SDKOB)\public;$(HL2SDKOB)\public\engine;$(HL2SDKOB)\public\game\server;$(HL2SDKOB)\public\mathlib;$(HL2SDKOB)\public\tier0;$(HL2SDKOB)\public\tier1;$(HL2SDKOB)\public\vstdlib;$(MMSOURCE19)\core;$(MMSOURCE19)\core\sourcehook;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
  61.966 +      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;SOURCEMOD_MM_EXPORTS;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;SOURCEMOD_BUILD;SM_DEFAULT_THREADER;SOURCE_ENGINE=3;%(PreprocessorDefinitions)</PreprocessorDefinitions>
  61.967 +      <MinimalRebuild>true</MinimalRebuild>
  61.968 +      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
  61.969 +      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
  61.970 +      <EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
  61.971 +      <RuntimeTypeInfo>false</RuntimeTypeInfo>
  61.972 +      <PrecompiledHeader>
  61.973 +      </PrecompiledHeader>
  61.974 +      <WarningLevel>Level3</WarningLevel>
  61.975 +      <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
  61.976 +    </ClCompile>
  61.977 +    <ResourceCompile>
  61.978 +      <PreprocessorDefinitions>BINARY_NAME="\"$(TargetFileName)\"";%(PreprocessorDefinitions)</PreprocessorDefinitions>
  61.979 +      <AdditionalIncludeDirectories>..\..\public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
  61.980 +    </ResourceCompile>
  61.981 +    <Link>
  61.982 +      <AdditionalDependencies>$(HL2SDKOB)\lib\public\tier0.lib;$(HL2SDKOB)\lib\public\tier1.lib;$(HL2SDKOB)\lib\public\vstdlib.lib;$(HL2SDKOB)\lib\public\mathlib.lib;Wsock32.lib;%(AdditionalDependencies)</AdditionalDependencies>
  61.983 +      <OutputFile>$(OutDir)$(TargetFileName)</OutputFile>
  61.984 +      <IgnoreSpecificDefaultLibraries>LIBC;LIBCD;LIBCMT;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
  61.985 +      <GenerateDebugInformation>true</GenerateDebugInformation>
  61.986 +      <SubSystem>Windows</SubSystem>
  61.987 +      <RandomizedBaseAddress>false</RandomizedBaseAddress>
  61.988 +      <DataExecutionPrevention>
  61.989 +      </DataExecutionPrevention>
  61.990 +      <TargetMachine>MachineX86</TargetMachine>
  61.991 +    </Link>
  61.992 +    <PostBuildEvent>
  61.993 +      <Command>IF NOT "%SMOUTDIR%"=="" copy /Y "$(TargetDir)$(TargetFileName)" "%SMOUTDIR%\bin"</Command>
  61.994 +    </PostBuildEvent>
  61.995 +  </ItemDefinitionGroup>
  61.996 +  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release - Orange Box|Win32'">
  61.997 +    <ClCompile>
  61.998 +      <AdditionalOptions>/D SE_EPISODEONE=1 /D SE_DARKMESSIAH=2 /D SE_ORANGEBOX=3 /D SE_BLOODYGOODTIME=4 /D SE_EYE=5 /D SE_CSS=6 /D SE_ORANGEBOXVALVE=7 /D SE_LEFT4DEAD=8 /D SE_LEFT4DEAD2=9 /D SE_ALIENSWARM=10 /D SE_PORTAL2=11 /D SE_CSGO=12</AdditionalOptions>
  61.999 +      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
 61.1000 +      <AdditionalIncludeDirectories>..\;..\systems;..\..\public;..\..\public\sourcepawn;$(HL2SDKOB)\public;$(HL2SDKOB)\public\engine;$(HL2SDKOB)\public\game\server;$(HL2SDKOB)\public\mathlib;$(HL2SDKOB)\public\tier0;$(HL2SDKOB)\public\tier1;$(HL2SDKOB)\public\vstdlib;$(MMSOURCE19)\core;$(MMSOURCE19)\core\sourcehook;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
 61.1001 +      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;SOURCEMOD_MM_EXPORTS;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;SOURCEMOD_BUILD;SM_DEFAULT_THREADER;SOURCE_ENGINE=3;%(PreprocessorDefinitions)</PreprocessorDefinitions>
 61.1002 +      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
 61.1003 +      <EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
 61.1004 +      <RuntimeTypeInfo>false</RuntimeTypeInfo>
 61.1005 +      <PrecompiledHeader>
 61.1006 +      </PrecompiledHeader>
 61.1007 +      <WarningLevel>Level3</WarningLevel>
 61.1008 +      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
 61.1009 +      <MultiProcessorCompilation>true</MultiProcessorCompilation>
 61.1010 +    </ClCompile>
 61.1011 +    <ResourceCompile>
 61.1012 +      <PreprocessorDefinitions>BINARY_NAME="\"$(TargetFileName)\"";%(PreprocessorDefinitions)</PreprocessorDefinitions>
 61.1013 +      <AdditionalIncludeDirectories>..\..\public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
 61.1014 +    </ResourceCompile>
 61.1015 +    <Link>
 61.1016 +      <AdditionalDependencies>$(HL2SDKOB)\lib\public\tier0.lib;$(HL2SDKOB)\lib\public\tier1.lib;$(HL2SDKOB)\lib\public\vstdlib.lib;$(HL2SDKOB)\lib\public\mathlib.lib;Wsock32.lib;%(AdditionalDependencies)</AdditionalDependencies>
 61.1017 +      <OutputFile>$(OutDir)$(TargetFileName)</OutputFile>
 61.1018 +      <IgnoreSpecificDefaultLibraries>LIBC;LIBCD;LIBCMTD;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
 61.1019 +      <GenerateDebugInformation>true</GenerateDebugInformation>
 61.1020 +      <SubSystem>Windows</SubSystem>
 61.1021 +      <OptimizeReferences>true</OptimizeReferences>
 61.1022 +      <EnableCOMDATFolding>true</EnableCOMDATFolding>
 61.1023 +      <RandomizedBaseAddress>false</RandomizedBaseAddress>
 61.1024 +      <DataExecutionPrevention>
 61.1025 +      </DataExecutionPrevention>
 61.1026 +      <TargetMachine>MachineX86</TargetMachine>
 61.1027 +    </Link>
 61.1028 +    <PostBuildEvent>
 61.1029 +      <Command>IF NOT "%SMOUTDIR%"=="" copy /Y "$(TargetDir)$(TargetFileName)" "%SMOUTDIR%\bin"</Command>
 61.1030 +    </PostBuildEvent>
 61.1031 +  </ItemDefinitionGroup>
 61.1032 +  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Episode 1|Win32'">
 61.1033 +    <ClCompile>
 61.1034 +      <AdditionalOptions>/D SE_EPISODEONE=1 /D SE_DARKMESSIAH=2 /D SE_ORANGEBOX=3 /D SE_BLOODYGOODTIME=4 /D SE_EYE=5 /D SE_CSS=6 /D SE_ORANGEBOXVALVE=7 /D SE_LEFT4DEAD=8 /D SE_LEFT4DEAD2=9 /D SE_ALIENSWARM=10 /D SE_PORTAL2=11 /D SE_CSGO=12</AdditionalOptions>
 61.1035 +      <Optimization>Disabled</Optimization>
 61.1036 +      <AdditionalIncludeDirectories>..\;..\systems;..\..\public;..\..\public\sourcepawn;$(HL2SDK)\public;$(HL2SDK)\public\dlls;$(HL2SDK)\public\engine;$(HL2SDK)\public\mathlib;$(HL2SDK)\public\tier0;$(HL2SDK)\public\tier1;$(HL2SDK)\public\vstdlib;$(MMSOURCE19)\core;$(MMSOURCE19)\core\sourcehook;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
 61.1037 +      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;SOURCEMOD_MM_EXPORTS;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;SOURCEMOD_BUILD;SM_DEFAULT_THREADER;SOURCE_ENGINE=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
 61.1038 +      <MinimalRebuild>true</MinimalRebuild>
 61.1039 +      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
 61.1040 +      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
 61.1041 +      <EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
 61.1042 +      <RuntimeTypeInfo>false</RuntimeTypeInfo>
 61.1043 +      <PrecompiledHeader>
 61.1044 +      </PrecompiledHeader>
 61.1045 +      <WarningLevel>Level3</WarningLevel>
 61.1046 +      <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
 61.1047 +    </ClCompile>
 61.1048 +    <ResourceCompile>
 61.1049 +      <PreprocessorDefinitions>BINARY_NAME="\"$(TargetFileName)\"";%(PreprocessorDefinitions)</PreprocessorDefinitions>
 61.1050 +      <AdditionalIncludeDirectories>..\..\public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
 61.1051 +    </ResourceCompile>
 61.1052 +    <Link>
 61.1053 +      <AdditionalDependencies>$(HL2SDK)\lib\public\tier0.lib;$(HL2SDK)\lib\public\tier1.lib;$(HL2SDK)\lib\public\vstdlib.lib;$(HL2SDK)\lib\public\mathlib.lib;dbghelp.lib;Wsock32.lib;%(AdditionalDependencies)</AdditionalDependencies>
 61.1054 +      <OutputFile>$(OutDir)$(TargetFileName)</OutputFile>
 61.1055 +      <IgnoreSpecificDefaultLibraries>LIBC;LIBCD;LIBCMT;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
 61.1056 +      <GenerateDebugInformation>true</GenerateDebugInformation>
 61.1057 +      <SubSystem>Windows</SubSystem>
 61.1058 +      <RandomizedBaseAddress>false</RandomizedBaseAddress>
 61.1059 +      <DataExecutionPrevention>
 61.1060 +      </DataExecutionPrevention>
 61.1061 +      <TargetMachine>MachineX86</TargetMachine>
 61.1062 +    </Link>
 61.1063 +    <PostBuildEvent>
 61.1064 +      <Command>IF NOT "%SMOUTDIR%"=="" copy /Y "$(TargetDir)$(TargetFileName)" "%SMOUTDIR%\bin"</Command>
 61.1065 +    </PostBuildEvent>
 61.1066 +  </ItemDefinitionGroup>
 61.1067 +  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug - Episode 1|Win32'">
 61.1068 +    <ClCompile>
 61.1069 +      <AdditionalOptions>/D SE_EPISODEONE=1 /D SE_DARKMESSIAH=2 /D SE_ORANGEBOX=3 /D SE_BLOODYGOODTIME=4 /D SE_EYE=5 /D SE_CSS=6 /D SE_ORANGEBOXVALVE=7 /D SE_LEFT4DEAD=8 /D SE_LEFT4DEAD2=9 /D SE_ALIENSWARM=10 /D SE_PORTAL2=11 /D SE_CSGO=12</AdditionalOptions>
 61.1070 +      <Optimization>Disabled</Optimization>
 61.1071 +      <AdditionalIncludeDirectories>..\;..\systems;..\..\public;..\..\public\sourcepawn;$(HL2SDK)\public;$(HL2SDK)\public\dlls;$(HL2SDK)\public\engine;$(HL2SDK)\public\mathlib;$(HL2SDK)\public\tier0;$(HL2SDK)\public\tier1;$(HL2SDK)\public\vstdlib;$(MMSOURCE19)\core;$(MMSOURCE19)\core\sourcehook;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
 61.1072 +      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;SOURCEMOD_MM_EXPORTS;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;SOURCEMOD_BUILD;SM_DEFAULT_THREADER;SOURCE_ENGINE=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
 61.1073 +      <MinimalRebuild>true</MinimalRebuild>
 61.1074 +      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
 61.1075 +      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
 61.1076 +      <EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
 61.1077 +      <RuntimeTypeInfo>false</RuntimeTypeInfo>
 61.1078 +      <PrecompiledHeader>
 61.1079 +      </PrecompiledHeader>
 61.1080 +      <WarningLevel>Level3</WarningLevel>
 61.1081 +      <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
 61.1082 +    </ClCompile>
 61.1083 +    <ResourceCompile>
 61.1084 +      <PreprocessorDefinitions>BINARY_NAME="\"$(TargetFileName)\"";%(PreprocessorDefinitions)</PreprocessorDefinitions>
 61.1085 +      <AdditionalIncludeDirectories>..\..\public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
 61.1086 +    </ResourceCompile>
 61.1087 +    <Link>
 61.1088 +      <AdditionalDependencies>$(HL2SDK)\lib\public\tier0.lib;$(HL2SDK)\lib\public\tier1.lib;$(HL2SDK)\lib\public\vstdlib.lib;$(HL2SDK)\lib\public\mathlib.lib;Wsock32.lib;%(AdditionalDependencies)</AdditionalDependencies>
 61.1089 +      <OutputFile>$(OutDir)$(TargetFileName)</OutputFile>
 61.1090 +      <IgnoreSpecificDefaultLibraries>LIBC;LIBCD;LIBCMT;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
 61.1091 +      <GenerateDebugInformation>true</GenerateDebugInformation>
 61.1092 +      <SubSystem>Windows</SubSystem>
 61.1093 +      <RandomizedBaseAddress>false</RandomizedBaseAddress>
 61.1094 +      <DataExecutionPrevention>
 61.1095 +      </DataExecutionPrevention>
 61.1096 +      <TargetMachine>MachineX86</TargetMachine>
 61.1097 +    </Link>
 61.1098 +    <PostBuildEvent>
 61.1099 +      <Command>IF NOT "%SMOUTDIR%"=="" copy /Y "$(TargetDir)$(TargetFileName)" "%SMOUTDIR%\bin"</Command>
 61.1100 +    </PostBuildEvent>
 61.1101 +  </ItemDefinitionGroup>
 61.1102 +  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release - Episode 1|Win32'">
 61.1103 +    <ClCompile>
 61.1104 +      <AdditionalOptions>/D SE_EPISODEONE=1 /D SE_DARKMESSIAH=2 /D SE_ORANGEBOX=3 /D SE_BLOODYGOODTIME=4 /D SE_EYE=5 /D SE_CSS=6 /D SE_ORANGEBOXVALVE=7 /D SE_LEFT4DEAD=8 /D SE_LEFT4DEAD2=9 /D SE_ALIENSWARM=10 /D SE_PORTAL2=11 /D SE_CSGO=12</AdditionalOptions>
 61.1105 +      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
 61.1106 +      <AdditionalIncludeDirectories>..\;..\systems;..\..\public;..\..\public\sourcepawn;$(HL2SDK)\public;$(HL2SDK)\public\dlls;$(HL2SDK)\public\engine;$(HL2SDK)\public\mathlib;$(HL2SDK)\public\tier0;$(HL2SDK)\public\tier1;$(HL2SDK)\public\vstdlib;$(MMSOURCE19)\core;$(MMSOURCE19)\core\sourcehook;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
 61.1107 +      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;SOURCEMOD_MM_EXPORTS;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;SOURCEMOD_BUILD;SM_DEFAULT_THREADER;SOURCE_ENGINE=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
 61.1108 +      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
 61.1109 +      <EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
 61.1110 +      <RuntimeTypeInfo>false</RuntimeTypeInfo>
 61.1111 +      <PrecompiledHeader>
 61.1112 +      </PrecompiledHeader>
 61.1113 +      <WarningLevel>Level3</WarningLevel>
 61.1114 +      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
 61.1115 +      <MultiProcessorCompilation>true</MultiProcessorCompilation>
 61.1116 +    </ClCompile>
 61.1117 +    <ResourceCompile>
 61.1118 +      <PreprocessorDefinitions>BINARY_NAME="\"$(TargetFileName)\"";%(PreprocessorDefinitions)</PreprocessorDefinitions>
 61.1119 +      <AdditionalIncludeDirectories>..\..\public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
 61.1120 +    </ResourceCompile>
 61.1121 +    <Link>
 61.1122 +      <AdditionalDependencies>$(HL2SDK)\lib\public\tier0.lib;$(HL2SDK)\lib\public\tier1.lib;$(HL2SDK)\lib\public\vstdlib.lib;$(HL2SDK)\lib\public\mathlib.lib;Wsock32.lib;%(AdditionalDependencies)</AdditionalDependencies>
 61.1123 +      <OutputFile>$(OutDir)$(TargetFileName)</OutputFile>
 61.1124 +      <IgnoreSpecificDefaultLibraries>LIBC;LIBCD;LIBCMTD;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
 61.1125 +      <GenerateDebugInformation>true</GenerateDebugInformation>
 61.1126 +      <SubSystem>Windows</SubSystem>
 61.1127 +      <OptimizeReferences>true</OptimizeReferences>
 61.1128 +      <EnableCOMDATFolding>true</EnableCOMDATFolding>
 61.1129 +      <RandomizedBaseAddress>false</RandomizedBaseAddress>
 61.1130 +      <DataExecutionPrevention>
 61.1131 +      </DataExecutionPrevention>
 61.1132 +      <TargetMachine>MachineX86</TargetMachine>
 61.1133 +    </Link>
 61.1134 +    <PostBuildEvent>
 61.1135 +      <Command>IF NOT "%SMOUTDIR%"=="" copy /Y "$(TargetDir)$(TargetFileName)" "%SMOUTDIR%\bin"</Command>
 61.1136 +    </PostBuildEvent>
 61.1137 +  </ItemDefinitionGroup>
 61.1138 +  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Left 4 Dead|Win32'">
 61.1139 +    <ClCompile>
 61.1140 +      <AdditionalOptions>/D SE_EPISODEONE=1 /D SE_DARKMESSIAH=2 /D SE_ORANGEBOX=3 /D SE_BLOODYGOODTIME=4 /D SE_EYE=5 /D SE_CSS=6 /D SE_ORANGEBOXVALVE=7 /D SE_LEFT4DEAD=8 /D SE_LEFT4DEAD2=9 /D SE_ALIENSWARM=10 /D SE_PORTAL2=11 /D SE_CSGO=12</AdditionalOptions>
 61.1141 +      <Optimization>Disabled</Optimization>
 61.1142 +      <AdditionalIncludeDirectories>..\;..\systems;..\..\public;..\..\public\sourcepawn;$(HL2SDKL4D)\public;$(HL2SDKL4D)\public\engine;$(HL2SDKL4D)\public\game\server;$(HL2SDKL4D)\public\mathlib;$(HL2SDKL4D)\public\tier0;$(HL2SDKL4D)\public\tier1;$(HL2SDKL4D)\public\vstdlib;$(MMSOURCE19)\core;$(MMSOURCE19)\core\sourcehook;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
 61.1143 +      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;SOURCEMOD_MM_EXPORTS;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;SOURCEMOD_BUILD;SM_DEFAULT_THREADER;SOURCE_ENGINE=8;%(PreprocessorDefinitions)</PreprocessorDefinitions>
 61.1144 +      <MinimalRebuild>true</MinimalRebuild>
 61.1145 +      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
 61.1146 +      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
 61.1147 +      <EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
 61.1148 +      <RuntimeTypeInfo>false</RuntimeTypeInfo>
 61.1149 +      <PrecompiledHeader>
 61.1150 +      </PrecompiledHeader>
 61.1151 +      <WarningLevel>Level3</WarningLevel>
 61.1152 +      <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
 61.1153 +    </ClCompile>
 61.1154 +    <ResourceCompile>
 61.1155 +      <PreprocessorDefinitions>BINARY_NAME="\"$(TargetFileName)\"";%(PreprocessorDefinitions)</PreprocessorDefinitions>
 61.1156 +      <AdditionalIncludeDirectories>..\..\public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
 61.1157 +    </ResourceCompile>
 61.1158 +    <Link>
 61.1159 +      <AdditionalDependencies>$(HL2SDKL4D)\lib\public\tier0.lib;$(HL2SDKL4D)\lib\public\tier1.lib;$(HL2SDKL4D)\lib\public\vstdlib.lib;$(HL2SDKL4D)\lib\public\mathlib.lib;dbghelp.lib;Wsock32.lib;%(AdditionalDependencies)</AdditionalDependencies>
 61.1160 +      <OutputFile>$(OutDir)$(TargetFileName)</OutputFile>
 61.1161 +      <IgnoreSpecificDefaultLibraries>LIBC;LIBCD;LIBCMT;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
 61.1162 +      <GenerateDebugInformation>true</GenerateDebugInformation>
 61.1163 +      <SubSystem>Windows</SubSystem>
 61.1164 +      <RandomizedBaseAddress>false</RandomizedBaseAddress>
 61.1165 +      <DataExecutionPrevention>
 61.1166 +      </DataExecutionPrevention>
 61.1167 +      <TargetMachine>MachineX86</TargetMachine>
 61.1168 +    </Link>
 61.1169 +    <PostBuildEvent>
 61.1170 +      <Command>IF NOT "%SMOUTDIR%"=="" copy /Y "$(TargetDir)$(TargetFileName)" "%SMOUTDIR%\bin"</Command>
 61.1171 +    </PostBuildEvent>
 61.1172 +  </ItemDefinitionGroup>
 61.1173 +  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug - Left 4 Dead|Win32'">
 61.1174 +    <ClCompile>
 61.1175 +      <AdditionalOptions>/D SE_EPISODEONE=1 /D SE_DARKMESSIAH=2 /D SE_ORANGEBOX=3 /D SE_BLOODYGOODTIME=4 /D SE_EYE=5 /D SE_CSS=6 /D SE_ORANGEBOXVALVE=7 /D SE_LEFT4DEAD=8 /D SE_LEFT4DEAD2=9 /D SE_ALIENSWARM=10 /D SE_PORTAL2=11 /D SE_CSGO=12</AdditionalOptions>
 61.1176 +      <Optimization>Disabled</Optimization>
 61.1177 +      <AdditionalIncludeDirectories>..\;..\systems;..\..\public;..\..\public\sourcepawn;$(HL2SDKL4D)\public;$(HL2SDKL4D)\public\engine;$(HL2SDKL4D)\public\game\server;$(HL2SDKL4D)\public\mathlib;$(HL2SDKL4D)\public\tier0;$(HL2SDKL4D)\public\tier1;$(HL2SDKL4D)\public\vstdlib;$(MMSOURCE19)\core;$(MMSOURCE19)\core\sourcehook;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
 61.1178 +      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;SOURCEMOD_MM_EXPORTS;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;SOURCEMOD_BUILD;SM_DEFAULT_THREADER;SOURCE_ENGINE=8;%(PreprocessorDefinitions)</PreprocessorDefinitions>
 61.1179 +      <MinimalRebuild>true</MinimalRebuild>
 61.1180 +      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
 61.1181 +      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
 61.1182 +      <EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
 61.1183 +      <RuntimeTypeInfo>false</RuntimeTypeInfo>
 61.1184 +      <PrecompiledHeader>
 61.1185 +      </PrecompiledHeader>
 61.1186 +      <WarningLevel>Level3</WarningLevel>
 61.1187 +      <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
 61.1188 +    </ClCompile>
 61.1189 +    <ResourceCompile>
 61.1190 +      <PreprocessorDefinitions>BINARY_NAME="\"$(TargetFileName)\"";%(PreprocessorDefinitions)</PreprocessorDefinitions>
 61.1191 +      <AdditionalIncludeDirectories>..\..\public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
 61.1192 +    </ResourceCompile>
 61.1193 +    <Link>
 61.1194 +      <AdditionalDependencies>$(HL2SDKL4D)\lib\public\tier0.lib;$(HL2SDKL4D)\lib\public\tier1.lib;$(HL2SDKL4D)\lib\public\vstdlib.lib;$(HL2SDKL4D)\lib\public\mathlib.lib;Wsock32.lib;%(AdditionalDependencies)</AdditionalDependencies>
 61.1195 +      <OutputFile>$(OutDir)$(TargetFileName)</OutputFile>
 61.1196 +      <IgnoreSpecificDefaultLibraries>LIBC;LIBCD;LIBCMT;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
 61.1197 +      <GenerateDebugInformation>true</GenerateDebugInformation>
 61.1198 +      <SubSystem>Windows</SubSystem>
 61.1199 +      <RandomizedBaseAddress>false</RandomizedBaseAddress>
 61.1200 +      <DataExecutionPrevention>
 61.1201 +      </DataExecutionPrevention>
 61.1202 +      <TargetMachine>MachineX86</TargetMachine>
 61.1203 +    </Link>
 61.1204 +    <PostBuildEvent>
 61.1205 +      <Command>IF NOT "%SMOUTDIR%"=="" copy /Y "$(TargetDir)$(TargetFileName)" "%SMOUTDIR%\bin"</Command>
 61.1206 +    </PostBuildEvent>
 61.1207 +  </ItemDefinitionGroup>
 61.1208 +  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release - Left 4 Dead|Win32'">
 61.1209 +    <ClCompile>
 61.1210 +      <AdditionalOptions>/D SE_EPISODEONE=1 /D SE_DARKMESSIAH=2 /D SE_ORANGEBOX=3 /D SE_BLOODYGOODTIME=4 /D SE_EYE=5 /D SE_CSS=6 /D SE_ORANGEBOXVALVE=7 /D SE_LEFT4DEAD=8 /D SE_LEFT4DEAD2=9 /D SE_ALIENSWARM=10 /D SE_PORTAL2=11 /D SE_CSGO=12</AdditionalOptions>
 61.1211 +      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
 61.1212 +      <AdditionalIncludeDirectories>..\;..\systems;..\..\public;..\..\public\sourcepawn;$(HL2SDKL4D)\public;$(HL2SDKL4D)\public\engine;$(HL2SDKL4D)\public\game\server;$(HL2SDKL4D)\public\mathlib;$(HL2SDKL4D)\public\tier0;$(HL2SDKL4D)\public\tier1;$(HL2SDKL4D)\public\vstdlib;$(MMSOURCE19)\core;$(MMSOURCE19)\core\sourcehook;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
 61.1213 +      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;SOURCEMOD_MM_EXPORTS;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;SOURCEMOD_BUILD;SM_DEFAULT_THREADER;SOURCE_ENGINE=8;%(PreprocessorDefinitions)</PreprocessorDefinitions>
 61.1214 +      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
 61.1215 +      <EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
 61.1216 +      <RuntimeTypeInfo>false</RuntimeTypeInfo>
 61.1217 +      <PrecompiledHeader>
 61.1218 +      </PrecompiledHeader>
 61.1219 +      <WarningLevel>Level3</WarningLevel>
 61.1220 +      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
 61.1221 +      <MultiProcessorCompilation>true</MultiProcessorCompilation>
 61.1222 +    </ClCompile>
 61.1223 +    <ResourceCompile>
 61.1224 +      <PreprocessorDefinitions>BINARY_NAME="\"$(TargetFileName)\"";%(PreprocessorDefinitions)</PreprocessorDefinitions>
 61.1225 +      <AdditionalIncludeDirectories>..\..\public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
 61.1226 +    </ResourceCompile>
 61.1227 +    <Link>
 61.1228 +      <AdditionalDependencies>$(HL2SDKL4D)\lib\public\tier0.lib;$(HL2SDKL4D)\lib\public\tier1.lib;$(HL2SDKL4D)\lib\public\vstdlib.lib;$(HL2SDKL4D)\lib\public\mathlib.lib;Wsock32.lib;%(AdditionalDependencies)</AdditionalDependencies>
 61.1229 +      <OutputFile>$(OutDir)$(TargetFileName)</OutputFile>
 61.1230 +      <IgnoreSpecificDefaultLibraries>LIBC;LIBCD;LIBCMTD;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
 61.1231 +      <GenerateDebugInformation>true</GenerateDebugInformation>
 61.1232 +      <SubSystem>Windows</SubSystem>
 61.1233 +      <OptimizeReferences>true</OptimizeReferences>
 61.1234 +      <EnableCOMDATFolding>true</EnableCOMDATFolding>
 61.1235 +      <RandomizedBaseAddress>false</RandomizedBaseAddress>
 61.1236 +      <DataExecutionPrevention>
 61.1237 +      </DataExecutionPrevention>
 61.1238 +      <TargetMachine>MachineX86</TargetMachine>
 61.1239 +    </Link>
 61.1240 +    <PostBuildEvent>
 61.1241 +      <Command>IF NOT "%SMOUTDIR%"=="" copy /Y "$(TargetDir)$(TargetFileName)" "%SMOUTDIR%\bin"</Command>
 61.1242 +    </PostBuildEvent>
 61.1243 +  </ItemDefinitionGroup>
 61.1244 +  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Orange Box Valve|Win32'">
 61.1245 +    <ClCompile>
 61.1246 +      <AdditionalOptions>/D SE_EPISODEONE=1 /D SE_DARKMESSIAH=2 /D SE_ORANGEBOX=3 /D SE_BLOODYGOODTIME=4 /D SE_EYE=5 /D SE_CSS=6 /D SE_ORANGEBOXVALVE=7 /D SE_LEFT4DEAD=8 /D SE_LEFT4DEAD2=9 /D SE_ALIENSWARM=10 /D SE_PORTAL2=11 /D SE_CSGO=12</AdditionalOptions>
 61.1247 +      <Optimization>Disabled</Optimization>
 61.1248 +      <AdditionalIncludeDirectories>..\;..\systems;..\..\public;..\..\public\sourcepawn;$(HL2SDKOBVALVE)\public;$(HL2SDKOBVALVE)\public\engine;$(HL2SDKOBVALVE)\public\game\server;$(HL2SDKOBVALVE)\public\mathlib;$(HL2SDKOBVALVE)\public\tier0;$(HL2SDKOBVALVE)\public\tier1;$(HL2SDKOBVALVE)\public\vstdlib;$(MMSOURCE19)\core;$(MMSOURCE19)\core\sourcehook;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
 61.1249 +      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;SOURCEMOD_MM_EXPORTS;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;SOURCEMOD_BUILD;SM_DEFAULT_THREADER;SOURCE_ENGINE=7;%(PreprocessorDefinitions)</PreprocessorDefinitions>
 61.1250 +      <MinimalRebuild>true</MinimalRebuild>
 61.1251 +      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
 61.1252 +      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
 61.1253 +      <EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
 61.1254 +      <RuntimeTypeInfo>false</RuntimeTypeInfo>
 61.1255 +      <PrecompiledHeader>
 61.1256 +      </PrecompiledHeader>
 61.1257 +      <WarningLevel>Level3</WarningLevel>
 61.1258 +      <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
 61.1259 +    </ClCompile>
 61.1260 +    <ResourceCompile>
 61.1261 +      <PreprocessorDefinitions>BINARY_NAME="\"$(TargetFileName)\"";%(PreprocessorDefinitions)</PreprocessorDefinitions>
 61.1262 +      <AdditionalIncludeDirectories>..\..\public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
 61.1263 +    </ResourceCompile>
 61.1264 +    <Link>
 61.1265 +      <AdditionalDependencies>$(HL2SDKOBVALVE)\lib\public\tier0.lib;$(HL2SDKOBVALVE)\lib\public\tier1.lib;$(HL2SDKOBVALVE)\lib\public\vstdlib.lib;$(HL2SDKOBVALVE)\lib\public\mathlib.lib;dbghelp.lib;Wsock32.lib;%(AdditionalDependencies)</AdditionalDependencies>
 61.1266 +      <OutputFile>$(OutDir)$(TargetFileName)</OutputFile>
 61.1267 +      <IgnoreSpecificDefaultLibraries>LIBC;LIBCD;LIBCMT;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
 61.1268 +      <GenerateDebugInformation>true</GenerateDebugInformation>
 61.1269 +      <SubSystem>Windows</SubSystem>
 61.1270 +      <RandomizedBaseAddress>false</RandomizedBaseAddress>
 61.1271 +      <DataExecutionPrevention>
 61.1272 +      </DataExecutionPrevention>
 61.1273 +      <TargetMachine>MachineX86</TargetMachine>
 61.1274 +    </Link>
 61.1275 +    <PostBuildEvent>
 61.1276 +      <Command>IF NOT "%SMOUTDIR%"=="" copy /Y "$(TargetDir)$(TargetFileName)" "%SMOUTDIR%\bin"</Command>
 61.1277 +    </PostBuildEvent>
 61.1278 +  </ItemDefinitionGroup>
 61.1279 +  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - CSS|Win32'">
 61.1280 +    <ClCompile>
 61.1281 +      <AdditionalOptions>/D SE_EPISODEONE=1 /D SE_DARKMESSIAH=2 /D SE_ORANGEBOX=3 /D SE_BLOODYGOODTIME=4 /D SE_EYE=5 /D SE_CSS=6 /D SE_ORANGEBOXVALVE=7 /D SE_LEFT4DEAD=8 /D SE_LEFT4DEAD2=9 /D SE_ALIENSWARM=10 /D SE_PORTAL2=11 /D SE_CSGO=12</AdditionalOptions>
 61.1282 +      <Optimization>Disabled</Optimization>
 61.1283 +      <AdditionalIncludeDirectories>..\;..\systems;..\..\public;..\..\public\sourcepawn;$(HL2SDKCSS)\public;$(HL2SDKCSS)\public\engine;$(HL2SDKCSS)\public\game\server;$(HL2SDKCSS)\public\mathlib;$(HL2SDKCSS)\public\tier0;$(HL2SDKCSS)\public\tier1;$(HL2SDKCSS)\public\vstdlib;$(MMSOURCE19)\core;$(MMSOURCE19)\core\sourcehook;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
 61.1284 +      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;SOURCEMOD_MM_EXPORTS;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;SOURCEMOD_BUILD;SM_DEFAULT_THREADER;SOURCE_ENGINE=6;%(PreprocessorDefinitions)</PreprocessorDefinitions>
 61.1285 +      <MinimalRebuild>true</MinimalRebuild>
 61.1286 +      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
 61.1287 +      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
 61.1288 +      <EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
 61.1289 +      <RuntimeTypeInfo>false</RuntimeTypeInfo>
 61.1290 +      <PrecompiledHeader>
 61.1291 +      </PrecompiledHeader>
 61.1292 +      <WarningLevel>Level3</WarningLevel>
 61.1293 +      <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
 61.1294 +    </ClCompile>
 61.1295 +    <ResourceCompile>
 61.1296 +      <PreprocessorDefinitions>BINARY_NAME="\"$(TargetFileName)\"";%(PreprocessorDefinitions)</PreprocessorDefinitions>
 61.1297 +      <AdditionalIncludeDirectories>..\..\public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
 61.1298 +    </ResourceCompile>
 61.1299 +    <Link>
 61.1300 +      <AdditionalDependencies>$(HL2SDKCSS)\lib\public\tier0.lib;$(HL2SDKCSS)\lib\public\tier1.lib;$(HL2SDKCSS)\lib\public\vstdlib.lib;$(HL2SDKCSS)\lib\public\mathlib.lib;dbghelp.lib;Wsock32.lib;%(AdditionalDependencies)</AdditionalDependencies>
 61.1301 +      <OutputFile>$(OutDir)$(TargetFileName)</OutputFile>
 61.1302 +      <IgnoreSpecificDefaultLibraries>LIBC;LIBCD;LIBCMT;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
 61.1303 +      <GenerateDebugInformation>true</GenerateDebugInformation>
 61.1304 +      <SubSystem>Windows</SubSystem>
 61.1305 +      <RandomizedBaseAddress>false</RandomizedBaseAddress>
 61.1306 +      <DataExecutionPrevention>
 61.1307 +      </DataExecutionPrevention>
 61.1308 +      <TargetMachine>MachineX86</TargetMachine>
 61.1309 +    </Link>
 61.1310 +    <PostBuildEvent>
 61.1311 +      <Command>IF NOT "%SMOUTDIR%"=="" copy /Y "$(TargetDir)$(TargetFileName)" "%SMOUTDIR%\bin"</Command>
 61.1312 +    </PostBuildEvent>
 61.1313 +  </ItemDefinitionGroup>
 61.1314 +  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug - Orange Box Valve|Win32'">
 61.1315 +    <ClCompile>
 61.1316 +      <AdditionalOptions>/D SE_EPISODEONE=1 /D SE_DARKMESSIAH=2 /D SE_ORANGEBOX=3 /D SE_BLOODYGOODTIME=4 /D SE_EYE=5 /D SE_CSS=6 /D SE_ORANGEBOXVALVE=7 /D SE_LEFT4DEAD=8 /D SE_LEFT4DEAD2=9 /D SE_ALIENSWARM=10 /D SE_PORTAL2=11 /D SE_CSGO=12</AdditionalOptions>
 61.1317 +      <Optimization>Disabled</Optimization>
 61.1318 +      <AdditionalIncludeDirectories>..\;..\systems;..\..\public;..\..\public\sourcepawn;$(HL2SDKOBVALVE)\public;$(HL2SDKOBVALVE)\public\engine;$(HL2SDKOBVALVE)\public\game\server;$(HL2SDKOBVALVE)\public\mathlib;$(HL2SDKOBVALVE)\public\tier0;$(HL2SDKOBVALVE)\public\tier1;$(HL2SDKOBVALVE)\public\vstdlib;$(MMSOURCE19)\core;$(MMSOURCE19)\core\sourcehook;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
 61.1319 +      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;SOURCEMOD_MM_EXPORTS;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;SOURCEMOD_BUILD;SM_DEFAULT_THREADER;SOURCE_ENGINE=7;%(PreprocessorDefinitions)</PreprocessorDefinitions>
 61.1320 +      <MinimalRebuild>true</MinimalRebuild>
 61.1321 +      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
 61.1322 +      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
 61.1323 +      <EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
 61.1324 +      <RuntimeTypeInfo>false</RuntimeTypeInfo>
 61.1325 +      <PrecompiledHeader>
 61.1326 +      </PrecompiledHeader>
 61.1327 +      <WarningLevel>Level3</WarningLevel>
 61.1328 +      <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
 61.1329 +    </ClCompile>
 61.1330 +    <ResourceCompile>
 61.1331 +      <PreprocessorDefinitions>BINARY_NAME="\"$(TargetFileName)\"";%(PreprocessorDefinitions)</PreprocessorDefinitions>
 61.1332 +      <AdditionalIncludeDirectories>..\..\public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
 61.1333 +    </ResourceCompile>
 61.1334 +    <Link>
 61.1335 +      <AdditionalDependencies>$(HL2SDKOBVALVE)\lib\public\tier0.lib;$(HL2SDKOBVALVE)\lib\public\tier1.lib;$(HL2SDKOBVALVE)\lib\public\vstdlib.lib;$(HL2SDKOBVALVE)\lib\public\mathlib.lib;Wsock32.lib;%(AdditionalDependencies)</AdditionalDependencies>
 61.1336 +      <OutputFile>$(OutDir)$(TargetFileName)</OutputFile>
 61.1337 +      <IgnoreSpecificDefaultLibraries>LIBC;LIBCD;LIBCMT;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
 61.1338 +      <GenerateDebugInformation>true</GenerateDebugInformation>
 61.1339 +      <SubSystem>Windows</SubSystem>
 61.1340 +      <RandomizedBaseAddress>false</RandomizedBaseAddress>
 61.1341 +      <DataExecutionPrevention>
 61.1342 +      </DataExecutionPrevention>
 61.1343 +      <TargetMachine>MachineX86</TargetMachine>
 61.1344 +    </Link>
 61.1345 +    <PostBuildEvent>
 61.1346 +      <Command>IF NOT "%SMOUTDIR%"=="" copy /Y "$(TargetDir)$(TargetFileName)" "%SMOUTDIR%\bin"</Command>
 61.1347 +    </PostBuildEvent>
 61.1348 +  </ItemDefinitionGroup>
 61.1349 +  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug - CSS|Win32'">
 61.1350 +    <ClCompile>
 61.1351 +      <AdditionalOptions>/D SE_EPISODEONE=1 /D SE_DARKMESSIAH=2 /D SE_ORANGEBOX=3 /D SE_BLOODYGOODTIME=4 /D SE_EYE=5 /D SE_CSS=6 /D SE_ORANGEBOXVALVE=7 /D SE_LEFT4DEAD=8 /D SE_LEFT4DEAD2=9 /D SE_ALIENSWARM=10 /D SE_PORTAL2=11 /D SE_CSGO=12</AdditionalOptions>
 61.1352 +      <Optimization>Disabled</Optimization>
 61.1353 +      <AdditionalIncludeDirectories>..\;..\systems;..\..\public;..\..\public\sourcepawn;$(HL2SDKCSS)\public;$(HL2SDKCSS)\public\engine;$(HL2SDKCSS)\public\game\server;$(HL2SDKCSS)\public\mathlib;$(HL2SDKCSS)\public\tier0;$(HL2SDKCSS)\public\tier1;$(HL2SDKCSS)\public\vstdlib;$(MMSOURCE19)\core;$(MMSOURCE19)\core\sourcehook;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
 61.1354 +      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;SOURCEMOD_MM_EXPORTS;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;SOURCEMOD_BUILD;SM_DEFAULT_THREADER;SOURCE_ENGINE=6;%(PreprocessorDefinitions)</PreprocessorDefinitions>
 61.1355 +      <MinimalRebuild>true</MinimalRebuild>
 61.1356 +      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
 61.1357 +      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
 61.1358 +      <EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
 61.1359 +      <RuntimeTypeInfo>false</RuntimeTypeInfo>
 61.1360 +      <PrecompiledHeader>
 61.1361 +      </PrecompiledHeader>
 61.1362 +      <WarningLevel>Level3</WarningLevel>
 61.1363 +      <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
 61.1364 +    </ClCompile>
 61.1365 +    <ResourceCompile>
 61.1366 +      <PreprocessorDefinitions>BINARY_NAME="\"$(TargetFileName)\"";%(PreprocessorDefinitions)</PreprocessorDefinitions>
 61.1367 +      <AdditionalIncludeDirectories>..\..\public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
 61.1368 +    </ResourceCompile>
 61.1369 +    <Link>
 61.1370 +      <AdditionalDependencies>$(HL2SDKCSS)\lib\public\tier0.lib;$(HL2SDKCSS)\lib\public\tier1.lib;$(HL2SDKCSS)\lib\public\vstdlib.lib;$(HL2SDKCSS)\lib\public\mathlib.lib;Wsock32.lib;%(AdditionalDependencies)</AdditionalDependencies>
 61.1371 +      <OutputFile>$(OutDir)$(TargetFileName)</OutputFile>
 61.1372 +      <IgnoreSpecificDefaultLibraries>LIBC;LIBCD;LIBCMT;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
 61.1373 +      <GenerateDebugInformation>true</GenerateDebugInformation>
 61.1374 +      <SubSystem>Windows</SubSystem>
 61.1375 +      <RandomizedBaseAddress>false</RandomizedBaseAddress>
 61.1376 +      <DataExecutionPrevention>
 61.1377 +      </DataExecutionPrevention>
 61.1378 +      <TargetMachine>MachineX86</TargetMachine>
 61.1379 +    </Link>
 61.1380 +    <PostBuildEvent>
 61.1381 +      <Command>IF NOT "%SMOUTDIR%"=="" copy /Y "$(TargetDir)$(TargetFileName)" "%SMOUTDIR%\bin"</Command>
 61.1382 +    </PostBuildEvent>
 61.1383 +  </ItemDefinitionGroup>
 61.1384 +  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release - Orange Box Valve|Win32'">
 61.1385 +    <ClCompile>
 61.1386 +      <AdditionalOptions>/D SE_EPISODEONE=1 /D SE_DARKMESSIAH=2 /D SE_ORANGEBOX=3 /D SE_BLOODYGOODTIME=4 /D SE_EYE=5 /D SE_CSS=6 /D SE_ORANGEBOXVALVE=7 /D SE_LEFT4DEAD=8 /D SE_LEFT4DEAD2=9 /D SE_ALIENSWARM=10 /D SE_PORTAL2=11 /D SE_CSGO=12</AdditionalOptions>
 61.1387 +      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
 61.1388 +      <AdditionalIncludeDirectories>..\;..\systems;..\..\public;..\..\public\sourcepawn;$(HL2SDKOBVALVE)\public;$(HL2SDKOBVALVE)\public\engine;$(HL2SDKOBVALVE)\public\game\server;$(HL2SDKOBVALVE)\public\mathlib;$(HL2SDKOBVALVE)\public\tier0;$(HL2SDKOBVALVE)\public\tier1;$(HL2SDKOBVALVE)\public\vstdlib;$(MMSOURCE19)\core;$(MMSOURCE19)\core\sourcehook;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
 61.1389 +      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;SOURCEMOD_MM_EXPORTS;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;SOURCEMOD_BUILD;SM_DEFAULT_THREADER;SOURCE_ENGINE=7;%(PreprocessorDefinitions)</PreprocessorDefinitions>
 61.1390 +      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
 61.1391 +      <EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
 61.1392 +      <RuntimeTypeInfo>false</RuntimeTypeInfo>
 61.1393 +      <PrecompiledHeader>
 61.1394 +      </PrecompiledHeader>
 61.1395 +      <AssemblerOutput>
 61.1396 +      </AssemblerOutput>
 61.1397 +      <WarningLevel>Level3</WarningLevel>
 61.1398 +      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
 61.1399 +      <MultiProcessorCompilation>true</MultiProcessorCompilation>
 61.1400 +    </ClCompile>
 61.1401 +    <ResourceCompile>
 61.1402 +      <PreprocessorDefinitions>BINARY_NAME="\"$(TargetFileName)\"";%(PreprocessorDefinitions)</PreprocessorDefinitions>
 61.1403 +      <AdditionalIncludeDirectories>..\..\public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
 61.1404 +    </ResourceCompile>
 61.1405 +    <Link>
 61.1406 +      <AdditionalDependencies>$(HL2SDKOBVALVE)\lib\public\tier0.lib;$(HL2SDKOBVALVE)\lib\public\tier1.lib;$(HL2SDKOBVALVE)\lib\public\vstdlib.lib;$(HL2SDKOBVALVE)\lib\public\mathlib.lib;Wsock32.lib;%(AdditionalDependencies)</AdditionalDependencies>
 61.1407 +      <OutputFile>$(OutDir)$(TargetFileName)</OutputFile>
 61.1408 +      <IgnoreSpecificDefaultLibraries>LIBC;LIBCD;LIBCMTD;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
 61.1409 +      <GenerateDebugInformation>true</GenerateDebugInformation>
 61.1410 +      <SubSystem>Windows</SubSystem>
 61.1411 +      <OptimizeReferences>true</OptimizeReferences>
 61.1412 +      <EnableCOMDATFolding>true</EnableCOMDATFolding>
 61.1413 +      <RandomizedBaseAddress>false</RandomizedBaseAddress>
 61.1414 +      <DataExecutionPrevention>
 61.1415 +      </DataExecutionPrevention>
 61.1416 +      <TargetMachine>MachineX86</TargetMachine>
 61.1417 +    </Link>
 61.1418 +    <PostBuildEvent>
 61.1419 +      <Command>IF NOT "%SMOUTDIR%"=="" copy /Y "$(TargetDir)$(TargetFileName)" "%SMOUTDIR%\bin"</Command>
 61.1420 +    </PostBuildEvent>
 61.1421 +  </ItemDefinitionGroup>
 61.1422 +  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release - CSS|Win32'">
 61.1423 +    <ClCompile>
 61.1424 +      <AdditionalOptions>/D SE_EPISODEONE=1 /D SE_DARKMESSIAH=2 /D SE_ORANGEBOX=3 /D SE_BLOODYGOODTIME=4 /D SE_EYE=5 /D SE_CSS=6 /D SE_ORANGEBOXVALVE=7 /D SE_LEFT4DEAD=8 /D SE_LEFT4DEAD2=9 /D SE_ALIENSWARM=10 /D SE_PORTAL2=11 /D SE_CSGO=12</AdditionalOptions>
 61.1425 +      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
 61.1426 +      <AdditionalIncludeDirectories>..\;..\systems;..\..\public;..\..\public\sourcepawn;$(HL2SDKCSS)\public;$(HL2SDKCSS)\public\engine;$(HL2SDKCSS)\public\game\server;$(HL2SDKCSS)\public\mathlib;$(HL2SDKCSS)\public\tier0;$(HL2SDKCSS)\public\tier1;$(HL2SDKCSS)\public\vstdlib;$(MMSOURCE19)\core;$(MMSOURCE19)\core\sourcehook;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
 61.1427 +      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;SOURCEMOD_MM_EXPORTS;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;SOURCEMOD_BUILD;SM_DEFAULT_THREADER;SOURCE_ENGINE=6;%(PreprocessorDefinitions)</PreprocessorDefinitions>
 61.1428 +      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
 61.1429 +      <EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
 61.1430 +      <RuntimeTypeInfo>false</RuntimeTypeInfo>
 61.1431 +      <PrecompiledHeader>
 61.1432 +      </PrecompiledHeader>
 61.1433 +      <AssemblerOutput>
 61.1434 +      </AssemblerOutput>
 61.1435 +      <WarningLevel>Level3</WarningLevel>
 61.1436 +      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
 61.1437 +      <MultiProcessorCompilation>true</MultiProcessorCompilation>
 61.1438 +    </ClCompile>
 61.1439 +    <ResourceCompile>
 61.1440 +      <PreprocessorDefinitions>BINARY_NAME="\"$(TargetFileName)\"";%(PreprocessorDefinitions)</PreprocessorDefinitions>
 61.1441 +      <AdditionalIncludeDirectories>..\..\public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
 61.1442 +    </ResourceCompile>
 61.1443 +    <Link>
 61.1444 +      <AdditionalDependencies>$(HL2SDKCSS)\lib\public\tier0.lib;$(HL2SDKCSS)\lib\public\tier1.lib;$(HL2SDKCSS)\lib\public\vstdlib.lib;$(HL2SDKCSS)\lib\public\mathlib.lib;Wsock32.lib;%(AdditionalDependencies)</AdditionalDependencies>
 61.1445 +      <OutputFile>$(OutDir)$(TargetFileName)</OutputFile>
 61.1446 +      <IgnoreSpecificDefaultLibraries>LIBC;LIBCD;LIBCMTD;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
 61.1447 +      <GenerateDebugInformation>true</GenerateDebugInformation>
 61.1448 +      <SubSystem>Windows</SubSystem>
 61.1449 +      <OptimizeReferences>true</OptimizeReferences>
 61.1450 +      <EnableCOMDATFolding>true</EnableCOMDATFolding>
 61.1451 +      <RandomizedBaseAddress>false</RandomizedBaseAddress>
 61.1452 +      <DataExecutionPrevention>
 61.1453 +      </DataExecutionPrevention>
 61.1454 +      <TargetMachine>MachineX86</TargetMachine>
 61.1455 +    </Link>
 61.1456 +    <PostBuildEvent>
 61.1457 +      <Command>IF NOT "%SMOUTDIR%"=="" copy /Y "$(TargetDir)$(TargetFileName)" "%SMOUTDIR%\bin"</Command>
 61.1458 +    </PostBuildEvent>
 61.1459 +  </ItemDefinitionGroup>
 61.1460 +  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Left 4 Dead 2|Win32'">
 61.1461 +    <ClCompile>
 61.1462 +      <AdditionalOptions>/D SE_EPISODEONE=1 /D SE_DARKMESSIAH=2 /D SE_ORANGEBOX=3 /D SE_BLOODYGOODTIME=4 /D SE_EYE=5 /D SE_CSS=6 /D SE_ORANGEBOXVALVE=7 /D SE_LEFT4DEAD=8 /D SE_LEFT4DEAD2=9 /D SE_ALIENSWARM=10 /D SE_PORTAL2=11 /D SE_CSGO=12</AdditionalOptions>
 61.1463 +      <Optimization>Disabled</Optimization>
 61.1464 +      <AdditionalIncludeDirectories>..\;..\systems;..\..\public;..\..\public\sourcepawn;$(HL2SDKL4D2)\public;$(HL2SDKL4D2)\public\engine;$(HL2SDKL4D2)\public\game\server;$(HL2SDKL4D2)\public\mathlib;$(HL2SDKL4D2)\public\tier0;$(HL2SDKL4D2)\public\tier1;$(HL2SDKL4D2)\public\vstdlib;$(MMSOURCE19)\core;$(MMSOURCE19)\core\sourcehook;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
 61.1465 +      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;SOURCEMOD_MM_EXPORTS;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;SOURCEMOD_BUILD;SM_DEFAULT_THREADER;SOURCE_ENGINE=9;%(PreprocessorDefinitions)</PreprocessorDefinitions>
 61.1466 +      <MinimalRebuild>true</MinimalRebuild>
 61.1467 +      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
 61.1468 +      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
 61.1469 +      <EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
 61.1470 +      <RuntimeTypeInfo>false</RuntimeTypeInfo>
 61.1471 +      <PrecompiledHeader>
 61.1472 +      </PrecompiledHeader>
 61.1473 +      <WarningLevel>Level3</WarningLevel>
 61.1474 +      <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
 61.1475 +    </ClCompile>
 61.1476 +    <ResourceCompile>
 61.1477 +      <PreprocessorDefinitions>BINARY_NAME="\"$(TargetFileName)\"";%(PreprocessorDefinitions)</PreprocessorDefinitions>
 61.1478 +      <AdditionalIncludeDirectories>..\..\public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
 61.1479 +    </ResourceCompile>
 61.1480 +    <Link>
 61.1481 +      <AdditionalDependencies>$(HL2SDKL4D2)\lib\public\tier0.lib;$(HL2SDKL4D2)\lib\public\tier1.lib;$(HL2SDKL4D2)\lib\public\vstdlib.lib;$(HL2SDKL4D2)\lib\public\mathlib.lib;dbghelp.lib;Wsock32.lib;%(AdditionalDependencies)</AdditionalDependencies>
 61.1482 +      <OutputFile>$(OutDir)$(TargetFileName)</OutputFile>
 61.1483 +      <IgnoreSpecificDefaultLibraries>LIBC;LIBCD;LIBCMT;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
 61.1484 +      <GenerateDebugInformation>true</GenerateDebugInformation>
 61.1485 +      <SubSystem>Windows</SubSystem>
 61.1486 +      <RandomizedBaseAddress>false</RandomizedBaseAddress>
 61.1487 +      <DataExecutionPrevention>
 61.1488 +      </DataExecutionPrevention>
 61.1489 +      <TargetMachine>MachineX86</TargetMachine>
 61.1490 +    </Link>
 61.1491 +    <PostBuildEvent>
 61.1492 +      <Command>IF NOT "%SMOUTDIR%"=="" copy /Y "$(TargetDir)$(TargetFileName)" "%SMOUTDIR%\bin"</Command>
 61.1493 +    </PostBuildEvent>
 61.1494 +  </ItemDefinitionGroup>
 61.1495 +  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug - Left 4 Dead 2|Win32'">
 61.1496 +    <ClCompile>
 61.1497 +      <AdditionalOptions>/D SE_EPISODEONE=1 /D SE_DARKMESSIAH=2 /D SE_ORANGEBOX=3 /D SE_BLOODYGOODTIME=4 /D SE_EYE=5 /D SE_CSS=6 /D SE_ORANGEBOXVALVE=7 /D SE_LEFT4DEAD=8 /D SE_LEFT4DEAD2=9 /D SE_ALIENSWARM=10 /D SE_PORTAL2=11 /D SE_CSGO=12</AdditionalOptions>
 61.1498 +      <Optimization>Disabled</Optimization>
 61.1499 +      <AdditionalIncludeDirectories>..\;..\systems;..\..\public;..\..\public\sourcepawn;$(HL2SDKL4D2)\public;$(HL2SDKL4D2)\public\engine;$(HL2SDKL4D2)\public\game\server;$(HL2SDKL4D2)\public\mathlib;$(HL2SDKL4D2)\public\tier0;$(HL2SDKL4D2)\public\tier1;$(HL2SDKL4D2)\public\vstdlib;$(MMSOURCE19)\core;$(MMSOURCE19)\core\sourcehook;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
 61.1500 +      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;SOURCEMOD_MM_EXPORTS;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;SOURCEMOD_BUILD;SM_DEFAULT_THREADER;SOURCE_ENGINE=9;%(PreprocessorDefinitions)</PreprocessorDefinitions>
 61.1501 +      <MinimalRebuild>true</MinimalRebuild>
 61.1502 +      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
 61.1503 +      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
 61.1504 +      <EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
 61.1505 +      <RuntimeTypeInfo>false</RuntimeTypeInfo>
 61.1506 +      <PrecompiledHeader>
 61.1507 +      </PrecompiledHeader>
 61.1508 +      <WarningLevel>Level3</WarningLevel>
 61.1509 +      <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
 61.1510 +    </ClCompile>
 61.1511 +    <ResourceCompile>
 61.1512 +      <PreprocessorDefinitions>BINARY_NAME="\"$(TargetFileName)\"";%(PreprocessorDefinitions)</PreprocessorDefinitions>
 61.1513 +      <AdditionalIncludeDirectories>..\..\public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
 61.1514 +    </ResourceCompile>
 61.1515 +    <Link>
 61.1516 +      <AdditionalDependencies>$(HL2SDKL4D2)\lib\public\tier0.lib;$(HL2SDKL4D2)\lib\public\tier1.lib;$(HL2SDKL4D2)\lib\public\vstdlib.lib;$(HL2SDKL4D2)\lib\public\mathlib.lib;Wsock32.lib;%(AdditionalDependencies)</AdditionalDependencies>
 61.1517 +      <OutputFile>$(OutDir)$(TargetFileName)</OutputFile>
 61.1518 +      <IgnoreSpecificDefaultLibraries>LIBC;LIBCD;LIBCMT;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
 61.1519 +      <GenerateDebugInformation>true</GenerateDebugInformation>
 61.1520 +      <SubSystem>Windows</SubSystem>
 61.1521 +      <RandomizedBaseAddress>false</RandomizedBaseAddress>
 61.1522 +      <DataExecutionPrevention>
 61.1523 +      </DataExecutionPrevention>
 61.1524 +      <TargetMachine>MachineX86</TargetMachine>
 61.1525 +    </Link>
 61.1526 +    <PostBuildEvent>
 61.1527 +      <Command>IF NOT "%SMOUTDIR%"=="" copy /Y "$(TargetDir)$(TargetFileName)" "%SMOUTDIR%\bin"</Command>
 61.1528 +    </PostBuildEvent>
 61.1529 +  </ItemDefinitionGroup>
 61.1530 +  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release - Left 4 Dead 2|Win32'">
 61.1531 +    <ClCompile>
 61.1532 +      <AdditionalOptions>/D SE_EPISODEONE=1 /D SE_DARKMESSIAH=2 /D SE_ORANGEBOX=3 /D SE_BLOODYGOODTIME=4 /D SE_EYE=5 /D SE_CSS=6 /D SE_ORANGEBOXVALVE=7 /D SE_LEFT4DEAD=8 /D SE_LEFT4DEAD2=9 /D SE_ALIENSWARM=10 /D SE_PORTAL2=11 /D SE_CSGO=12</AdditionalOptions>
 61.1533 +      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
 61.1534 +      <AdditionalIncludeDirectories>..\;..\systems;..\..\public;..\..\public\sourcepawn;$(HL2SDKL4D2)\public;$(HL2SDKL4D2)\public\engine;$(HL2SDKL4D2)\public\game\server;$(HL2SDKL4D2)\public\mathlib;$(HL2SDKL4D2)\public\tier0;$(HL2SDKL4D2)\public\tier1;$(HL2SDKL4D2)\public\vstdlib;$(MMSOURCE19)\core;$(MMSOURCE19)\core\sourcehook;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
 61.1535 +      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;SOURCEMOD_MM_EXPORTS;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;SOURCEMOD_BUILD;SM_DEFAULT_THREADER;SOURCE_ENGINE=9;%(PreprocessorDefinitions)</PreprocessorDefinitions>
 61.1536 +      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
 61.1537 +      <EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
 61.1538 +      <RuntimeTypeInfo>false</RuntimeTypeInfo>
 61.1539 +      <PrecompiledHeader>
 61.1540 +      </PrecompiledHeader>
 61.1541 +      <WarningLevel>Level3</WarningLevel>
 61.1542 +      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
 61.1543 +      <MultiProcessorCompilation>true</MultiProcessorCompilation>
 61.1544 +    </ClCompile>
 61.1545 +    <ResourceCompile>
 61.1546 +      <PreprocessorDefinitions>BINARY_NAME="\"$(TargetFileName)\"";%(PreprocessorDefinitions)</PreprocessorDefinitions>
 61.1547 +      <AdditionalIncludeDirectories>..\..\public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
 61.1548 +    </ResourceCompile>
 61.1549 +    <Link>
 61.1550 +      <AdditionalDependencies>$(HL2SDKL4D2)\lib\public\tier0.lib;$(HL2SDKL4D2)\lib\public\tier1.lib;$(HL2SDKL4D2)\lib\public\vstdlib.lib;$(HL2SDKL4D2)\lib\public\mathlib.lib;Wsock32.lib;%(AdditionalDependencies)</AdditionalDependencies>
 61.1551 +      <OutputFile>$(OutDir)$(TargetFileName)</OutputFile>
 61.1552 +      <IgnoreSpecificDefaultLibraries>LIBC;LIBCD;LIBCMTD;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
 61.1553 +      <GenerateDebugInformation>true</GenerateDebugInformation>
 61.1554 +      <SubSystem>Windows</SubSystem>
 61.1555 +      <OptimizeReferences>true</OptimizeReferences>
 61.1556 +      <EnableCOMDATFolding>true</EnableCOMDATFolding>
 61.1557 +      <RandomizedBaseAddress>false</RandomizedBaseAddress>
 61.1558 +      <DataExecutionPrevention>
 61.1559 +      </DataExecutionPrevention>
 61.1560 +      <TargetMachine>MachineX86</TargetMachine>
 61.1561 +    </Link>
 61.1562 +    <PostBuildEvent>
 61.1563 +      <Command>IF NOT "%SMOUTDIR%"=="" copy /Y "$(TargetDir)$(TargetFileName)" "%SMOUTDIR%\bin"</Command>
 61.1564 +    </PostBuildEvent>
 61.1565 +  </ItemDefinitionGroup>
 61.1566 +  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Bloody Good Time|Win32'">
 61.1567 +    <ClCompile>
 61.1568 +      <AdditionalOptions>/D SE_EPISODEONE=1 /D SE_DARKMESSIAH=2 /D SE_ORANGEBOX=3 /D SE_BLOODYGOODTIME=4 /D SE_EYE=5 /D SE_CSS=6 /D SE_ORANGEBOXVALVE=7 /D SE_LEFT4DEAD=8 /D SE_LEFT4DEAD2=9 /D SE_ALIENSWARM=10 /D SE_PORTAL2=11 /D SE_CSGO=12</AdditionalOptions>
 61.1569 +      <Optimization>Disabled</Optimization>
 61.1570 +      <AdditionalIncludeDirectories>..\;..\systems;..\..\public;..\..\public\sourcepawn;$(HL2SDK-BGT)\public;$(HL2SDK-BGT)\public\engine;$(HL2SDK-BGT)\public\game\server;$(HL2SDK-BGT)\public\mathlib;$(HL2SDK-BGT)\public\tier0;$(HL2SDK-BGT)\public\tier1;$(HL2SDK-BGT)\public\vstdlib;$(MMSOURCE19)\core;$(MMSOURCE19)\core\sourcehook;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
 61.1571 +      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;SOURCEMOD_MM_EXPORTS;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;SOURCEMOD_BUILD;SM_DEFAULT_THREADER;SOURCE_ENGINE=4;%(PreprocessorDefinitions)</PreprocessorDefinitions>
 61.1572 +      <MinimalRebuild>true</MinimalRebuild>
 61.1573 +      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
 61.1574 +      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
 61.1575 +      <EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
 61.1576 +      <RuntimeTypeInfo>false</RuntimeTypeInfo>
 61.1577 +      <PrecompiledHeader>
 61.1578 +      </PrecompiledHeader>
 61.1579 +      <WarningLevel>Level3</WarningLevel>
 61.1580 +      <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
 61.1581 +    </ClCompile>
 61.1582 +    <ResourceCompile>
 61.1583 +      <PreprocessorDefinitions>BINARY_NAME="\"$(TargetFileName)\"";%(PreprocessorDefinitions)</PreprocessorDefinitions>
 61.1584 +      <AdditionalIncludeDirectories>..\..\public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
 61.1585 +    </ResourceCompile>
 61.1586 +    <Link>
 61.1587 +      <AdditionalDependencies>$(HL2SDK-BGT)\lib\public\tier0.lib;$(HL2SDK-BGT)\lib\public\tier1.lib;$(HL2SDK-BGT)\lib\public\vstdlib.lib;$(HL2SDK-BGT)\lib\public\mathlib.lib;dbghelp.lib;Wsock32.lib;%(AdditionalDependencies)</AdditionalDependencies>
 61.1588 +      <OutputFile>$(OutDir)$(TargetFileName)</OutputFile>
 61.1589 +      <IgnoreSpecificDefaultLibraries>LIBC;LIBCD;LIBCMT;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
 61.1590 +      <GenerateDebugInformation>true</GenerateDebugInformation>
 61.1591 +      <SubSystem>Windows</SubSystem>
 61.1592 +      <RandomizedBaseAddress>false</RandomizedBaseAddress>
 61.1593 +      <DataExecutionPrevention>
 61.1594 +      </DataExecutionPrevention>
 61.1595 +      <TargetMachine>MachineX86</TargetMachine>
 61.1596 +    </Link>
 61.1597 +    <PostBuildEvent>
 61.1598 +      <Command>IF NOT "%SMOUTDIR%"=="" copy /Y "$(TargetDir)$(TargetFileName)" "%SMOUTDIR%\bin"</Command>
 61.1599 +    </PostBuildEvent>
 61.1600 +  </ItemDefinitionGroup>
 61.1601 +  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug - Bloody Good Time|Win32'">
 61.1602 +    <ClCompile>
 61.1603 +      <AdditionalOptions>/D SE_EPISODEONE=1 /D SE_DARKMESSIAH=2 /D SE_ORANGEBOX=3 /D SE_BLOODYGOODTIME=4 /D SE_EYE=5 /D SE_CSS=6 /D SE_ORANGEBOXVALVE=7 /D SE_LEFT4DEAD=8 /D SE_LEFT4DEAD2=9 /D SE_ALIENSWARM=10 /D SE_PORTAL2=11 /D SE_CSGO=12</AdditionalOptions>
 61.1604 +      <Optimization>Disabled</Optimization>
 61.1605 +      <AdditionalIncludeDirectories>..\;..\systems;..\..\public;..\..\public\sourcepawn;$(HL2SDK-BGT)\public;$(HL2SDK-BGT)\public\engine;$(HL2SDK-BGT)\public\game\server;$(HL2SDK-BGT)\public\mathlib;$(HL2SDK-BGT)\public\tier0;$(HL2SDK-BGT)\public\tier1;$(HL2SDK-BGT)\public\vstdlib;$(MMSOURCE19)\core;$(MMSOURCE19)\core\sourcehook;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
 61.1606 +      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;SOURCEMOD_MM_EXPORTS;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;SOURCEMOD_BUILD;SM_DEFAULT_THREADER;SOURCE_ENGINE=4;%(PreprocessorDefinitions)</PreprocessorDefinitions>
 61.1607 +      <MinimalRebuild>true</MinimalRebuild>
 61.1608 +      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
 61.1609 +      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
 61.1610 +      <EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
 61.1611 +      <RuntimeTypeInfo>false</RuntimeTypeInfo>
 61.1612 +      <PrecompiledHeader>
 61.1613 +      </PrecompiledHeader>
 61.1614 +      <WarningLevel>Level3</WarningLevel>
 61.1615 +      <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
 61.1616 +    </ClCompile>
 61.1617 +    <ResourceCompile>
 61.1618 +      <PreprocessorDefinitions>BINARY_NAME="\"$(TargetFileName)\"";%(PreprocessorDefinitions)</PreprocessorDefinitions>
 61.1619 +      <AdditionalIncludeDirectories>..\..\public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
 61.1620 +    </ResourceCompile>
 61.1621 +    <Link>
 61.1622 +      <AdditionalDependencies>$(HL2SDK-BGT)\lib\public\tier0.lib;$(HL2SDK-BGT)\lib\public\tier1.lib;$(HL2SDK-BGT)\lib\public\vstdlib.lib;$(HL2SDK-BGT)\lib\public\mathlib.lib;Wsock32.lib;%(AdditionalDependencies)</AdditionalDependencies>
 61.1623 +      <OutputFile>$(OutDir)$(TargetFileName)</OutputFile>
 61.1624 +      <IgnoreSpecificDefaultLibraries>LIBC;LIBCD;LIBCMT;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
 61.1625 +      <GenerateDebugInformation>true</GenerateDebugInformation>
 61.1626 +      <SubSystem>Windows</SubSystem>
 61.1627 +      <RandomizedBaseAddress>false</RandomizedBaseAddress>
 61.1628 +      <DataExecutionPrevention>
 61.1629 +      </DataExecutionPrevention>
 61.1630 +      <TargetMachine>MachineX86</TargetMachine>
 61.1631 +    </Link>
 61.1632 +    <PostBuildEvent>
 61.1633 +      <Command>IF NOT "%SMOUTDIR%"=="" copy /Y "$(TargetDir)$(TargetFileName)" "%SMOUTDIR%\bin"</Command>
 61.1634 +    </PostBuildEvent>
 61.1635 +  </ItemDefinitionGroup>
 61.1636 +  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release - Bloody Good Time|Win32'">
 61.1637 +    <ClCompile>
 61.1638 +      <AdditionalOptions>/D SE_EPISODEONE=1 /D SE_DARKMESSIAH=2 /D SE_ORANGEBOX=3 /D SE_BLOODYGOODTIME=4 /D SE_EYE=5 /D SE_CSS=6 /D SE_ORANGEBOXVALVE=7 /D SE_LEFT4DEAD=8 /D SE_LEFT4DEAD2=9 /D SE_ALIENSWARM=10 /D SE_PORTAL2=11 /D SE_CSGO=12</AdditionalOptions>
 61.1639 +      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
 61.1640 +      <AdditionalIncludeDirectories>..\;..\systems;..\..\public;..\..\public\sourcepawn;$(HL2SDK-BGT)\public;$(HL2SDK-BGT)\public\engine;$(HL2SDK-BGT)\public\game\server;$(HL2SDK-BGT)\public\mathlib;$(HL2SDK-BGT)\public\tier0;$(HL2SDK-BGT)\public\tier1;$(HL2SDK-BGT)\public\vstdlib;$(MMSOURCE19)\core;$(MMSOURCE19)\core\sourcehook;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
 61.1641 +      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;SOURCEMOD_MM_EXPORTS;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;SOURCEMOD_BUILD;SM_DEFAULT_THREADER;SOURCE_ENGINE=4;%(PreprocessorDefinitions)</PreprocessorDefinitions>
 61.1642 +      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
 61.1643 +      <EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
 61.1644 +      <RuntimeTypeInfo>false</RuntimeTypeInfo>
 61.1645 +      <PrecompiledHeader>
 61.1646 +      </PrecompiledHeader>
 61.1647 +      <AssemblerOutput>
 61.1648 +      </AssemblerOutput>
 61.1649 +      <WarningLevel>Level3</WarningLevel>
 61.1650 +      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
 61.1651 +      <MultiProcessorCompilation>true</MultiProcessorCompilation>
 61.1652 +    </ClCompile>
 61.1653 +    <ResourceCompile>
 61.1654 +      <PreprocessorDefinitions>BINARY_NAME="\"$(TargetFileName)\"";%(PreprocessorDefinitions)</PreprocessorDefinitions>
 61.1655 +      <AdditionalIncludeDirectories>..\..\public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
 61.1656 +    </ResourceCompile>
 61.1657 +    <Link>
 61.1658 +      <AdditionalDependencies>$(HL2SDK-BGT)\lib\public\tier0.lib;$(HL2SDK-BGT)\lib\public\tier1.lib;$(HL2SDK-BGT)\lib\public\vstdlib.lib;$(HL2SDK-BGT)\lib\public\mathlib.lib;Wsock32.lib;%(AdditionalDependencies)</AdditionalDependencies>
 61.1659 +      <OutputFile>$(OutDir)$(TargetFileName)</OutputFile>
 61.1660 +      <IgnoreSpecificDefaultLibraries>LIBC;LIBCD;LIBCMTD;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
 61.1661 +      <GenerateDebugInformation>true</GenerateDebugInformation>
 61.1662 +      <SubSystem>Windows</SubSystem>
 61.1663 +      <OptimizeReferences>true</OptimizeReferences>
 61.1664 +      <EnableCOMDATFolding>true</EnableCOMDATFolding>
 61.1665 +      <RandomizedBaseAddress>false</RandomizedBaseAddress>
 61.1666 +      <DataExecutionPrevention>
 61.1667 +      </DataExecutionPrevention>
 61.1668 +      <TargetMachine>MachineX86</TargetMachine>
 61.1669 +    </Link>
 61.1670 +    <PostBuildEvent>
 61.1671 +      <Command>IF NOT "%SMOUTDIR%"=="" copy /Y "$(TargetDir)$(TargetFileName)" "%SMOUTDIR%\bin"</Command>
 61.1672 +    </PostBuildEvent>
 61.1673 +  </ItemDefinitionGroup>
 61.1674 +  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - EYE|Win32'">
 61.1675 +    <ClCompile>
 61.1676 +      <AdditionalOptions>/D SE_EPISODEONE=1 /D SE_DARKMESSIAH=2 /D SE_ORANGEBOX=3 /D SE_BLOODYGOODTIME=4 /D SE_EYE=5 /D SE_CSS=6 /D SE_ORANGEBOXVALVE=7 /D SE_LEFT4DEAD=8 /D SE_LEFT4DEAD2=9 /D SE_ALIENSWARM=10 /D SE_PORTAL2=11 /D SE_CSGO=12</AdditionalOptions>
 61.1677 +      <Optimization>Disabled</Optimization>
 61.1678 +      <AdditionalIncludeDirectories>..\;..\systems;..\..\public;..\..\public\sourcepawn;$(HL2SDK-EYE)\public;$(HL2SDK-EYE)\public\engine;$(HL2SDK-EYE)\public\game\server;$(HL2SDK-EYE)\public\mathlib;$(HL2SDK-EYE)\public\tier0;$(HL2SDK-EYE)\public\tier1;$(HL2SDK-EYE)\public\vstdlib;$(MMSOURCE19)\core;$(MMSOURCE19)\core\sourcehook;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
 61.1679 +      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;SOURCEMOD_MM_EXPORTS;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;SOURCEMOD_BUILD;SM_DEFAULT_THREADER;SOURCE_ENGINE=5;%(PreprocessorDefinitions)</PreprocessorDefinitions>
 61.1680 +      <MinimalRebuild>true</MinimalRebuild>
 61.1681 +      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
 61.1682 +      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
 61.1683 +      <EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
 61.1684 +      <RuntimeTypeInfo>false</RuntimeTypeInfo>
 61.1685 +      <PrecompiledHeader>
 61.1686 +      </PrecompiledHeader>
 61.1687 +      <WarningLevel>Level3</WarningLevel>
 61.1688 +      <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
 61.1689 +    </ClCompile>
 61.1690 +    <ResourceCompile>
 61.1691 +      <PreprocessorDefinitions>BINARY_NAME="\"$(TargetFileName)\"";%(PreprocessorDefinitions)</PreprocessorDefinitions>
 61.1692 +      <AdditionalIncludeDirectories>..\..\public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
 61.1693 +    </ResourceCompile>
 61.1694 +    <Link>
 61.1695 +      <AdditionalDependencies>$(HL2SDK-EYE)\lib\public\tier0.lib;$(HL2SDK-EYE)\lib\public\tier1.lib;$(HL2SDK-EYE)\lib\public\vstdlib.lib;$(HL2SDK-EYE)\lib\public\mathlib.lib;dbghelp.lib;Wsock32.lib;%(AdditionalDependencies)</AdditionalDependencies>
 61.1696 +      <OutputFile>$(OutDir)$(TargetFileName)</OutputFile>
 61.1697 +      <IgnoreSpecificDefaultLibraries>LIBC;LIBCD;LIBCMT;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
 61.1698 +      <GenerateDebugInformation>true</GenerateDebugInformation>
 61.1699 +      <SubSystem>Windows</SubSystem>
 61.1700 +      <RandomizedBaseAddress>false</RandomizedBaseAddress>
 61.1701 +      <DataExecutionPrevention>
 61.1702 +      </DataExecutionPrevention>
 61.1703 +      <TargetMachine>MachineX86</TargetMachine>
 61.1704 +    </Link>
 61.1705 +    <PostBuildEvent>
 61.1706 +      <Command>IF NOT "%SMOUTDIR%"=="" copy /Y "$(TargetDir)$(TargetFileName)" "%SMOUTDIR%\bin"</Command>
 61.1707 +    </PostBuildEvent>
 61.1708 +  </ItemDefinitionGroup>
 61.1709 +  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug - EYE|Win32'">
 61.1710 +    <ClCompile>
 61.1711 +      <AdditionalOptions>/D SE_EPISODEONE=1 /D SE_DARKMESSIAH=2 /D SE_ORANGEBOX=3 /D SE_BLOODYGOODTIME=4 /D SE_EYE=5 /D SE_CSS=6 /D SE_ORANGEBOXVALVE=7 /D SE_LEFT4DEAD=8 /D SE_LEFT4DEAD2=9 /D SE_ALIENSWARM=10 /D SE_PORTAL2=11 /D SE_CSGO=12</AdditionalOptions>
 61.1712 +      <Optimization>Disabled</Optimization>
 61.1713 +      <AdditionalIncludeDirectories>..\;..\systems;..\..\public;..\..\public\sourcepawn;$(HL2SDK-EYE)\public;$(HL2SDK-EYE)\public\engine;$(HL2SDK-EYE)\public\game\server;$(HL2SDK-EYE)\public\mathlib;$(HL2SDK-EYE)\public\tier0;$(HL2SDK-EYE)\public\tier1;$(HL2SDK-EYE)\public\vstdlib;$(MMSOURCE19)\core;$(MMSOURCE19)\core\sourcehook;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
 61.1714 +      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;SOURCEMOD_MM_EXPORTS;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;SOURCEMOD_BUILD;SM_DEFAULT_THREADER;SOURCE_ENGINE=5;%(PreprocessorDefinitions)</PreprocessorDefinitions>
 61.1715 +      <MinimalRebuild>true</MinimalRebuild>
 61.1716 +      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
 61.1717 +      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
 61.1718 +      <EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
 61.1719 +      <RuntimeTypeInfo>false</RuntimeTypeInfo>
 61.1720 +      <PrecompiledHeader>
 61.1721 +      </PrecompiledHeader>
 61.1722 +      <WarningLevel>Level3</WarningLevel>
 61.1723 +      <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
 61.1724 +    </ClCompile>
 61.1725 +    <ResourceCompile>
 61.1726 +      <PreprocessorDefinitions>BINARY_NAME="\"$(TargetFileName)\"";%(PreprocessorDefinitions)</PreprocessorDefinitions>
 61.1727 +      <AdditionalIncludeDirectories>..\..\public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
 61.1728 +    </ResourceCompile>
 61.1729 +    <Link>
 61.1730 +      <AdditionalDependencies>$(HL2SDK-EYE)\lib\public\tier0.lib;$(HL2SDK-EYE)\lib\public\tier1.lib;$(HL2SDK-EYE)\lib\public\vstdlib.lib;$(HL2SDK-EYE)\lib\public\mathlib.lib;Wsock32.lib;%(AdditionalDependencies)</AdditionalDependencies>
 61.1731 +      <OutputFile>$(OutDir)$(TargetFileName)</OutputFile>
 61.1732 +      <IgnoreSpecificDefaultLibraries>LIBC;LIBCD;LIBCMT;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
 61.1733 +      <GenerateDebugInformation>true</GenerateDebugInformation>
 61.1734 +      <SubSystem>Windows</SubSystem>
 61.1735 +      <RandomizedBaseAddress>false</RandomizedBaseAddress>
 61.1736 +      <DataExecutionPrevention>
 61.1737 +      </DataExecutionPrevention>
 61.1738 +      <TargetMachine>MachineX86</TargetMachine>
 61.1739 +    </Link>
 61.1740 +    <PostBuildEvent>
 61.1741 +      <Command>IF NOT "%SMOUTDIR%"=="" copy /Y "$(TargetDir)$(TargetFileName)" "%SMOUTDIR%\bin"</Command>
 61.1742 +    </PostBuildEvent>
 61.1743 +  </ItemDefinitionGroup>
 61.1744 +  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release - EYE|Win32'">
 61.1745 +    <ClCompile>
 61.1746 +      <AdditionalOptions>/D SE_EPISODEONE=1 /D SE_DARKMESSIAH=2 /D SE_ORANGEBOX=3 /D SE_BLOODYGOODTIME=4 /D SE_EYE=5 /D SE_CSS=6 /D SE_ORANGEBOXVALVE=7 /D SE_LEFT4DEAD=8 /D SE_LEFT4DEAD2=9 /D SE_ALIENSWARM=10 /D SE_PORTAL2=11 /D SE_CSGO=12</AdditionalOptions>
 61.1747 +      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
 61.1748 +      <AdditionalIncludeDirectories>..\;..\systems;..\..\public;..\..\public\sourcepawn;$(HL2SDK-EYE)\public;$(HL2SDK-EYE)\public\engine;$(HL2SDK-EYE)\public\game\server;$(HL2SDK-EYE)\public\mathlib;$(HL2SDK-EYE)\public\tier0;$(HL2SDK-EYE)\public\tier1;$(HL2SDK-EYE)\public\vstdlib;$(MMSOURCE19)\core;$(MMSOURCE19)\core\sourcehook;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
 61.1749 +      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;SOURCEMOD_MM_EXPORTS;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;SOURCEMOD_BUILD;SM_DEFAULT_THREADER;SOURCE_ENGINE=5;%(PreprocessorDefinitions)</PreprocessorDefinitions>
 61.1750 +      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
 61.1751 +      <EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
 61.1752 +      <RuntimeTypeInfo>false</RuntimeTypeInfo>
 61.1753 +      <PrecompiledHeader>
 61.1754 +      </PrecompiledHeader>
 61.1755 +      <AssemblerOutput>
 61.1756 +      </AssemblerOutput>
 61.1757 +      <WarningLevel>Level3</WarningLevel>
 61.1758 +      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
 61.1759 +      <MultiProcessorCompilation>true</MultiProcessorCompilation>
 61.1760 +    </ClCompile>
 61.1761 +    <ResourceCompile>
 61.1762 +      <PreprocessorDefinitions>BINARY_NAME="\"$(TargetFileName)\"";%(PreprocessorDefinitions)</PreprocessorDefinitions>
 61.1763 +      <AdditionalIncludeDirectories>..\..\public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
 61.1764 +    </ResourceCompile>
 61.1765 +    <Link>
 61.1766 +      <AdditionalDependencies>$(HL2SDK-EYE)\lib\public\tier0.lib;$(HL2SDK-EYE)\lib\public\tier1.lib;$(HL2SDK-EYE)\lib\public\vstdlib.lib;$(HL2SDK-EYE)\lib\public\mathlib.lib;Wsock32.lib;%(AdditionalDependencies)</AdditionalDependencies>
 61.1767 +      <OutputFile>$(OutDir)$(TargetFileName)</OutputFile>
 61.1768 +      <IgnoreSpecificDefaultLibraries>LIBC;LIBCD;LIBCMTD;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
 61.1769 +      <GenerateDebugInformation>true</GenerateDebugInformation>
 61.1770 +      <SubSystem>Windows</SubSystem>
 61.1771 +      <OptimizeReferences>true</OptimizeReferences>
 61.1772 +      <EnableCOMDATFolding>true</EnableCOMDATFolding>
 61.1773 +      <RandomizedBaseAddress>false</RandomizedBaseAddress>
 61.1774 +      <DataExecutionPrevention>
 61.1775 +      </DataExecutionPrevention>
 61.1776 +      <TargetMachine>MachineX86</TargetMachine>
 61.1777 +    </Link>
 61.1778 +    <PostBuildEvent>
 61.1779 +      <Command>IF NOT "%SMOUTDIR%"=="" copy /Y "$(TargetDir)$(TargetFileName)" "%SMOUTDIR%\bin"</Command>
 61.1780 +    </PostBuildEvent>
 61.1781 +  </ItemDefinitionGroup>
 61.1782 +  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Alien Swarm|Win32'">
 61.1783 +    <ClCompile>
 61.1784 +      <AdditionalOptions>/D SE_EPISODEONE=1 /D SE_DARKMESSIAH=2 /D SE_ORANGEBOX=3 /D SE_BLOODYGOODTIME=4 /D SE_EYE=5 /D SE_CSS=6 /D SE_ORANGEBOXVALVE=7 /D SE_LEFT4DEAD=8 /D SE_LEFT4DEAD2=9 /D SE_ALIENSWARM=10 /D SE_PORTAL2=11 /D SE_CSGO=12</AdditionalOptions>
 61.1785 +      <Optimization>Disabled</Optimization>
 61.1786 +      <AdditionalIncludeDirectories>..\;..\systems;..\..\public;..\..\public\sourcepawn;$(HL2SDK-SWARM)\public;$(HL2SDK-SWARM)\public\engine;$(HL2SDK-SWARM)\public\game\server;$(HL2SDK-SWARM)\public\mathlib;$(HL2SDK-SWARM)\public\tier0;$(HL2SDK-SWARM)\public\tier1;$(HL2SDK-SWARM)\public\vstdlib;$(MMSOURCE19)\core;$(MMSOURCE19)\core\sourcehook;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
 61.1787 +      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;SOURCEMOD_MM_EXPORTS;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;SOURCEMOD_BUILD;SM_DEFAULT_THREADER;SOURCE_ENGINE=10;COMPILER_MSVC;COMPILER_MSVC32;%(PreprocessorDefinitions)</PreprocessorDefinitions>
 61.1788 +      <MinimalRebuild>true</MinimalRebuild>
 61.1789 +      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
 61.1790 +      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
 61.1791 +      <EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
 61.1792 +      <RuntimeTypeInfo>false</RuntimeTypeInfo>
 61.1793 +      <PrecompiledHeader>
 61.1794 +      </PrecompiledHeader>
 61.1795 +      <WarningLevel>Level3</WarningLevel>
 61.1796 +      <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
 61.1797 +    </ClCompile>
 61.1798 +    <ResourceCompile>
 61.1799 +      <PreprocessorDefinitions>BINARY_NAME="\"$(TargetFileName)\"";%(PreprocessorDefinitions)</PreprocessorDefinitions>
 61.1800 +      <AdditionalIncludeDirectories>..\..\public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
 61.1801 +    </ResourceCompile>
 61.1802 +    <Link>
 61.1803 +      <AdditionalDependencies>$(HL2SDK-SWARM)\lib\public\tier0.lib;$(HL2SDK-SWARM)\lib\public\tier1.lib;$(HL2SDK-SWARM)\lib\public\vstdlib.lib;$(HL2SDK-SWARM)\lib\public\mathlib.lib;$(HL2SDK-SWARM)\lib\public\interfaces.lib;dbghelp.lib;Wsock32.lib;%(AdditionalDependencies)</AdditionalDependencies>
 61.1804 +      <OutputFile>$(OutDir)$(TargetFileName)</OutputFile>
 61.1805 +      <IgnoreSpecificDefaultLibraries>LIBC;LIBCD;LIBCMT;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
 61.1806 +      <GenerateDebugInformation>true</GenerateDebugInformation>
 61.1807 +      <SubSystem>Windows</SubSystem>
 61.1808 +      <RandomizedBaseAddress>false</RandomizedBaseAddress>
 61.1809 +      <DataExecutionPrevention>
 61.1810 +      </DataExecutionPrevention>
 61.1811 +      <TargetMachine>MachineX86</TargetMachine>
 61.1812 +    </Link>
 61.1813 +    <PostBuildEvent>
 61.1814 +      <Command>IF NOT "%SMOUTDIR%"=="" copy /Y "$(TargetDir)$(TargetFileName)" "%SMOUTDIR%\bin"</Command>
 61.1815 +    </PostBuildEvent>
 61.1816 +  </ItemDefinitionGroup>
 61.1817 +  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug - Alien Swarm|Win32'">
 61.1818 +    <ClCompile>
 61.1819 +      <AdditionalOptions>/D SE_EPISODEONE=1 /D SE_DARKMESSIAH=2 /D SE_ORANGEBOX=3 /D SE_BLOODYGOODTIME=4 /D SE_EYE=5 /D SE_CSS=6 /D SE_ORANGEBOXVALVE=7 /D SE_LEFT4DEAD=8 /D SE_LEFT4DEAD2=9 /D SE_ALIENSWARM=10 /D SE_PORTAL2=11 /D SE_CSGO=12</AdditionalOptions>
 61.1820 +      <Optimization>Disabled</Optimization>
 61.1821 +      <AdditionalIncludeDirectories>..\;..\systems;..\..\public;..\..\public\sourcepawn;$(HL2SDK-SWARM)\public;$(HL2SDK-SWARM)\public\engine;$(HL2SDK-SWARM)\public\game\server;$(HL2SDK-SWARM)\public\mathlib;$(HL2SDK-SWARM)\public\tier0;$(HL2SDK-SWARM)\public\tier1;$(HL2SDK-SWARM)\public\vstdlib;$(MMSOURCE19)\core;$(MMSOURCE19)\core\sourcehook;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
 61.1822 +      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;SOURCEMOD_MM_EXPORTS;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;SOURCEMOD_BUILD;SM_DEFAULT_THREADER;SOURCE_ENGINE=10;COMPILER_MSVC;COMPILER_MSVC32;%(PreprocessorDefinitions)</PreprocessorDefinitions>
 61.1823 +      <MinimalRebuild>true</MinimalRebuild>
 61.1824 +      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
 61.1825 +      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
 61.1826 +      <EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
 61.1827 +      <RuntimeTypeInfo>false</RuntimeTypeInfo>
 61.1828 +      <PrecompiledHeader>
 61.1829 +      </PrecompiledHeader>
 61.1830 +      <WarningLevel>Level3</WarningLevel>
 61.1831 +      <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
 61.1832 +    </ClCompile>
 61.1833 +    <ResourceCompile>
 61.1834 +      <PreprocessorDefinitions>BINARY_NAME="\"$(TargetFileName)\"";%(PreprocessorDefinitions)</PreprocessorDefinitions>
 61.1835 +      <AdditionalIncludeDirectories>..\..\public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
 61.1836 +    </ResourceCompile>
 61.1837 +    <Link>
 61.1838 +      <AdditionalDependencies>$(HL2SDK-SWARM)\lib\public\tier0.lib;$(HL2SDK-SWARM)\lib\public\tier1.lib;$(HL2SDK-SWARM)\lib\public\vstdlib.lib;$(HL2SDK-SWARM)\lib\public\mathlib.lib;$(HL2SDK-SWARM)\lib\public\interfaces.lib;Wsock32.lib;%(AdditionalDependencies)</AdditionalDependencies>
 61.1839 +      <OutputFile>$(OutDir)$(TargetFileName)</OutputFile>
 61.1840 +      <IgnoreSpecificDefaultLibraries>LIBC;LIBCD;LIBCMT;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
 61.1841 +      <GenerateDebugInformation>true</GenerateDebugInformation>
 61.1842 +      <SubSystem>Windows</SubSystem>
 61.1843 +      <RandomizedBaseAddress>false</RandomizedBaseAddress>
 61.1844 +      <DataExecutionPrevention>
 61.1845 +      </DataExecutionPrevention>
 61.1846 +      <TargetMachine>MachineX86</TargetMachine>
 61.1847 +    </Link>
 61.1848 +    <PostBuildEvent>
 61.1849 +      <Command>IF NOT "%SMOUTDIR%"=="" copy /Y "$(TargetDir)$(TargetFileName)" "%SMOUTDIR%\bin"</Command>
 61.1850 +    </PostBuildEvent>
 61.1851 +  </ItemDefinitionGroup>
 61.1852 +  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release - Alien Swarm|Win32'">
 61.1853 +    <ClCompile>
 61.1854 +      <AdditionalOptions>/D SE_EPISODEONE=1 /D SE_DARKMESSIAH=2 /D SE_ORANGEBOX=3 /D SE_BLOODYGOODTIME=4 /D SE_EYE=5 /D SE_CSS=6 /D SE_ORANGEBOXVALVE=7 /D SE_LEFT4DEAD=8 /D SE_LEFT4DEAD2=9 /D SE_ALIENSWARM=10 /D SE_PORTAL2=11 /D SE_CSGO=12</AdditionalOptions>
 61.1855 +      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
 61.1856 +      <AdditionalIncludeDirectories>..\;..\systems;..\..\public;..\..\public\sourcepawn;$(HL2SDK-SWARM)\public;$(HL2SDK-SWARM)\public\engine;$(HL2SDK-SWARM)\public\game\server;$(HL2SDK-SWARM)\public\mathlib;$(HL2SDK-SWARM)\public\tier0;$(HL2SDK-SWARM)\public\tier1;$(HL2SDK-SWARM)\public\vstdlib;$(MMSOURCE19)\core;$(MMSOURCE19)\core\sourcehook;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
 61.1857 +      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;SOURCEMOD_MM_EXPORTS;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;SOURCEMOD_BUILD;SM_DEFAULT_THREADER;SOURCE_ENGINE=10;COMPILER_MSVC;COMPILER_MSVC32;%(PreprocessorDefinitions)</PreprocessorDefinitions>
 61.1858 +      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
 61.1859 +      <EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
 61.1860 +      <RuntimeTypeInfo>false</RuntimeTypeInfo>
 61.1861 +      <PrecompiledHeader>
 61.1862 +      </PrecompiledHeader>
 61.1863 +      <WarningLevel>Level3</WarningLevel>
 61.1864 +      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
 61.1865 +      <MultiProcessorCompilation>true</MultiProcessorCompilation>
 61.1866 +    </ClCompile>
 61.1867 +    <ResourceCompile>
 61.1868 +      <PreprocessorDefinitions>BINARY_NAME="\"$(TargetFileName)\"";%(PreprocessorDefinitions)</PreprocessorDefinitions>
 61.1869 +      <AdditionalIncludeDirectories>..\..\public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
 61.1870 +    </ResourceCompile>
 61.1871 +    <Link>
 61.1872 +      <AdditionalDependencies>$(HL2SDK-SWARM)\lib\public\tier0.lib;$(HL2SDK-SWARM)\lib\public\tier1.lib;$(HL2SDK-SWARM)\lib\public\vstdlib.lib;$(HL2SDK-SWARM)\lib\public\mathlib.lib;$(HL2SDK-SWARM)\lib\public\interfaces.lib;Wsock32.lib;%(AdditionalDependencies)</AdditionalDependencies>
 61.1873 +      <OutputFile>$(OutDir)$(TargetFileName)</OutputFile>
 61.1874 +      <IgnoreSpecificDefaultLibraries>LIBC;LIBCD;LIBCMTD;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
 61.1875 +      <GenerateDebugInformation>true</GenerateDebugInformation>
 61.1876 +      <SubSystem>Windows</SubSystem>
 61.1877 +      <OptimizeReferences>true</OptimizeReferences>
 61.1878 +      <EnableCOMDATFolding>true</EnableCOMDATFolding>
 61.1879 +      <RandomizedBaseAddress>false</RandomizedBaseAddress>
 61.1880 +      <DataExecutionPrevention>
 61.1881 +      </DataExecutionPrevention>
 61.1882 +      <TargetMachine>MachineX86</TargetMachine>
 61.1883 +    </Link>
 61.1884 +    <PostBuildEvent>
 61.1885 +      <Command>IF NOT "%SMOUTDIR%"=="" copy /Y "$(TargetDir)$(TargetFileName)" "%SMOUTDIR%\bin"</Command>
 61.1886 +    </PostBuildEvent>
 61.1887 +  </ItemDefinitionGroup>
 61.1888 +  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - CS GO|Win32'">
 61.1889 +    <ClCompile>
 61.1890 +      <AdditionalOptions>/D SE_EPISODEONE=1 /D SE_DARKMESSIAH=2 /D SE_ORANGEBOX=3 /D SE_BLOODYGOODTIME=4 /D SE_EYE=5 /D SE_CSS=6 /D SE_ORANGEBOXVALVE=7 /D SE_LEFT4DEAD=8 /D SE_LEFT4DEAD2=9 /D SE_ALIENSWARM=10 /D SE_PORTAL2=11 /D SE_CSGO=12</AdditionalOptions>
 61.1891 +      <Optimization>Disabled</Optimization>
 61.1892 +      <AdditionalIncludeDirectories>..\;..\systems;..\..\public;..\..\public\sourcepawn;$(HL2SDKCSGO)\common\protobuf-2.3.0\src;$(HL2SDKCSGO)\public;$(HL2SDKCSGO)\public\engine;$(HL2SDKCSGO)\public\engine\protobuf;$(HL2SDKCSGO)\public\game\server;$(HL2SDKCSGO)\public\game\shared\csgo\protobuf;$(HL2SDKCSGO)\public\mathlib;$(HL2SDKCSGO)\public\tier0;$(HL2SDKCSGO)\public\tier1;$(HL2SDKCSGO)\public\vstdlib;$(MMSOURCE19)\core;$(MMSOURCE19)\core\sourcehook;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
 61.1893 +      <PreprocessorDefinitions>_ITERATOR_DEBUG_LEVEL=0;WIN32;_DEBUG;_WINDOWS;_USRDLL;SOURCEMOD_MM_EXPORTS;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;SOURCEMOD_BUILD;SM_DEFAULT_THREADER;SOURCE_ENGINE=12;COMPILER_MSVC;COMPILER_MSVC32;%(PreprocessorDefinitions)</PreprocessorDefinitions>
 61.1894 +      <MinimalRebuild>true</MinimalRebuild>
 61.1895 +      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
 61.1896 +      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
 61.1897 +      <EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
 61.1898 +      <RuntimeTypeInfo>false</RuntimeTypeInfo>
 61.1899 +      <PrecompiledHeader>
 61.1900 +      </PrecompiledHeader>
 61.1901 +      <WarningLevel>Level3</WarningLevel>
 61.1902 +      <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
 61.1903 +    </ClCompile>
 61.1904 +    <ResourceCompile>
 61.1905 +      <PreprocessorDefinitions>BINARY_NAME="\"$(TargetFileName)\"";%(PreprocessorDefinitions)</PreprocessorDefinitions>
 61.1906 +      <AdditionalIncludeDirectories>..\..\public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
 61.1907 +    </ResourceCompile>
 61.1908 +    <Link>
 61.1909 +      <AdditionalDependencies>$(HL2SDKCSGO)\lib\public\tier0.lib;$(HL2SDKCSGO)\lib\public\tier1.lib;$(HL2SDKL4D2)\lib\public\vstdlib.lib;$(HL2SDKCSGO)\lib\public\mathlib.lib;$(HL2SDKCSGO)\lib\public\interfaces.lib;dbghelp.lib;Wsock32.lib;%(AdditionalDependencies)</AdditionalDependencies>
 61.1910 +      <OutputFile>$(OutDir)$(TargetFileName)</OutputFile>
 61.1911 +      <IgnoreSpecificDefaultLibraries>LIBC;LIBCD;LIBCMT;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
 61.1912 +      <GenerateDebugInformation>true</GenerateDebugInformation>
 61.1913 +      <SubSystem>Windows</SubSystem>
 61.1914 +      <RandomizedBaseAddress>false</RandomizedBaseAddress>
 61.1915 +      <DataExecutionPrevention>
 61.1916 +      </DataExecutionPrevention>
 61.1917 +      <TargetMachine>MachineX86</TargetMachine>
 61.1918 +    </Link>
 61.1919 +    <PostBuildEvent>
 61.1920 +      <Command>IF NOT "%SMOUTDIR%"=="" copy /Y "$(TargetDir)$(TargetFileName)" "%SMOUTDIR%\bin"</Command>
 61.1921 +    </PostBuildEvent>
 61.1922 +  </ItemDefinitionGroup>
 61.1923 +  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug - CS GO|Win32'">
 61.1924 +    <ClCompile>
 61.1925 +      <AdditionalOptions>/D SE_EPISODEONE=1 /D SE_DARKMESSIAH=2 /D SE_ORANGEBOX=3 /D SE_BLOODYGOODTIME=4 /D SE_EYE=5 /D SE_CSS=6 /D SE_ORANGEBOXVALVE=7 /D SE_LEFT4DEAD=8 /D SE_LEFT4DEAD2=9 /D SE_ALIENSWARM=10 /D SE_PORTAL2=11 /D SE_CSGO=12</AdditionalOptions>
 61.1926 +      <Optimization>Disabled</Optimization>
 61.1927 +      <AdditionalIncludeDirectories>..\;..\systems;..\..\public;..\..\public\sourcepawn;$(HL2SDKCSGO)\common\protobuf-2.3.0\src;$(HL2SDKCSGO)\public;$(HL2SDKCSGO)\public\engine;$(HL2SDKCSGO)\public\engine\protobuf;$(HL2SDKCSGO)\public\game\server;$(HL2SDKCSGO)\public\game\shared\csgo\protobuf;$(HL2SDKCSGO)\public\mathlib;$(HL2SDKCSGO)\public\tier0;$(HL2SDKCSGO)\public\tier1;$(HL2SDKCSGO)\public\vstdlib;$(MMSOURCE19)\core;$(MMSOURCE19)\core\sourcehook;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
 61.1928 +      <PreprocessorDefinitions>_ITERATOR_DEBUG_LEVEL=0;WIN32;_DEBUG;_WINDOWS;_USRDLL;SOURCEMOD_MM_EXPORTS;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;SOURCEMOD_BUILD;SM_DEFAULT_THREADER;SOURCE_ENGINE=12;COMPILER_MSVC;COMPILER_MSVC32;%(PreprocessorDefinitions)</PreprocessorDefinitions>
 61.1929 +      <MinimalRebuild>true</MinimalRebuild>
 61.1930 +      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
 61.1931 +      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
 61.1932 +      <EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
 61.1933 +      <RuntimeTypeInfo>false</RuntimeTypeInfo>
 61.1934 +      <PrecompiledHeader>
 61.1935 +      </PrecompiledHeader>
 61.1936 +      <WarningLevel>Level3</WarningLevel>
 61.1937 +      <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
 61.1938 +    </ClCompile>
 61.1939 +    <ResourceCompile>
 61.1940 +      <PreprocessorDefinitions>BINARY_NAME="\"$(TargetFileName)\"";%(PreprocessorDefinitions)</PreprocessorDefinitions>
 61.1941 +      <AdditionalIncludeDirectories>..\..\public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
 61.1942 +    </ResourceCompile>
 61.1943 +    <Link>
 61.1944 +      <AdditionalDependencies>$(HL2SDKCSGO)\lib\public\tier0.lib;$(HL2SDKCSGO)\lib\public\tier1.lib;$(HL2SDKCSGO)\lib\public\vstdlib.lib;$(HL2SDKCSGO)\lib\public\mathlib.lib;$(HL2SDKCSGO)\lib\public\interfaces.lib;Wsock32.lib;%(AdditionalDependencies)</AdditionalDependencies>
 61.1945 +      <OutputFile>$(OutDir)$(TargetFileName)</OutputFile>
 61.1946 +      <IgnoreSpecificDefaultLibraries>LIBC;LIBCD;LIBCMT;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
 61.1947 +      <GenerateDebugInformation>true</GenerateDebugInformation>
 61.1948 +      <SubSystem>Windows</SubSystem>
 61.1949 +      <RandomizedBaseAddress>false</RandomizedBaseAddress>
 61.1950 +      <DataExecutionPrevention>
 61.1951 +      </DataExecutionPrevention>
 61.1952 +      <TargetMachine>MachineX86</TargetMachine>
 61.1953 +    </Link>
 61.1954 +    <PostBuildEvent>
 61.1955 +      <Command>IF NOT "%SMOUTDIR%"=="" copy /Y "$(TargetDir)$(TargetFileName)" "%SMOUTDIR%\bin"</Command>
 61.1956 +    </PostBuildEvent>
 61.1957 +  </ItemDefinitionGroup>
 61.1958 +  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release - CS GO|Win32'">
 61.1959 +    <ClCompile>
 61.1960 +      <AdditionalOptions>/D SE_EPISODEONE=1 /D SE_DARKMESSIAH=2 /D SE_ORANGEBOX=3 /D SE_BLOODYGOODTIME=4 /D SE_EYE=5 /D SE_CSS=6 /D SE_ORANGEBOXVALVE=7 /D SE_LEFT4DEAD=8 /D SE_LEFT4DEAD2=9 /D SE_ALIENSWARM=10 /D SE_PORTAL2=11 /D SE_CSGO=12</AdditionalOptions>
 61.1961 +      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
 61.1962 +      <AdditionalIncludeDirectories>..\;..\systems;..\..\public;..\..\public\sourcepawn;$(HL2SDKCSGO)\common\protobuf-2.3.0\src;$(HL2SDKCSGO)\public;$(HL2SDKCSGO)\public\engine;$(HL2SDKCSGO)\public\engine\protobuf;$(HL2SDKCSGO)\public\game\server;$(HL2SDKCSGO)\public\game\shared\csgo\protobuf;$(HL2SDKCSGO)\public\mathlib;$(HL2SDKCSGO)\public\tier0;$(HL2SDKCSGO)\public\tier1;$(HL2SDKCSGO)\public\vstdlib;$(MMSOURCE19)\core;$(MMSOURCE19)\core\sourcehook;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
 61.1963 +      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;SOURCEMOD_MM_EXPORTS;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;SOURCEMOD_BUILD;SM_DEFAULT_THREADER;SOURCE_ENGINE=12;COMPILER_MSVC;COMPILER_MSVC32;%(PreprocessorDefinitions)</PreprocessorDefinitions>
 61.1964 +      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
 61.1965 +      <EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
 61.1966 +      <RuntimeTypeInfo>false</RuntimeTypeInfo>
 61.1967 +      <PrecompiledHeader>
 61.1968 +      </PrecompiledHeader>
 61.1969 +      <WarningLevel>Level3</WarningLevel>
 61.1970 +      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
 61.1971 +      <MultiProcessorCompilation>true</MultiProcessorCompilation>
 61.1972 +    </ClCompile>
 61.1973 +    <ResourceCompile>
 61.1974 +      <PreprocessorDefinitions>BINARY_NAME="\"$(TargetFileName)\"";%(PreprocessorDefinitions)</PreprocessorDefinitions>
 61.1975 +      <AdditionalIncludeDirectories>..\..\public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
 61.1976 +    </ResourceCompile>
 61.1977 +    <Link>
 61.1978 +      <AdditionalDependencies>$(HL2SDKCSGO)\lib\public\tier0.lib;$(HL2SDKCSGO)\lib\public\tier1.lib;$(HL2SDKCSGO)\lib\public\vstdlib.lib;$(HL2SDKCSGO)\lib\public\mathlib.lib;$(HL2SDKCSGO)\lib\public\interfaces.lib;Wsock32.lib;%(AdditionalDependencies)</AdditionalDependencies>
 61.1979 +      <OutputFile>$(OutDir)$(TargetFileName)</OutputFile>
 61.1980 +      <IgnoreSpecificDefaultLibraries>LIBC;LIBCD;LIBCMTD;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
 61.1981 +      <GenerateDebugInformation>true</GenerateDebugInformation>
 61.1982 +      <SubSystem>Windows</SubSystem>
 61.1983 +      <OptimizeReferences>true</OptimizeReferences>
 61.1984 +      <EnableCOMDATFolding>true</EnableCOMDATFolding>
 61.1985 +      <RandomizedBaseAddress>false</RandomizedBaseAddress>
 61.1986 +      <DataExecutionPrevention>
 61.1987 +      </DataExecutionPrevention>
 61.1988 +      <TargetMachine>MachineX86</TargetMachine>
 61.1989 +    </Link>
 61.1990 +    <PostBuildEvent>
 61.1991 +      <Command>IF NOT "%SMOUTDIR%"=="" copy /Y "$(TargetDir)$(TargetFileName)" "%SMOUTDIR%\bin"</Command>
 61.1992 +    </PostBuildEvent>
 61.1993 +  </ItemDefinitionGroup>
 61.1994 +  <ItemGroup>
 61.1995 +    <ClCompile Include="..\..\..\hl2sdks\hl2sdk-csgo\public\engine\protobuf\netmessages.pb.cc">
 61.1996 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Alien Swarm|Win32'">true</ExcludedFromBuild>
 61.1997 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Bloody Good Time|Win32'">true</ExcludedFromBuild>
 61.1998 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - CS GO|Win32'">false</ExcludedFromBuild>
 61.1999 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - CSS|Win32'">true</ExcludedFromBuild>
 61.2000 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Dark Messiah|Win32'">true</ExcludedFromBuild>
 61.2001 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Episode 1|Win32'">true</ExcludedFromBuild>
 61.2002 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - EYE|Win32'">true</ExcludedFromBuild>
 61.2003 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Left 4 Dead|Win32'">true</ExcludedFromBuild>
 61.2004 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Left 4 Dead 2|Win32'">true</ExcludedFromBuild>
 61.2005 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Old Metamod|Win32'">true</ExcludedFromBuild>
 61.2006 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Orange Box|Win32'">true</ExcludedFromBuild>
 61.2007 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Orange Box Valve|Win32'">true</ExcludedFromBuild>
 61.2008 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - Orange Box|Win32'">true</ExcludedFromBuild>
 61.2009 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - Alien Swarm|Win32'">true</ExcludedFromBuild>
 61.2010 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - Bloody Good Time|Win32'">true</ExcludedFromBuild>
 61.2011 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - CSS|Win32'">true</ExcludedFromBuild>
 61.2012 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - Dark Messiah|Win32'">true</ExcludedFromBuild>
 61.2013 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - Episode 1|Win32'">true</ExcludedFromBuild>
 61.2014 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - EYE|Win32'">true</ExcludedFromBuild>
 61.2015 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - Left 4 Dead|Win32'">true</ExcludedFromBuild>
 61.2016 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - Left 4 Dead 2|Win32'">true</ExcludedFromBuild>
 61.2017 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - Old Metamod|Win32'">true</ExcludedFromBuild>
 61.2018 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - Orange Box Valve|Win32'">true</ExcludedFromBuild>
 61.2019 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - Orange Box|Win32'">true</ExcludedFromBuild>
 61.2020 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - Alien Swarm|Win32'">true</ExcludedFromBuild>
 61.2021 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - Bloody Good Time|Win32'">true</ExcludedFromBuild>
 61.2022 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - CSS|Win32'">true</ExcludedFromBuild>
 61.2023 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - Dark Messiah|Win32'">true</ExcludedFromBuild>
 61.2024 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - Episode 1|Win32'">true</ExcludedFromBuild>
 61.2025 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - EYE|Win32'">true</ExcludedFromBuild>
 61.2026 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - Left 4 Dead|Win32'">true</ExcludedFromBuild>
 61.2027 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - Left 4 Dead 2|Win32'">true</ExcludedFromBuild>
 61.2028 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - Old Metamod|Win32'">true</ExcludedFromBuild>
 61.2029 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - Orange Box Valve|Win32'">true</ExcludedFromBuild>
 61.2030 +    </ClCompile>
 61.2031 +    <ClCompile Include="..\..\..\hl2sdks\hl2sdk-csgo\public\game\shared\csgo\protobuf\cstrike15_usermessages.pb.cc">
 61.2032 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Alien Swarm|Win32'">true</ExcludedFromBuild>
 61.2033 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Bloody Good Time|Win32'">true</ExcludedFromBuild>
 61.2034 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - CS GO|Win32'">false</ExcludedFromBuild>
 61.2035 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - CSS|Win32'">true</ExcludedFromBuild>
 61.2036 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Dark Messiah|Win32'">true</ExcludedFromBuild>
 61.2037 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Episode 1|Win32'">true</ExcludedFromBuild>
 61.2038 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - EYE|Win32'">true</ExcludedFromBuild>
 61.2039 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Left 4 Dead|Win32'">true</ExcludedFromBuild>
 61.2040 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Left 4 Dead 2|Win32'">true</ExcludedFromBuild>
 61.2041 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Old Metamod|Win32'">true</ExcludedFromBuild>
 61.2042 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Orange Box|Win32'">true</ExcludedFromBuild>
 61.2043 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Orange Box Valve|Win32'">true</ExcludedFromBuild>
 61.2044 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - Orange Box|Win32'">true</ExcludedFromBuild>
 61.2045 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - Alien Swarm|Win32'">true</ExcludedFromBuild>
 61.2046 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - Bloody Good Time|Win32'">true</ExcludedFromBuild>
 61.2047 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - CSS|Win32'">true</ExcludedFromBuild>
 61.2048 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - Dark Messiah|Win32'">true</ExcludedFromBuild>
 61.2049 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - Episode 1|Win32'">true</ExcludedFromBuild>
 61.2050 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - EYE|Win32'">true</ExcludedFromBuild>
 61.2051 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - Left 4 Dead|Win32'">true</ExcludedFromBuild>
 61.2052 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - Left 4 Dead 2|Win32'">true</ExcludedFromBuild>
 61.2053 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - Old Metamod|Win32'">true</ExcludedFromBuild>
 61.2054 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - Orange Box Valve|Win32'">true</ExcludedFromBuild>
 61.2055 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - Orange Box|Win32'">true</ExcludedFromBuild>
 61.2056 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - Alien Swarm|Win32'">true</ExcludedFromBuild>
 61.2057 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - Bloody Good Time|Win32'">true</ExcludedFromBuild>
 61.2058 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - CSS|Win32'">true</ExcludedFromBuild>
 61.2059 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - Dark Messiah|Win32'">true</ExcludedFromBuild>
 61.2060 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - Episode 1|Win32'">true</ExcludedFromBuild>
 61.2061 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - EYE|Win32'">true</ExcludedFromBuild>
 61.2062 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - Left 4 Dead|Win32'">true</ExcludedFromBuild>
 61.2063 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - Left 4 Dead 2|Win32'">true</ExcludedFromBuild>
 61.2064 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - Old Metamod|Win32'">true</ExcludedFromBuild>
 61.2065 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - Orange Box Valve|Win32'">true</ExcludedFromBuild>
 61.2066 +    </ClCompile>
 61.2067 +    <ClCompile Include="..\..\..\hl2sdks\hl2sdk-csgo\public\game\shared\csgo\protobuf\cstrike15_usermessage_helpers.cpp">
 61.2068 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Alien Swarm|Win32'">true</ExcludedFromBuild>
 61.2069 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Bloody Good Time|Win32'">true</ExcludedFromBuild>
 61.2070 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - CS GO|Win32'">false</ExcludedFromBuild>
 61.2071 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - CSS|Win32'">true</ExcludedFromBuild>
 61.2072 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Dark Messiah|Win32'">true</ExcludedFromBuild>
 61.2073 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Episode 1|Win32'">true</ExcludedFromBuild>
 61.2074 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - EYE|Win32'">true</ExcludedFromBuild>
 61.2075 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Left 4 Dead|Win32'">true</ExcludedFromBuild>
 61.2076 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Left 4 Dead 2|Win32'">true</ExcludedFromBuild>
 61.2077 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Old Metamod|Win32'">true</ExcludedFromBuild>
 61.2078 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Orange Box|Win32'">true</ExcludedFromBuild>
 61.2079 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Orange Box Valve|Win32'">true</ExcludedFromBuild>
 61.2080 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - Orange Box|Win32'">true</ExcludedFromBuild>
 61.2081 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - Alien Swarm|Win32'">true</ExcludedFromBuild>
 61.2082 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - Bloody Good Time|Win32'">true</ExcludedFromBuild>
 61.2083 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - CSS|Win32'">true</ExcludedFromBuild>
 61.2084 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - Dark Messiah|Win32'">true</ExcludedFromBuild>
 61.2085 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - Episode 1|Win32'">true</ExcludedFromBuild>
 61.2086 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - EYE|Win32'">true</ExcludedFromBuild>
 61.2087 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - Left 4 Dead|Win32'">true</ExcludedFromBuild>
 61.2088 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - Left 4 Dead 2|Win32'">true</ExcludedFromBuild>
 61.2089 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - Old Metamod|Win32'">true</ExcludedFromBuild>
 61.2090 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - Orange Box Valve|Win32'">true</ExcludedFromBuild>
 61.2091 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - Orange Box|Win32'">true</ExcludedFromBuild>
 61.2092 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - Alien Swarm|Win32'">true</ExcludedFromBuild>
 61.2093 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - Bloody Good Time|Win32'">true</ExcludedFromBuild>
 61.2094 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - CSS|Win32'">true</ExcludedFromBuild>
 61.2095 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - Dark Messiah|Win32'">true</ExcludedFromBuild>
 61.2096 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - Episode 1|Win32'">true</ExcludedFromBuild>
 61.2097 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - EYE|Win32'">true</ExcludedFromBuild>
 61.2098 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - Left 4 Dead|Win32'">true</ExcludedFromBuild>
 61.2099 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - Left 4 Dead 2|Win32'">true</ExcludedFromBuild>
 61.2100 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - Old Metamod|Win32'">true</ExcludedFromBuild>
 61.2101 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - Orange Box Valve|Win32'">true</ExcludedFromBuild>
 61.2102 +    </ClCompile>
 61.2103 +    <ClCompile Include="..\AdminCache.cpp" />
 61.2104 +    <ClCompile Include="..\ADTFactory.cpp" />
 61.2105 +    <ClCompile Include="..\CDataPack.cpp" />
 61.2106 +    <ClCompile Include="..\ChatTriggers.cpp" />
 61.2107 +    <ClCompile Include="..\concmd_cleaner.cpp" />
 61.2108 +    <ClCompile Include="..\ConCmdManager.cpp" />
 61.2109 +    <ClCompile Include="..\ConsoleDetours.cpp" />
 61.2110 +    <ClCompile Include="..\ConVarManager.cpp" />
 61.2111 +    <ClCompile Include="..\CoreConfig.cpp" />
 61.2112 +    <ClCompile Include="..\CrazyDebugger.cpp">
 61.2113 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - Dark Messiah|Win32'">true</ExcludedFromBuild>
 61.2114 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - Episode 1|Win32'">true</ExcludedFromBuild>
 61.2115 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - Left 4 Dead 2|Win32'">true</ExcludedFromBuild>
 61.2116 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - Left 4 Dead|Win32'">true</ExcludedFromBuild>
 61.2117 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - Old Metamod|Win32'">true</ExcludedFromBuild>
 61.2118 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - Orange Box Valve|Win32'">true</ExcludedFromBuild>
 61.2119 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - CSS|Win32'">true</ExcludedFromBuild>
 61.2120 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - Orange Box|Win32'">true</ExcludedFromBuild>
 61.2121 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - Bloody Good Time|Win32'">true</ExcludedFromBuild>
 61.2122 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - EYE|Win32'">true</ExcludedFromBuild>
 61.2123 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - Alien Swarm|Win32'">true</ExcludedFromBuild>
 61.2124 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - CS GO|Win32'">true</ExcludedFromBuild>
 61.2125 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - Dark Messiah|Win32'">true</ExcludedFromBuild>
 61.2126 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - Episode 1|Win32'">true</ExcludedFromBuild>
 61.2127 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - Left 4 Dead 2|Win32'">true</ExcludedFromBuild>
 61.2128 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - Left 4 Dead|Win32'">true</ExcludedFromBuild>
 61.2129 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - Old Metamod|Win32'">true</ExcludedFromBuild>
 61.2130 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - Orange Box Valve|Win32'">true</ExcludedFromBuild>
 61.2131 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - CSS|Win32'">true</ExcludedFromBuild>
 61.2132 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - Orange Box|Win32'">true</ExcludedFromBuild>
 61.2133 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - Bloody Good Time|Win32'">true</ExcludedFromBuild>
 61.2134 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - EYE|Win32'">true</ExcludedFromBuild>
 61.2135 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - Alien Swarm|Win32'">true</ExcludedFromBuild>
 61.2136 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - CS GO|Win32'">true</ExcludedFromBuild>
 61.2137 +    </ClCompile>
 61.2138 +    <ClCompile Include="..\Database.cpp" />
 61.2139 +    <ClCompile Include="..\EventManager.cpp" />
 61.2140 +    <ClCompile Include="..\ForwardSys.cpp" />
 61.2141 +    <ClCompile Include="..\frame_hooks.cpp" />
 61.2142 +    <ClCompile Include="..\HalfLife2.cpp" />
 61.2143 +    <ClCompile Include="..\LibrarySys.cpp" />
 61.2144 +    <ClCompile Include="..\Logger.cpp" />
 61.2145 +    <ClCompile Include="..\logic_bridge.cpp" />
 61.2146 +    <ClCompile Include="..\MenuManager.cpp" />
 61.2147 +    <ClCompile Include="..\MenuStyle_Base.cpp" />
 61.2148 +    <ClCompile Include="..\MenuStyle_Radio.cpp" />
 61.2149 +    <ClCompile Include="..\MenuStyle_Valve.cpp" />
 61.2150 +    <ClCompile Include="..\MenuVoting.cpp" />
 61.2151 +    <ClCompile Include="..\NextMap.cpp" />
 61.2152 +    <ClCompile Include="..\PlayerManager.cpp" />
 61.2153 +    <ClCompile Include="..\smn_protobuf.cpp">
 61.2154 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Alien Swarm|Win32'">true</ExcludedFromBuild>
 61.2155 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Bloody Good Time|Win32'">true</ExcludedFromBuild>
 61.2156 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - CSS|Win32'">true</ExcludedFromBuild>
 61.2157 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Dark Messiah|Win32'">true</ExcludedFromBuild>
 61.2158 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - EYE|Win32'">true</ExcludedFromBuild>
 61.2159 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Episode 1|Win32'">true</ExcludedFromBuild>
 61.2160 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Left 4 Dead|Win32'">true</ExcludedFromBuild>
 61.2161 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Left 4 Dead 2|Win32'">true</ExcludedFromBuild>
 61.2162 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Old Metamod|Win32'">true</ExcludedFromBuild>
 61.2163 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Orange Box|Win32'">true</ExcludedFromBuild>
 61.2164 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Orange Box Valve|Win32'">true</ExcludedFromBuild>
 61.2165 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - Alien Swarm|Win32'">true</ExcludedFromBuild>
 61.2166 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - Bloody Good Time|Win32'">true</ExcludedFromBuild>
 61.2167 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - CSS|Win32'">true</ExcludedFromBuild>
 61.2168 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - Dark Messiah|Win32'">true</ExcludedFromBuild>
 61.2169 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - EYE|Win32'">true</ExcludedFromBuild>
 61.2170 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - Episode 1|Win32'">true</ExcludedFromBuild>
 61.2171 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - Left 4 Dead|Win32'">true</ExcludedFromBuild>
 61.2172 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - Left 4 Dead 2|Win32'">true</ExcludedFromBuild>
 61.2173 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - Old Metamod|Win32'">true</ExcludedFromBuild>
 61.2174 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - Orange Box|Win32'">true</ExcludedFromBuild>
 61.2175 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - Orange Box Valve|Win32'">true</ExcludedFromBuild>
 61.2176 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - Alien Swarm|Win32'">true</ExcludedFromBuild>
 61.2177 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - Bloody Good Time|Win32'">true</ExcludedFromBuild>
 61.2178 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - CSS|Win32'">true</ExcludedFromBuild>
 61.2179 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - Dark Messiah|Win32'">true</ExcludedFromBuild>
 61.2180 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - EYE|Win32'">true</ExcludedFromBuild>
 61.2181 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - Episode 1|Win32'">true</ExcludedFromBuild>
 61.2182 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - Left 4 Dead|Win32'">true</ExcludedFromBuild>
 61.2183 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - Left 4 Dead 2|Win32'">true</ExcludedFromBuild>
 61.2184 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - Old Metamod|Win32'">true</ExcludedFromBuild>
 61.2185 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - Orange Box|Win32'">true</ExcludedFromBuild>
 61.2186 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - Orange Box Valve|Win32'">true</ExcludedFromBuild>
 61.2187 +    </ClCompile>
 61.2188 +    <ClCompile Include="..\sm_autonatives.cpp" />
 61.2189 +    <ClCompile Include="..\sm_srvcmds.cpp" />
 61.2190 +    <ClCompile Include="..\sm_stringutil.cpp" />
 61.2191 +    <ClCompile Include="..\sm_trie.cpp" />
 61.2192 +    <ClCompile Include="..\sourcemm_api.cpp" />
 61.2193 +    <ClCompile Include="..\sourcemod.cpp" />
 61.2194 +    <ClCompile Include="..\TimerSys.cpp" />
 61.2195 +    <ClCompile Include="..\UserMessages.cpp" />
 61.2196 +    <ClCompile Include="..\smn_bitbuffer.cpp">
 61.2197 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - CS GO|Win32'">true</ExcludedFromBuild>
 61.2198 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - CS GO|Win32'">true</ExcludedFromBuild>
 61.2199 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - CS GO|Win32'">true</ExcludedFromBuild>
 61.2200 +    </ClCompile>
 61.2201 +    <ClCompile Include="..\smn_console.cpp" />
 61.2202 +    <ClCompile Include="..\smn_core.cpp" />
 61.2203 +    <ClCompile Include="..\smn_database.cpp" />
 61.2204 +    <ClCompile Include="..\smn_entities.cpp" />
 61.2205 +    <ClCompile Include="..\smn_events.cpp" />
 61.2206 +    <ClCompile Include="..\smn_halflife.cpp" />
 61.2207 +    <ClCompile Include="..\smn_hudtext.cpp" />
 61.2208 +    <ClCompile Include="..\smn_keyvalues.cpp" />
 61.2209 +    <ClCompile Include="..\smn_menus.cpp" />
 61.2210 +    <ClCompile Include="..\smn_nextmap.cpp" />
 61.2211 +    <ClCompile Include="..\smn_player.cpp" />
 61.2212 +    <ClCompile Include="..\smn_usermsgs.cpp" />
 61.2213 +    <ClCompile Include="..\smn_vector.cpp" />
 61.2214 +  </ItemGroup>
 61.2215 +  <ItemGroup>
 61.2216 +    <ClInclude Include="..\..\..\hl2sdks\hl2sdk-csgo\public\engine\protobuf\netmessages.pb.h">
 61.2217 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Alien Swarm|Win32'">true</ExcludedFromBuild>
 61.2218 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Bloody Good Time|Win32'">true</ExcludedFromBuild>
 61.2219 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - CS GO|Win32'">false</ExcludedFromBuild>
 61.2220 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - CSS|Win32'">true</ExcludedFromBuild>
 61.2221 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Dark Messiah|Win32'">true</ExcludedFromBuild>
 61.2222 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Episode 1|Win32'">true</ExcludedFromBuild>
 61.2223 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - EYE|Win32'">true</ExcludedFromBuild>
 61.2224 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Left 4 Dead|Win32'">true</ExcludedFromBuild>
 61.2225 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Left 4 Dead 2|Win32'">true</ExcludedFromBuild>
 61.2226 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Old Metamod|Win32'">true</ExcludedFromBuild>
 61.2227 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Orange Box|Win32'">true</ExcludedFromBuild>
 61.2228 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Orange Box Valve|Win32'">true</ExcludedFromBuild>
 61.2229 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - Orange Box|Win32'">true</ExcludedFromBuild>
 61.2230 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - Alien Swarm|Win32'">true</ExcludedFromBuild>
 61.2231 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - Bloody Good Time|Win32'">true</ExcludedFromBuild>
 61.2232 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - CSS|Win32'">true</ExcludedFromBuild>
 61.2233 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - Dark Messiah|Win32'">true</ExcludedFromBuild>
 61.2234 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - Episode 1|Win32'">true</ExcludedFromBuild>
 61.2235 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - EYE|Win32'">true</ExcludedFromBuild>
 61.2236 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - Left 4 Dead|Win32'">true</ExcludedFromBuild>
 61.2237 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - Left 4 Dead 2|Win32'">true</ExcludedFromBuild>
 61.2238 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - Old Metamod|Win32'">true</ExcludedFromBuild>
 61.2239 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - Orange Box Valve|Win32'">true</ExcludedFromBuild>
 61.2240 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - Orange Box|Win32'">true</ExcludedFromBuild>
 61.2241 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - Alien Swarm|Win32'">true</ExcludedFromBuild>
 61.2242 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - Bloody Good Time|Win32'">true</ExcludedFromBuild>
 61.2243 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - CSS|Win32'">true</ExcludedFromBuild>
 61.2244 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - Dark Messiah|Win32'">true</ExcludedFromBuild>
 61.2245 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - Episode 1|Win32'">true</ExcludedFromBuild>
 61.2246 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - EYE|Win32'">true</ExcludedFromBuild>
 61.2247 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - Left 4 Dead|Win32'">true</ExcludedFromBuild>
 61.2248 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - Left 4 Dead 2|Win32'">true</ExcludedFromBuild>
 61.2249 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - Old Metamod|Win32'">true</ExcludedFromBuild>
 61.2250 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - Orange Box Valve|Win32'">true</ExcludedFromBuild>
 61.2251 +    </ClInclude>
 61.2252 +    <ClInclude Include="..\..\..\hl2sdks\hl2sdk-csgo\public\game\shared\csgo\protobuf\cstrike15_usermessages.pb.h">
 61.2253 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Alien Swarm|Win32'">true</ExcludedFromBuild>
 61.2254 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Bloody Good Time|Win32'">true</ExcludedFromBuild>
 61.2255 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - CS GO|Win32'">false</ExcludedFromBuild>
 61.2256 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - CSS|Win32'">true</ExcludedFromBuild>
 61.2257 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Dark Messiah|Win32'">true</ExcludedFromBuild>
 61.2258 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Episode 1|Win32'">true</ExcludedFromBuild>
 61.2259 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - EYE|Win32'">true</ExcludedFromBuild>
 61.2260 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Left 4 Dead|Win32'">true</ExcludedFromBuild>
 61.2261 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Left 4 Dead 2|Win32'">true</ExcludedFromBuild>
 61.2262 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Old Metamod|Win32'">true</ExcludedFromBuild>
 61.2263 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Orange Box|Win32'">true</ExcludedFromBuild>
 61.2264 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Orange Box Valve|Win32'">true</ExcludedFromBuild>
 61.2265 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - Orange Box|Win32'">true</ExcludedFromBuild>
 61.2266 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - Alien Swarm|Win32'">true</ExcludedFromBuild>
 61.2267 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - Bloody Good Time|Win32'">true</ExcludedFromBuild>
 61.2268 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - CSS|Win32'">true</ExcludedFromBuild>
 61.2269 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - Dark Messiah|Win32'">true</ExcludedFromBuild>
 61.2270 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - Episode 1|Win32'">true</ExcludedFromBuild>
 61.2271 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - EYE|Win32'">true</ExcludedFromBuild>
 61.2272 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - Left 4 Dead|Win32'">true</ExcludedFromBuild>
 61.2273 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - Left 4 Dead 2|Win32'">true</ExcludedFromBuild>
 61.2274 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - Old Metamod|Win32'">true</ExcludedFromBuild>
 61.2275 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - Orange Box Valve|Win32'">true</ExcludedFromBuild>
 61.2276 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - Orange Box|Win32'">true</ExcludedFromBuild>
 61.2277 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - Alien Swarm|Win32'">true</ExcludedFromBuild>
 61.2278 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - Bloody Good Time|Win32'">true</ExcludedFromBuild>
 61.2279 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - CSS|Win32'">true</ExcludedFromBuild>
 61.2280 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - Dark Messiah|Win32'">true</ExcludedFromBuild>
 61.2281 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - Episode 1|Win32'">true</ExcludedFromBuild>
 61.2282 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - EYE|Win32'">true</ExcludedFromBuild>
 61.2283 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - Left 4 Dead|Win32'">true</ExcludedFromBuild>
 61.2284 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - Left 4 Dead 2|Win32'">true</ExcludedFromBuild>
 61.2285 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - Old Metamod|Win32'">true</ExcludedFromBuild>
 61.2286 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - Orange Box Valve|Win32'">true</ExcludedFromBuild>
 61.2287 +    </ClInclude>
 61.2288 +    <ClInclude Include="..\..\..\hl2sdks\hl2sdk-csgo\public\game\shared\csgo\protobuf\cstrike15_usermessage_helpers.h">
 61.2289 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Alien Swarm|Win32'">true</ExcludedFromBuild>
 61.2290 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Bloody Good Time|Win32'">true</ExcludedFromBuild>
 61.2291 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - CS GO|Win32'">false</ExcludedFromBuild>
 61.2292 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - CSS|Win32'">true</ExcludedFromBuild>
 61.2293 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Dark Messiah|Win32'">true</ExcludedFromBuild>
 61.2294 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Episode 1|Win32'">true</ExcludedFromBuild>
 61.2295 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - EYE|Win32'">true</ExcludedFromBuild>
 61.2296 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Left 4 Dead|Win32'">true</ExcludedFromBuild>
 61.2297 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Left 4 Dead 2|Win32'">true</ExcludedFromBuild>
 61.2298 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Old Metamod|Win32'">true</ExcludedFromBuild>
 61.2299 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Orange Box|Win32'">true</ExcludedFromBuild>
 61.2300 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Orange Box Valve|Win32'">true</ExcludedFromBuild>
 61.2301 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - Orange Box|Win32'">true</ExcludedFromBuild>
 61.2302 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - Alien Swarm|Win32'">true</ExcludedFromBuild>
 61.2303 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - Bloody Good Time|Win32'">true</ExcludedFromBuild>
 61.2304 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - CSS|Win32'">true</ExcludedFromBuild>
 61.2305 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - Dark Messiah|Win32'">true</ExcludedFromBuild>
 61.2306 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - Episode 1|Win32'">true</ExcludedFromBuild>
 61.2307 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - EYE|Win32'">true</ExcludedFromBuild>
 61.2308 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - Left 4 Dead|Win32'">true</ExcludedFromBuild>
 61.2309 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - Left 4 Dead 2|Win32'">true</ExcludedFromBuild>
 61.2310 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - Old Metamod|Win32'">true</ExcludedFromBuild>
 61.2311 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - Orange Box Valve|Win32'">true</ExcludedFromBuild>
 61.2312 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - Orange Box|Win32'">true</ExcludedFromBuild>
 61.2313 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - Alien Swarm|Win32'">true</ExcludedFromBuild>
 61.2314 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - Bloody Good Time|Win32'">true</ExcludedFromBuild>
 61.2315 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - CSS|Win32'">true</ExcludedFromBuild>
 61.2316 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - Dark Messiah|Win32'">true</ExcludedFromBuild>
 61.2317 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - Episode 1|Win32'">true</ExcludedFromBuild>
 61.2318 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - EYE|Win32'">true</ExcludedFromBuild>
 61.2319 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - Left 4 Dead|Win32'">true</ExcludedFromBuild>
 61.2320 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - Left 4 Dead 2|Win32'">true</ExcludedFromBuild>
 61.2321 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - Old Metamod|Win32'">true</ExcludedFromBuild>
 61.2322 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - Orange Box Valve|Win32'">true</ExcludedFromBuild>
 61.2323 +    </ClInclude>
 61.2324 +    <ClInclude Include="..\..\public\sm_platform.h" />
 61.2325 +    <ClInclude Include="..\..\public\sourcemod_version.h" />
 61.2326 +    <ClInclude Include="..\AdminCache.h" />
 61.2327 +    <ClInclude Include="..\ADTFactory.h" />
 61.2328 +    <ClInclude Include="..\CDataPack.h" />
 61.2329 +    <ClInclude Include="..\CellRecipientFilter.h" />
 61.2330 +    <ClInclude Include="..\ChatTriggers.h" />
 61.2331 +    <ClInclude Include="..\..\public\compat_wrappers.h" />
 61.2332 +    <ClInclude Include="..\concmd_cleaner.h" />
 61.2333 +    <ClInclude Include="..\ConCmdManager.h" />
 61.2334 +    <ClInclude Include="..\ConCommandBaseIterator.h" />
 61.2335 +    <ClInclude Include="..\ConsoleDetours.h" />
 61.2336 +    <ClInclude Include="..\ConVarManager.h" />
 61.2337 +    <ClInclude Include="..\convar_sm_l4d.h" />
 61.2338 +    <ClInclude Include="..\convar_sm_ob.h" />
 61.2339 +    <ClInclude Include="..\convar_sm_swarm.h" />
 61.2340 +    <ClInclude Include="..\CoreConfig.h" />
 61.2341 +    <ClInclude Include="..\Database.h" />
 61.2342 +    <ClInclude Include="..\EventManager.h" />
 61.2343 +    <ClInclude Include="..\ForwardSys.h" />
 61.2344 +    <ClInclude Include="..\frame_hooks.h" />
 61.2345 +    <ClInclude Include="..\HalfLife2.h" />
 61.2346 +    <ClInclude Include="..\LibrarySys.h" />
 61.2347 +    <ClInclude Include="..\Logger.h" />
 61.2348 +    <ClInclude Include="..\logic_bridge.h" />
 61.2349 +    <ClInclude Include="..\MenuManager.h" />
 61.2350 +    <ClInclude Include="..\MenuStyle_Base.h" />
 61.2351 +    <ClInclude Include="..\MenuStyle_Radio.h" />
 61.2352 +    <ClInclude Include="..\MenuStyle_Valve.h" />
 61.2353 +    <ClInclude Include="..\MenuVoting.h" />
 61.2354 +    <ClInclude Include="..\NextMap.h" />
 61.2355 +    <ClInclude Include="..\PlayerManager.h" />
 61.2356 +    <ClInclude Include="..\sm_autonatives.h" />
 61.2357 +    <ClInclude Include="..\sm_fastlink.h" />
 61.2358 +    <ClInclude Include="..\sm_globals.h" />
 61.2359 +    <ClInclude Include="..\sm_memtable.h" />
 61.2360 +    <ClInclude Include="..\sm_queue.h" />
 61.2361 +    <ClInclude Include="..\sm_simple_prioqueue.h" />
 61.2362 +    <ClInclude Include="..\sm_srvcmds.h" />
 61.2363 +    <ClInclude Include="..\sm_stringutil.h" />
 61.2364 +    <ClInclude Include="..\sm_trie.h" />
 61.2365 +    <ClInclude Include="..\..\public\sm_trie_tpl.h" />
 61.2366 +    <ClInclude Include="..\smn_usermsgs.h" />
 61.2367 +    <ClInclude Include="..\sourcemm_api.h" />
 61.2368 +    <ClInclude Include="..\sourcemod.h" />
 61.2369 +    <ClInclude Include="..\TimerSys.h" />
 61.2370 +    <ClInclude Include="..\UserMessages.h" />
 61.2371 +    <ClInclude Include="..\..\public\IAdminSystem.h" />
 61.2372 +    <ClInclude Include="..\..\public\IADTFactory.h" />
 61.2373 +    <ClInclude Include="..\..\public\IDataPack.h" />
 61.2374 +    <ClInclude Include="..\..\public\IDBDriver.h" />
 61.2375 +    <ClInclude Include="..\..\public\IExtensionSys.h" />
 61.2376 +    <ClInclude Include="..\..\public\IForwardSys.h" />
 61.2377 +    <ClInclude Include="..\..\public\IGameConfigs.h" />
 61.2378 +    <ClInclude Include="..\..\public\IGameHelpers.h" />
 61.2379 +    <ClInclude Include="..\..\public\IHandleSys.h" />
 61.2380 +    <ClInclude Include="..\..\public\ILibrarySys.h" />
 61.2381 +    <ClInclude Include="..\..\public\IMemoryUtils.h" />
 61.2382 +    <ClInclude Include="..\..\public\IMenuManager.h" />
 61.2383 +    <ClInclude Include="..\..\public\INativeInvoker.h" />
 61.2384 +    <ClInclude Include="..\..\public\IPlayerHelpers.h" />
 61.2385 +    <ClInclude Include="..\..\public\IPluginSys.h" />
 61.2386 +    <ClInclude Include="..\..\public\IRootConsoleMenu.h" />
 61.2387 +    <ClInclude Include="..\..\public\IShareSys.h" />
 61.2388 +    <ClInclude Include="..\..\public\ISourceMod.h" />
 61.2389 +    <ClInclude Include="..\..\public\ITextParsers.h" />
 61.2390 +    <ClInclude Include="..\..\public\ITimerSystem.h" />
 61.2391 +    <ClInclude Include="..\..\public\ITranslator.h" />
 61.2392 +    <ClInclude Include="..\..\public\IUserMessages.h" />
 61.2393 +    <ClInclude Include="..\..\public\sourcepawn\sp_file_headers.h" />
 61.2394 +    <ClInclude Include="..\..\public\sourcepawn\sp_typeutil.h" />
 61.2395 +    <ClInclude Include="..\..\public\sourcepawn\sp_vm_api.h" />
 61.2396 +    <ClInclude Include="..\..\public\sourcepawn\sp_vm_base.h" />
 61.2397 +    <ClInclude Include="..\..\public\sourcepawn\sp_vm_types.h" />
 61.2398 +    <ClInclude Include="..\convar_sm.h" />
 61.2399 +  </ItemGroup>
 61.2400 +  <ItemGroup>
 61.2401 +    <ResourceCompile Include="..\version.rc" />
 61.2402 +  </ItemGroup>
 61.2403 +  <ItemGroup>
 61.2404 +    <Library Include="..\..\..\hl2sdks\hl2sdk-csgo\lib\win32\debug\vs2010\libprotobuf.lib">
 61.2405 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Alien Swarm|Win32'">true</ExcludedFromBuild>
 61.2406 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Bloody Good Time|Win32'">true</ExcludedFromBuild>
 61.2407 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - CS GO|Win32'">false</ExcludedFromBuild>
 61.2408 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - CSS|Win32'">true</ExcludedFromBuild>
 61.2409 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Dark Messiah|Win32'">true</ExcludedFromBuild>
 61.2410 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Episode 1|Win32'">true</ExcludedFromBuild>
 61.2411 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - EYE|Win32'">true</ExcludedFromBuild>
 61.2412 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Left 4 Dead|Win32'">true</ExcludedFromBuild>
 61.2413 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Left 4 Dead 2|Win32'">true</ExcludedFromBuild>
 61.2414 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Old Metamod|Win32'">true</ExcludedFromBuild>
 61.2415 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Orange Box|Win32'">true</ExcludedFromBuild>
 61.2416 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Orange Box Valve|Win32'">true</ExcludedFromBuild>
 61.2417 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - Orange Box|Win32'">true</ExcludedFromBuild>
 61.2418 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - Alien Swarm|Win32'">true</ExcludedFromBuild>
 61.2419 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - Bloody Good Time|Win32'">true</ExcludedFromBuild>
 61.2420 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - CSS|Win32'">true</ExcludedFromBuild>
 61.2421 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - Dark Messiah|Win32'">true</ExcludedFromBuild>
 61.2422 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - Episode 1|Win32'">true</ExcludedFromBuild>
 61.2423 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - EYE|Win32'">true</ExcludedFromBuild>
 61.2424 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - Left 4 Dead|Win32'">true</ExcludedFromBuild>
 61.2425 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - Left 4 Dead 2|Win32'">true</ExcludedFromBuild>
 61.2426 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - Old Metamod|Win32'">true</ExcludedFromBuild>
 61.2427 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - Orange Box Valve|Win32'">true</ExcludedFromBuild>
 61.2428 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - Orange Box|Win32'">true</ExcludedFromBuild>
 61.2429 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - Alien Swarm|Win32'">true</ExcludedFromBuild>
 61.2430 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - Bloody Good Time|Win32'">true</ExcludedFromBuild>
 61.2431 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - CS GO|Win32'">true</ExcludedFromBuild>
 61.2432 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - CSS|Win32'">true</ExcludedFromBuild>
 61.2433 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - Dark Messiah|Win32'">true</ExcludedFromBuild>
 61.2434 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - Episode 1|Win32'">true</ExcludedFromBuild>
 61.2435 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - EYE|Win32'">true</ExcludedFromBuild>
 61.2436 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - Left 4 Dead|Win32'">true</ExcludedFromBuild>
 61.2437 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - Left 4 Dead 2|Win32'">true</ExcludedFromBuild>
 61.2438 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - Old Metamod|Win32'">true</ExcludedFromBuild>
 61.2439 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - Orange Box Valve|Win32'">true</ExcludedFromBuild>
 61.2440 +    </Library>
 61.2441 +    <Library Include="..\..\..\hl2sdks\hl2sdk-csgo\lib\win32\release\vs2010\libprotobuf.lib">
 61.2442 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - CS GO|Win32'">true</ExcludedFromBuild>
 61.2443 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Alien Swarm|Win32'">true</ExcludedFromBuild>
 61.2444 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Bloody Good Time|Win32'">true</ExcludedFromBuild>
 61.2445 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - CS GO|Win32'">true</ExcludedFromBuild>
 61.2446 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - CSS|Win32'">true</ExcludedFromBuild>
 61.2447 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Dark Messiah|Win32'">true</ExcludedFromBuild>
 61.2448 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Episode 1|Win32'">true</ExcludedFromBuild>
 61.2449 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - EYE|Win32'">true</ExcludedFromBuild>
 61.2450 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Left 4 Dead|Win32'">true</ExcludedFromBuild>
 61.2451 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Left 4 Dead 2|Win32'">true</ExcludedFromBuild>
 61.2452 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Old Metamod|Win32'">true</ExcludedFromBuild>
 61.2453 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Orange Box|Win32'">true</ExcludedFromBuild>
 61.2454 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Orange Box Valve|Win32'">true</ExcludedFromBuild>
 61.2455 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - Orange Box|Win32'">true</ExcludedFromBuild>
 61.2456 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - Alien Swarm|Win32'">true</ExcludedFromBuild>
 61.2457 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - Bloody Good Time|Win32'">true</ExcludedFromBuild>
 61.2458 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - CSS|Win32'">true</ExcludedFromBuild>
 61.2459 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - Dark Messiah|Win32'">true</ExcludedFromBuild>
 61.2460 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - Episode 1|Win32'">true</ExcludedFromBuild>
 61.2461 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - EYE|Win32'">true</ExcludedFromBuild>
 61.2462 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - Left 4 Dead|Win32'">true</ExcludedFromBuild>
 61.2463 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - Left 4 Dead 2|Win32'">true</ExcludedFromBuild>
 61.2464 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - Old Metamod|Win32'">true</ExcludedFromBuild>
 61.2465 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - Orange Box Valve|Win32'">true</ExcludedFromBuild>
 61.2466 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - Orange Box|Win32'">true</ExcludedFromBuild>
 61.2467 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - Alien Swarm|Win32'">true</ExcludedFromBuild>
 61.2468 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - Bloody Good Time|Win32'">true</ExcludedFromBuild>
 61.2469 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - CSS|Win32'">true</ExcludedFromBuild>
 61.2470 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - Dark Messiah|Win32'">true</ExcludedFromBuild>
 61.2471 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - Episode 1|Win32'">true</ExcludedFromBuild>
 61.2472 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - EYE|Win32'">true</ExcludedFromBuild>
 61.2473 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - Left 4 Dead|Win32'">true</ExcludedFromBuild>
 61.2474 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - Left 4 Dead 2|Win32'">true</ExcludedFromBuild>
 61.2475 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - Old Metamod|Win32'">true</ExcludedFromBuild>
 61.2476 +      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - Orange Box Valve|Win32'">true</ExcludedFromBuild>
 61.2477 +    </Library>
 61.2478 +  </ItemGroup>
 61.2479 +  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
 61.2480 +  <ImportGroup Label="ExtensionTargets">
 61.2481 +  </ImportGroup>
 61.2482 +</Project>
 61.2483 \ No newline at end of file
    62.1 --- a/core/sm_autonatives.cpp	Fri Mar 29 12:28:02 2013 -0400
    62.2 +++ b/core/sm_autonatives.cpp	Fri Mar 29 11:37:29 2013 -0700
    62.3 @@ -30,14 +30,9 @@
    62.4   */
    62.5  
    62.6  #include "sm_autonatives.h"
    62.7 -#include "PluginSys.h"
    62.8 -#include "NativeOwner.h"
    62.9 -
   62.10 -CNativeOwner g_CoreNatives;
   62.11 -
   62.12 -CNativeOwner *g_pCoreNatives = &g_CoreNatives;
   62.13 +#include "logic_bridge.h"
   62.14  
   62.15  void CoreNativesToAdd::OnSourceModAllInitialized()
   62.16  {
   62.17 -	g_CoreNatives.AddNatives(m_NativeList);
   62.18 +	logicore.AddNatives(m_NativeList);
   62.19  }
    63.1 --- a/core/sm_autonatives.h	Fri Mar 29 12:28:02 2013 -0400
    63.2 +++ b/core/sm_autonatives.h	Fri Mar 29 11:37:29 2013 -0700
    63.3 @@ -50,8 +50,4 @@
    63.4  	sp_nativeinfo_t *m_NativeList;
    63.5  };
    63.6  
    63.7 -class CNativeOwner;
    63.8 -
    63.9 -extern CNativeOwner *g_pCoreNatives;
   63.10 -
   63.11  #endif //_INCLUDE_SOURCEMOD_CORE_AUTONATIVES_H_
    64.1 --- a/core/sm_srvcmds.cpp	Fri Mar 29 12:28:02 2013 -0400
    64.2 +++ b/core/sm_srvcmds.cpp	Fri Mar 29 11:37:29 2013 -0700
    64.3 @@ -32,10 +32,9 @@
    64.4  #include "sm_srvcmds.h"
    64.5  #include <sourcemod_version.h>
    64.6  #include "sm_stringutil.h"
    64.7 -#include "HandleSys.h"
    64.8  #include "CoreConfig.h"
    64.9  #include "ConVarManager.h"
   64.10 -#include "ShareSys.h"
   64.11 +#include "logic_bridge.h"
   64.12  
   64.13  RootConsoleMenu g_RootMenu;
   64.14  
   64.15 @@ -71,7 +70,7 @@
   64.16  
   64.17  void RootConsoleMenu::OnSourceModAllInitialized()
   64.18  {
   64.19 -	g_ShareSys.AddInterface(NULL, this);
   64.20 +	sharesys->AddInterface(NULL, this);
   64.21  }
   64.22  
   64.23  void RootConsoleMenu::OnSourceModShutdown()
   64.24 @@ -406,14 +405,14 @@
   64.25  		}
   64.26  
   64.27  		g_pHndlLog = fp;
   64.28 -		g_HandleSys.Dump(write_handles_to_log);
   64.29 +		logicore.DumpHandles(write_handles_to_log);
   64.30  		g_pHndlLog = NULL;
   64.31  
   64.32  		fclose(fp);
   64.33  	}
   64.34  	else
   64.35  	{
   64.36 -		g_HandleSys.Dump(write_handles_to_game);
   64.37 +		logicore.DumpHandles(write_handles_to_game);
   64.38  	}
   64.39  }
   64.40  
    65.1 --- a/core/sm_srvcmds.h	Fri Mar 29 12:28:02 2013 -0400
    65.2 +++ b/core/sm_srvcmds.h	Fri Mar 29 11:37:29 2013 -0700
    65.3 @@ -34,7 +34,6 @@
    65.4  
    65.5  #include "sourcemod.h"
    65.6  #include <IRootConsoleMenu.h>
    65.7 -#include "PluginSys.h"
    65.8  #include "sourcemm_api.h"
    65.9  #include <sh_list.h>
   65.10  #include <sh_string.h>
    66.1 --- a/core/sm_stringutil.cpp	Fri Mar 29 12:28:02 2013 -0400
    66.2 +++ b/core/sm_stringutil.cpp	Fri Mar 29 11:37:29 2013 -0700
    66.3 @@ -32,11 +32,12 @@
    66.4  #include <stdlib.h>
    66.5  #include <ctype.h>
    66.6  #include <stdarg.h>
    66.7 +#include <ITextParsers.h>
    66.8  #include "sm_stringutil.h"
    66.9  #include "Logger.h"
   66.10 -#include "PluginSys.h"
   66.11  #include "PlayerManager.h"
   66.12  #include "logic_bridge.h"
   66.13 +#include "sourcemod.h"
   66.14  
   66.15  #define LADJUST			0x00000004		/* left adjustment */
   66.16  #define ZEROPAD			0x00000080		/* zero (as opposed to blank) pad */
   66.17 @@ -72,7 +73,7 @@
   66.18  	unsigned int langid;
   66.19  	*error = false;
   66.20  	Translation pTrans;
   66.21 -	CPlugin *pl = (CPlugin *)g_PluginSys.FindPluginByContext(pCtx->GetContext());
   66.22 +	IPlugin *pl = scripts->FindPluginByContext(pCtx->GetContext());
   66.23  	unsigned int max_params = 0;
   66.24  	IPhraseCollection *pPhrases;
   66.25  
    67.1 --- a/core/smn_bitbuffer.cpp	Fri Mar 29 12:28:02 2013 -0400
    67.2 +++ b/core/smn_bitbuffer.cpp	Fri Mar 29 11:37:29 2013 -0700
    67.3 @@ -34,11 +34,12 @@
    67.4  #ifndef USE_PROTOBUF_USERMESSAGES
    67.5  
    67.6  #include "sourcemod.h"
    67.7 -#include "HandleSys.h"
    67.8  #include <bitbuf.h>
    67.9  #include <vector.h>
   67.10  #include <HalfLife2.h>
   67.11  #include "smn_usermsgs.h"
   67.12 +#include "sourcemod.h"
   67.13 +#include "logic_bridge.h"
   67.14  
   67.15  static cell_t smn_BfWriteBool(IPluginContext *pCtx, const cell_t *params)
   67.16  {
   67.17 @@ -50,7 +51,7 @@
   67.18  	sec.pOwner = NULL;
   67.19  	sec.pIdentity = g_pCoreIdent;
   67.20  
   67.21 -	if ((herr=g_HandleSys.ReadHandle(hndl, g_WrBitBufType, &sec, (void **)&pBitBuf))
   67.22 +	if ((herr=handlesys->ReadHandle(hndl, g_WrBitBufType, &sec, (void **)&pBitBuf))
   67.23  		!= HandleError_None)
   67.24  	{
   67.25  		return pCtx->ThrowNativeError("Invalid bit buffer handle %x (error %d)", hndl, herr);
   67.26 @@ -71,7 +72,7 @@
   67.27  	sec.pOwner = NULL;
   67.28  	sec.pIdentity = g_pCoreIdent;
   67.29  
   67.30 -	if ((herr=g_HandleSys.ReadHandle(hndl, g_WrBitBufType, &sec, (void **)&pBitBuf))
   67.31 +	if ((herr=handlesys->ReadHandle(hndl, g_WrBitBufType, &sec, (void **)&pBitBuf))
   67.32  		!= HandleError_None)
   67.33  	{
   67.34  		return pCtx->ThrowNativeError("Invalid bit buffer handle %x (error %d)", hndl, herr);
   67.35 @@ -92,7 +93,7 @@
   67.36  	sec.pOwner = NULL;
   67.37  	sec.pIdentity = g_pCoreIdent;
   67.38  
   67.39 -	if ((herr=g_HandleSys.ReadHandle(hndl, g_WrBitBufType, &sec, (void **)&pBitBuf))
   67.40 +	if ((herr=handlesys->ReadHandle(hndl, g_WrBitBufType, &sec, (void **)&pBitBuf))
   67.41  		!= HandleError_None)
   67.42  	{
   67.43  		return pCtx->ThrowNativeError("Invalid bit buffer handle %x (error %d)", hndl, herr);
   67.44 @@ -113,7 +114,7 @@
   67.45  	sec.pOwner = NULL;
   67.46  	sec.pIdentity = g_pCoreIdent;
   67.47  
   67.48 -	if ((herr=g_HandleSys.ReadHandle(hndl, g_WrBitBufType, &sec, (void **)&pBitBuf))
   67.49 +	if ((herr=handlesys->ReadHandle(hndl, g_WrBitBufType, &sec, (void **)&pBitBuf))
   67.50  		!= HandleError_None)
   67.51  	{
   67.52  		return pCtx->ThrowNativeError("Invalid bit buffer handle %x (error %d)", hndl, herr);
   67.53 @@ -134,7 +135,7 @@
   67.54  	sec.pOwner = NULL;
   67.55  	sec.pIdentity = g_pCoreIdent;
   67.56  
   67.57 -	if ((herr=g_HandleSys.ReadHandle(hndl, g_WrBitBufType, &sec, (void **)&pBitBuf))
   67.58 +	if ((herr=handlesys->ReadHandle(hndl, g_WrBitBufType, &sec, (void **)&pBitBuf))
   67.59  		!= HandleError_None)
   67.60  	{
   67.61  		return pCtx->ThrowNativeError("Invalid bit buffer handle %x (error %d)", hndl, herr);
   67.62 @@ -155,7 +156,7 @@
   67.63  	sec.pOwner = NULL;
   67.64  	sec.pIdentity = g_pCoreIdent;
   67.65  
   67.66 -	if ((herr=g_HandleSys.ReadHandle(hndl, g_WrBitBufType, &sec, (void **)&pBitBuf))
   67.67 +	if ((herr=handlesys->ReadHandle(hndl, g_WrBitBufType, &sec, (void **)&pBitBuf))
   67.68  		!= HandleError_None)
   67.69  	{
   67.70  		return pCtx->ThrowNativeError("Invalid bit buffer handle %x (error %d)", hndl, herr);
   67.71 @@ -176,7 +177,7 @@
   67.72  	sec.pOwner = NULL;
   67.73  	sec.pIdentity = g_pCoreIdent;
   67.74  
   67.75 -	if ((herr=g_HandleSys.ReadHandle(hndl, g_WrBitBufType, &sec, (void **)&pBitBuf))
   67.76 +	if ((herr=handlesys->ReadHandle(hndl, g_WrBitBufType, &sec, (void **)&pBitBuf))
   67.77  		!= HandleError_None)
   67.78  	{
   67.79  		return pCtx->ThrowNativeError("Invalid bit buffer handle %x (error %d)", hndl, herr);
   67.80 @@ -198,7 +199,7 @@
   67.81  	sec.pOwner = NULL;
   67.82  	sec.pIdentity = g_pCoreIdent;
   67.83  
   67.84 -	if ((herr=g_HandleSys.ReadHandle(hndl, g_WrBitBufType, &sec, (void **)&pBitBuf))
   67.85 +	if ((herr=handlesys->ReadHandle(hndl, g_WrBitBufType, &sec, (void **)&pBitBuf))
   67.86  		!= HandleError_None)
   67.87  	{
   67.88  		return pCtx->ThrowNativeError("Invalid bit buffer handle %x (error %d)", hndl, herr);
   67.89 @@ -226,7 +227,7 @@
   67.90  	sec.pOwner = NULL;
   67.91  	sec.pIdentity = g_pCoreIdent;
   67.92  
   67.93 -	if ((herr=g_HandleSys.ReadHandle(hndl, g_WrBitBufType, &sec, (void **)&pBitBuf))
   67.94 +	if ((herr=handlesys->ReadHandle(hndl, g_WrBitBufType, &sec, (void **)&pBitBuf))
   67.95  		!= HandleError_None)
   67.96  	{
   67.97  		return pCtx->ThrowNativeError("Invalid bit buffer handle %x (error %d)", hndl, herr);
   67.98 @@ -254,7 +255,7 @@
   67.99  	sec.pOwner = NULL;
  67.100  	sec.pIdentity = g_pCoreIdent;
  67.101  
  67.102 -	if ((herr=g_HandleSys.ReadHandle(hndl, g_WrBitBufType, &sec, (void **)&pBitBuf))
  67.103 +	if ((herr=handlesys->ReadHandle(hndl, g_WrBitBufType, &sec, (void **)&pBitBuf))
  67.104  		!= HandleError_None)
  67.105  	{
  67.106  		return pCtx->ThrowNativeError("Invalid bit buffer handle %x (error %d)", hndl, herr);
  67.107 @@ -275,7 +276,7 @@
  67.108  	sec.pOwner = NULL;
  67.109  	sec.pIdentity = g_pCoreIdent;
  67.110  
  67.111 -	if ((herr=g_HandleSys.ReadHandle(hndl, g_WrBitBufType, &sec, (void **)&pBitBuf))
  67.112 +	if ((herr=handlesys->ReadHandle(hndl, g_WrBitBufType, &sec, (void **)&pBitBuf))
  67.113  		!= HandleError_None)
  67.114  	{
  67.115  		return pCtx->ThrowNativeError("Invalid bit buffer handle %x (error %d)", hndl, herr);
  67.116 @@ -296,7 +297,7 @@
  67.117  	sec.pOwner = NULL;
  67.118  	sec.pIdentity = g_pCoreIdent;
  67.119  
  67.120 -	if ((herr=g_HandleSys.ReadHandle(hndl, g_WrBitBufType, &sec, (void **)&pBitBuf))
  67.121 +	if ((herr=handlesys->ReadHandle(hndl, g_WrBitBufType, &sec, (void **)&pBitBuf))
  67.122  		!= HandleError_None)
  67.123  	{
  67.124  		return pCtx->ThrowNativeError("Invalid bit buffer handle %x (error %d)", hndl, herr);
  67.125 @@ -320,7 +321,7 @@
  67.126  	sec.pOwner = NULL;
  67.127  	sec.pIdentity = g_pCoreIdent;
  67.128  
  67.129 -	if ((herr=g_HandleSys.ReadHandle(hndl, g_WrBitBufType, &sec, (void **)&pBitBuf))
  67.130 +	if ((herr=handlesys->ReadHandle(hndl, g_WrBitBufType, &sec, (void **)&pBitBuf))
  67.131  		!= HandleError_None)
  67.132  	{
  67.133  		return pCtx->ThrowNativeError("Invalid bit buffer handle %x (error %d)", hndl, herr);
  67.134 @@ -344,7 +345,7 @@
  67.135  	sec.pOwner = NULL;
  67.136  	sec.pIdentity = g_pCoreIdent;
  67.137  
  67.138 -	if ((herr=g_HandleSys.ReadHandle(hndl, g_WrBitBufType, &sec, (void **)&pBitBuf))
  67.139 +	if ((herr=handlesys->ReadHandle(hndl, g_WrBitBufType, &sec, (void **)&pBitBuf))
  67.140  		!= HandleError_None)
  67.141  	{
  67.142  		return pCtx->ThrowNativeError("Invalid bit buffer handle %x (error %d)", hndl, herr);
  67.143 @@ -368,7 +369,7 @@
  67.144  	sec.pOwner = NULL;
  67.145  	sec.pIdentity = g_pCoreIdent;
  67.146  
  67.147 -	if ((herr=g_HandleSys.ReadHandle(hndl, g_RdBitBufType, &sec, (void **)&pBitBuf))
  67.148 +	if ((herr=handlesys->ReadHandle(hndl, g_RdBitBufType, &sec, (void **)&pBitBuf))
  67.149  		!= HandleError_None)
  67.150  	{
  67.151  		return pCtx->ThrowNativeError("Invalid bit buffer handle %x (error %d)", hndl, herr);
  67.152 @@ -387,7 +388,7 @@
  67.153  	sec.pOwner = NULL;
  67.154  	sec.pIdentity = g_pCoreIdent;
  67.155  
  67.156 -	if ((herr=g_HandleSys.ReadHandle(hndl, g_RdBitBufType, &sec, (void **)&pBitBuf))
  67.157 +	if ((herr=handlesys->ReadHandle(hndl, g_RdBitBufType, &sec, (void **)&pBitBuf))
  67.158  		!= HandleError_None)
  67.159  	{
  67.160  		return pCtx->ThrowNativeError("Invalid bit buffer handle %x (error %d)", hndl, herr);
  67.161 @@ -406,7 +407,7 @@
  67.162  	sec.pOwner = NULL;
  67.163  	sec.pIdentity = g_pCoreIdent;
  67.164  
  67.165 -	if ((herr=g_HandleSys.ReadHandle(hndl, g_RdBitBufType, &sec, (void **)&pBitBuf))
  67.166 +	if ((herr=handlesys->ReadHandle(hndl, g_RdBitBufType, &sec, (void **)&pBitBuf))
  67.167  		!= HandleError_None)
  67.168  	{
  67.169  		return pCtx->ThrowNativeError("Invalid bit buffer handle %x (error %d)", hndl, herr);
  67.170 @@ -425,7 +426,7 @@
  67.171  	sec.pOwner = NULL;
  67.172  	sec.pIdentity = g_pCoreIdent;
  67.173  
  67.174 -	if ((herr=g_HandleSys.ReadHandle(hndl, g_RdBitBufType, &sec, (void **)&pBitBuf))
  67.175 +	if ((herr=handlesys->ReadHandle(hndl, g_RdBitBufType, &sec, (void **)&pBitBuf))
  67.176  		!= HandleError_None)
  67.177  	{
  67.178  		return pCtx->ThrowNativeError("Invalid bit buffer handle %x (error %d)", hndl, herr);
  67.179 @@ -444,7 +445,7 @@
  67.180  	sec.pOwner = NULL;
  67.181  	sec.pIdentity = g_pCoreIdent;
  67.182  
  67.183 -	if ((herr=g_HandleSys.ReadHandle(hndl, g_RdBitBufType, &sec, (void **)&pBitBuf))
  67.184 +	if ((herr=handlesys->ReadHandle(hndl, g_RdBitBufType, &sec, (void **)&pBitBuf))
  67.185  		!= HandleError_None)
  67.186  	{
  67.187  		return pCtx->ThrowNativeError("Invalid bit buffer handle %x (error %d)", hndl, herr);
  67.188 @@ -463,7 +464,7 @@
  67.189  	sec.pOwner = NULL;
  67.190  	sec.pIdentity = g_pCoreIdent;
  67.191  
  67.192 -	if ((herr=g_HandleSys.ReadHandle(hndl, g_RdBitBufType, &sec, (void **)&pBitBuf))
  67.193 +	if ((herr=handlesys->ReadHandle(hndl, g_RdBitBufType, &sec, (void **)&pBitBuf))
  67.194  		!= HandleError_None)
  67.195  	{
  67.196  		return pCtx->ThrowNativeError("Invalid bit buffer handle %x (error %d)", hndl, herr);
  67.197 @@ -482,7 +483,7 @@
  67.198  	sec.pOwner = NULL;
  67.199  	sec.pIdentity = g_pCoreIdent;
  67.200  
  67.201 -	if ((herr=g_HandleSys.ReadHandle(hndl, g_RdBitBufType, &sec, (void **)&pBitBuf))
  67.202 +	if ((herr=handlesys->ReadHandle(hndl, g_RdBitBufType, &sec, (void **)&pBitBuf))
  67.203  		!= HandleError_None)
  67.204  	{
  67.205  		return pCtx->ThrowNativeError("Invalid bit buffer handle %x (error %d)", hndl, herr);
  67.206 @@ -503,7 +504,7 @@
  67.207  	sec.pOwner = NULL;
  67.208  	sec.pIdentity = g_pCoreIdent;
  67.209  
  67.210 -	if ((herr=g_HandleSys.ReadHandle(hndl, g_RdBitBufType, &sec, (void **)&pBitBuf))
  67.211 +	if ((herr=handlesys->ReadHandle(hndl, g_RdBitBufType, &sec, (void **)&pBitBuf))
  67.212  		!= HandleError_None)
  67.213  	{
  67.214  		return pCtx->ThrowNativeError("Invalid bit buffer handle %x (error %d)", hndl, herr);
  67.215 @@ -530,7 +531,7 @@
  67.216  	sec.pOwner = NULL;
  67.217  	sec.pIdentity = g_pCoreIdent;
  67.218  
  67.219 -	if ((herr=g_HandleSys.ReadHandle(hndl, g_RdBitBufType, &sec, (void **)&pBitBuf))
  67.220 +	if ((herr=handlesys->ReadHandle(hndl, g_RdBitBufType, &sec, (void **)&pBitBuf))
  67.221  		!= HandleError_None)
  67.222  	{
  67.223  		return pCtx->ThrowNativeError("Invalid bit buffer handle %x (error %d)", hndl, herr);
  67.224 @@ -551,7 +552,7 @@
  67.225  	sec.pOwner = NULL;
  67.226  	sec.pIdentity = g_pCoreIdent;
  67.227  
  67.228 -	if ((herr=g_HandleSys.ReadHandle(hndl, g_RdBitBufType, &sec, (void **)&pBitBuf))
  67.229 +	if ((herr=handlesys->ReadHandle(hndl, g_RdBitBufType, &sec, (void **)&pBitBuf))
  67.230  		!= HandleError_None)
  67.231  	{
  67.232  		return pCtx->ThrowNativeError("Invalid bit buffer handle %x (error %d)", hndl, herr);
  67.233 @@ -570,7 +571,7 @@
  67.234  	sec.pOwner = NULL;
  67.235  	sec.pIdentity = g_pCoreIdent;
  67.236  
  67.237 -	if ((herr=g_HandleSys.ReadHandle(hndl, g_RdBitBufType, &sec, (void **)&pBitBuf))
  67.238 +	if ((herr=handlesys->ReadHandle(hndl, g_RdBitBufType, &sec, (void **)&pBitBuf))
  67.239  		!= HandleError_None)
  67.240  	{
  67.241  		return pCtx->ThrowNativeError("Invalid bit buffer handle %x (error %d)", hndl, herr);
  67.242 @@ -589,7 +590,7 @@
  67.243  	sec.pOwner = NULL;
  67.244  	sec.pIdentity = g_pCoreIdent;
  67.245  
  67.246 -	if ((herr=g_HandleSys.ReadHandle(hndl, g_RdBitBufType, &sec, (void **)&pBitBuf))
  67.247 +	if ((herr=handlesys->ReadHandle(hndl, g_RdBitBufType, &sec, (void **)&pBitBuf))
  67.248  		!= HandleError_None)
  67.249  	{
  67.250  		return pCtx->ThrowNativeError("Invalid bit buffer handle %x (error %d)", hndl, herr);
  67.251 @@ -618,7 +619,7 @@
  67.252  	sec.pOwner = NULL;
  67.253  	sec.pIdentity = g_pCoreIdent;
  67.254  
  67.255 -	if ((herr=g_HandleSys.ReadHandle(hndl, g_RdBitBufType, &sec, (void **)&pBitBuf))
  67.256 +	if ((herr=handlesys->ReadHandle(hndl, g_RdBitBufType, &sec, (void **)&pBitBuf))
  67.257  		!= HandleError_None)
  67.258  	{
  67.259  		return pCtx->ThrowNativeError("Invalid bit buffer handle %x (error %d)", hndl, herr);
  67.260 @@ -647,7 +648,7 @@
  67.261  	sec.pOwner = NULL;
  67.262  	sec.pIdentity = g_pCoreIdent;
  67.263  
  67.264 -	if ((herr=g_HandleSys.ReadHandle(hndl, g_RdBitBufType, &sec, (void **)&pBitBuf))
  67.265 +	if ((herr=handlesys->ReadHandle(hndl, g_RdBitBufType, &sec, (void **)&pBitBuf))
  67.266  		!= HandleError_None)
  67.267  	{
  67.268  		return pCtx->ThrowNativeError("Invalid bit buffer handle %x (error %d)", hndl, herr);
  67.269 @@ -676,7 +677,7 @@
  67.270  	sec.pOwner = NULL;
  67.271  	sec.pIdentity = g_pCoreIdent;
  67.272  
  67.273 -	if ((herr=g_HandleSys.ReadHandle(hndl, g_RdBitBufType, &sec, (void **)&pBitBuf))
  67.274 +	if ((herr=handlesys->ReadHandle(hndl, g_RdBitBufType, &sec, (void **)&pBitBuf))
  67.275  		!= HandleError_None)
  67.276  	{
  67.277  		return pCtx->ThrowNativeError("Invalid bit buffer handle %x (error %d)", hndl, herr);
    68.1 --- a/core/smn_console.cpp	Fri Mar 29 12:28:02 2013 -0400
    68.2 +++ b/core/smn_console.cpp	Fri Mar 29 11:37:29 2013 -0700
    68.3 @@ -32,10 +32,8 @@
    68.4  #include "sm_globals.h"
    68.5  #include "HalfLife2.h"
    68.6  #include "sourcemm_api.h"
    68.7 -#include "HandleSys.h"
    68.8  #include "ConVarManager.h"
    68.9  #include "ConCmdManager.h"
   68.10 -#include "PluginSys.h"
   68.11  #include "sm_stringutil.h"
   68.12  #include "PlayerManager.h"
   68.13  #include "ChatTriggers.h"
   68.14 @@ -47,6 +45,7 @@
   68.15  #include "Logger.h"
   68.16  #include "ConsoleDetours.h"
   68.17  #include "ConCommandBaseIterator.h"
   68.18 +#include "logic_bridge.h"
   68.19  
   68.20  #if SOURCE_ENGINE == SE_CSGO || SOURCE_ENGINE == SE_DOTA
   68.21  #include <netmessages.pb.h>
   68.22 @@ -88,13 +87,13 @@
   68.23  	{
   68.24  		HandleAccess access;
   68.25  
   68.26 -		g_HandleSys.InitAccessDefaults(NULL, &access);
   68.27 +		handlesys->InitAccessDefaults(NULL, &access);
   68.28  
   68.29 -		htConCmdIter = g_HandleSys.CreateType("ConCmdIter", this, 0, NULL, &access, g_pCoreIdent, NULL);
   68.30 +		htConCmdIter = handlesys->CreateType("ConCmdIter", this, 0, NULL, &access, g_pCoreIdent, NULL);
   68.31  
   68.32  		access.access[HandleAccess_Clone] = HANDLE_RESTRICT_OWNER | HANDLE_RESTRICT_IDENTITY;
   68.33  
   68.34 -		hCmdIterType = g_HandleSys.CreateType("CmdIter", this, 0, NULL, &access, g_pCoreIdent, NULL);
   68.35 +		hCmdIterType = handlesys->CreateType("CmdIter", this, 0, NULL, &access, g_pCoreIdent, NULL);
   68.36  	}
   68.37  	virtual void OnHandleDestroy(HandleType_t type, void *object)
   68.38  	{
   68.39 @@ -726,7 +725,7 @@
   68.40  		return pContext->ThrowNativeError("Invalid function id (%X)", params[2]);
   68.41  	}
   68.42  
   68.43 -	CPlugin *pPlugin = g_PluginSys.GetPluginByCtx(pContext->GetContext());
   68.44 +	IPlugin *pPlugin = scripts->FindPluginByContext(pContext->GetContext());
   68.45  	const char *group = pPlugin->GetFilename();
   68.46  	if (!g_ConCmds.AddAdminCommand(pFunction, name, group, 0, help, params[4]))
   68.47  	{
   68.48 @@ -757,7 +756,7 @@
   68.49  
   68.50  	if (group[0] == '\0')
   68.51  	{
   68.52 -		CPlugin *pPlugin = g_PluginSys.GetPluginByCtx(pContext->GetContext());
   68.53 +		IPlugin *pPlugin = scripts->FindPluginByContext(pContext->GetContext());
   68.54  		group = pPlugin->GetFilename();
   68.55  	}
   68.56  
   68.57 @@ -1211,7 +1210,7 @@
   68.58  	GlobCmdIter *iter = new GlobCmdIter;
   68.59  	iter->started = false;
   68.60  
   68.61 -	Handle_t hndl = g_HandleSys.CreateHandle(hCmdIterType, iter, pContext->GetIdentity(), g_pCoreIdent, NULL);
   68.62 +	Handle_t hndl = handlesys->CreateHandle(hCmdIterType, iter, pContext->GetIdentity(), g_pCoreIdent, NULL);
   68.63  	if (hndl == BAD_HANDLE)
   68.64  	{
   68.65  		delete iter;
   68.66 @@ -1226,7 +1225,7 @@
   68.67  	HandleError err;
   68.68  	HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent);
   68.69  
   68.70 -	if ((err = g_HandleSys.ReadHandle(params[1], hCmdIterType, &sec, (void **)&iter))
   68.71 +	if ((err = handlesys->ReadHandle(params[1], hCmdIterType, &sec, (void **)&iter))
   68.72  		!= HandleError_None)
   68.73  	{
   68.74  		return pContext->ThrowNativeError("Invalid GlobCmdIter Handle %x", params[1]);
   68.75 @@ -1365,7 +1364,7 @@
   68.76  		pContext->StringToLocalUTF8(params[5], params[6], (desc && desc[0]) ? desc : "", NULL);
   68.77  	}
   68.78  
   68.79 -	if ((hndl = g_HandleSys.CreateHandle(htConCmdIter, pIter, pContext->GetIdentity(), g_pCoreIdent, NULL))
   68.80 +	if ((hndl = handlesys->CreateHandle(htConCmdIter, pIter, pContext->GetIdentity(), g_pCoreIdent, NULL))
   68.81  		== BAD_HANDLE)
   68.82  	{
   68.83  		delete pIter;
   68.84 @@ -1384,7 +1383,7 @@
   68.85  	const ConCommandBase *pConCmd;
   68.86  	HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent);
   68.87  
   68.88 -	if ((err = g_HandleSys.ReadHandle(params[1], htConCmdIter, &sec, (void **)&pIter)) != HandleError_None)
   68.89 +	if ((err = handlesys->ReadHandle(params[1], htConCmdIter, &sec, (void **)&pIter)) != HandleError_None)
   68.90  	{
   68.91  		return pContext->ThrowNativeError("Invalid Handle %x (error %d)", params[1], err);
   68.92  	}
    69.1 --- a/core/smn_core.cpp	Fri Mar 29 12:28:02 2013 -0400
    69.2 +++ b/core/smn_core.cpp	Fri Mar 29 11:37:29 2013 -0700
    69.3 @@ -35,15 +35,13 @@
    69.4  #include "sm_stringutil.h"
    69.5  #include "sm_globals.h"
    69.6  #include "sourcemod.h"
    69.7 -#include "PluginSys.h"
    69.8 -#include "HandleSys.h"
    69.9  #include "LibrarySys.h"
   69.10  #include "TimerSys.h"
   69.11  #include "ForwardSys.h"
   69.12  #include "Logger.h"
   69.13 -#include "ExtensionSys.h"
   69.14  #include <sm_trie_tpl.h>
   69.15  #include <sh_memory.h>
   69.16 +#include "logic_bridge.h"
   69.17  
   69.18  #if defined PLATFORM_WINDOWS
   69.19  #include <windows.h>
   69.20 @@ -65,10 +63,10 @@
   69.21  	void OnSourceModAllInitialized()
   69.22  	{
   69.23  		HandleAccess hacc;
   69.24 -		g_HandleSys.InitAccessDefaults(NULL,  &hacc);
   69.25 +		handlesys->InitAccessDefaults(NULL,  &hacc);
   69.26  		hacc.access[HandleAccess_Clone] = HANDLE_RESTRICT_IDENTITY|HANDLE_RESTRICT_OWNER;
   69.27  
   69.28 -		g_PlIter = g_HandleSys.CreateType("PluginIterator", this, 0, NULL, NULL, g_pCoreIdent, NULL);
   69.29 +		g_PlIter = handlesys->CreateType("PluginIterator", this, 0, NULL, NULL, g_pCoreIdent, NULL);
   69.30  
   69.31  		g_OnLogAction = g_Forwards.CreateForward("OnLogAction", 
   69.32  			ET_Hook, 
   69.33 @@ -88,7 +86,7 @@
   69.34  	void OnSourceModShutdown()
   69.35  	{
   69.36  		g_Forwards.ReleaseForward(g_OnLogAction);
   69.37 -		g_HandleSys.RemoveType(g_PlIter, g_pCoreIdent);
   69.38 +		handlesys->RemoveType(g_PlIter, g_pCoreIdent);
   69.39  	}
   69.40  } g_CoreNativeHelpers;
   69.41  
   69.42 @@ -114,7 +112,7 @@
   69.43  	if (type == 2)
   69.44  	{
   69.45  		HandleError err;
   69.46 -		IPlugin *pPlugin = g_PluginSys.PluginFromHandle(hndl, &err);
   69.47 +		IPlugin *pPlugin = scripts->FindPluginByHandle(hndl, &err);
   69.48  		if (pPlugin)
   69.49  		{
   69.50  			logtag = pPlugin->GetFilename();
   69.51 @@ -197,9 +195,9 @@
   69.52  
   69.53  static cell_t GetPluginIterator(IPluginContext *pContext, const cell_t *params)
   69.54  {
   69.55 -	IPluginIterator *iter = g_PluginSys.GetPluginIterator();
   69.56 +	IPluginIterator *iter = scripts->GetPluginIterator();
   69.57  
   69.58 -	Handle_t hndl = g_HandleSys.CreateHandle(g_PlIter, iter, pContext->GetIdentity(), g_pCoreIdent, NULL);
   69.59 +	Handle_t hndl = handlesys->CreateHandle(g_PlIter, iter, pContext->GetIdentity(), g_pCoreIdent, NULL);
   69.60  
   69.61  	if (hndl == BAD_HANDLE)
   69.62  	{
   69.63 @@ -219,7 +217,7 @@
   69.64  	sec.pIdentity = g_pCoreIdent;
   69.65  	sec.pOwner = pContext->GetIdentity();
   69.66  
   69.67 -	if ((err=g_HandleSys.ReadHandle(hndl, g_PlIter, &sec, (void **)&pIter)) != HandleError_None)
   69.68 +	if ((err=handlesys->ReadHandle(hndl, g_PlIter, &sec, (void **)&pIter)) != HandleError_None)
   69.69  	{
   69.70  		return pContext->ThrowNativeError("Could not read Handle %x (error %d)", hndl, err);
   69.71  	}
   69.72 @@ -237,12 +235,12 @@
   69.73  	sec.pIdentity = g_pCoreIdent;
   69.74  	sec.pOwner = pContext->GetIdentity();
   69.75  
   69.76 -	if ((err=g_HandleSys.ReadHandle(hndl, g_PlIter, &sec, (void **)&pIter)) != HandleError_None)
   69.77 +	if ((err=handlesys->ReadHandle(hndl, g_PlIter, &sec, (void **)&pIter)) != HandleError_None)
   69.78  	{
   69.79  		return pContext->ThrowNativeError("Could not read Handle %x (error %d)", hndl, err);
   69.80  	}
   69.81  
   69.82 -	CPlugin *pPlugin = (CPlugin *)pIter->GetPlugin();
   69.83 +	IPlugin *pPlugin = pIter->GetPlugin();
   69.84  	if (!pPlugin)
   69.85  	{
   69.86  		return BAD_HANDLE;
   69.87 @@ -253,14 +251,14 @@
   69.88  	return pPlugin->GetMyHandle();
   69.89  }
   69.90  
   69.91 -CPlugin *GetPluginFromHandle(IPluginContext *pContext, Handle_t hndl)
   69.92 +IPlugin *GetPluginFromHandle(IPluginContext *pContext, Handle_t hndl)
   69.93  {
   69.94  	if (hndl == BAD_HANDLE)
   69.95  	{
   69.96 -		return g_PluginSys.GetPluginByCtx(pContext->GetContext());
   69.97 +		return scripts->FindPluginByContext(pContext->GetContext());
   69.98  	} else {
   69.99  		HandleError err;
  69.100 -		CPlugin *pPlugin = (CPlugin *)g_PluginSys.PluginFromHandle(hndl, &err);
  69.101 +		IPlugin *pPlugin = scripts->FindPluginByHandle(hndl, &err);
  69.102  		if (!pPlugin)
  69.103  		{
  69.104  			pContext->ThrowNativeError("Could not read Handle %x (error %d)", hndl, err);
  69.105 @@ -271,7 +269,7 @@
  69.106  
  69.107  static cell_t GetPluginStatus(IPluginContext *pContext, const cell_t *params)
  69.108  {
  69.109 -	CPlugin *pPlugin = GetPluginFromHandle(pContext, params[1]);
  69.110 +	IPlugin *pPlugin = GetPluginFromHandle(pContext, params[1]);
  69.111  	if (!pPlugin)
  69.112  	{
  69.113  		return 0;
  69.114 @@ -282,7 +280,7 @@
  69.115  
  69.116  static cell_t GetPluginFilename(IPluginContext *pContext, const cell_t *params)
  69.117  {
  69.118 -	CPlugin *pPlugin = GetPluginFromHandle(pContext, params[1]);
  69.119 +	IPlugin *pPlugin = GetPluginFromHandle(pContext, params[1]);
  69.120  	if (!pPlugin)
  69.121  	{
  69.122  		return 0;
  69.123 @@ -295,7 +293,7 @@
  69.124  
  69.125  static cell_t IsPluginDebugging(IPluginContext *pContext, const cell_t *params)
  69.126  {
  69.127 -	CPlugin *pPlugin = GetPluginFromHandle(pContext, params[1]);
  69.128 +	IPlugin *pPlugin = GetPluginFromHandle(pContext, params[1]);
  69.129  	if (!pPlugin)
  69.130  	{
  69.131  		return 0;
  69.132 @@ -316,7 +314,7 @@
  69.133  
  69.134  static cell_t GetPluginInfo(IPluginContext *pContext, const cell_t *params)
  69.135  {
  69.136 -	CPlugin *pPlugin = GetPluginFromHandle(pContext, params[1]);
  69.137 +	IPlugin *pPlugin = GetPluginFromHandle(pContext, params[1]);
  69.138  	if (!pPlugin)
  69.139  	{
  69.140  		return 0;
  69.141 @@ -373,10 +371,10 @@
  69.142  static cell_t SetFailState(IPluginContext *pContext, const cell_t *params)
  69.143  {
  69.144  	char *str;
  69.145 -	CPlugin *pPlugin;
  69.146 +	SMPlugin *pPlugin;
  69.147  
  69.148  	pContext->LocalToString(params[1], &str);
  69.149 -	pPlugin = g_PluginSys.GetPluginByCtx(pContext->GetContext());
  69.150 +	pPlugin = scripts->FindPluginByContext(pContext->GetContext());
  69.151  
  69.152  	if (params[0] == 1)
  69.153  	{
  69.154 @@ -425,7 +423,7 @@
  69.155  
  69.156  static cell_t AutoExecConfig(IPluginContext *pContext, const cell_t *params)
  69.157  {
  69.158 -	CPlugin *plugin = g_PluginSys.GetPluginByCtx(pContext->GetContext());
  69.159 +	SMPlugin *plugin = scripts->FindPluginByContext(pContext->GetContext());
  69.160  
  69.161  	char *cfg, *folder;
  69.162  	pContext->LocalToString(params[2], &cfg);
  69.163 @@ -476,12 +474,11 @@
  69.164  static cell_t RegPluginLibrary(IPluginContext *pContext, const cell_t *params)
  69.165  {
  69.166  	char *name;
  69.167 -	CPlugin *pl = g_PluginSys.GetPluginByCtx(pContext->GetContext());
  69.168 +	SMPlugin *pl = scripts->FindPluginByContext(pContext->GetContext());
  69.169  
  69.170  	pContext->LocalToString(params[1], &name);
  69.171  
  69.172  	pl->AddLibrary(name);
  69.173 -
  69.174  	return 1;
  69.175  }
  69.176  
  69.177 @@ -495,12 +492,12 @@
  69.178  		return 1;
  69.179  	}
  69.180  
  69.181 -	if (g_PluginSys.LibraryExists(str))
  69.182 +	if (scripts->LibraryExists(str))
  69.183  	{
  69.184  		return 1;
  69.185  	}
  69.186  
  69.187 -	if (g_Extensions.LibraryExists(str))
  69.188 +	if (extsys->LibraryExists(str))
  69.189  	{
  69.190  		return 1;
  69.191  	}
  69.192 @@ -519,7 +516,7 @@
  69.193  		return 0;
  69.194  	}
  69.195  
  69.196 -	CPlugin *pPlugin = g_PluginSys.GetPluginByCtx(pContext->GetContext());
  69.197 +	IPlugin *pPlugin = scripts->FindPluginByContext(pContext->GetContext());
  69.198  
  69.199  	LogAction(pPlugin->GetMyHandle(), 2, params[1], params[2], buffer);
  69.200  
  69.201 @@ -550,7 +547,7 @@
  69.202  		return 0;
  69.203  	}
  69.204  
  69.205 -	CPlugin *pPlugin = g_PluginSys.GetPluginByCtx(pContext->GetContext());
  69.206 +	IPlugin *pPlugin = scripts->FindPluginByContext(pContext->GetContext());
  69.207  
  69.208  	g_Logger.LogToOpenFile(fp, "[%s] %s", pPlugin->GetFilename(), buffer);
  69.209  
  69.210 @@ -595,7 +592,7 @@
  69.211  	char *str;
  69.212  	pContext->LocalToString(params[1], &str);
  69.213  
  69.214 -	IExtension *pExtension = g_Extensions.FindExtensionByFile(str);
  69.215 +	IExtension *pExtension = extsys->FindExtensionByFile(str);
  69.216  	
  69.217  	if (!pExtension)
  69.218  	{
  69.219 @@ -619,7 +616,7 @@
  69.220  
  69.221  static cell_t FindPluginByNumber(IPluginContext *pContext, const cell_t *params)
  69.222  {
  69.223 -	CPlugin *pPlugin = g_PluginSys.GetPluginByOrder(params[1]);
  69.224 +	IPlugin *pPlugin = scripts->FindPluginByOrder(params[1]);
  69.225  	
  69.226  	if (pPlugin == NULL)
  69.227  	{
  69.228 @@ -641,7 +638,7 @@
  69.229  
  69.230  	pContext->LocalToString(params[2], &name);
  69.231  
  69.232 -	return g_ShareSys.TestFeature(pContext->GetRuntime(),type, name);
  69.233 +	return sharesys->TestFeature(pContext->GetRuntime(), type, name);
  69.234  }
  69.235  
  69.236  static cell_t RequireFeature(IPluginContext *pContext, const cell_t *params)
  69.237 @@ -651,12 +648,12 @@
  69.238  
  69.239  	pContext->LocalToString(params[2], &name);
  69.240  
  69.241 -	if (g_ShareSys.TestFeature(pContext->GetRuntime(),type, name) != FeatureStatus_Available)
  69.242 +	if (sharesys->TestFeature(pContext->GetRuntime(), type, name) != FeatureStatus_Available)
  69.243  	{
  69.244  		char buffer[255];
  69.245  		char *msg = buffer;
  69.246  		char default_message[255];
  69.247 -		CPlugin *pPlugin = g_PluginSys.GetPluginByCtx(pContext->GetContext());
  69.248 +		SMPlugin *pPlugin = scripts->FindPluginByContext(pContext->GetContext());
  69.249  
  69.250  		g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, 3);
  69.251  		if (pContext->GetLastNativeError() != SP_ERROR_NONE || buffer[0] == '\0')
    70.1 --- a/core/smn_database.cpp	Fri Mar 29 12:28:02 2013 -0400
    70.2 +++ b/core/smn_database.cpp	Fri Mar 29 11:37:29 2013 -0700
    70.3 @@ -30,11 +30,11 @@
    70.4   */
    70.5  
    70.6  #include "sm_globals.h"
    70.7 -#include "HandleSys.h"
    70.8  #include "Database.h"
    70.9 -#include "ExtensionSys.h"
   70.10 -#include "PluginSys.h"
   70.11  #include "sm_stringutil.h"
   70.12 +#include "logic_bridge.h"
   70.13 +#include "KeyValues.h"
   70.14 +#include "sourcemod.h"
   70.15  
   70.16  HandleType_t hStmtType;
   70.17  
   70.18 @@ -55,22 +55,22 @@
   70.19  		HandleAccess acc;
   70.20  
   70.21  		/* Disable cloning */
   70.22 -		g_HandleSys.InitAccessDefaults(NULL, &acc);
   70.23 +		handlesys->InitAccessDefaults(NULL, &acc);
   70.24  		acc.access[HandleAccess_Clone] = HANDLE_RESTRICT_OWNER|HANDLE_RESTRICT_IDENTITY;
   70.25  
   70.26  		TypeAccess tacc;
   70.27  
   70.28 -		g_HandleSys.InitAccessDefaults(&tacc, NULL);
   70.29 +		handlesys->InitAccessDefaults(&tacc, NULL);
   70.30  		tacc.ident = g_pCoreIdent;
   70.31  
   70.32 -		hCombinedQueryType = g_HandleSys.CreateType("IQuery", this, 0, &tacc, &acc, g_pCoreIdent, NULL);
   70.33 -		hStmtType = g_HandleSys.CreateType("IPreparedQuery", this, 0, &tacc, &acc, g_pCoreIdent, NULL);
   70.34 +		hCombinedQueryType = handlesys->CreateType("IQuery", this, 0, &tacc, &acc, g_pCoreIdent, NULL);
   70.35 +		hStmtType = handlesys->CreateType("IPreparedQuery", this, 0, &tacc, &acc, g_pCoreIdent, NULL);
   70.36  	}
   70.37  
   70.38  	virtual void OnSourceModShutdown()
   70.39  	{
   70.40 -		g_HandleSys.RemoveType(hStmtType, g_pCoreIdent);
   70.41 -		g_HandleSys.RemoveType(hCombinedQueryType, g_pCoreIdent);
   70.42 +		handlesys->RemoveType(hStmtType, g_pCoreIdent);
   70.43 +		handlesys->RemoveType(hCombinedQueryType, g_pCoreIdent);
   70.44  	}
   70.45  
   70.46  	virtual void OnHandleDestroy(HandleType_t type, void *object)
   70.47 @@ -97,9 +97,9 @@
   70.48  
   70.49  	HandleError ret;
   70.50  	
   70.51 -	if ((ret = g_HandleSys.ReadHandle(hndl, hStmtType, &sec, (void **)query)) != HandleError_None)
   70.52 +	if ((ret = handlesys->ReadHandle(hndl, hStmtType, &sec, (void **)query)) != HandleError_None)
   70.53  	{
   70.54 -		ret = g_HandleSys.ReadHandle(hndl, hCombinedQueryType, &sec, (void **)&c);
   70.55 +		ret = handlesys->ReadHandle(hndl, hCombinedQueryType, &sec, (void **)&c);
   70.56  		if (ret == HandleError_None)
   70.57  		{
   70.58  			*query = c->query;
   70.59 @@ -115,7 +115,7 @@
   70.60  	sec.pOwner = pContext->GetIdentity();
   70.61  	sec.pIdentity = g_pCoreIdent;
   70.62  
   70.63 -	HandleError ret = g_HandleSys.ReadHandle(hndl, hCombinedQueryType, &sec, (void **)&c);
   70.64 +	HandleError ret = handlesys->ReadHandle(hndl, hCombinedQueryType, &sec, (void **)&c);
   70.65  	if (ret == HandleError_None)
   70.66  	{
   70.67  		*query = c->query;
   70.68 @@ -130,7 +130,7 @@
   70.69  	sec.pOwner = pContext->GetIdentity();
   70.70  	sec.pIdentity = g_pCoreIdent;
   70.71  
   70.72 -	return g_HandleSys.ReadHandle(hndl, hStmtType, &sec, (void **)query);
   70.73 +	return handlesys->ReadHandle(hndl, hStmtType, &sec, (void **)query);
   70.74  }
   70.75  
   70.76  inline HandleError ReadDbOrStmtHndl(Handle_t hndl, IPluginContext *pContext, IDatabase **db, IPreparedQuery **query)
   70.77 @@ -149,7 +149,7 @@
   70.78  public:
   70.79  	TQueryOp(IDatabase *db, IPluginFunction *pf, const char *query, cell_t data) : 
   70.80  	  m_pDatabase(db), m_pFunction(pf), m_Query(query), m_Data(data),
   70.81 -	  me(g_PluginSys.GetPluginByCtx(pf->GetParentContext()->GetContext())),
   70.82 +	  me(scripts->FindPluginByContext(pf->GetParentContext()->GetContext())),
   70.83  	  m_pQuery(NULL)
   70.84  	{
   70.85  		/* We always increase the reference count because this is potentially
   70.86 @@ -163,9 +163,9 @@
   70.87  		 */
   70.88  		HandleSecurity sec(me->GetIdentity(), g_pCoreIdent);
   70.89  		HandleAccess access;
   70.90 -		g_HandleSys.InitAccessDefaults(NULL, &access);
   70.91 +		handlesys->InitAccessDefaults(NULL, &access);
   70.92  		access.access[HandleAccess_Delete] = HANDLE_RESTRICT_IDENTITY|HANDLE_RESTRICT_OWNER;
   70.93 -		m_MyHandle = g_HandleSys.CreateHandleEx(g_DBMan.GetDatabaseType(),
   70.94 +		m_MyHandle = handlesys->CreateHandleEx(g_DBMan.GetDatabaseType(),
   70.95  			db,
   70.96  			&sec,
   70.97  			&access,
   70.98 @@ -182,7 +182,7 @@
   70.99  		if (m_MyHandle != BAD_HANDLE)
  70.100  		{
  70.101  			HandleSecurity sec(me->GetIdentity(), g_pCoreIdent);
  70.102 -			g_HandleSys.FreeHandle(m_MyHandle, &sec);
  70.103 +			handlesys->FreeHandle(m_MyHandle, &sec);
  70.104  		} else {
  70.105  			/* Otherwise, there is an open ref to the db */
  70.106  			m_pDatabase->Close();
  70.107 @@ -219,7 +219,7 @@
  70.108  		/* Create a Handle for our query */
  70.109  		HandleSecurity sec(me->GetIdentity(), g_pCoreIdent);
  70.110  		HandleAccess access;
  70.111 -		g_HandleSys.InitAccessDefaults(NULL, &access);
  70.112 +		handlesys->InitAccessDefaults(NULL, &access);
  70.113  		access.access[HandleAccess_Delete] = HANDLE_RESTRICT_IDENTITY|HANDLE_RESTRICT_OWNER;
  70.114  
  70.115  		Handle_t qh = BAD_HANDLE;
  70.116 @@ -230,7 +230,7 @@
  70.117  			c->query = m_pQuery;
  70.118  			c->db = m_pDatabase;
  70.119  			
  70.120 -			qh = g_HandleSys.CreateHandle(hCombinedQueryType, c, me->GetIdentity(), g_pCoreIdent, NULL);
  70.121 +			qh = handlesys->CreateHandle(hCombinedQueryType, c, me->GetIdentity(), g_pCoreIdent, NULL);
  70.122  			if (qh != BAD_HANDLE)
  70.123  			{
  70.124  				m_pQuery = NULL;
  70.125 @@ -248,7 +248,7 @@
  70.126  
  70.127  		if (qh != BAD_HANDLE)
  70.128  		{
  70.129 -			g_HandleSys.FreeHandle(qh, &sec);
  70.130 +			handlesys->FreeHandle(qh, &sec);
  70.131  		}
  70.132  	}
  70.133  	void Destroy()
  70.134 @@ -260,7 +260,7 @@
  70.135  	IPluginFunction *m_pFunction;
  70.136  	String m_Query;
  70.137  	cell_t m_Data;
  70.138 -	CPlugin *me;
  70.139 +	IPlugin *me;
  70.140  	IQuery *m_pQuery;
  70.141  	char error[255];
  70.142  	Handle_t m_MyHandle;
  70.143 @@ -277,7 +277,7 @@
  70.144  		m_Data = data;
  70.145  		error[0] = '\0';
  70.146  		strncopy(dbname, _dbname, sizeof(dbname));
  70.147 -		me = g_PluginSys.GetPluginByCtx(m_pFunction->GetParentContext()->GetContext());
  70.148 +		me = scripts->FindPluginByContext(m_pFunction->GetParentContext()->GetContext());
  70.149  	}
  70.150  	IdentityToken_t *GetOwner()
  70.151  	{
  70.152 @@ -336,7 +336,7 @@
  70.153  		delete this;
  70.154  	}
  70.155  private:
  70.156 -	CPlugin *me;
  70.157 +	IPlugin *me;
  70.158  	IPluginFunction *m_pFunction;
  70.159  	IDBDriver *m_pDriver;
  70.160  	IDatabase *m_pDatabase;
  70.161 @@ -369,10 +369,10 @@
  70.162  	}
  70.163  
  70.164  	/* HACK! Add us to the dependency list */
  70.165 -	CExtension *pExt = g_Extensions.GetExtensionFromIdent(driver->GetIdentity());
  70.166 +	IExtension *pExt = extsys->GetExtensionFromIdent(driver->GetIdentity());
  70.167  	if (pExt)
  70.168  	{
  70.169 -		g_Extensions.BindChildPlugin(pExt, g_PluginSys.GetPluginByCtx(pContext->GetContext()));
  70.170 +		extsys->BindChildPlugin(pExt, scripts->FindPluginByContext(pContext->GetContext()));
  70.171  	}
  70.172  
  70.173  	return hndl;
  70.174 @@ -427,15 +427,15 @@
  70.175  	}
  70.176  
  70.177  	/* HACK! Add us to the dependency list */
  70.178 -	CExtension *pExt = g_Extensions.GetExtensionFromIdent(driver->GetIdentity());
  70.179 +	IExtension *pExt = extsys->GetExtensionFromIdent(driver->GetIdentity());
  70.180  	if (pExt)
  70.181  	{
  70.182 -		g_Extensions.BindChildPlugin(pExt, g_PluginSys.GetPluginByCtx(pContext->GetContext()));
  70.183 +		extsys->BindChildPlugin(pExt, scripts->FindPluginByContext(pContext->GetContext()));
  70.184  	}
  70.185  
  70.186  	/* Finally, add to the thread if we can */
  70.187  	TConnectOp *op = new TConnectOp(pf, driver, conf, params[3]);
  70.188 -	CPlugin *pPlugin = g_PluginSys.GetPluginByCtx(pContext->GetContext());
  70.189 +	IPlugin *pPlugin = scripts->FindPluginByContext(pContext->GetContext());
  70.190  	if (pPlugin->GetProperty("DisallowDBThreads", NULL)
  70.191  		|| !g_DBMan.AddToThreadQueue(op, PrioQueue_High))
  70.192  	{
  70.193 @@ -498,10 +498,10 @@
  70.194  		}
  70.195  
  70.196  		/* HACK! Add us to the dependency list */
  70.197 -		CExtension *pExt = g_Extensions.GetExtensionFromIdent(driver->GetIdentity());
  70.198 +		IExtension *pExt = extsys->GetExtensionFromIdent(driver->GetIdentity());
  70.199  		if (pExt)
  70.200  		{
  70.201 -			g_Extensions.BindChildPlugin(pExt, g_PluginSys.GetPluginByCtx(pContext->GetContext()));
  70.202 +			extsys->BindChildPlugin(pExt, scripts->FindPluginByContext(pContext->GetContext()));
  70.203  		}
  70.204  
  70.205  		return hndl;
  70.206 @@ -741,7 +741,7 @@
  70.207  	CombinedQuery *c = new CombinedQuery;
  70.208  	c->query = qr;
  70.209  	c->db = db;
  70.210 -	Handle_t hndl = g_HandleSys.CreateHandle(hCombinedQueryType, c, pContext->GetIdentity(), g_pCoreIdent, NULL);
  70.211 +	Handle_t hndl = handlesys->CreateHandle(hCombinedQueryType, c, pContext->GetIdentity(), g_pCoreIdent, NULL);
  70.212  	if (hndl == BAD_HANDLE)
  70.213  	{
  70.214  		qr->Destroy();
  70.215 @@ -786,7 +786,7 @@
  70.216  		level = PrioQueue_Low;
  70.217  	}
  70.218  
  70.219 -	CPlugin *pPlugin = g_PluginSys.GetPluginByCtx(pContext->GetContext());
  70.220 +	IPlugin *pPlugin = scripts->FindPluginByContext(pContext->GetContext());
  70.221  
  70.222  	TQueryOp *op = new TQueryOp(db, pf, query, data);
  70.223  	if (pPlugin->GetProperty("DisallowDBThreads", NULL)
  70.224 @@ -856,7 +856,7 @@
  70.225  		return BAD_HANDLE;
  70.226  	}
  70.227  
  70.228 -	Handle_t hndl = g_HandleSys.CreateHandle(hStmtType, qr, pContext->GetIdentity(), g_pCoreIdent, NULL);
  70.229 +	Handle_t hndl = handlesys->CreateHandle(hStmtType, qr, pContext->GetIdentity(), g_pCoreIdent, NULL);
  70.230  	if (hndl == BAD_HANDLE)
  70.231  	{
  70.232  		qr->Destroy();
  70.233 @@ -1398,10 +1398,10 @@
  70.234  	}
  70.235  
  70.236  	/* HACK! Add us to the dependency list */
  70.237 -	CExtension *pExt = g_Extensions.GetExtensionFromIdent(driver->GetIdentity());
  70.238 +	IExtension *pExt = extsys->GetExtensionFromIdent(driver->GetIdentity());
  70.239  	if (pExt)
  70.240  	{
  70.241 -		g_Extensions.BindChildPlugin(pExt, g_PluginSys.GetPluginByCtx(pContext->GetContext()));
  70.242 +		extsys->BindChildPlugin(pExt, scripts->FindPluginByContext(pContext->GetContext()));
  70.243  	}
  70.244  
  70.245  	return hndl;
    71.1 --- a/core/smn_events.cpp	Fri Mar 29 12:28:02 2013 -0400
    71.2 +++ b/core/smn_events.cpp	Fri Mar 29 11:37:29 2013 -0700
    71.3 @@ -31,8 +31,8 @@
    71.4  
    71.5  #include "sm_globals.h"
    71.6  #include "sourcemm_api.h"
    71.7 -#include "HandleSys.h"
    71.8  #include "EventManager.h"
    71.9 +#include "logic_bridge.h"
   71.10  
   71.11  static cell_t sm_HookEvent(IPluginContext *pContext, const cell_t *params)
   71.12  {
   71.13 @@ -113,7 +113,7 @@
   71.14  
   71.15  	if (pInfo)
   71.16  	{
   71.17 -		return g_HandleSys.CreateHandle(g_EventManager.GetHandleType(), pInfo, pContext->GetIdentity(), g_pCoreIdent, NULL);
   71.18 +		return handlesys->CreateHandle(g_EventManager.GetHandleType(), pInfo, pContext->GetIdentity(), g_pCoreIdent, NULL);
   71.19  	}
   71.20  
   71.21  	return BAD_HANDLE;
   71.22 @@ -125,7 +125,7 @@
   71.23  	HandleError err;
   71.24  	EventInfo *pInfo;
   71.25  
   71.26 -	if ((err=g_HandleSys.ReadHandle(hndl, g_EventManager.GetHandleType(), NULL, (void **)&pInfo))
   71.27 +	if ((err=handlesys->ReadHandle(hndl, g_EventManager.GetHandleType(), NULL, (void **)&pInfo))
   71.28  		!= HandleError_None)
   71.29  	{
   71.30  		return pContext->ThrowNativeError("Invalid game event handle %x (error %d)", hndl, err);
   71.31 @@ -141,7 +141,7 @@
   71.32  
   71.33  	/* Free handle on game event */
   71.34  	HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent);
   71.35 -	g_HandleSys.FreeHandle(hndl, &sec);
   71.36 +	handlesys->FreeHandle(hndl, &sec);
   71.37  
   71.38  	return 1;
   71.39  }
   71.40 @@ -152,7 +152,7 @@
   71.41  	HandleError err;
   71.42  	EventInfo *pInfo;
   71.43  
   71.44 -	if ((err=g_HandleSys.ReadHandle(hndl, g_EventManager.GetHandleType(), NULL, (void **)&pInfo))
   71.45 +	if ((err=handlesys->ReadHandle(hndl, g_EventManager.GetHandleType(), NULL, (void **)&pInfo))
   71.46  		!= HandleError_None)
   71.47  	{
   71.48  		return pContext->ThrowNativeError("Invalid game event handle %x (error %d)", hndl, err);
   71.49 @@ -168,7 +168,7 @@
   71.50  
   71.51  	/* Free handle on game event */
   71.52  	HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent);
   71.53 -	g_HandleSys.FreeHandle(hndl, &sec);
   71.54 +	handlesys->FreeHandle(hndl, &sec);
   71.55  
   71.56  	return 1;
   71.57  }
   71.58 @@ -179,7 +179,7 @@
   71.59  	HandleError err;
   71.60  	EventInfo *pInfo;
   71.61  
   71.62 -	if ((err=g_HandleSys.ReadHandle(hndl, g_EventManager.GetHandleType(), NULL, (void **)&pInfo))
   71.63 +	if ((err=handlesys->ReadHandle(hndl, g_EventManager.GetHandleType(), NULL, (void **)&pInfo))
   71.64  		!= HandleError_None)
   71.65  	{
   71.66  		return pContext->ThrowNativeError("Invalid game event handle %x (error %d)", hndl, err);
   71.67 @@ -196,7 +196,7 @@
   71.68  	HandleError err;
   71.69  	EventInfo *pInfo;
   71.70  
   71.71 -	if ((err=g_HandleSys.ReadHandle(hndl, g_EventManager.GetHandleType(), NULL, (void **)&pInfo))
   71.72 +	if ((err=handlesys->ReadHandle(hndl, g_EventManager.GetHandleType(), NULL, (void **)&pInfo))
   71.73  		!= HandleError_None)
   71.74  	{
   71.75  		return pContext->ThrowNativeError("Invalid game event handle %x (error %d)", hndl, err);
   71.76 @@ -214,7 +214,7 @@
   71.77  	HandleError err;
   71.78  	EventInfo *pInfo;
   71.79  
   71.80 -	if ((err=g_HandleSys.ReadHandle(hndl, g_EventManager.GetHandleType(), NULL, (void **)&pInfo))
   71.81 +	if ((err=handlesys->ReadHandle(hndl, g_EventManager.GetHandleType(), NULL, (void **)&pInfo))
   71.82  		!= HandleError_None)
   71.83  	{
   71.84  		return pContext->ThrowNativeError("Invalid game event handle %x (error %d)", hndl, err);
   71.85 @@ -232,7 +232,7 @@
   71.86  	HandleError err;
   71.87  	EventInfo *pInfo;
   71.88  
   71.89 -	if ((err=g_HandleSys.ReadHandle(hndl, g_EventManager.GetHandleType(), NULL, (void **)&pInfo))
   71.90 +	if ((err=handlesys->ReadHandle(hndl, g_EventManager.GetHandleType(), NULL, (void **)&pInfo))
   71.91  		!= HandleError_None)
   71.92  	{
   71.93  		return pContext->ThrowNativeError("Invalid game event handle %x (error %d)", hndl, err);
   71.94 @@ -252,7 +252,7 @@
   71.95  	HandleError err;
   71.96  	EventInfo *pInfo;
   71.97  
   71.98 -	if ((err=g_HandleSys.ReadHandle(hndl, g_EventManager.GetHandleType(), NULL, (void **)&pInfo))
   71.99 +	if ((err=handlesys->ReadHandle(hndl, g_EventManager.GetHandleType(), NULL, (void **)&pInfo))
  71.100  		!= HandleError_None)
  71.101  	{
  71.102  		return pContext->ThrowNativeError("Invalid game event handle %x (error %d)", hndl, err);
  71.103 @@ -272,7 +272,7 @@
  71.104  	HandleError err;
  71.105  	EventInfo *pInfo;
  71.106  
  71.107 -	if ((err=g_HandleSys.ReadHandle(hndl, g_EventManager.GetHandleType(), NULL, (void **)&pInfo))
  71.108 +	if ((err=handlesys->ReadHandle(hndl, g_EventManager.GetHandleType(), NULL, (void **)&pInfo))
  71.109  		!= HandleError_None)
  71.110  	{
  71.111  		return pContext->ThrowNativeError("Invalid game event handle %x (error %d)", hndl, err);
  71.112 @@ -292,7 +292,7 @@
  71.113  	HandleError err;
  71.114  	EventInfo *pInfo;
  71.115  
  71.116 -	if ((err=g_HandleSys.ReadHandle(hndl, g_EventManager.GetHandleType(), NULL, (void **)&pInfo))
  71.117 +	if ((err=handlesys->ReadHandle(hndl, g_EventManager.GetHandleType(), NULL, (void **)&pInfo))
  71.118  		!= HandleError_None)
  71.119  	{
  71.120  		return pContext->ThrowNativeError("Invalid game event handle %x (error %d)", hndl, err);
  71.121 @@ -312,7 +312,7 @@
  71.122  	HandleError err;
  71.123  	EventInfo *pInfo;
  71.124  
  71.125 -	if ((err=g_HandleSys.ReadHandle(hndl, g_EventManager.GetHandleType(), NULL, (void **)&pInfo))
  71.126 +	if ((err=handlesys->ReadHandle(hndl, g_EventManager.GetHandleType(), NULL, (void **)&pInfo))
  71.127  		!= HandleError_None)
  71.128  	{
  71.129  		return pContext->ThrowNativeError("Invalid game event handle %x (error %d)", hndl, err);
  71.130 @@ -333,7 +333,7 @@
  71.131  	HandleError err;
  71.132  	EventInfo *pInfo;
  71.133  
  71.134 -	if ((err=g_HandleSys.ReadHandle(hndl, g_EventManager.GetHandleType(), NULL, (void **)&pInfo))
  71.135 +	if ((err=handlesys->ReadHandle(hndl, g_EventManager.GetHandleType(), NULL, (void **)&pInfo))
  71.136  		!= HandleError_None)
  71.137  	{
  71.138  		return pContext->ThrowNativeError("Invalid game event handle %x (error %d)", hndl, err);
  71.139 @@ -354,7 +354,7 @@
  71.140  	HandleError err;
  71.141  	EventInfo *pInfo;
  71.142  
  71.143 -	if ((err=g_HandleSys.ReadHandle(hndl, g_EventManager.GetHandleType(), NULL, (void **)&pInfo))
  71.144 +	if ((err=handlesys->ReadHandle(hndl, g_EventManager.GetHandleType(), NULL, (void **)&pInfo))
  71.145  		!= HandleError_None)
  71.146  	{
  71.147  		return pContext->ThrowNativeError("Invalid game event handle %x (error %d)", hndl, err);
    72.1 --- a/core/smn_fakenatives.cpp	Fri Mar 29 12:28:02 2013 -0400
    72.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    72.3 @@ -1,454 +0,0 @@
    72.4 -/**
    72.5 - * vim: set ts=4 :
    72.6 - * =============================================================================
    72.7 - * SourceMod
    72.8 - * Copyright (C) 2004-2008 AlliedModders LLC.  All rights reserved.
    72.9 - * =============================================================================
   72.10 - *
   72.11 - * This program is free software; you can redistribute it and/or modify it under
   72.12 - * the terms of the GNU General Public License, version 3.0, as published by the
   72.13 - * Free Software Foundation.
   72.14 - * 
   72.15 - * This program is distributed in the hope that it will be useful, but WITHOUT
   72.16 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   72.17 - * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
   72.18 - * details.
   72.19 - *
   72.20 - * You should have received a copy of the GNU General Public License along with
   72.21 - * this program.  If not, see <http://www.gnu.org/licenses/>.
   72.22 - *
   72.23 - * As a special exception, AlliedModders LLC gives you permission to link the
   72.24 - * code of this program (as well as its derivative works) to "Half-Life 2," the
   72.25 - * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
   72.26 - * by the Valve Corporation.  You must obey the GNU General Public License in
   72.27 - * all respects for all other code used.  Additionally, AlliedModders LLC grants
   72.28 - * this exception to all derivative works.  AlliedModders LLC defines further
   72.29 - * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
   72.30 - * or <http://www.sourcemod.net/license.php>.
   72.31 - *
   72.32 - * Version: $Id$
   72.33 - */
   72.34 -
   72.35 -#include <sh_list.h>
   72.36 -#include <sh_string.h>
   72.37 -#include "sm_trie.h"
   72.38 -#include "sm_globals.h"
   72.39 -#include "PluginSys.h"
   72.40 -#include "sourcemod.h"
   72.41 -#include "sm_stringutil.h"
   72.42 -
   72.43 -using namespace SourceHook;
   72.44 -
   72.45 -static cell_t s_curparams[SP_MAX_EXEC_PARAMS+1];
   72.46 -static FakeNative *s_curnative = NULL;
   72.47 -static IPluginContext *s_curcaller = NULL;
   72.48 -
   72.49 -cell_t FakeNativeRouter(IPluginContext *pContext, const cell_t *params, void *pData)
   72.50 -{
   72.51 -	FakeNative *native = (FakeNative *)pData;
   72.52 -
   72.53 -	/* Check if too many parameters were passed */
   72.54 -	if (params[0] > SP_MAX_EXEC_PARAMS)
   72.55 -	{
   72.56 -		return pContext->ThrowNativeError("Called native with too many parameters (%d>%d)", params[9], SP_MAX_EXEC_PARAMS);
   72.57 -	}
   72.58 -
   72.59 -	/* Check if the native is paused */
   72.60 -	if (native->ctx->GetRuntime()->IsPaused())
   72.61 -	{
   72.62 -		return pContext->ThrowNativeError("Plugin owning this native is currently paused.");
   72.63 -	}
   72.64 -
   72.65 -	CPlugin *pCaller = g_PluginSys.GetPluginByCtx(pContext->GetContext());
   72.66 -
   72.67 -	/* Save any old data on the stack */
   72.68 -	FakeNative *pSaveNative = s_curnative;
   72.69 -	IPluginContext *pSaveCaller = s_curcaller;
   72.70 -	cell_t save_params[SP_MAX_EXEC_PARAMS+1];
   72.71 -	if (pSaveNative != NULL)
   72.72 -	{
   72.73 -		/* Copy all old parameters */
   72.74 -		for (cell_t i=0; i<=s_curparams[0]; i++)
   72.75 -		{
   72.76 -			save_params[i] = s_curparams[i];
   72.77 -		}
   72.78 -	}
   72.79 -
   72.80 -	/* Save the current parameters */
   72.81 -	s_curnative = native;
   72.82 -	s_curcaller = pContext;
   72.83 -	for (cell_t i=0; i<=params[0]; i++)
   72.84 -	{
   72.85 -		s_curparams[i] = params[i];
   72.86 -	}
   72.87 -
   72.88 -	/* Push info and execute. */
   72.89 -	cell_t result = 0;
   72.90 -	native->call->PushCell(pCaller->GetMyHandle());
   72.91 -	native->call->PushCell(params[0]);
   72.92 -	int error;
   72.93 -	if ((error=native->call->Execute(&result)) != SP_ERROR_NONE)
   72.94 -	{
   72.95 -		if (pContext->GetLastNativeError() == SP_ERROR_NONE)
   72.96 -		{
   72.97 -			pContext->ThrowNativeErrorEx(error, "Error encountered while processing a dynamic native");
   72.98 -		}
   72.99 -	}
  72.100 -
  72.101 -	/* Restore everything from the stack if necessary */
  72.102 -	s_curnative = pSaveNative;
  72.103 -	s_curcaller = pSaveCaller;
  72.104 -	if (pSaveNative != NULL)
  72.105 -	{
  72.106 -		for (cell_t i=0; i<=save_params[0]; i++)
  72.107 -		{
  72.108 -			s_curparams[i] = save_params[i];
  72.109 -		}
  72.110 -	}
  72.111 -
  72.112 -	return result;
  72.113 -}
  72.114 -
  72.115 -static cell_t CreateNative(IPluginContext *pContext, const cell_t *params)
  72.116 -{
  72.117 -	char *name;
  72.118 -	CPlugin *pPlugin;
  72.119 -
  72.120 -	pContext->LocalToString(params[1], &name);
  72.121 -
  72.122 -	IPluginFunction *pFunction = pContext->GetFunctionById(params[2]);
  72.123 -	if (!pFunction)
  72.124 -	{
  72.125 -		return pContext->ThrowNativeError("Function %x is not a valid function", params[2]);
  72.126 -	}
  72.127 -
  72.128 -	pPlugin = g_PluginSys.GetPluginByCtx(pContext->GetContext());
  72.129 -
  72.130 -	if (!pPlugin->AddFakeNative(pFunction, name, FakeNativeRouter))
  72.131 -	{
  72.132 -		return pContext->ThrowNativeError("Fatal error creating dynamic native!");
  72.133 -	}
  72.134 -
  72.135 -	return 1;
  72.136 -}
  72.137 -
  72.138 -static cell_t ThrowNativeError(IPluginContext *pContext, const cell_t *params)
  72.139 -{
  72.140 -	if (!s_curnative || (s_curnative->ctx != pContext))
  72.141 -	{
  72.142 -		return pContext->ThrowNativeError("Not called from inside a native function");
  72.143 -	}
  72.144 -
  72.145 -	g_SourceMod.SetGlobalTarget(SOURCEMOD_SERVER_LANGUAGE);
  72.146 -
  72.147 -	char buffer[512];
  72.148 -
  72.149 -	g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, 2);
  72.150 -
  72.151 -	if (pContext->GetLastNativeError() != SP_ERROR_NONE)
  72.152 -	{
  72.153 -		s_curcaller->ThrowNativeError("Error encountered while processing a dynamic native");
  72.154 -	} else {
  72.155 -		s_curcaller->ThrowNativeErrorEx(params[1], "%s", buffer);
  72.156 -	}
  72.157 -
  72.158 -	return 0;
  72.159 -}
  72.160 -
  72.161 -static cell_t GetNativeStringLength(IPluginContext *pContext, const cell_t *params)
  72.162 -{
  72.163 -	if (!s_curnative || (s_curnative->ctx != pContext))
  72.164 -	{
  72.165 -		return pContext->ThrowNativeError("Not called from inside a native function");
  72.166 -	}
  72.167 -
  72.168 -	cell_t param = params[1];
  72.169 -	if (param < 1 || param > s_curparams[0])
  72.170 -	{
  72.171 -		return pContext->ThrowNativeErrorEx(SP_ERROR_PARAM, "Invalid parameter number: %d", param);
  72.172 -	}
  72.173 -
  72.174 -	int err;
  72.175 -	char *str;
  72.176 -	if ((err=s_curcaller->LocalToString(s_curparams[param], &str)) != SP_ERROR_NONE)
  72.177 -	{
  72.178 -		return err;
  72.179 -	}
  72.180 -
  72.181 -	cell_t *addr;
  72.182 -	pContext->LocalToPhysAddr(params[2], &addr);
  72.183 -	*addr = (cell_t)strlen(str);
  72.184 -
  72.185 -	return SP_ERROR_NONE;
  72.186 -}
  72.187 -
  72.188 -static cell_t GetNativeString(IPluginContext *pContext, const cell_t *params)
  72.189 -{
  72.190 -	if (!s_curnative || (s_curnative->ctx != pContext))
  72.191 -	{
  72.192 -		return pContext->ThrowNativeError("Not called from inside a native function");
  72.193 -	}
  72.194 -
  72.195 -	cell_t param = params[1];
  72.196 -	if (param < 1 || param > s_curparams[0])
  72.197 -	{
  72.198 -		return pContext->ThrowNativeErrorEx(SP_ERROR_PARAM, "Invalid parameter number: %d", param);
  72.199 -	}
  72.200 -
  72.201 -	int err;
  72.202 -	char *str;
  72.203 -	if ((err=s_curcaller->LocalToString(s_curparams[param], &str)) != SP_ERROR_NONE)
  72.204 -	{
  72.205 -		return err;
  72.206 -	}
  72.207 -
  72.208 -	size_t bytes = 0;
  72.209 -	pContext->StringToLocalUTF8(params[2], params[3], str, &bytes);
  72.210 -
  72.211 -	cell_t *addr;
  72.212 -	pContext->LocalToPhysAddr(params[4], &addr);
  72.213 -	*addr = (cell_t)bytes;
  72.214 -
  72.215 -	return SP_ERROR_NONE;
  72.216 -}
  72.217 -
  72.218 -static cell_t SetNativeString(IPluginContext *pContext, const cell_t *params)
  72.219 -{
  72.220 -	if (!s_curnative || (s_curnative->ctx != pContext))
  72.221 -	{
  72.222 -		return pContext->ThrowNativeError("Not called from inside a native function");
  72.223 -	}
  72.224 -
  72.225 -	cell_t param = params[1];
  72.226 -	if (param < 1 || param > s_curparams[0])
  72.227 -	{
  72.228 -		return pContext->ThrowNativeErrorEx(SP_ERROR_PARAM, "Invalid parameter number: %d", param);
  72.229 -	}
  72.230 -
  72.231 -	char *str;
  72.232 -	pContext->LocalToString(params[2], &str);
  72.233 -
  72.234 -	int err;
  72.235 -	size_t bytes = 0;
  72.236 -	if (params[4])
  72.237 -	{
  72.238 -		err = s_curcaller->StringToLocalUTF8(s_curparams[param], params[3], str, &bytes);
  72.239 -	} else {
  72.240 -		err = s_curcaller->StringToLocal(s_curparams[param], params[3], str);
  72.241 -		/* Eww */
  72.242 -		bytes = strlen(str);
  72.243 -		if (bytes >= (size_t)params[3])
  72.244 -		{
  72.245 -			bytes = params[3] - 1;
  72.246 -		}
  72.247 -	}
  72.248 -
  72.249 -	if (err != SP_ERROR_NONE)
  72.250 -	{
  72.251 -		return err;
  72.252 -	}
  72.253 -
  72.254 -	cell_t *addr;
  72.255 -	pContext->LocalToPhysAddr(params[5], &addr);
  72.256 -	*addr = (cell_t)bytes;
  72.257 -
  72.258 -	return SP_ERROR_NONE;
  72.259 -}
  72.260 -
  72.261 -static cell_t GetNativeCell(IPluginContext *pContext, const cell_t *params)
  72.262 -{
  72.263 -	if (!s_curnative || (s_curnative->ctx != pContext))
  72.264 -	{
  72.265 -		return pContext->ThrowNativeError("Not called from inside a native function");
  72.266 -	}
  72.267 -
  72.268 -	cell_t param = params[1];
  72.269 -	if (param < 1 || param > s_curparams[0])
  72.270 -	{
  72.271 -		return pContext->ThrowNativeErrorEx(SP_ERROR_PARAM, "Invalid parameter number: %d", param);
  72.272 -	}
  72.273 -
  72.274 -	return s_curparams[param];
  72.275 -}
  72.276 -
  72.277 -static cell_t GetNativeCellRef(IPluginContext *pContext, const cell_t *params)
  72.278 -{
  72.279 -	if (!s_curnative || (s_curnative->ctx != pContext))
  72.280 -	{
  72.281 -		return pContext->ThrowNativeError("Not called from inside a native function");
  72.282 -	}
  72.283 -
  72.284 -	cell_t param = params[1];
  72.285 -	if (param < 1 || param > s_curparams[0])
  72.286 -	{
  72.287 -		return pContext->ThrowNativeErrorEx(SP_ERROR_PARAM, "Invalid parameter number: %d", param);
  72.288 -	}
  72.289 -
  72.290 -	cell_t *addr;
  72.291 -	if (s_curcaller->LocalToPhysAddr(s_curparams[param], &addr) != SP_ERROR_NONE)
  72.292 -	{
  72.293 -		return s_curcaller->ThrowNativeErrorEx(SP_ERROR_INVALID_ADDRESS, "Invalid address value");
  72.294 -	}
  72.295 -
  72.296 -	return *addr;
  72.297 -}
  72.298 -
  72.299 -static cell_t SetNativeCellRef(IPluginContext *pContext, const cell_t *params)
  72.300 -{
  72.301 -	if (!s_curnative || (s_curnative->ctx != pContext))
  72.302 -	{
  72.303 -		return pContext->ThrowNativeError("Not called from inside a native function");
  72.304 -	}
  72.305 -
  72.306 -	cell_t param = params[1];
  72.307 -	if (param < 1 || param > s_curparams[0])
  72.308 -	{
  72.309 -		return pContext->ThrowNativeErrorEx(SP_ERROR_PARAM, "Invalid parameter number: %d", param);
  72.310 -	}
  72.311 -
  72.312 -	cell_t *addr;
  72.313 -	if (s_curcaller->LocalToPhysAddr(s_curparams[param], &addr) != SP_ERROR_NONE)
  72.314 -	{
  72.315 -		return s_curcaller->ThrowNativeErrorEx(SP_ERROR_INVALID_ADDRESS, "Invalid address value");
  72.316 -	}
  72.317 -
  72.318 -	*addr = params[2];
  72.319 -
  72.320 -	return 1;
  72.321 -}
  72.322 -
  72.323 -static cell_t GetNativeArray(IPluginContext *pContext, const cell_t *params)
  72.324 -{
  72.325 -	if (!s_curnative || (s_curnative->ctx != pContext))
  72.326 -	{
  72.327 -		return pContext->ThrowNativeError("Not called from inside a native function");
  72.328 -	}
  72.329 -
  72.330 -	cell_t param = params[1];
  72.331 -	if (param < 1 || param > s_curparams[0])
  72.332 -	{
  72.333 -		return pContext->ThrowNativeErrorEx(SP_ERROR_PARAM, "Invalid parameter number: %d", param);
  72.334 -	}
  72.335 -
  72.336 -	int err;
  72.337 -	cell_t *addr;
  72.338 -	if ((err=s_curcaller->LocalToPhysAddr(s_curparams[param], &addr)) != SP_ERROR_NONE)
  72.339 -	{
  72.340 -		return err;
  72.341 -	}
  72.342 -
  72.343 -	cell_t *src;
  72.344 -	pContext->LocalToPhysAddr(params[2], &src);
  72.345 -
  72.346 -	memcpy(src, addr, sizeof(cell_t) * params[3]);
  72.347 -
  72.348 -	return SP_ERROR_NONE;
  72.349 -}
  72.350 -
  72.351 -static cell_t SetNativeArray(IPluginContext *pContext, const cell_t *params)
  72.352 -{
  72.353 -	if (!s_curnative || (s_curnative->ctx != pContext))
  72.354 -	{
  72.355 -		return pContext->ThrowNativeError("Not called from inside a native function");
  72.356 -	}
  72.357 -
  72.358 -	cell_t param = params[1];
  72.359 -	if (param < 1 || param > s_curparams[0])
  72.360 -	{
  72.361 -		return pContext->ThrowNativeErrorEx(SP_ERROR_PARAM, "Invalid parameter number: %d", param);
  72.362 -	}
  72.363 -
  72.364 -	int err;
  72.365 -	cell_t *addr;
  72.366 -	if ((err=s_curcaller->LocalToPhysAddr(s_curparams[param], &addr)) != SP_ERROR_NONE)
  72.367 -	{
  72.368 -		return err;
  72.369 -	}
  72.370 -
  72.371 -	cell_t *src;
  72.372 -	pContext->LocalToPhysAddr(params[2], &src);
  72.373 -
  72.374 -	memcpy(addr, src, sizeof(cell_t) * params[3]);
  72.375 -
  72.376 -	return SP_ERROR_NONE;
  72.377 -}
  72.378 -
  72.379 -static cell_t FormatNativeString(IPluginContext *pContext, const cell_t *params)
  72.380 -{
  72.381 -	if (!s_curnative || (s_curnative->ctx != pContext))
  72.382 -	{
  72.383 -		return pContext->ThrowNativeError("Not called from inside a native function");
  72.384 -	}
  72.385 -
  72.386 -	int out_param = params[1];
  72.387 -	int fmt_param = params[2];
  72.388 -	int var_param = params[3];
  72.389 -
  72.390 -	/* Validate input */
  72.391 -	if (out_param && (out_param < 1 || out_param > s_curparams[0]))
  72.392 -	{
  72.393 -		return pContext->ThrowNativeErrorEx(SP_ERROR_PARAM, "Invalid parameter number: %d", out_param);
  72.394 -	}
  72.395 -	if (fmt_param && (fmt_param < 1 || fmt_param > s_curparams[0]))
  72.396 -	{
  72.397 -		return pContext->ThrowNativeErrorEx(SP_ERROR_PARAM, "Invalid parameter number: %d", fmt_param);
  72.398 -	}
  72.399 -	if (var_param && (var_param < 1 || var_param > s_curparams[0] + 1))
  72.400 -	{
  72.401 -		return pContext->ThrowNativeErrorEx(SP_ERROR_PARAM, "Invalid parameter number: %d", fmt_param);
  72.402 -	}
  72.403 -
  72.404 -	/* Get buffer information */
  72.405 -	int err;
  72.406 -	char *output_buffer;
  72.407 -	char *format_buffer;
  72.408 -
  72.409 -	if (out_param)
  72.410 -	{
  72.411 -		if ((err=s_curcaller->LocalToString(s_curparams[out_param], &output_buffer)) != SP_ERROR_NONE)
  72.412 -		{
  72.413 -			return err;
  72.414 -		}
  72.415 -	} else {
  72.416 -		pContext->LocalToString(params[6], &output_buffer);
  72.417 -	}
  72.418 -
  72.419 -	if (fmt_param)
  72.420 -	{
  72.421 -		if ((err=s_curcaller->LocalToString(s_curparams[fmt_param], &format_buffer)) != SP_ERROR_NONE)
  72.422 -		{
  72.423 -			return err;
  72.424 -		}
  72.425 -	} else {
  72.426 -		pContext->LocalToString(params[7], &format_buffer);
  72.427 -	}
  72.428 -
  72.429 -	/* Get maximum length */
  72.430 -	size_t maxlen = (size_t)params[4];
  72.431 -
  72.432 -	/* Do the format */
  72.433 -	size_t written = atcprintf(output_buffer, maxlen, format_buffer, s_curcaller, s_curparams, &var_param);
  72.434 -
  72.435 -	cell_t *addr;
  72.436 -	pContext->LocalToPhysAddr(params[5], &addr);
  72.437 -	*addr = (cell_t)written;
  72.438 -
  72.439 -	return s_curcaller->GetLastNativeError();
  72.440 -}
  72.441 -
  72.442 -//tee hee
  72.443 -REGISTER_NATIVES(nativeNatives)
  72.444 -{
  72.445 -	{"CreateNative",			CreateNative},
  72.446 -	{"GetNativeArray",			GetNativeArray},
  72.447 -	{"GetNativeCell",			GetNativeCell},
  72.448 -	{"GetNativeCellRef",		GetNativeCellRef},
  72.449 -	{"GetNativeString",			GetNativeString},
  72.450 -	{"GetNativeStringLength",	GetNativeStringLength},
  72.451 -	{"FormatNativeString",		FormatNativeString},
  72.452 -	{"ThrowNativeError",		ThrowNativeError},
  72.453 -	{"SetNativeArray",			SetNativeArray},
  72.454 -	{"SetNativeCellRef",		SetNativeCellRef},
  72.455 -	{"SetNativeString",			SetNativeString},
  72.456 -	{NULL,						NULL},
  72.457 -};
    73.1 --- a/core/smn_halflife.cpp	Fri Mar 29 12:28:02 2013 -0400
    73.2 +++ b/core/smn_halflife.cpp	Fri Mar 29 11:37:29 2013 -0700
    73.3 @@ -32,7 +32,6 @@
    73.4  #include "sm_globals.h"
    73.5  #include "sourcemod.h"
    73.6  #include "sourcemm_api.h"
    73.7 -#include "HandleSys.h"
    73.8  #include "PlayerManager.h"
    73.9  #include "HalfLife2.h"
   73.10  
    74.1 --- a/core/smn_hudtext.cpp	Fri Mar 29 12:28:02 2013 -0400
    74.2 +++ b/core/smn_hudtext.cpp	Fri Mar 29 11:37:29 2013 -0700
    74.3 @@ -34,8 +34,8 @@
    74.4  #include "UserMessages.h"
    74.5  #include "TimerSys.h"
    74.6  #include "PlayerManager.h"
    74.7 -#include "HandleSys.h"
    74.8  #include "logic_bridge.h"
    74.9 +#include "sourcemod.h"
   74.10  
   74.11  #if SOURCE_ENGINE == SE_DOTA
   74.12  #include <game/shared/protobuf/usermessages.pb.h>
   74.13 @@ -101,7 +101,7 @@
   74.14  		}
   74.15  
   74.16  		m_PlayerHuds = new player_chaninfo_t[256+1];
   74.17 -		m_hHudSyncObj = g_HandleSys.CreateType("HudSyncObj", this, 0, NULL, NULL, g_pCoreIdent, NULL);
   74.18 +		m_hHudSyncObj = handlesys->CreateType("HudSyncObj", this, 0, NULL, NULL, g_pCoreIdent, NULL);
   74.19  
   74.20  		g_Players.AddClientListener(this);
   74.21  	}
   74.22 @@ -114,7 +114,7 @@
   74.23  		}
   74.24  
   74.25  		delete [] m_PlayerHuds;
   74.26 -		g_HandleSys.RemoveType(m_hHudSyncObj, g_pCoreIdent);
   74.27 +		handlesys->RemoveType(m_hHudSyncObj, g_pCoreIdent);
   74.28  
   74.29  		g_Players.RemoveClientListener(this);
   74.30  	}
   74.31 @@ -154,7 +154,7 @@
   74.32  
   74.33  		sec = HandleSecurity(pIdent, g_pCoreIdent);
   74.34  		
   74.35 -		if ((hndl = g_HandleSys.CreateHandleEx(m_hHudSyncObj, obj, &sec, NULL, &err))
   74.36 +		if ((hndl = handlesys->CreateHandleEx(m_hHudSyncObj, obj, &sec, NULL, &err))
   74.37  			== BAD_HANDLE)
   74.38  		{
   74.39  			delete obj;
   74.40 @@ -168,7 +168,7 @@
   74.41  		hud_syncobj_t **pObj)
   74.42  	{
   74.43  		HandleSecurity sec(pOwner, g_pCoreIdent);
   74.44 -		return g_HandleSys.ReadHandle(hndl, m_hHudSyncObj, &sec, (void **)pObj);
   74.45 +		return handlesys->ReadHandle(hndl, m_hHudSyncObj, &sec, (void **)pObj);
   74.46  	}
   74.47  
   74.48  	unsigned int AutoSelectChannel(unsigned int client)
    75.1 --- a/core/smn_keyvalues.cpp	Fri Mar 29 12:28:02 2013 -0400
    75.2 +++ b/core/smn_keyvalues.cpp	Fri Mar 29 11:37:29 2013 -0700
    75.3 @@ -32,10 +32,10 @@
    75.4  #include "sourcemod.h"
    75.5  #include "sourcemm_api.h"
    75.6  #include "sm_stringutil.h"
    75.7 -#include "HandleSys.h"
    75.8  #include "HalfLife2.h"
    75.9  #include <KeyValues.h>
   75.10  #include "utlbuffer.h"
   75.11 +#include "logic_bridge.h"
   75.12  
   75.13  HandleType_t g_KeyValueType;
   75.14  
   75.15 @@ -52,11 +52,11 @@
   75.16  public:
   75.17  	void OnSourceModAllInitialized()
   75.18  	{
   75.19 -		g_KeyValueType = g_HandleSys.CreateType("KeyValues", this, 0, NULL, NULL, g_pCoreIdent, NULL);
   75.20 +		g_KeyValueType = handlesys->CreateType("KeyValues", this, 0, NULL, NULL, g_pCoreIdent, NULL);
   75.21  	}
   75.22  	void OnSourceModShutdown()
   75.23  	{
   75.24 -		g_HandleSys.RemoveType(g_KeyValueType, g_pCoreIdent);
   75.25 +		handlesys->RemoveType(g_KeyValueType, g_pCoreIdent);
   75.26  		g_KeyValueType = 0;
   75.27  	}
   75.28  	void OnHandleDestroy(HandleType_t type, void *object)
   75.29 @@ -100,7 +100,7 @@
   75.30  	sec.pOwner = NULL;
   75.31  	sec.pIdentity = g_pCoreIdent;
   75.32  
   75.33 -	if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
   75.34 +	if ((herr=handlesys->ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
   75.35  		!= HandleError_None)
   75.36  	{
   75.37  		if (err)
   75.38 @@ -128,7 +128,7 @@
   75.39  	sec.pOwner = NULL;
   75.40  	sec.pIdentity = g_pCoreIdent;
   75.41  
   75.42 -	if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
   75.43 +	if ((herr=handlesys->ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
   75.44  		!= HandleError_None)
   75.45  	{
   75.46  		return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
   75.47 @@ -153,7 +153,7 @@
   75.48  	sec.pOwner = NULL;
   75.49  	sec.pIdentity = g_pCoreIdent;
   75.50  
   75.51 -	if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
   75.52 +	if ((herr=handlesys->ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
   75.53  		!= HandleError_None)
   75.54  	{
   75.55  		return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
   75.56 @@ -177,7 +177,7 @@
   75.57  	sec.pOwner = NULL;
   75.58  	sec.pIdentity = g_pCoreIdent;
   75.59  
   75.60 -	if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
   75.61 +	if ((herr=handlesys->ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
   75.62  		!= HandleError_None)
   75.63  	{
   75.64  		return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
   75.65 @@ -205,7 +205,7 @@
   75.66  	sec.pOwner = NULL;
   75.67  	sec.pIdentity = g_pCoreIdent;
   75.68  
   75.69 -	if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
   75.70 +	if ((herr=handlesys->ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
   75.71  		!= HandleError_None)
   75.72  	{
   75.73  		return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
   75.74 @@ -229,7 +229,7 @@
   75.75  	sec.pOwner = NULL;
   75.76  	sec.pIdentity = g_pCoreIdent;
   75.77  
   75.78 -	if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
   75.79 +	if ((herr=handlesys->ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
   75.80  		!= HandleError_None)
   75.81  	{
   75.82  		return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
   75.83 @@ -254,7 +254,7 @@
   75.84  	sec.pOwner = NULL;
   75.85  	sec.pIdentity = g_pCoreIdent;
   75.86  
   75.87 -	if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
   75.88 +	if ((herr=handlesys->ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
   75.89  		!= HandleError_None)
   75.90  	{
   75.91  		return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
   75.92 @@ -283,7 +283,7 @@
   75.93  	sec.pOwner = NULL;
   75.94  	sec.pIdentity = g_pCoreIdent;
   75.95  
   75.96 -	if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
   75.97 +	if ((herr=handlesys->ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
   75.98  		!= HandleError_None)
   75.99  	{
  75.100  		return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
  75.101 @@ -310,7 +310,7 @@
  75.102  	sec.pOwner = NULL;
  75.103  	sec.pIdentity = g_pCoreIdent;
  75.104  
  75.105 -	if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
  75.106 +	if ((herr=handlesys->ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
  75.107  		!= HandleError_None)
  75.108  	{
  75.109  		return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
  75.110 @@ -335,7 +335,7 @@
  75.111  	sec.pOwner = NULL;
  75.112  	sec.pIdentity = g_pCoreIdent;
  75.113  
  75.114 -	if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
  75.115 +	if ((herr=handlesys->ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
  75.116  		!= HandleError_None)
  75.117  	{
  75.118  		return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
  75.119 @@ -360,7 +360,7 @@
  75.120  	sec.pOwner = NULL;
  75.121  	sec.pIdentity = g_pCoreIdent;
  75.122  
  75.123 -	if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
  75.124 +	if ((herr=handlesys->ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
  75.125  		!= HandleError_None)
  75.126  	{
  75.127  		return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
  75.128 @@ -394,7 +394,7 @@
  75.129  	sec.pOwner = NULL;
  75.130  	sec.pIdentity = g_pCoreIdent;
  75.131  
  75.132 -	if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
  75.133 +	if ((herr=handlesys->ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
  75.134  		!= HandleError_None)
  75.135  	{
  75.136  		return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
  75.137 @@ -423,7 +423,7 @@
  75.138  	sec.pOwner = NULL;
  75.139  	sec.pIdentity = g_pCoreIdent;
  75.140  
  75.141 -	if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
  75.142 +	if ((herr=handlesys->ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
  75.143  		!= HandleError_None)
  75.144  	{
  75.145  		return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
  75.146 @@ -501,7 +501,7 @@
  75.147  	pStk->pBase = new KeyValues(name, is_empty ? NULL : firstkey, (is_empty||(firstvalue[0]=='\0')) ? NULL : firstvalue);
  75.148  	pStk->pCurRoot.push(pStk->pBase);
  75.149  
  75.150 -	return g_HandleSys.CreateHandle(g_KeyValueType, pStk, pCtx->GetIdentity(), g_pCoreIdent, NULL);
  75.151 +	return handlesys->CreateHandle(g_KeyValueType, pStk, pCtx->GetIdentity(), g_pCoreIdent, NULL);
  75.152  }
  75.153  
  75.154  static cell_t smn_KvJumpToKey(IPluginContext *pCtx, const cell_t *params)
  75.155 @@ -515,7 +515,7 @@
  75.156  	sec.pOwner = NULL;
  75.157  	sec.pIdentity = g_pCoreIdent;
  75.158  
  75.159 -	if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
  75.160 +	if ((herr=handlesys->ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
  75.161  		!= HandleError_None)
  75.162  	{
  75.163  		return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
  75.164 @@ -544,7 +544,7 @@
  75.165  	sec.pOwner = NULL;
  75.166  	sec.pIdentity = g_pCoreIdent;
  75.167  
  75.168 -	if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
  75.169 +	if ((herr=handlesys->ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
  75.170  		!= HandleError_None)
  75.171  	{
  75.172  		return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
  75.173 @@ -571,7 +571,7 @@
  75.174  	sec.pOwner = NULL;
  75.175  	sec.pIdentity = g_pCoreIdent;
  75.176  
  75.177 -	if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
  75.178 +	if ((herr=handlesys->ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
  75.179  		!= HandleError_None)
  75.180  	{
  75.181  		return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
  75.182 @@ -605,7 +605,7 @@
  75.183  	sec.pOwner = NULL;
  75.184  	sec.pIdentity = g_pCoreIdent;
  75.185  
  75.186 -	if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
  75.187 +	if ((herr=handlesys->ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
  75.188  		!= HandleError_None)
  75.189  	{
  75.190  		return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
  75.191 @@ -638,7 +638,7 @@
  75.192  	sec.pOwner = NULL;
  75.193  	sec.pIdentity = g_pCoreIdent;
  75.194  
  75.195 -	if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
  75.196 +	if ((herr=handlesys->ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
  75.197  		!= HandleError_None)
  75.198  	{
  75.199  		return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
  75.200 @@ -663,7 +663,7 @@
  75.201  	sec.pOwner = NULL;
  75.202  	sec.pIdentity = g_pCoreIdent;
  75.203  
  75.204 -	if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
  75.205 +	if ((herr=handlesys->ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
  75.206  		!= HandleError_None)
  75.207  	{
  75.208  		return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
  75.209 @@ -687,7 +687,7 @@
  75.210  	sec.pOwner = NULL;
  75.211  	sec.pIdentity = g_pCoreIdent;
  75.212  
  75.213 -	if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
  75.214 +	if ((herr=handlesys->ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
  75.215  		!= HandleError_None)
  75.216  	{
  75.217  		return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
  75.218 @@ -715,7 +715,7 @@
  75.219  	sec.pOwner = NULL;
  75.220  	sec.pIdentity = g_pCoreIdent;
  75.221  
  75.222 -	if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
  75.223 +	if ((herr=handlesys->ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
  75.224  		!= HandleError_None)
  75.225  	{
  75.226  		return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
  75.227 @@ -740,7 +740,7 @@
  75.228  	sec.pOwner = NULL;
  75.229  	sec.pIdentity = g_pCoreIdent;
  75.230  
  75.231 -	if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
  75.232 +	if ((herr=handlesys->ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
  75.233  		!= HandleError_None)
  75.234  	{
  75.235  		return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
  75.236 @@ -762,7 +762,7 @@
  75.237  	sec.pOwner = NULL;
  75.238  	sec.pIdentity = g_pCoreIdent;
  75.239  
  75.240 -	if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
  75.241 +	if ((herr=handlesys->ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
  75.242  		!= HandleError_None)
  75.243  	{
  75.244  		return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
  75.245 @@ -785,7 +785,7 @@
  75.246  	sec.pOwner = NULL;
  75.247  	sec.pIdentity = g_pCoreIdent;
  75.248  
  75.249 -	if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
  75.250 +	if ((herr=handlesys->ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
  75.251  		!= HandleError_None)
  75.252  	{
  75.253  		return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
  75.254 @@ -807,7 +807,7 @@
  75.255  	sec.pOwner = NULL;
  75.256  	sec.pIdentity = g_pCoreIdent;
  75.257  
  75.258 -	if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
  75.259 +	if ((herr=handlesys->ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
  75.260  		!= HandleError_None)
  75.261  	{
  75.262  		return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
  75.263 @@ -828,7 +828,7 @@
  75.264  	sec.pOwner = NULL;
  75.265  	sec.pIdentity = g_pCoreIdent;
  75.266  
  75.267 -	if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
  75.268 +	if ((herr=handlesys->ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
  75.269  		!= HandleError_None)
  75.270  	{
  75.271  		return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
  75.272 @@ -847,7 +847,7 @@
  75.273  	sec.pOwner = NULL;
  75.274  	sec.pIdentity = g_pCoreIdent;
  75.275  
  75.276 -	if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
  75.277 +	if ((herr=handlesys->ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
  75.278  		!= HandleError_None)
  75.279  	{
  75.280  		return pContext->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
  75.281 @@ -901,7 +901,7 @@
  75.282  	sec.pOwner = NULL;
  75.283  	sec.pIdentity = g_pCoreIdent;
  75.284  
  75.285 -	if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
  75.286 +	if ((herr=handlesys->ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
  75.287  		!= HandleError_None)
  75.288  	{
  75.289  		return pContext->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
  75.290 @@ -938,7 +938,7 @@
  75.291  	sec.pOwner = NULL;
  75.292  	sec.pIdentity = g_pCoreIdent;
  75.293  
  75.294 -	if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
  75.295 +	if ((herr=handlesys->ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
  75.296  		!= HandleError_None)
  75.297  	{
  75.298  		return pContext->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
  75.299 @@ -966,12 +966,12 @@
  75.300  	sec.pOwner = NULL;
  75.301  	sec.pIdentity = g_pCoreIdent;
  75.302  
  75.303 -	if ((herr=g_HandleSys.ReadHandle(hndl_copied, g_KeyValueType, &sec, (void **)&pStk_copied))
  75.304 +	if ((herr=handlesys->ReadHandle(hndl_copied, g_KeyValueType, &sec, (void **)&pStk_copied))
  75.305  		!= HandleError_None)
  75.306  	{
  75.307  		return pContext->ThrowNativeError("Invalid key value handle %x (error %d)", hndl_copied, herr);
  75.308  	}
  75.309 -	if ((herr=g_HandleSys.ReadHandle(hndl_parent, g_KeyValueType, &sec, (void **)&pStk_parent))
  75.310 +	if ((herr=handlesys->ReadHandle(hndl_parent, g_KeyValueType, &sec, (void **)&pStk_parent))
  75.311  		!= HandleError_None)
  75.312  	{
  75.313  		return pContext->ThrowNativeError("Invalid key value handle %x (error %d)", hndl_parent, herr);
  75.314 @@ -994,7 +994,7 @@
  75.315  	sec.pOwner = NULL;
  75.316  	sec.pIdentity = g_pCoreIdent;
  75.317  
  75.318 -	if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
  75.319 +	if ((herr=handlesys->ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
  75.320  		!= HandleError_None)
  75.321  	{
  75.322  		return pContext->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
  75.323 @@ -1028,7 +1028,7 @@
  75.324  	sec.pOwner = NULL;
  75.325  	sec.pIdentity = g_pCoreIdent;
  75.326  
  75.327 -	if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
  75.328 +	if ((herr=handlesys->ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
  75.329  		!= HandleError_None)
  75.330  	{
  75.331  		return pContext->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
  75.332 @@ -1056,7 +1056,7 @@
  75.333  	sec.pOwner = NULL;
  75.334  	sec.pIdentity = g_pCoreIdent;
  75.335  
  75.336 -	if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
  75.337 +	if ((herr=handlesys->ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
  75.338  		!= HandleError_None)
  75.339  	{
  75.340  		return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
    76.1 --- a/core/smn_menus.cpp	Fri Mar 29 12:28:02 2013 -0400
    76.2 +++ b/core/smn_menus.cpp	Fri Mar 29 11:37:29 2013 -0700
    76.3 @@ -34,8 +34,6 @@
    76.4  #include "MenuManager.h"
    76.5  #include "MenuStyle_Valve.h"
    76.6  #include "MenuStyle_Radio.h"
    76.7 -#include "HandleSys.h"
    76.8 -#include "PluginSys.h"
    76.9  #include "PlayerManager.h"
   76.10  #include "sm_stringutil.h"
   76.11  #include "sourcemm_api.h"
   76.12 @@ -44,6 +42,7 @@
   76.13  #endif
   76.14  #include "ChatTriggers.h"
   76.15  #include "logic_bridge.h"
   76.16 +#include "sourcemod.h"
   76.17  
   76.18  #if defined CreateMenu
   76.19  #undef CreateMenu
   76.20 @@ -126,15 +125,16 @@
   76.21  public:
   76.22  	virtual void OnSourceModAllInitialized()
   76.23  	{
   76.24 -		m_PanelType = g_HandleSys.CreateType("IMenuPanel", this, 0, NULL, NULL, g_pCoreIdent, NULL);
   76.25 -		m_TempPanelType = g_HandleSys.CreateType("TempIMenuPanel", this, m_PanelType, NULL, NULL, g_pCoreIdent, NULL);
   76.26 -		g_PluginSys.AddPluginsListener(this);
   76.27 +		m_PanelType = handlesys->CreateType("IMenuPanel", this, 0, NULL, NULL, g_pCoreIdent, NULL);
   76.28 +		m_TempPanelType = handlesys->CreateType("TempIMenuPanel", this, m_PanelType, NULL, NULL, g_pCoreIdent, NULL);
   76.29 +		scripts->AddPluginsListener(this);
   76.30  	}
   76.31  
   76.32  	virtual void OnSourceModShutdown()
   76.33  	{
   76.34 -		g_HandleSys.RemoveType(m_TempPanelType, g_pCoreIdent);
   76.35 -		g_HandleSys.RemoveType(m_PanelType, g_pCoreIdent);
   76.36 +		scripts->RemovePluginsListener(this);
   76.37 +		handlesys->RemoveType(m_TempPanelType, g_pCoreIdent);
   76.38 +		handlesys->RemoveType(m_PanelType, g_pCoreIdent);
   76.39  
   76.40  		while (!m_FreePanelHandlers.empty())
   76.41  		{
   76.42 @@ -208,7 +208,7 @@
   76.43  			m_FreePanelHandlers.pop();
   76.44  		}
   76.45  		handler->m_pFunc = pFunction;
   76.46 -		handler->m_pPlugin = g_PluginSys.GetPluginByCtx(pFunction->GetParentContext()->GetContext());
   76.47 +		handler->m_pPlugin = scripts->FindPluginByContext(pFunction->GetParentContext()->GetContext());
   76.48  		return handler;
   76.49  	}
   76.50  
   76.51 @@ -311,14 +311,14 @@
   76.52  		sec.pOwner = m_pBasic->GetParentContext()->GetIdentity();
   76.53  	
   76.54  		HandleAccess access;
   76.55 -		g_HandleSys.InitAccessDefaults(NULL, &access);
   76.56 +		handlesys->InitAccessDefaults(NULL, &access);
   76.57  		access.access[HandleAccess_Delete] = HANDLE_RESTRICT_IDENTITY|HANDLE_RESTRICT_OWNER;
   76.58  
   76.59 -		Handle_t hndl = g_HandleSys.CreateHandleEx(g_MenuHelpers.GetTempPanelType(), panel, &sec, &access, NULL);
   76.60 +		Handle_t hndl = handlesys->CreateHandleEx(g_MenuHelpers.GetTempPanelType(), panel, &sec, &access, NULL);
   76.61  
   76.62  		DoAction(menu, MenuAction_Display, client, hndl);
   76.63  
   76.64 -		g_HandleSys.FreeHandle(hndl, &sec);
   76.65 +		handlesys->FreeHandle(hndl, &sec);
   76.66  	}
   76.67  }
   76.68  
   76.69 @@ -570,7 +570,7 @@
   76.70  
   76.71  inline Handle_t MakePanelHandle(IMenuPanel *panel, IPluginContext *pContext)
   76.72  {
   76.73 -	return g_HandleSys.CreateHandle(g_MenuHelpers.GetPanelType(), panel, pContext->GetIdentity(), g_pCoreIdent, NULL);
   76.74 +	return handlesys->CreateHandle(g_MenuHelpers.GetPanelType(), panel, pContext->GetIdentity(), g_pCoreIdent, NULL);
   76.75  }
   76.76  
   76.77  inline HandleError ReadPanelHandle(Handle_t hndl, IMenuPanel **panel)
   76.78 @@ -578,7 +578,7 @@
   76.79  	HandleSecurity sec;
   76.80  	sec.pIdentity = g_pCoreIdent;
   76.81  	sec.pOwner = NULL;
   76.82 -	return g_HandleSys.ReadHandle(hndl, g_MenuHelpers.GetPanelType(), &sec, (void **)panel);
   76.83 +	return handlesys->ReadHandle(hndl, g_MenuHelpers.GetPanelType(), &sec, (void **)panel);
   76.84  }
   76.85  
   76.86  inline IMenuStyle *GetStyleFromCell(cell_t cell)
    77.1 --- a/core/smn_protobuf.cpp	Fri Mar 29 12:28:02 2013 -0400
    77.2 +++ b/core/smn_protobuf.cpp	Fri Mar 29 11:37:29 2013 -0700
    77.3 @@ -47,7 +47,7 @@
    77.4  	sec.pOwner = NULL;                                \
    77.5  	sec.pIdentity = g_pCoreIdent;                     \
    77.6  	                                                  \
    77.7 -	if ((herr=g_HandleSys.ReadHandle(hndl, g_ProtobufType, &sec, (void **)&msg)) \
    77.8 +	if ((herr=handlesys->ReadHandle(hndl, g_ProtobufType, &sec, (void **)&msg)) \
    77.9  		!= HandleError_None)                          \
   77.10  	{                                                 \
   77.11  		return pCtx->ThrowNativeError("Invalid protobuf message handle %x (error %d)", hndl, herr); \
   77.12 @@ -872,7 +872,7 @@
   77.13  		return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName().c_str());
   77.14  	}
   77.15  
   77.16 -	Handle_t outHndl = g_HandleSys.CreateHandle(g_ProtobufType, new SMProtobufMessage(innerMsg), NULL, g_pCoreIdent, NULL);
   77.17 +	Handle_t outHndl = handlesys->CreateHandle(g_ProtobufType, new SMProtobufMessage(innerMsg), NULL, g_pCoreIdent, NULL);
   77.18  	msg->AddChildHandle(outHndl);
   77.19  
   77.20  	return outHndl;
   77.21 @@ -889,7 +889,7 @@
   77.22  		return pCtx->ThrowNativeError("Invalid field \"%s\"[%d] for message \"%s\"", strField, params[3], msg->GetProtobufMessage()->GetTypeName().c_str());
   77.23  	}
   77.24  
   77.25 -	Handle_t outHndl = g_HandleSys.CreateHandle(g_ProtobufType, new SMProtobufMessage(const_cast<protobuf::Message *>(innerMsg)), NULL, g_pCoreIdent, NULL);
   77.26 +	Handle_t outHndl = handlesys->CreateHandle(g_ProtobufType, new SMProtobufMessage(const_cast<protobuf::Message *>(innerMsg)), NULL, g_pCoreIdent, NULL);
   77.27  	msg->AddChildHandle(outHndl);
   77.28  
   77.29  	return outHndl;
   77.30 @@ -906,7 +906,7 @@
   77.31  		return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName().c_str());
   77.32  	}
   77.33  
   77.34 -	Handle_t outHndl = g_HandleSys.CreateHandle(g_ProtobufType, new SMProtobufMessage(innerMsg), NULL, g_pCoreIdent, NULL);
   77.35 +	Handle_t outHndl = handlesys->CreateHandle(g_ProtobufType, new SMProtobufMessage(innerMsg), NULL, g_pCoreIdent, NULL);
   77.36  	msg->AddChildHandle(outHndl);
   77.37  
   77.38  	return outHndl;
    78.1 --- a/core/smn_usermsgs.cpp	Fri Mar 29 12:28:02 2013 -0400
    78.2 +++ b/core/smn_usermsgs.cpp	Fri Mar 29 11:37:29 2013 -0700
    78.3 @@ -29,10 +29,9 @@
    78.4   * Version: $Id$
    78.5   */
    78.6  
    78.7 -#include "HandleSys.h"
    78.8 -#include "PluginSys.h"
    78.9  #include "PlayerManager.h"
   78.10  #include "smn_usermsgs.h"
   78.11 +#include "logic_bridge.h"
   78.12  #ifdef USE_PROTOBUF_USERMESSAGES
   78.13  #include "UserMessagePBHelpers.h"
   78.14  #endif
   78.15 @@ -89,19 +88,19 @@
   78.16  {
   78.17  	HandleAccess sec;
   78.18  
   78.19 -	g_HandleSys.InitAccessDefaults(NULL, &sec);
   78.20 +	handlesys->InitAccessDefaults(NULL, &sec);
   78.21  	sec.access[HandleAccess_Delete] = HANDLE_RESTRICT_IDENTITY;
   78.22  
   78.23  #ifdef USE_PROTOBUF_USERMESSAGES
   78.24 -	g_ProtobufType = g_HandleSys.CreateType("ProtobufUM", this, 0, NULL, NULL, g_pCoreIdent, NULL);
   78.25 +	g_ProtobufType = handlesys->CreateType("ProtobufUM", this, 0, NULL, NULL, g_pCoreIdent, NULL);
   78.26  #else
   78.27 -	g_WrBitBufType = g_HandleSys.CreateType("BitBufWriter", this, 0, NULL, NULL, g_pCoreIdent, NULL);
   78.28 -	g_RdBitBufType = g_HandleSys.CreateType("BitBufReader", this, 0, NULL, &sec, g_pCoreIdent, NULL);
   78.29 +	g_WrBitBufType = handlesys->CreateType("BitBufWriter", this, 0, NULL, NULL, g_pCoreIdent, NULL);
   78.30 +	g_RdBitBufType = handlesys->CreateType("BitBufReader", this, 0, NULL, &sec, g_pCoreIdent, NULL);
   78.31  
   78.32 -	g_ReadBufHandle = g_HandleSys.CreateHandle(g_RdBitBufType, &g_ReadBitBuf, NULL, g_pCoreIdent, NULL);
   78.33 +	g_ReadBufHandle = handlesys->CreateHandle(g_RdBitBufType, &g_ReadBitBuf, NULL, g_pCoreIdent, NULL);
   78.34  #endif
   78.35  
   78.36 -	g_PluginSys.AddPluginsListener(this);
   78.37 +	scripts->AddPluginsListener(this);
   78.38  }
   78.39  
   78.40  void UsrMessageNatives::OnSourceModShutdown()
   78.41 @@ -110,14 +109,14 @@
   78.42  	sec.pIdentity = g_pCoreIdent;
   78.43  
   78.44  #ifdef USE_PROTOBUF_USERMESSAGES
   78.45 -	g_HandleSys.RemoveType(g_ProtobufType, g_pCoreIdent);
   78.46 +	handlesys->RemoveType(g_ProtobufType, g_pCoreIdent);
   78.47  
   78.48  	g_ProtobufType = 0;
   78.49  #else
   78.50 -	g_HandleSys.FreeHandle(g_ReadBufHandle, &sec);
   78.51 +	handlesys->FreeHandle(g_ReadBufHandle, &sec);
   78.52  
   78.53 -	g_HandleSys.RemoveType(g_WrBitBufType, g_pCoreIdent);
   78.54 -	g_HandleSys.RemoveType(g_RdBitBufType, g_pCoreIdent);
   78.55 +	handlesys->RemoveType(g_WrBitBufType, g_pCoreIdent);
   78.56 +	handlesys->RemoveType(g_RdBitBufType, g_pCoreIdent);
   78.57  
   78.58  	g_WrBitBufType = 0;
   78.59  	g_RdBitBufType = 0;
   78.60 @@ -169,7 +168,7 @@
   78.61  {
   78.62  	MsgWrapperList *pList;
   78.63  	MsgListenerWrapper *pListener;
   78.64 -	IPlugin *pl = g_PluginSys.FindPluginByContext(pCtx->GetContext());
   78.65 +	IPlugin *pl = scripts->FindPluginByContext(pCtx->GetContext());
   78.66  
   78.67  	if (m_FreeListeners.empty())
   78.68  	{
   78.69 @@ -195,7 +194,7 @@
   78.70  	MsgWrapperList *pList;
   78.71  	MsgWrapperIter _iter;
   78.72  	MsgListenerWrapper *pListener;
   78.73 -	IPlugin *pl = g_PluginSys.FindPluginByContext(pCtx->GetContext());
   78.74 +	IPlugin *pl = scripts->FindPluginByContext(pCtx->GetContext());
   78.75  
   78.76  	if (!pl->GetProperty("MsgListeners", reinterpret_cast<void **>(&pList)))
   78.77  	{
   78.78 @@ -221,7 +220,7 @@
   78.79  {
   78.80  	MsgWrapperList *pList;
   78.81  	MsgListenerWrapper *pListener;
   78.82 -	IPlugin *pl = g_PluginSys.FindPluginByContext(pCtx->GetContext());
   78.83 +	IPlugin *pl = scripts->FindPluginByContext(pCtx->GetContext());
   78.84  
   78.85  	if (!pl->GetProperty("MsgListeners", reinterpret_cast<void **>(&pList)))
   78.86  	{
   78.87 @@ -311,7 +310,7 @@
   78.88  	size_t size = _FillInPlayers(g_MsgPlayers, pFilter);
   78.89  
   78.90  #ifdef USE_PROTOBUF_USERMESSAGES
   78.91 -	hndl = g_HandleSys.CreateHandle(g_ProtobufType, new SMProtobufMessage(msg), NULL, g_pCoreIdent, NULL);
   78.92 +	hndl = handlesys->CreateHandle(g_ProtobufType, new SMProtobufMessage(msg), NULL, g_pCoreIdent, NULL);
   78.93  #else
   78.94  	g_ReadBitBuf.StartReading(bf->GetBasePointer(), bf->GetNumBytesWritten());
   78.95  	hndl = g_ReadBufHandle;
   78.96 @@ -328,7 +327,7 @@
   78.97  #ifdef USE_PROTOBUF_USERMESSAGES
   78.98  	HandleSecurity sec;
   78.99  	sec.pIdentity = g_pCoreIdent;
  78.100 -	g_HandleSys.FreeHandle(hndl, &sec);
  78.101 +	handlesys->FreeHandle(hndl, &sec);
  78.102  #endif
  78.103  }
  78.104  
  78.105 @@ -343,7 +342,7 @@
  78.106  	size_t size = _FillInPlayers(g_MsgPlayers, pFilter);
  78.107  
  78.108  #ifdef USE_PROTOBUF_USERMESSAGES
  78.109 -	hndl = g_HandleSys.CreateHandle(g_ProtobufType, new SMProtobufMessage(msg), NULL, g_pCoreIdent, NULL);
  78.110 +	hndl = handlesys->CreateHandle(g_ProtobufType, new SMProtobufMessage(msg), NULL, g_pCoreIdent, NULL);
  78.111  #else
  78.112  	g_ReadBitBuf.StartReading(bf->GetBasePointer(), bf->GetNumBytesWritten());
  78.113  	hndl = g_ReadBufHandle;
  78.114 @@ -360,7 +359,7 @@
  78.115  #ifdef USE_PROTOBUF_USERMESSAGES
  78.116  	HandleSecurity sec;
  78.117  	sec.pIdentity = g_pCoreIdent;
  78.118 -	g_HandleSys.FreeHandle(hndl, &sec);
  78.119 +	handlesys->FreeHandle(hndl, &sec);
  78.120  #endif
  78.121  
  78.122  	return static_cast<ResultType>(res);
  78.123 @@ -455,7 +454,7 @@
  78.124  		return pCtx->ThrowNativeError("Unable to execute a new message while in hook");
  78.125  	}
  78.126  
  78.127 -	g_CurMsgHandle = g_HandleSys.CreateHandle(g_ProtobufType, new SMProtobufMessage(msg), pCtx->GetIdentity(), g_pCoreIdent, NULL);
  78.128 +	g_CurMsgHandle = handlesys->CreateHandle(g_ProtobufType, new SMProtobufMessage(msg), pCtx->GetIdentity(), g_pCoreIdent, NULL);
  78.129  #else
  78.130  	bf_write *pBitBuf = g_UserMsgs.StartBitBufMessage(msgid, cl_array, numClients, params[4]);
  78.131  	if (!pBitBuf)
  78.132 @@ -463,7 +462,7 @@
  78.133  		return pCtx->ThrowNativeError("Unable to execute a new message while in hook");
  78.134  	}
  78.135  
  78.136 -	g_CurMsgHandle = g_HandleSys.CreateHandle(g_WrBitBufType, pBitBuf, pCtx->GetIdentity(), g_pCoreIdent, NULL);
  78.137 +	g_CurMsgHandle = handlesys->CreateHandle(g_WrBitBufType, pBitBuf, pCtx->GetIdentity(), g_pCoreIdent, NULL);
  78.138  #endif
  78.139  
  78.140  	g_IsMsgInExec = true;
  78.141 @@ -514,7 +513,7 @@
  78.142  		return pCtx->ThrowNativeError("Unable to execute a new message while in hook");
  78.143  	}
  78.144  
  78.145 -	g_CurMsgHandle = g_HandleSys.CreateHandle(g_ProtobufType, new SMProtobufMessage(msg), pCtx->GetIdentity(), g_pCoreIdent, NULL);
  78.146 +	g_CurMsgHandle = handlesys->CreateHandle(g_ProtobufType, new SMProtobufMessage(msg), pCtx->GetIdentity(), g_pCoreIdent, NULL);
  78.147  #else
  78.148  	bf_write *pBitBuf = g_UserMsgs.StartBitBufMessage(msgid, cl_array, numClients, params[4]);
  78.149  	if (!pBitBuf)
  78.150 @@ -522,7 +521,7 @@
  78.151  		return pCtx->ThrowNativeError("Unable to execute a new message while in hook");
  78.152  	}
  78.153  
  78.154 -	g_CurMsgHandle = g_HandleSys.CreateHandle(g_WrBitBufType, pBitBuf, pCtx->GetIdentity(), g_pCoreIdent, NULL);
  78.155 +	g_CurMsgHandle = handlesys->CreateHandle(g_WrBitBufType, pBitBuf, pCtx->GetIdentity(), g_pCoreIdent, NULL);
  78.156  #endif
  78.157  	g_IsMsgInExec = true;
  78.158  
  78.159 @@ -542,7 +541,7 @@
  78.160  
  78.161  	sec.pOwner = pCtx->GetIdentity();
  78.162  	sec.pIdentity = g_pCoreIdent;
  78.163 -	g_HandleSys.FreeHandle(g_CurMsgHandle, &sec);
  78.164 +	handlesys->FreeHandle(g_CurMsgHandle, &sec);
  78.165  
  78.166  	g_IsMsgInExec = false;
  78.167  
    79.1 --- a/core/sourcemm_api.cpp	Fri Mar 29 12:28:02 2013 -0400
    79.2 +++ b/core/sourcemm_api.cpp	Fri Mar 29 11:37:29 2013 -0700
    79.3 @@ -33,9 +33,9 @@
    79.4  #include "sourcemm_api.h"
    79.5  #include <sourcemod_version.h>
    79.6  #include "Logger.h"
    79.7 -#include "ExtensionSys.h"
    79.8  #include "concmd_cleaner.h"
    79.9  #include "compat_wrappers.h"
   79.10 +#include "logic_bridge.h"
   79.11  
   79.12  SourceMod_Core g_SourceMod_Core;
   79.13  IVEngineServer *engine = NULL;
   79.14 @@ -231,7 +231,7 @@
   79.15  
   79.16  	if (strcmp(iface, SOURCEMOD_INTERFACE_EXTENSIONS) == 0)
   79.17  	{
   79.18 -		ptr = (IExtensionManager *)&g_Extensions;
   79.19 +		ptr = extsys;
   79.20  	}
   79.21  
   79.22  	if (ret != NULL)
    80.1 --- a/core/sourcemod.cpp	Fri Mar 29 12:28:02 2013 -0400
    80.2 +++ b/core/sourcemod.cpp	Fri Mar 29 11:37:29 2013 -0700
    80.3 @@ -34,11 +34,8 @@
    80.4  #include "sourcemm_api.h"
    80.5  #include "LibrarySys.h"
    80.6  #include <sh_string.h>
    80.7 -#include "PluginSys.h"
    80.8 -#include "ShareSys.h"
    80.9  #include "CoreConfig.h"
   80.10  #include "Logger.h"
   80.11 -#include "ExtensionSys.h"
   80.12  #include "AdminCache.h"
   80.13  #include "sm_stringutil.h"
   80.14  #include "PlayerManager.h"
   80.15 @@ -263,11 +260,6 @@
   80.16  	enginePatch = SH_GET_CALLCLASS(engine);
   80.17  	gamedllPatch = SH_GET_CALLCLASS(gamedll);
   80.18  
   80.19 -	g_ShareSys.Initialize();
   80.20 -
   80.21 -	/* Make the global core identity */
   80.22 -	g_pCoreIdent = g_ShareSys.CreateCoreIdentity();
   80.23 -
   80.24  	InitLogicBridge();
   80.25  
   80.26  	/* Notify! */
   80.27 @@ -296,7 +288,7 @@
   80.28  	}
   80.29  
   80.30  	/* Add us now... */
   80.31 -	g_ShareSys.AddInterface(NULL, this);
   80.32 +	sharesys->AddInterface(NULL, this);
   80.33  
   80.34  	/* We're loaded! */
   80.35  	g_Loaded = true;
   80.36 @@ -311,7 +303,7 @@
   80.37  	const char *disabled = GetCoreConfigValue("DisableAutoUpdate");
   80.38  	if (disabled == NULL || strcasecmp(disabled, "yes") != 0)
   80.39  	{
   80.40 -		g_Extensions.LoadAutoExtension("updater.ext." PLATFORM_LIB_EXT);
   80.41 +		extsys->LoadAutoExtension("updater.ext." PLATFORM_LIB_EXT);
   80.42  	}
   80.43  }
   80.44  
   80.45 @@ -383,7 +375,7 @@
   80.46  
   80.47  	if (m_ExecPluginReload)
   80.48  	{
   80.49 -		g_PluginSys.ReloadOrUnloadPlugins();
   80.50 +		scripts->RefreshAll();
   80.51  		m_ExecPluginReload = false;
   80.52  	}
   80.53  }
   80.54 @@ -406,7 +398,7 @@
   80.55  		"plugins");
   80.56  
   80.57  	/* Load any auto extensions */
   80.58 -	g_Extensions.TryAutoload();
   80.59 +	extsys->TryAutoload();
   80.60  
   80.61  	/* Fire the extensions ready message */
   80.62  	g_SMAPI->MetaFactory(SOURCEMOD_NOTICE_EXTENSIONS, NULL, NULL);
   80.63 @@ -417,23 +409,10 @@
   80.64  	{
   80.65  		char path[PLATFORM_MAX_PATH];
   80.66  		UTIL_Format(path, sizeof(path), "%s.ext." PLATFORM_LIB_EXT, game_ext);
   80.67 -		g_Extensions.LoadAutoExtension(path);
   80.68 +		extsys->LoadAutoExtension(path);
   80.69  	}
   80.70  
   80.71 -	/* Run the first pass */
   80.72 -	g_PluginSys.LoadAll_FirstPass(config_path, plugins_path);
   80.73 -
   80.74 -	/* Mark any extensions as loaded */
   80.75 -	g_Extensions.MarkAllLoaded();
   80.76 -
   80.77 -	/* No modules yet, it's safe to call this from here */
   80.78 -	g_PluginSys.LoadAll_SecondPass();
   80.79 -
   80.80 -	/* Re-mark any extensions as loaded */
   80.81 -	g_Extensions.MarkAllLoaded();
   80.82 -
   80.83 -	/* Call OnAllPluginsLoaded */
   80.84 -	g_PluginSys.AllPluginsLoaded();
   80.85 +	scripts->LoadAll(config_path, plugins_path);
   80.86  }
   80.87  
   80.88  size_t SourceModBase::BuildPath(PathType type, char *buffer, size_t maxlength, const char *format, ...)
   80.89 @@ -484,10 +463,10 @@
   80.90  	LevelShutdown();
   80.91  
   80.92  	/* Unload plugins */
   80.93 -	g_PluginSys.Shutdown();
   80.94 +	scripts->Shutdown();
   80.95  
   80.96  	/* Unload extensions */
   80.97 -	g_Extensions.Shutdown();
   80.98 +	extsys->Shutdown();
   80.99  
  80.100  	SH_REMOVE_HOOK(IServerGameDLL, LevelInit, gamedll, SH_MEMBER(this, &SourceModBase::LevelInit), false);
  80.101  
    81.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    81.2 +++ b/public/AutoHandleRooter.h	Fri Mar 29 11:37:29 2013 -0700
    81.3 @@ -0,0 +1,91 @@
    81.4 +/**
    81.5 + * vim: set ts=4 sw=4 tw=99 noet :
    81.6 + * =============================================================================
    81.7 + * SourceMod
    81.8 + * Copyright (C) 2004-2009 AlliedModders LLC.  All rights reserved.
    81.9 + * =============================================================================
   81.10 + *
   81.11 + * This program is free software; you can redistribute it and/or modify it under
   81.12 + * the terms of the GNU General Public License, version 3.0, as published by the
   81.13 + * Free Software Foundation.
   81.14 + * 
   81.15 + * This program is distributed in the hope that it will be useful, but WITHOUT
   81.16 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   81.17 + * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
   81.18 + * details.
   81.19 + *
   81.20 + * You should have received a copy of the GNU General Public License along with
   81.21 + * this program.  If not, see <http://www.gnu.org/licenses/>.
   81.22 + *
   81.23 + * As a special exception, AlliedModders LLC gives you permission to link the
   81.24 + * code of this program (as well as its derivative works) to "Half-Life 2," the
   81.25 + * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
   81.26 + * by the Valve Corporation.  You must obey the GNU General Public License in
   81.27 + * all respects for all other code used.  Additionally, AlliedModders LLC grants
   81.28 + * this exception to all derivative works.  AlliedModders LLC defines further
   81.29 + * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
   81.30 + * or <http://www.sourcemod.net/license.php>.
   81.31 + *
   81.32 + * Version: $Id$
   81.33 + */
   81.34 +
   81.35 +#ifndef _INCLUDE_SOURCEMOD_AUTO_HANDLE_ROOTER_H_
   81.36 +#define _INCLUDE_SOURCEMOD_AUTO_HANDLE_ROOTER_H_
   81.37 +
   81.38 +#include <IHandleSys.h>
   81.39 +
   81.40 +class AutoHandleRooter
   81.41 +{
   81.42 +public:
   81.43 +	AutoHandleRooter(Handle_t hndl)
   81.44 +	{
   81.45 +		if (hndl != BAD_HANDLE)
   81.46 +			this->hndl = handlesys->FastCloneHandle(hndl);
   81.47 +		else
   81.48 +			this->hndl = BAD_HANDLE;
   81.49 +	}
   81.50 +
   81.51 +	~AutoHandleRooter()
   81.52 +	{
   81.53 +		if (hndl != BAD_HANDLE)
   81.54 +		{
   81.55 +			HandleSecurity sec(g_pCoreIdent, g_pCoreIdent);
   81.56 +			handlesys->FreeHandle(hndl, &sec);
   81.57 +		}
   81.58 +	}
   81.59 +
   81.60 +	Handle_t getHandle()
   81.61 +	{
   81.62 +		return hndl;
   81.63 +	}
   81.64 +private:
   81.65 +	Handle_t hndl;
   81.66 +};
   81.67 +
   81.68 +class AutoHandleCloner
   81.69 +{
   81.70 +	Handle_t original;
   81.71 +	HandleSecurity sec;
   81.72 +	AutoHandleRooter ahr;
   81.73 +public:
   81.74 +	AutoHandleCloner(Handle_t original, HandleSecurity sec)
   81.75 +	  : original(original), sec(sec), ahr(original)
   81.76 +	{
   81.77 +	}
   81.78 +
   81.79 +	~AutoHandleCloner()
   81.80 +	{
   81.81 +		if (original != BAD_HANDLE)
   81.82 +		{
   81.83 +			handlesys->FreeHandle(original, &sec);
   81.84 +		}
   81.85 +	}
   81.86 +
   81.87 +	Handle_t getClone()
   81.88 +	{
   81.89 +		return ahr.getHandle();
   81.90 +	}
   81.91 +};
   81.92 +
   81.93 +#endif /* _INCLUDE_SOURCEMOD_AUTO_HANDLE_ROOTER_H_ */
   81.94 +
    82.1 --- a/public/IExtensionSys.h	Fri Mar 29 12:28:02 2013 -0400
    82.2 +++ b/public/IExtensionSys.h	Fri Mar 29 11:37:29 2013 -0700
    82.3 @@ -132,8 +132,10 @@
    82.4  	 *
    82.5  	 * Note: This is bumped when IShareSys is changed, because IShareSys 
    82.6  	 * itself is not versioned.
    82.7 +	 *
    82.8 +	 * V6 - added TestFeature() to IShareSys.
    82.9  	 */
   82.10 -	#define SMINTERFACE_EXTENSIONAPI_VERSION	5
   82.11 +	#define SMINTERFACE_EXTENSIONAPI_VERSION	6
   82.12  
   82.13  	/**
   82.14  	 * @brief The interface an extension must expose.
    83.1 --- a/public/IHandleSys.h	Fri Mar 29 12:28:02 2013 -0400
    83.2 +++ b/public/IHandleSys.h	Fri Mar 29 11:37:29 2013 -0700
    83.3 @@ -52,7 +52,7 @@
    83.4  #include <sp_vm_types.h>
    83.5  
    83.6  #define SMINTERFACE_HANDLESYSTEM_NAME			"IHandleSys"
    83.7 -#define SMINTERFACE_HANDLESYSTEM_VERSION		4
    83.8 +#define SMINTERFACE_HANDLESYSTEM_VERSION		5
    83.9  
   83.10  /** Specifies no Identity */
   83.11  #define DEFAULT_IDENTITY			NULL
   83.12 @@ -364,6 +364,15 @@
   83.13  		 * @return          A new Handle_t, or 0 on failure.
   83.14  		 */
   83.15  		virtual Handle_t FastCloneHandle(Handle_t hndl) =0;
   83.16 +
   83.17 +		/**
   83.18 +		 * @brief Type checks two handles.
   83.19 +		 *
   83.20 +		 * @param given		Type to test.
   83.21 +		 * @param actual	Type to check for.
   83.22 +		 * @return			True if "given" is a subtype of "actual", false otherwise.
   83.23 +		 */
   83.24 +		virtual bool TypeCheck(HandleType_t given, HandleType_t actual) = 0;
   83.25  	};
   83.26  }
   83.27  
    84.1 --- a/public/ILibrarySys.h	Fri Mar 29 12:28:02 2013 -0400
    84.2 +++ b/public/ILibrarySys.h	Fri Mar 29 11:37:29 2013 -0700
    84.3 @@ -43,7 +43,7 @@
    84.4  namespace SourceMod
    84.5  {
    84.6  	#define SMINTERFACE_LIBRARYSYS_NAME		"ILibrarySys"
    84.7 -	#define SMINTERFACE_LIBRARYSYS_VERSION	4
    84.8 +	#define SMINTERFACE_LIBRARYSYS_VERSION	5
    84.9  
   84.10  	enum FileTimeType
   84.11  	{
   84.12 @@ -223,6 +223,16 @@
   84.13  		 * @return			True on success, false on failure.
   84.14  		 */
   84.15  		virtual bool FileTime(const char *path, FileTimeType type, time_t *pTime) =0;
   84.16 +
   84.17 +		/**
   84.18 +		 * @brief Retrieve the file component of the given path.
   84.19 +		 *
   84.20 +		 * @param buffer	Output buffer.
   84.21 +		 * @param maxlength	Length of the output buffer.
   84.22 +		 * @param path		Path to search for a filename.
   84.23 +		 * @return			Number of bytes written to buffer, not including the null terminator.
   84.24 +		 */
   84.25 +		virtual size_t GetFileFromPath(char *buffer, size_t maxlength, const char *path) =0;
   84.26  	};
   84.27  }
   84.28  
    85.1 --- a/public/IShareSys.h	Fri Mar 29 12:28:02 2013 -0400
    85.2 +++ b/public/IShareSys.h	Fri Mar 29 11:37:29 2013 -0700
    85.3 @@ -38,7 +38,7 @@
    85.4   */
    85.5  
    85.6  #include <sp_vm_types.h>
    85.7 -
    85.8 +#include <sp_vm_api.h>
    85.9  
   85.10  namespace SourceMod
   85.11  {
   85.12 @@ -278,6 +278,19 @@
   85.13  		virtual void DropCapabilityProvider(IExtension *myself,
   85.14  		                                    IFeatureProvider *provider,
   85.15  		                                    const char *name) =0;
   85.16 +
   85.17 +		/**
   85.18 +		 * Tests for a feature.
   85.19 +		 *
   85.20 +		 * @param rt			Plugin to test.
   85.21 +		 * @param type			Feature type.
   85.22 +		 * @param name			Feature name.
   85.23 +		 * @return				Feature status.
   85.24 +		 */
   85.25 +		virtual FeatureStatus TestFeature(SourcePawn::IPluginRuntime *rt,
   85.26 +										  FeatureType type,
   85.27 +										  const char *name) =0;
   85.28 +
   85.29  	};
   85.30  }
   85.31