- moved gameframe hook to timersys

- rewrote simulation algorithm
- various internal improvements to timer
- removed the unused parameter to GetTickedTime()

--HG--
extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%401418
This commit is contained in:
David Anderson 2007-09-12 22:46:00 +00:00
parent 532f0bde47
commit 2920ba897c
11 changed files with 186 additions and 98 deletions

View File

@ -48,6 +48,7 @@ PlayerManager g_Players;
bool g_OnMapStarted = false;
IForward *PreAdminCheck = NULL;
IForward *PostAdminCheck = NULL;
const unsigned int *g_NumPlayersToAuth = NULL;
SH_DECL_HOOK5(IServerGameClients, ClientConnect, SH_NOATTRIB, 0, bool, edict_t *, const char *, const char *, char *, int);
SH_DECL_HOOK2_void(IServerGameClients, ClientPutInServer, SH_NOATTRIB, 0, edict_t *, const char *);
@ -86,6 +87,8 @@ PlayerManager::PlayerManager()
PlayerManager::~PlayerManager()
{
g_NumPlayersToAuth = NULL;
delete [] m_AuthQueue;
delete [] m_UserIdLookUp;
}
@ -187,6 +190,8 @@ void PlayerManager::OnServerActivate(edict_t *pEdictList, int edictCount, int cl
m_FirstPass = false;
memset(m_AuthQueue, 0, sizeof(unsigned int) * (m_maxClients + 1));
g_NumPlayersToAuth = &m_AuthQueue[0];
}
m_onActivate->Execute(NULL);
m_onActivate2->Execute(NULL);
@ -318,7 +323,6 @@ void PlayerManager::RunAuthChecks()
m_AuthQueue[0] -= removed;
} else {
m_AuthQueue[0] = 0;
g_SourceMod.SetAuthChecking(false);
}
}
}
@ -351,7 +355,6 @@ bool PlayerManager::OnClientConnect(edict_t *pEntity, const char *pszName, const
if (!m_Players[client].IsAuthorized())
{
m_AuthQueue[++m_AuthQueue[0]] = client;
g_SourceMod.SetAuthChecking(true);
}
} else {
RETURN_META_VALUE(MRES_SUPERCEDE, false);

View File

@ -168,5 +168,6 @@ private:
extern PlayerManager g_Players;
extern bool g_OnMapStarted;
extern const unsigned int *g_NumPlayersToAuth;
#endif //_INCLUDE_SOURCEMOD_CPLAYERMANAGER_H_

View File

@ -31,13 +31,20 @@
#include <time.h>
#include "TimerSys.h"
#include "ForwardSys.h"
#include "sourcemm_api.h"
#include "frame_hooks.h"
TimerSystem g_Timers;
float g_fUniversalTime = 0.0f;
const float *g_pUniversalTime = &g_fUniversalTime;
ConVar sm_time_adjustment("sm_time_adjustment", "0", 0, "Adjusts the server time in seconds");
__BUILD_INTENTIONALLY_BROKEN_BY_BAIL__
inline float GetSimulatedTime()
{
return g_fUniversalTime;
}
time_t GetAdjustedTime(time_t *buf)
{
@ -49,11 +56,6 @@ time_t GetAdjustedTime(time_t *buf)
return val;
}
inline float GetSimulatedTime()
{
return engine->Time();
}
void ITimer::Initialize(ITimedEvent *pCallbacks, float fInterval, float fToExec, void *pData, int flags)
{
m_Listener = pCallbacks;
@ -68,6 +70,9 @@ void ITimer::Initialize(ITimedEvent *pCallbacks, float fInterval, float fToExec,
TimerSystem::TimerSystem()
{
m_fnTimeLeft = NULL;
m_bHasMapTickedYet = false;
m_fLastTickedTime = 0.0f;
m_LastExecTime = 0.0f;
}
TimerSystem::~TimerSystem()
@ -83,6 +88,12 @@ TimerSystem::~TimerSystem()
void TimerSystem::OnSourceModAllInitialized()
{
g_ShareSys.AddInterface(NULL, this);
m_pOnGameFrame = g_Forwards.CreateForward("OnGameFrame", ET_Ignore, 0, NULL);
}
void TimerSystem::OnSourceModShutdown()
{
g_Forwards.ReleaseForward(m_pOnGameFrame);
}
void TimerSystem::OnSourceModLevelChange(const char *mapName)
@ -90,6 +101,38 @@ void TimerSystem::OnSourceModLevelChange(const char *mapName)
MapChange(true);
}
void TimerSystem::OnSourceModLevelEnd()
{
m_bHasMapTickedYet = false;
}
void TimerSystem::GameFrame(bool simulating)
{
if (simulating && m_bHasMapTickedYet)
{
g_fUniversalTime += gpGlobals->curtime - m_fLastTickedTime;
}
else
{
g_fUniversalTime += gpGlobals->interval_per_tick;
}
m_fLastTickedTime = gpGlobals->curtime;
m_bHasMapTickedYet = true;
if (g_fUniversalTime - m_LastExecTime >= 0.1)
{
RunFrame();
}
RunFrameHooks();
if (m_pOnGameFrame->GetFunctionCount())
{
m_pOnGameFrame->Execute(NULL);
}
}
void TimerSystem::RunFrame()
{
ITimer *pTimer;
@ -299,8 +342,6 @@ void TimerSystem::MapChange(bool real_mapchange)
if (real_mapchange && (pTimer->m_Flags & TIMER_FLAG_NO_MAPCHANGE))
{
s_tokill.push(pTimer);
} else {
pTimer->m_ToExec = pTimer->m_ToExec - m_LastExecTime + GetSimulatedTime();
}
}
@ -310,8 +351,6 @@ void TimerSystem::MapChange(bool real_mapchange)
if (real_mapchange && (pTimer->m_Flags & TIMER_FLAG_NO_MAPCHANGE))
{
s_tokill.push(pTimer);
} else {
pTimer->m_ToExec = pTimer->m_ToExec - m_LastExecTime + GetSimulatedTime();
}
}
@ -329,8 +368,6 @@ void TimerSystem::MapChange(bool real_mapchange)
KillTimer(s_tokill.front());
s_tokill.pop();
}
m_LastExecTime = GetSimulatedTime();
}
SM_TIMELEFT_FUNCTION TimerSystem::SetTimeLeftFunction(SM_TIMELEFT_FUNCTION fn)

