- Added ForceChangeLevel and Map History to nextmap api
- Changed base plugins to use new api - Added sm_maphistory command to nextmap.sp --HG-- extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%402413
This commit is contained in:
		
							parent
							
								
									8126aa6bb8
								
							
						
					
					
						commit
						c75d607a00
					
				
							
								
								
									
										135
									
								
								core/NextMap.cpp
									
									
									
									
									
								
							
							
						
						
									
										135
									
								
								core/NextMap.cpp
									
									
									
									
									
								
							@ -33,13 +33,26 @@
 | 
				
			|||||||
#include "Logger.h"
 | 
					#include "Logger.h"
 | 
				
			||||||
#include "sourcemm_api.h"
 | 
					#include "sourcemm_api.h"
 | 
				
			||||||
#include "sm_stringutil.h"
 | 
					#include "sm_stringutil.h"
 | 
				
			||||||
 | 
					#include "sourcehook.h"
 | 
				
			||||||
 | 
					#include "sm_srvcmds.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
NextMapManager g_NextMap;
 | 
					NextMapManager g_NextMap;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
SH_DECL_HOOK2_void(IVEngineServer, ChangeLevel, SH_NOATTRIB, 0, const char *, const char *);
 | 
					SH_DECL_HOOK2_void(IVEngineServer, ChangeLevel, SH_NOATTRIB, 0, const char *, const char *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if defined ORANGEBOX_BUILD
 | 
				
			||||||
 | 
					SH_DECL_EXTERN1_void(ConCommand, Dispatch, SH_NOATTRIB, false, const CCommand &);
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					extern bool __SourceHook_FHAddConCommandDispatch(void *,bool,class fastdelegate::FastDelegate0<void>);
 | 
				
			||||||
 | 
					extern bool __SourceHook_FHRemoveConCommandDispatch(void *,bool,class fastdelegate::FastDelegate0<void>);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ConCommand *changeLevelCmd = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ConVar sm_nextmap("sm_nextmap", "", FCVAR_NOTIFY);
 | 
					ConVar sm_nextmap("sm_nextmap", "", FCVAR_NOTIFY);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool g_forcedChange = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void NextMapManager::OnSourceModAllInitialized_Post()
 | 
					void NextMapManager::OnSourceModAllInitialized_Post()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
#if defined ORANGEBOX_BUILD
 | 
					#if defined ORANGEBOX_BUILD
 | 
				
			||||||
@ -47,6 +60,30 @@ void NextMapManager::OnSourceModAllInitialized_Post()
 | 
				
			|||||||
#else
 | 
					#else
 | 
				
			||||||
	SH_ADD_HOOK_MEMFUNC(IVEngineServer, ChangeLevel, engine, this, &NextMapManager::HookChangeLevel, false);
 | 
						SH_ADD_HOOK_MEMFUNC(IVEngineServer, ChangeLevel, engine, this, &NextMapManager::HookChangeLevel, false);
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ConCommandBase *pBase = icvar->GetCommands();
 | 
				
			||||||
 | 
						ConCommand *pCmd = NULL;
 | 
				
			||||||
 | 
						while (pBase)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							if (strcmp(pBase->GetName(), "changelevel") == 0)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								/* Don't want to return convar with same name */
 | 
				
			||||||
 | 
								if (!pBase->IsCommand())
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								pCmd = (ConCommand *)pBase;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							pBase = const_cast<ConCommandBase *>(pBase->GetNext());
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (pCmd != NULL)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							SH_ADD_HOOK_STATICFUNC(ConCommand, Dispatch, pCmd, CmdChangeLevelCallback, false);
 | 
				
			||||||
 | 
							changeLevelCmd = pCmd;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void NextMapManager::OnSourceModShutdown()
 | 
					void NextMapManager::OnSourceModShutdown()
 | 
				
			||||||
@ -56,6 +93,20 @@ void NextMapManager::OnSourceModShutdown()
 | 
				
			|||||||
#else
 | 
					#else
 | 
				
			||||||
	SH_REMOVE_HOOK_MEMFUNC(IVEngineServer, ChangeLevel, engine, this, &NextMapManager::HookChangeLevel, false);
 | 
						SH_REMOVE_HOOK_MEMFUNC(IVEngineServer, ChangeLevel, engine, this, &NextMapManager::HookChangeLevel, false);
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (changeLevelCmd != NULL)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							SH_REMOVE_HOOK_STATICFUNC(ConCommand, Dispatch, changeLevelCmd, CmdChangeLevelCallback, false);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						SourceHook::List<MapChangeData *>::iterator iter;
 | 
				
			||||||
 | 
						iter = m_mapHistory.begin();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						while (iter != m_mapHistory.end())
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							delete (MapChangeData *)*iter;
 | 
				
			||||||
 | 
							iter = m_mapHistory.erase(iter);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const char *NextMapManager::GetNextMap()
 | 
					const char *NextMapManager::GetNextMap()
 | 
				
			||||||
@ -77,6 +128,12 @@ bool NextMapManager::SetNextMap(const char *map)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
void NextMapManager::HookChangeLevel(const char *map, const char *unknown)
 | 
					void NextMapManager::HookChangeLevel(const char *map, const char *unknown)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						if (g_forcedChange)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							g_Logger.LogMessage("[SM] Changed map to \"%s\"", map);
 | 
				
			||||||
 | 
							RETURN_META(MRES_IGNORED);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	const char *newmap = sm_nextmap.GetString();
 | 
						const char *newmap = sm_nextmap.GetString();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (newmap[0] == 0 || !engine->IsMapValid(newmap))
 | 
						if (newmap[0] == 0 || !engine->IsMapValid(newmap))
 | 
				
			||||||
@ -86,5 +143,83 @@ void NextMapManager::HookChangeLevel(const char *map, const char *unknown)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	g_Logger.LogMessage("[SM] Changed map to \"%s\"", newmap);
 | 
						g_Logger.LogMessage("[SM] Changed map to \"%s\"", newmap);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						UTIL_Format(m_tempChangeInfo.m_mapName, sizeof(m_tempChangeInfo.m_mapName), newmap);
 | 
				
			||||||
 | 
						UTIL_Format(m_tempChangeInfo.m_changeReason, sizeof(m_tempChangeInfo.m_changeReason), "Normal level change");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	RETURN_META_NEWPARAMS(MRES_IGNORED, &IVEngineServer::ChangeLevel, (newmap, unknown));
 | 
						RETURN_META_NEWPARAMS(MRES_IGNORED, &IVEngineServer::ChangeLevel, (newmap, unknown));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void NextMapManager::OnSourceModLevelChange( const char *mapName )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						/* Skip the first 'mapchange' when the server starts up */
 | 
				
			||||||
 | 
						if (m_tempChangeInfo.startTime != 0)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							if (strcmp(mapName, m_tempChangeInfo.m_mapName) == 0)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								/* The map change was as we expected */
 | 
				
			||||||
 | 
								m_mapHistory.push_back(new MapChangeData(lastMap, m_tempChangeInfo.m_changeReason, m_tempChangeInfo.startTime));
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								/* Something intercepted the mapchange */
 | 
				
			||||||
 | 
								char newReason[255];
 | 
				
			||||||
 | 
								UTIL_Format(newReason, sizeof(newReason), "%s (Map overridden)", m_tempChangeInfo.m_changeReason);
 | 
				
			||||||
 | 
								m_mapHistory.push_back(new MapChangeData(lastMap, newReason, m_tempChangeInfo.startTime));
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/* TODO: Should this be customizable? */
 | 
				
			||||||
 | 
							if (m_mapHistory.size() > 20)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								SourceHook::List<MapChangeData *>::iterator iter;
 | 
				
			||||||
 | 
								iter = m_mapHistory.begin();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								delete (MapChangeData *)*iter;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								m_mapHistory.erase(iter);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						m_tempChangeInfo.m_mapName[0] ='\0';
 | 
				
			||||||
 | 
						m_tempChangeInfo.m_changeReason[0] = '\0';
 | 
				
			||||||
 | 
						m_tempChangeInfo.startTime = time(NULL);
 | 
				
			||||||
 | 
						UTIL_Format(lastMap, sizeof(lastMap), mapName);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void NextMapManager::ForceChangeLevel( const char *mapName, const char* changeReason )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						/* Store the mapname and reason */
 | 
				
			||||||
 | 
						UTIL_Format(m_tempChangeInfo.m_mapName, sizeof(m_tempChangeInfo.m_mapName), mapName);
 | 
				
			||||||
 | 
						UTIL_Format(m_tempChangeInfo.m_changeReason, sizeof(m_tempChangeInfo.m_changeReason), changeReason);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Change level and skip our hook */
 | 
				
			||||||
 | 
						g_forcedChange = true;
 | 
				
			||||||
 | 
						engine->ChangeLevel(mapName, NULL);
 | 
				
			||||||
 | 
						g_forcedChange = false;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					NextMapManager::NextMapManager()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						m_tempChangeInfo = MapChangeData();
 | 
				
			||||||
 | 
						m_mapHistory = SourceHook::List<MapChangeData *>();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if defined ORANGEBOX_BUILD
 | 
				
			||||||
 | 
					void CmdChangeLevelCallback(const CCommand &command)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					void CmdChangeLevelCallback()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						CCommand command;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (command.ArgC() < 2)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (g_NextMap.m_tempChangeInfo.m_mapName[0] == '\0')
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							UTIL_Format(g_NextMap.m_tempChangeInfo.m_mapName, sizeof(g_NextMap.m_tempChangeInfo.m_mapName), command.Arg(1));
 | 
				
			||||||
 | 
							UTIL_Format(g_NextMap.m_tempChangeInfo.m_changeReason, sizeof(g_NextMap.m_tempChangeInfo.m_changeReason), "changelevel Command");
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -34,17 +34,58 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include "sm_globals.h"
 | 
					#include "sm_globals.h"
 | 
				
			||||||
#include "eiface.h"
 | 
					#include "eiface.h"
 | 
				
			||||||
 | 
					#include "sh_list.h"
 | 
				
			||||||
 | 
					#include "sm_stringutil.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct MapChangeData
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						MapChangeData(const char *mapName, const char *changeReason, time_t time)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							UTIL_Format(m_mapName, sizeof(m_mapName), mapName);
 | 
				
			||||||
 | 
							UTIL_Format(m_changeReason, sizeof(m_changeReason), changeReason);
 | 
				
			||||||
 | 
							startTime = time;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						MapChangeData()
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							m_mapName[0] = '\0';
 | 
				
			||||||
 | 
							m_changeReason[0] = '\0';
 | 
				
			||||||
 | 
							startTime = 0;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						char m_mapName[32];
 | 
				
			||||||
 | 
						char m_changeReason[100];
 | 
				
			||||||
 | 
						time_t startTime;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class NextMapManager : public SMGlobalClass
 | 
					class NextMapManager : public SMGlobalClass
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
 | 
						NextMapManager();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if defined ORANGEBOX_BUILD
 | 
				
			||||||
 | 
						friend void CmdChangeLevelCallback(const CCommand &command);
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
						friend void CmdChangeLevelCallback();
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void OnSourceModAllInitialized_Post();
 | 
						void OnSourceModAllInitialized_Post();
 | 
				
			||||||
	void OnSourceModShutdown();
 | 
						void OnSourceModShutdown();
 | 
				
			||||||
 | 
						void OnSourceModLevelChange(const char *mapName);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	const char *GetNextMap();
 | 
						const char *GetNextMap();
 | 
				
			||||||
	bool SetNextMap(const char *map);
 | 
						bool SetNextMap(const char *map);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						void ForceChangeLevel(const char *mapName, const char* changeReason);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void HookChangeLevel(const char *map, const char *unknown);
 | 
						void HookChangeLevel(const char *map, const char *unknown);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
						SourceHook::List<MapChangeData *> m_mapHistory;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
						MapChangeData m_tempChangeInfo;
 | 
				
			||||||
 | 
						char lastMap[32];
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
extern NextMapManager g_NextMap;
 | 
					extern NextMapManager g_NextMap;
 | 
				
			||||||
 | 
				
			|||||||
@ -54,10 +54,58 @@ static cell_t sm_SetNextMap(IPluginContext *pCtx, const cell_t *params)
 | 
				
			|||||||
	return g_NextMap.SetNextMap(map);
 | 
						return g_NextMap.SetNextMap(map);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static cell_t sm_ForceChangeLevel(IPluginContext *pCtx, const cell_t *params)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						char *map;
 | 
				
			||||||
 | 
						char *changeReason;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						pCtx->LocalToString(params[1], &map);
 | 
				
			||||||
 | 
						pCtx->LocalToString(params[2], &changeReason);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						g_NextMap.ForceChangeLevel(map, changeReason);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static cell_t sm_GetMapHistorySize(IPluginContext *pCtx, const cell_t *params)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return g_NextMap.m_mapHistory.size();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static cell_t sm_GetMapHistory(IPluginContext *pCtx, const cell_t *params)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (params[1] < 0 || params[1] >= (int)g_NextMap.m_mapHistory.size())
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							return pCtx->ThrowNativeError("Invalid Map History Index");
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						SourceHook::List<MapChangeData *>::iterator iter;
 | 
				
			||||||
 | 
						iter = g_NextMap.m_mapHistory.end();
 | 
				
			||||||
 | 
						iter--;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (int i=0; i<params[1]; i++)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							iter--;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						MapChangeData *data = (MapChangeData *)*iter;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						pCtx->StringToLocal(params[2], params[3], data->m_mapName);
 | 
				
			||||||
 | 
						pCtx->StringToLocal(params[4], params[5], data->m_changeReason);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						cell_t *startTime;
 | 
				
			||||||
 | 
						pCtx->LocalToPhysAddr(params[6], &startTime);
 | 
				
			||||||
 | 
						*startTime = data->startTime;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
REGISTER_NATIVES(nextmapnatives)
 | 
					REGISTER_NATIVES(nextmapnatives)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	{"GetNextMap",		sm_GetNextMap},
 | 
						{"GetNextMap",			sm_GetNextMap},
 | 
				
			||||||
	{"SetNextMap",		sm_SetNextMap},
 | 
						{"SetNextMap",			sm_SetNextMap},
 | 
				
			||||||
	{NULL,						NULL},
 | 
						{"ForceChangeLevel",	sm_ForceChangeLevel},
 | 
				
			||||||
 | 
						{"GetMapHistorySize",	sm_GetMapHistorySize},
 | 
				
			||||||
 | 
						{"GetMapHistory",		sm_GetMapHistory},
 | 
				
			||||||
 | 
						{NULL,					NULL},
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
				
			|||||||
@ -109,7 +109,7 @@ public Action:Timer_ChangeMap(Handle:timer, Handle:dp)
 | 
				
			|||||||
	ResetPack(dp);
 | 
						ResetPack(dp);
 | 
				
			||||||
	ReadPackString(dp, map, sizeof(map));
 | 
						ReadPackString(dp, map, sizeof(map));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ServerCommand("changelevel \"%s\"", map);
 | 
						ForceChangeLevel(map, "sm_map Command");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return Plugin_Stop;
 | 
						return Plugin_Stop;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -54,9 +54,9 @@ new Handle:g_Cvar_WinLimit = INVALID_HANDLE;
 | 
				
			|||||||
new Handle:g_Cvar_FragLimit = INVALID_HANDLE;
 | 
					new Handle:g_Cvar_FragLimit = INVALID_HANDLE;
 | 
				
			||||||
new Handle:g_Cvar_MaxRounds = INVALID_HANDLE;
 | 
					new Handle:g_Cvar_MaxRounds = INVALID_HANDLE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define TIMELEFT_ALL_ALWAYS		0
 | 
					#define TIMELEFT_ALL_ALWAYS		0		/* Print to all players */
 | 
				
			||||||
#define TIMELEFT_ALL_MAYBE		1
 | 
					#define TIMELEFT_ALL_MAYBE		1		/* Print to all players if sm_trigger_show allows */
 | 
				
			||||||
#define TIMELEFT_ONE			2
 | 
					#define TIMELEFT_ONE			2		/* Print to a single player */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public OnPluginStart()
 | 
					public OnPluginStart()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
				
			|||||||
@ -424,7 +424,7 @@ public Action:Timer_ChangeMap(Handle:timer, Handle:dp)
 | 
				
			|||||||
	ResetPack(dp);
 | 
						ResetPack(dp);
 | 
				
			||||||
	ReadPackString(dp, mapname, sizeof(mapname));
 | 
						ReadPackString(dp, mapname, sizeof(mapname));
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	ServerCommand("changelevel \"%s\"", mapname);
 | 
						ForceChangeLevel(mapname, "sm_votemap Result");
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	return Plugin_Stop;
 | 
						return Plugin_Stop;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -52,3 +52,33 @@ native bool:SetNextMap(const String:map[]);
 | 
				
			|||||||
 * @return			True if a Map was found and copied, false if no nextmap is set (map will be unchanged).
 | 
					 * @return			True if a Map was found and copied, false if no nextmap is set (map will be unchanged).
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
native bool:GetNextMap(String:map[], maxlen);
 | 
					native bool:GetNextMap(String:map[], maxlen);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Changes the current map and records the reason for the change with maphistory
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @param map		Map to change to.
 | 
				
			||||||
 | 
					 * @param reason	Reason for change.
 | 
				
			||||||
 | 
					 * @noreturn
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					native ForceChangeLevel(const String:map[], const String:reason[]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Gets the current number of maps in the map history
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @return			Number of maps.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					native GetMapHistorySize();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Retrieves a map from the map history list.
 | 
				
			||||||
 | 
					 * 
 | 
				
			||||||
 | 
					 * @param item			Item number. Must be 0 or greater and less than GetMapHistorySize().
 | 
				
			||||||
 | 
					 * @param map			Buffer to store the map name.
 | 
				
			||||||
 | 
					 * @param mapLen		Length of map buffer.
 | 
				
			||||||
 | 
					 * @param reason		Buffer to store the change reason.
 | 
				
			||||||
 | 
					 * @param reasonLen		Length of the reason buffer.
 | 
				
			||||||
 | 
					 * @param startTime		Time the map started.
 | 
				
			||||||
 | 
					 * @noreturn
 | 
				
			||||||
 | 
					 * @error				Invalid item number.	
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					native GetMapHistory(item, String:map[], mapLen, String:reason[], reasonLen, &startTime);
 | 
				
			||||||
@ -771,7 +771,7 @@ public Action:Timer_ChangeMap(Handle:hTimer, Handle:dp)
 | 
				
			|||||||
		ReadPackString(dp, map, sizeof(map));		
 | 
							ReadPackString(dp, map, sizeof(map));		
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	ServerCommand("changelevel \"%s\"", map);
 | 
						ForceChangeLevel(map, "Map Vote");
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	return Plugin_Stop;
 | 
						return Plugin_Stop;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -52,6 +52,8 @@ new g_MapPos = -1;
 | 
				
			|||||||
new Handle:g_MapList = INVALID_HANDLE;
 | 
					new Handle:g_MapList = INVALID_HANDLE;
 | 
				
			||||||
new g_MapListSerial = -1;
 | 
					new g_MapListSerial = -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					new g_CurrentMapStartTime;
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
public OnPluginStart()
 | 
					public OnPluginStart()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	LoadTranslations("common.phrases");
 | 
						LoadTranslations("common.phrases");
 | 
				
			||||||
@ -65,6 +67,7 @@ public OnPluginStart()
 | 
				
			|||||||
	RegConsoleCmd("nextmap", Command_Nextmap);
 | 
						RegConsoleCmd("nextmap", Command_Nextmap);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	RegAdminCmd("sm_setnextmap", Command_SetNextmap, ADMFLAG_CHANGEMAP, "sm_setnextmap <map>");
 | 
						RegAdminCmd("sm_setnextmap", Command_SetNextmap, ADMFLAG_CHANGEMAP, "sm_setnextmap <map>");
 | 
				
			||||||
 | 
						RegAdminCmd("sm_maphistory", Command_MapHistory, ADMFLAG_CHANGEMAP, "Shows the most recent maps played");
 | 
				
			||||||
	RegConsoleCmd("listmaps", Command_List);
 | 
						RegConsoleCmd("listmaps", Command_List);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Set to the current map so OnMapStart() will know what to do
 | 
						// Set to the current map so OnMapStart() will know what to do
 | 
				
			||||||
@ -73,6 +76,11 @@ public OnPluginStart()
 | 
				
			|||||||
	SetNextMap(currentMap);
 | 
						SetNextMap(currentMap);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public OnMapStart()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						g_CurrentMapStartTime = GetTime();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
public OnConfigsExecuted()
 | 
					public OnConfigsExecuted()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	decl String:lastMap[64], String:currentMap[64];
 | 
						decl String:lastMap[64], String:currentMap[64];
 | 
				
			||||||
@ -228,3 +236,59 @@ FindAndSetNextMap()
 | 
				
			|||||||
 	GetArrayString(g_MapList, g_MapPos, mapName, sizeof(mapName));
 | 
					 	GetArrayString(g_MapList, g_MapPos, mapName, sizeof(mapName));
 | 
				
			||||||
	SetNextMap(mapName);
 | 
						SetNextMap(mapName);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public Action:Command_MapHistory(client, args)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						new mapCount = GetMapHistorySize();
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						decl String:mapName[32];
 | 
				
			||||||
 | 
						decl String:changeReason[100];
 | 
				
			||||||
 | 
						decl String:timeString[100];
 | 
				
			||||||
 | 
						decl String:playedTime[100];
 | 
				
			||||||
 | 
						new startTime;
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						new lastMapStartTime = g_CurrentMapStartTime;
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						PrintToConsole(client, "Map History:\n");
 | 
				
			||||||
 | 
						PrintToConsole(client, "Map : Started : Played Time : Reason for ending");
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						GetCurrentMap(mapName, sizeof(mapName));
 | 
				
			||||||
 | 
						PrintToConsole(client, "%02i. %s (Current Map)", 0, mapName);
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						for (new i=0; i<mapCount; i++)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							GetMapHistory(i, mapName, sizeof(mapName), changeReason, sizeof(changeReason), startTime);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							FormatTimeDuration(timeString, sizeof(timeString), GetTime() - startTime);
 | 
				
			||||||
 | 
							FormatTimeDuration(playedTime, sizeof(playedTime), lastMapStartTime - startTime);
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
							PrintToConsole(client, "%02i. %s : %s ago : %s : %s", i+1, mapName, timeString, playedTime, changeReason);
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
							lastMapStartTime = startTime;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					FormatTimeDuration(String:buffer[], maxlen, time)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						new	days = time / 86400;
 | 
				
			||||||
 | 
						new	hours = (time / 3600) % 24;
 | 
				
			||||||
 | 
						new	minutes = (time / 60) % 60;
 | 
				
			||||||
 | 
						new	seconds =  time % 60;
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						if (days > 0)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							Format(buffer, maxlen, "%id %ih %im", days, hours, (seconds >= 30) ? minutes+1 : minutes);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						else if (hours > 0)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							Format(buffer, maxlen, "%ih %im", hours, (seconds >= 30) ? minutes+1 : minutes);		
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						else if (minutes > 0)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							Format(buffer, maxlen, "%im", (seconds >= 30) ? minutes+1 : minutes);		
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							Format(buffer, maxlen, "%is", seconds);		
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -298,7 +298,7 @@ public Action:Timer_ChangeMap(Handle:hTimer)
 | 
				
			|||||||
	new String:map[65];
 | 
						new String:map[65];
 | 
				
			||||||
	if (GetNextMap(map, sizeof(map)))
 | 
						if (GetNextMap(map, sizeof(map)))
 | 
				
			||||||
	{	
 | 
						{	
 | 
				
			||||||
		ServerCommand("changelevel \"%s\"", map);
 | 
							ForceChangeLevel(map, "RTV after mapvote");
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	return Plugin_Stop;
 | 
						return Plugin_Stop;
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user