plugins get updated on map change
maponly plugins get unloaded on map change --HG-- extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%40338
This commit is contained in:
		
							parent
							
								
									d351566b25
								
							
						
					
					
						commit
						ba1daf3142
					
				@ -10,6 +10,7 @@
 | 
			
		||||
#include "ExtensionSys.h"
 | 
			
		||||
 | 
			
		||||
SH_DECL_HOOK6(IServerGameDLL, LevelInit, SH_NOATTRIB, false, bool, const char *, const char *, const char *, const char *, bool, bool);
 | 
			
		||||
SH_DECL_HOOK0_void(IServerGameDLL, LevelShutdown, SH_NOATTRIB, false);
 | 
			
		||||
 | 
			
		||||
SourcePawnEngine g_SourcePawn;
 | 
			
		||||
SourceModBase g_SourceMod;
 | 
			
		||||
@ -39,6 +40,7 @@ void ShutdownJIT()
 | 
			
		||||
SourceModBase::SourceModBase()
 | 
			
		||||
{
 | 
			
		||||
	m_IsMapLoading = false;
 | 
			
		||||
	m_ExecPluginReload = false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool SourceModBase::InitializeSourceMod(char *error, size_t err_max, bool late)
 | 
			
		||||
@ -131,6 +133,7 @@ void SourceModBase::StartSourceMod(bool late)
 | 
			
		||||
{
 | 
			
		||||
	/* First initialize the global hooks we need */
 | 
			
		||||
	SH_ADD_HOOK_MEMFUNC(IServerGameDLL, LevelInit, gamedll, this, &SourceModBase::LevelInit, false);
 | 
			
		||||
	SH_ADD_HOOK_MEMFUNC(IServerGameDLL, LevelShutdown, gamedll, this, &SourceModBase::LevelShutdown, false);
 | 
			
		||||
 | 
			
		||||
	/* Notify! */
 | 
			
		||||
	SMGlobalClass *pBase = SMGlobalClass::head;
 | 
			
		||||
@ -158,6 +161,7 @@ void SourceModBase::StartSourceMod(bool late)
 | 
			
		||||
bool SourceModBase::LevelInit(char const *pMapName, char const *pMapEntities, char const *pOldLevel, char const *pLandmarkName, bool loadGame, bool background)
 | 
			
		||||
{
 | 
			
		||||
	m_IsMapLoading = true;
 | 
			
		||||
	m_ExecPluginReload = true;
 | 
			
		||||
 | 
			
		||||
	g_Logger.MapChange(pMapName);
 | 
			
		||||
 | 
			
		||||
@ -168,6 +172,15 @@ bool SourceModBase::LevelInit(char const *pMapName, char const *pMapEntities, ch
 | 
			
		||||
	RETURN_META_VALUE(MRES_IGNORED, true);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void SourceModBase::LevelShutdown()
 | 
			
		||||
{
 | 
			
		||||
	if (m_ExecPluginReload)
 | 
			
		||||
	{
 | 
			
		||||
		g_PluginSys.ReloadOrUnloadPlugins();
 | 
			
		||||
		m_ExecPluginReload = false;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool SourceModBase::IsMapLoading()
 | 
			
		||||
{
 | 
			
		||||
	return m_IsMapLoading;
 | 
			
		||||
@ -241,6 +254,9 @@ void SourceModBase::CloseSourceMod()
 | 
			
		||||
		pBase = pBase->m_pGlobalClassNext;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	SH_REMOVE_HOOK_MEMFUNC(IServerGameDLL, LevelInit, gamedll, this, &SourceModBase::LevelInit, false);
 | 
			
		||||
	SH_REMOVE_HOOK_MEMFUNC(IServerGameDLL, LevelShutdown, gamedll, this, &SourceModBase::LevelShutdown, false);
 | 
			
		||||
 | 
			
		||||
	/* Rest In Peace */
 | 
			
		||||
	ShutdownJIT();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -33,6 +33,11 @@ public:
 | 
			
		||||
	 */
 | 
			
		||||
	bool LevelInit(char const *pMapName, char const *pMapEntities, char const *pOldLevel, char const *pLandmarkName, bool loadGame, bool background);
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	* @brief Level shutdown hook
 | 
			
		||||
	*/
 | 
			
		||||
	void LevelShutdown();
 | 
			
		||||
 | 
			
		||||
	/** 
 | 
			
		||||
	 * @brief Returns whether or not a mapload is in progress
 | 
			
		||||
	 */
 | 
			
		||||
@ -52,6 +57,7 @@ private:
 | 
			
		||||
private:
 | 
			
		||||
	char m_SMBaseDir[PLATFORM_MAX_PATH+1];
 | 
			
		||||
	bool m_IsMapLoading;
 | 
			
		||||
	bool m_ExecPluginReload;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
extern SourceModBase g_SourceMod;
 | 
			
		||||
 | 
			
		||||
@ -449,6 +449,35 @@ bool CPlugin::IsRunnable() const
 | 
			
		||||
	return (m_status <= Plugin_Paused) ? true : false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
time_t CPlugin::GetFileTimeStamp()
 | 
			
		||||
{
 | 
			
		||||
	char path[PLATFORM_MAX_PATH+1];
 | 
			
		||||
	g_SourceMod.BuildPath(Path_SM, path, sizeof(path), "plugins/%s", m_filename);
 | 
			
		||||
#ifdef PLATFORM_WINDOWS
 | 
			
		||||
	struct _stat s;
 | 
			
		||||
	if (_stat(path, &s) != 0)
 | 
			
		||||
#else if defined PLATFORM_POSIX
 | 
			
		||||
	struct stat s;
 | 
			
		||||
	if (stat(path, &s) != 0)
 | 
			
		||||
#endif
 | 
			
		||||
	{
 | 
			
		||||
		g_Logger.LogError("Could not obtain plugin time stamp, error: %d", errno);
 | 
			
		||||
		return 0;
 | 
			
		||||
	} else {
 | 
			
		||||
		return s.st_mtime;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
time_t CPlugin::GetTimeStamp() const
 | 
			
		||||
{
 | 
			
		||||
	return m_LastAccess;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void CPlugin::SetTimeStamp(time_t t)
 | 
			
		||||
{
 | 
			
		||||
	m_LastAccess = t;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*******************
 | 
			
		||||
 * PLUGIN ITERATOR *
 | 
			
		||||
 *******************/
 | 
			
		||||
@ -681,6 +710,10 @@ bool CPluginManager::_LoadPlugin(CPlugin **_plugin, const char *path, bool debug
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Save the time stamp */
 | 
			
		||||
	time_t t = pPlugin->GetFileTimeStamp();
 | 
			
		||||
	pPlugin->SetTimeStamp(t);
 | 
			
		||||
 | 
			
		||||
	if (_plugin)
 | 
			
		||||
	{
 | 
			
		||||
		*_plugin = pPlugin;
 | 
			
		||||
@ -1522,3 +1555,31 @@ void CPluginManager::OnRootConsoleCommand(const char *command, unsigned int argc
 | 
			
		||||
	g_RootMenu.DrawGenericOption("info", "Information about a plugin");
 | 
			
		||||
	g_RootMenu.DrawGenericOption("debug", "Toggle debug mode on a plugin");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void CPluginManager::ReloadOrUnloadPlugins()
 | 
			
		||||
{
 | 
			
		||||
	List<CPlugin *>::iterator iter;
 | 
			
		||||
	List<CPlugin *> tmp_list = m_plugins;
 | 
			
		||||
	CPlugin *pl;
 | 
			
		||||
	time_t t;
 | 
			
		||||
 | 
			
		||||
	for (iter=tmp_list.begin(); iter!=tmp_list.end(); iter++)
 | 
			
		||||
	{
 | 
			
		||||
		pl = (*iter);
 | 
			
		||||
		if (pl->GetType() ==  PluginType_MapOnly)
 | 
			
		||||
		{
 | 
			
		||||
			UnloadPlugin((IPlugin *)pl);
 | 
			
		||||
		} else if (pl->GetType() == PluginType_MapUpdated) {
 | 
			
		||||
			t=pl->GetFileTimeStamp();
 | 
			
		||||
			if (!t)
 | 
			
		||||
			{
 | 
			
		||||
				continue;
 | 
			
		||||
			}
 | 
			
		||||
			if (t > pl->GetTimeStamp())
 | 
			
		||||
			{
 | 
			
		||||
				pl->SetTimeStamp(t);
 | 
			
		||||
				UnloadPlugin((IPlugin *)pl);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -2,6 +2,8 @@
 | 
			
		||||
#define _INCLUDE_SOURCEMOD_PLUGINSYSTEM_H_
 | 
			
		||||
 | 
			
		||||
#include <time.h>
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <sys/stat.h>
 | 
			
		||||
#include <IPluginSys.h>
 | 
			
		||||
#include <IHandleSys.h>
 | 
			
		||||
#include <sh_list.h>
 | 
			
		||||
@ -155,7 +157,15 @@ public:
 | 
			
		||||
	 */
 | 
			
		||||
	bool IsRunnable() const;
 | 
			
		||||
public:
 | 
			
		||||
	time_t HasUpdatedFile();
 | 
			
		||||
	/**
 | 
			
		||||
	* Returns the modification time during last plugin load.
 | 
			
		||||
	*/
 | 
			
		||||
	time_t GetTimeStamp() const;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	* Returns the current modification time of the plugin file.
 | 
			
		||||
	*/
 | 
			
		||||
	time_t GetFileTimeStamp();
 | 
			
		||||
 | 
			
		||||
	/** 
 | 
			
		||||
	 * Returns true if the plugin was running, but is now invalid.
 | 
			
		||||
@ -163,6 +173,7 @@ public:
 | 
			
		||||
	bool WasRunning();
 | 
			
		||||
protected:
 | 
			
		||||
	void UpdateInfo();
 | 
			
		||||
	void SetTimeStamp(time_t t);
 | 
			
		||||
private:
 | 
			
		||||
	ContextPair m_ctx;
 | 
			
		||||
	PluginType m_type;
 | 
			
		||||
@ -272,6 +283,11 @@ public:
 | 
			
		||||
	 */
 | 
			
		||||
	const char *GetStatusText(PluginStatus status);
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	* Reload or update plugins on level shutdown.
 | 
			
		||||
	*/
 | 
			
		||||
	void ReloadOrUnloadPlugins();
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
	bool _LoadPlugin(CPlugin **pPlugin, const char *path, bool debug, PluginType type, char error[], size_t err_max);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -17,7 +17,6 @@ namespace SourceMod
 | 
			
		||||
	typedef unsigned int HandleType_t;
 | 
			
		||||
	typedef unsigned int Handle_t;
 | 
			
		||||
 | 
			
		||||
	class SourcePawn::IPluginContext;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * About type checking:
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user