View File

@ -67,6 +67,8 @@ public:
public: //SMGlobalClass
void OnSourceModAllInitialized();
void OnSourceModLevelChange(const char *mapName);
void OnSourceModLevelEnd();
void OnSourceModShutdown();
public: //ITimerSystem
ITimer *CreateTimer(ITimedEvent *pCallbacks, float fInterval, void *pData, int flags);
void KillTimer(ITimer *pTimer);
@ -75,6 +77,7 @@ public: //ITimerSystem
public:
void RunFrame();
void MapChange(bool real_mapchange);
void GameFrame(bool simulating);
private:
List<ITimer *> m_SingleTimers;
List<ITimer *> m_LoopTimers;
@ -82,10 +85,19 @@ private:
CStack<ITimer *> m_FreeTimers;
float m_LastExecTime;
SM_TIMELEFT_FUNCTION m_fnTimeLeft;
/* This is stuff for our manual ticking escapades. */
bool m_bHasMapTickedYet; /** Has the map ticked yet? */
float m_fLastTickedTime; /** Last time that the game currently gave
us while ticking.
*/
IForward *m_pOnGameFrame;
};
time_t GetAdjustedTime(time_t *buf = NULL);
extern const float *g_pUniversalTime;
extern TimerSystem g_Timers;
#endif //_INCLUDE_SOURCEMOD_CTIMERSYS_H_

63
core/frame_hooks.cpp Normal file
View File

@ -0,0 +1,63 @@
/**
* vim: set ts=4 :
* =============================================================================
* SourceMod
* Copyright (C) 2004-2007 AlliedModders LLC. All rights reserved.
* =============================================================================
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, version 3.0, as published by the
* Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*
* As a special exception, AlliedModders LLC gives you permission to link the
* code of this program (as well as its derivative works) to "Half-Life 2," the
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
* by the Valve Corporation. You must obey the GNU General Public License in
* all respects for all other code used. Additionally, AlliedModders LLC grants
* this exception to all derivative works. AlliedModders LLC defines further
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
* or <http://www.sourcemod.net/license.php>.
*
* Version: $Id$
*/
#include "frame_hooks.h"
#include "TimerSys.h"
#include "Database.h"
#include "HalfLife2.h"
#include "MenuStyle_Valve.h"
#include "MenuStyle_Radio.h"
#include "PlayerManager.h"
float g_LastMenuTime = 0.0f;
float g_LastAuthCheck = 0.0f;
void RunFrameHooks()
{
/* Frame based hooks */
g_DBMan.RunFrame();
g_HL2.ProcessFakeCliCmdQueue();
float curtime = *g_pUniversalTime;
if (curtime - g_LastMenuTime >= 1.0f)
{
g_ValveMenuStyle.ProcessWatchList();
g_RadioMenuStyle.ProcessWatchList();
g_LastMenuTime = curtime;
}
if (*g_NumPlayersToAuth && curtime - g_LastAuthCheck >= 0.7f)
{
g_Players.RunAuthChecks();
g_LastAuthCheck = curtime;
}
}

37
core/frame_hooks.h Normal file
View File

@ -0,0 +1,37 @@
/**
* vim: set ts=4 :
* =============================================================================
* SourceMod
* Copyright (C) 2004-2007 AlliedModders LLC. All rights reserved.
* =============================================================================
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, version 3.0, as published by the
* Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*
* As a special exception, AlliedModders LLC gives you permission to link the
* code of this program (as well as its derivative works) to "Half-Life 2," the
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
* by the Valve Corporation. You must obey the GNU General Public License in
* all respects for all other code used. Additionally, AlliedModders LLC grants
* this exception to all derivative works. AlliedModders LLC defines further
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
* or <http://www.sourcemod.net/license.php>.
*
* Version: $Id$
*/
#ifndef _INCLUDE_SOURCEMOD_FRAME_HOOKS_H_
#define _INCLUDE_SOURCEMOD_FRAME_HOOKS_H_
void RunFrameHooks();
#endif //_INCLUDE_SOURCEMOD_FRAME_HOOKS_H_

View File

@ -307,6 +307,10 @@
RelativePath="..\EventManager.cpp"
>
</File>
<File
RelativePath="..\frame_hooks.cpp"
>
</File>
<File
RelativePath="..\GameConfigs.cpp"
>
@ -453,6 +457,10 @@
RelativePath="..\EventManager.h"
>
</File>
<File
RelativePath="..\frame_hooks.h"
>
</File>
<File
RelativePath="..\GameConfigs.h"
>

View File

@ -255,8 +255,7 @@ static cell_t smn_TriggerTimer(IPluginContext *pCtx, const cell_t *params)
static cell_t smn_GetTickedTime(IPluginContext *pContext, const cell_t *params)
{
float t = engine->Time();
return sp_ftoc(t);
return sp_ftoc(*g_pUniversalTime);
}
REGISTER_NATIVES(timernatives)

View File

@ -46,10 +46,6 @@
#include "Translator.h"
#include "ForwardSys.h"
#include "TimerSys.h"
#include "MenuStyle_Valve.h"
#include "MenuStyle_Radio.h"
#include "Database.h"
#include "HalfLife2.h"
#include "GameConfigs.h"
SH_DECL_HOOK6(IServerGameDLL, LevelInit, SH_NOATTRIB, false, bool, const char *, const char *, const char *, const char *, bool, bool);
@ -65,10 +61,6 @@ SourceHook::String g_BaseDir;
ISourcePawnEngine *g_pSourcePawn = &g_SourcePawn;
IVirtualMachine *g_pVM;
IdentityToken_t *g_pCoreIdent = NULL;
float g_LastTime = 0.0f;
float g_LastMenuTime = 0.0f;
float g_LastAuthCheck = 0.0f;
IForward *g_pOnGameFrame = NULL;
IForward *g_pOnMapEnd = NULL;
bool g_Loaded = false;
IExtension *g_pGameExt = NULL;
@ -286,7 +278,7 @@ bool SourceModBase::InitializeSourceMod(char *error, size_t maxlength, bool late
void SourceModBase::StartSourceMod(bool late)
{
SH_ADD_HOOK_MEMFUNC(IServerGameDLL, LevelShutdown, gamedll, this, &SourceModBase::LevelShutdown, false);
SH_ADD_HOOK_MEMFUNC(IServerGameDLL, GameFrame, gamedll, this, &SourceModBase::GameFrame, false);
SH_ADD_HOOK_MEMFUNC(IServerGameDLL, GameFrame, gamedll, &g_Timers, &TimerSystem::GameFrame, false);
enginePatch = SH_GET_CALLCLASS(engine);
gamedllPatch = SH_GET_CALLCLASS(gamedll);
@ -330,9 +322,6 @@ bool SourceModBase::LevelInit(char const *pMapName, char const *pMapEntities, ch
m_IsMapLoading = true;
m_ExecPluginReload = true;
m_ExecOnMapEnd = true;
g_LastTime = 0.0f;
g_LastMenuTime = 0.0f;
g_LastAuthCheck = 0.0f;
/* Notify! */
SMGlobalClass *pBase = SMGlobalClass::head;
@ -354,11 +343,6 @@ bool SourceModBase::LevelInit(char const *pMapName, char const *pMapEntities, ch
pBase = pBase->m_pGlobalClassNext;
}
if (!g_pOnGameFrame)
{
g_pOnGameFrame = g_Forwards.CreateForward("OnGameFrame", ET_Ignore, 0, NULL);
}
if (!g_pOnMapEnd)
{
g_pOnMapEnd = g_Forwards.CreateForward("OnMapEnd", ET_Ignore, 0, NULL);
@ -369,43 +353,6 @@ bool SourceModBase::LevelInit(char const *pMapName, char const *pMapEntities, ch
RETURN_META_VALUE(MRES_IGNORED, true);
}
void SourceModBase::GameFrame(bool simulating)
{
g_DBMan.RunFrame();
g_HL2.ProcessFakeCliCmdQueue();
/**
* Note: This is all hardcoded rather than delegated to save
* precious CPU cycles.
*/
float curtime = engine->Time();
if (curtime - g_LastTime >= 0.1f)
{
if (m_CheckingAuth
&& (gpGlobals->curtime - g_LastAuthCheck > 0.7f))
{
g_LastAuthCheck = gpGlobals->curtime;
g_Players.RunAuthChecks();
}
g_Timers.RunFrame();
g_LastTime = curtime;
}
if (gpGlobals->curtime - g_LastMenuTime >= 1.0f)
{
g_ValveMenuStyle.ProcessWatchList();
g_RadioMenuStyle.ProcessWatchList();
g_LastMenuTime = curtime;
}
if (g_pOnGameFrame && g_pOnGameFrame->GetFunctionCount())
{
g_pOnGameFrame->Execute(NULL);
}
}
void SourceModBase::LevelShutdown()
{
if (g_LevelEndBarrier)
@ -521,11 +468,6 @@ void SourceModBase::CloseSourceMod()
if (g_Loaded)
{
if (g_pOnGameFrame)
{
g_Forwards.ReleaseForward(g_pOnGameFrame);
}
if (g_pOnMapEnd)
{
g_Forwards.ReleaseForward(g_pOnMapEnd);
@ -570,7 +512,7 @@ void SourceModBase::CloseSourceMod()
}
SH_REMOVE_HOOK_MEMFUNC(IServerGameDLL, LevelShutdown, gamedll, this, &SourceModBase::LevelShutdown, false);
SH_REMOVE_HOOK_MEMFUNC(IServerGameDLL, GameFrame, gamedll, this, &SourceModBase::GameFrame, false);
SH_REMOVE_HOOK_MEMFUNC(IServerGameDLL, GameFrame, gamedll, &g_Timers, &TimerSystem::GameFrame, false);
}
/* Rest In Peace */
@ -641,11 +583,6 @@ void SourceModBase::SetGlobalTarget(unsigned int index)
m_target = index;
}
void SourceModBase::SetAuthChecking(bool set)
{
m_CheckingAuth = set;
}
unsigned int SourceModBase::GetGlobalTarget() const
{
return m_target;

View File

@ -89,11 +89,6 @@ public:
* @brief Returns the global target index.
*/
unsigned int GetGlobalTarget() const;
/**
* @brief Sets whether if SoureMod needs to check player auths.
*/
void SetAuthChecking(bool set);
public: // SMGlobalClass
ConfigResult OnSourceModConfigChanged(const char *key,
const char *value,
@ -121,11 +116,6 @@ private:
* @brief Loading plugins
*/
void DoGlobalPluginLoads();
/**
* @brief GameFrame hook
*/
void GameFrame(bool simulating);
private:
CStack<CDataPack *> m_freepacks;
char m_SMBaseDir[PLATFORM_MAX_PATH];
@ -135,7 +125,6 @@ private:
bool m_ExecPluginReload;
bool m_ExecOnMapEnd;
unsigned int m_target;
bool m_CheckingAuth;
bool m_GotBasePath;
};

View File

@ -108,15 +108,17 @@ native KillTimer(Handle:timer, bool:autoClose=false);
native TriggerTimer(Handle:timer, bool:reset=false);
/**
* Returns the simulated game time.
* Returns the simulated game time.
*
* This time is internally maintained by SourceMod and is based on the game
* tick count and tick rate. Unlike GetGameTime(), it will increment past
* map changes and while no players are connected. Unlike GetEngineTime(),
* it will not increment based on the system clock (i.e. it is still bound
* to the ticking process).
*
* @param simulated Retrieves whether or not the tick count
* is being manually simulated by SourceMod.
* This is the case if no players have joined
* the map yet.
* @return Time based on the game tick count.
*/
native Float:GetTickedTime(&bool:simulated);
native Float:GetTickedTime();
/**
* Creates a timer associated with a new data pack, and returns the datapack.