feat(core): Ensure that all actions are compared to fixed point in time (#1236) (#1458)

i.e. world update start
This commit is contained in:
Viste(Кирилл)
2019-02-14 21:22:17 +03:00
committed by Francesco Borzì
parent 1b7522ff0e
commit 51b8773528
108 changed files with 933 additions and 509 deletions

View File

@@ -78,6 +78,8 @@
#include "ServerMotd.h"
#include "GameGraveyard.h"
#include <VMapManager2.h>
#include "GameTime.h"
#include "UpdateTime.h"
#ifdef ELUNA
#include "LuaEngine.h"
#endif
@@ -85,7 +87,6 @@
ACE_Atomic_Op<ACE_Thread_Mutex, bool> World::m_stopEvent = false;
uint8 World::m_ExitCode = SHUTDOWN_EXIT_CODE;
uint32 World::m_worldLoopCounter = 0;
uint32 World::m_gameMSTime = 0;
float World::m_MaxVisibleDistanceOnContinents = DEFAULT_VISIBILITY_DISTANCE;
float World::m_MaxVisibleDistanceInInstances = DEFAULT_VISIBILITY_INSTANCE;
@@ -99,9 +100,6 @@ World::World()
m_allowMovement = true;
m_ShutdownMask = 0;
m_ShutdownTimer = 0;
m_gameTime = time(NULL);
m_gameMSTime = getMSTime();
m_startTime = m_gameTime;
m_maxActiveSessionCount = 0;
m_maxQueuedSessionCount = 0;
m_PlayerCount = 0;
@@ -115,8 +113,6 @@ World::World()
m_defaultDbcLocale = LOCALE_enUS;
mail_expire_check_timer = 0;
m_updateTime = 0;
m_updateTimeSum = 0;
m_isClosed = false;
@@ -261,7 +257,7 @@ void World::AddSession_(WorldSession* s)
WorldSession* oldSession = old->second;
if (!RemoveQueuedPlayer(oldSession) && getIntConfig(CONFIG_INTERVAL_DISCONNECT_TOLERANCE))
m_disconnects[s->GetAccountId()] = time(NULL);
m_disconnects[s->GetAccountId()] = GameTime::GetGameTime();
// pussywizard:
if (oldSession->HandleSocketClosed())
@@ -275,7 +271,7 @@ void World::AddSession_(WorldSession* s)
tmp->SetShouldSetOfflineInDB(false);
delete tmp;
}
oldSession->SetOfflineTime(time(NULL));
oldSession->SetOfflineTime(GameTime::GetGameTime());
m_offlineSessions[oldSession->GetAccountId()] = oldSession;
}
else
@@ -317,7 +313,7 @@ bool World::HasRecentlyDisconnected(WorldSession* session)
{
for (DisconnectMap::iterator i = m_disconnects.begin(); i != m_disconnects.end();)
{
if ((time(NULL) - i->second) < tolerance)
if ((GameTime::GetGameTime() - i->second) < tolerance)
{
if (i->first == session->GetAccountId())
return true;
@@ -463,6 +459,9 @@ void World::LoadConfigSettings(bool reload)
// to change log confs at start
sLog->ReloadConfig();
// load update time related configs
sWorldUpdateTime.LoadFromConfig();
///- Read the player limit and the Message of the day from the config file
if (!reload)
SetPlayerAmountLimit(sConfigMgr->GetIntDefault("PlayerLimit", 100));
@@ -1231,8 +1230,6 @@ void World::LoadConfigSettings(bool reload)
m_bool_configs[CONFIG_NO_RESET_TALENT_COST] = sConfigMgr->GetBoolDefault("NoResetTalentsCost", false);
m_bool_configs[CONFIG_SHOW_KICK_IN_WORLD] = sConfigMgr->GetBoolDefault("ShowKickInWorld", false);
m_int_configs[CONFIG_INTERVAL_LOG_UPDATE] = sConfigMgr->GetIntDefault("RecordUpdateTimeDiffInterval", 60000);
m_int_configs[CONFIG_MIN_LOG_UPDATE] = sConfigMgr->GetIntDefault("MinRecordUpdateTimeDiff", 100);
m_int_configs[CONFIG_NUMTHREADS] = sConfigMgr->GetIntDefault("MapUpdate.Threads", 1);
m_int_configs[CONFIG_MAX_RESULTS_LOOKUP_COMMANDS] = sConfigMgr->GetIntDefault("Command.LookupMaxResults", 0);
@@ -1317,7 +1314,7 @@ void World::SetInitialWorldSettings()
uint32 startupBegin = getMSTime();
///- Initialize the random number generator
srand((unsigned int)time(NULL));
srand((unsigned int)GameTime::GetGameTime());
///- Initialize detour memory management
dtAllocSetCustom(dtCustomAlloc, dtCustomFree);
@@ -1834,11 +1831,10 @@ void World::SetInitialWorldSettings()
///- Initialize game time and timers
sLog->outString("Initialize game time and timers");
m_gameTime = time(NULL);
m_startTime = m_gameTime;
GameTime::UpdateGameTimers();
LoginDatabase.PExecute("INSERT INTO uptime (realmid, starttime, uptime, revision) VALUES(%u, %u, 0, '%s')",
realmID, uint32(m_startTime), GitRevision::GetFullVersion()); // One-time query
realmID, uint32(GameTime::GetStartTime()), GitRevision::GetFullVersion()); // One-time query
@@ -1859,7 +1855,7 @@ void World::SetInitialWorldSettings()
// our speed up
m_timers[WUPDATE_5_SECS].SetInterval(5*IN_MILLISECONDS);
mail_expire_check_timer = time(NULL) + 6*3600;
mail_expire_check_timer = GameTime::GetGameTime() + 6*3600;
///- Initilize static helper structures
AIRegistry::Initialize();
@@ -2047,18 +2043,14 @@ void World::LoadAutobroadcasts()
/// Update the World !
void World::Update(uint32 diff)
{
m_updateTime = diff;
///- Update the game time and check for shutdown time
_UpdateGameTime();
time_t currentGameTime = GameTime::GetGameTime();
if (m_int_configs[CONFIG_INTERVAL_LOG_UPDATE])
{
m_updateTimeSum += diff;
if (m_updateTimeSum > m_int_configs[CONFIG_INTERVAL_LOG_UPDATE])
{
sLog->outBasic("Average update time diff: %u. Players online: %u.", avgDiffTracker.getAverage(), (uint32)GetActiveSessionCount());
m_updateTimeSum = 0;
}
}
sWorldUpdateTime.UpdateWithDiff(diff);
// Record update if recording set in log and diff is greater then minimum set in log
sWorldUpdateTime.RecordUpdateTime(GameTime::GetGameTimeMS(), diff, GetActiveSessionCount());
DynamicVisibilityMgr::Update(GetActiveSessionCount());
///- Update the different timers
@@ -2083,25 +2075,22 @@ void World::Update(uint32 diff)
WhoListCacheMgr::Update();
}
///- Update the game time and check for shutdown time
_UpdateGameTime();
/// Handle daily quests reset time
if (m_gameTime > m_NextDailyQuestReset)
if (currentGameTime > m_NextDailyQuestReset)
ResetDailyQuests();
/// Handle weekly quests reset time
if (m_gameTime > m_NextWeeklyQuestReset)
if (currentGameTime > m_NextWeeklyQuestReset)
ResetWeeklyQuests();
/// Handle monthly quests reset time
if (m_gameTime > m_NextMonthlyQuestReset)
if (currentGameTime > m_NextMonthlyQuestReset)
ResetMonthlyQuests();
if (m_gameTime > m_NextRandomBGReset)
if (currentGameTime > m_NextRandomBGReset)
ResetRandomBG();
if (m_gameTime > m_NextGuildReset)
if (currentGameTime > m_NextGuildReset)
ResetGuildCap();
// pussywizard:
@@ -2122,13 +2111,15 @@ void World::Update(uint32 diff)
AsyncAuctionListingMgr::Update(diff);
if (m_gameTime > mail_expire_check_timer)
if (currentGameTime > mail_expire_check_timer)
{
sObjectMgr->ReturnOrDeleteOldMails(true);
mail_expire_check_timer = m_gameTime + 6*3600;
mail_expire_check_timer = currentGameTime + 6*3600;
}
sWorldUpdateTime.RecordUpdateTimeReset();
UpdateSessions(diff);
sWorldUpdateTime.RecordUpdateTimeDuration("UpdateSessions");
}
// end of section with mutex
AsyncAuctionListingMgr::SetAuctionListingAllowed(true);
@@ -2156,9 +2147,12 @@ void World::Update(uint32 diff)
}
}
sWorldUpdateTime.RecordUpdateTimeReset();
sLFGMgr->Update(diff, 0); // pussywizard: remove obsolete stuff before finding compatibility during map update
sWorldUpdateTime.RecordUpdateTimeDuration("UpdateLFGMgr");
sMapMgr->Update(diff);
sWorldUpdateTime.RecordUpdateTimeDuration("UpdateMapMgr");
if (sWorld->getBoolConfig(CONFIG_AUTOBROADCAST))
{
@@ -2170,20 +2164,25 @@ void World::Update(uint32 diff)
}
sBattlegroundMgr->Update(diff);
sWorldUpdateTime.RecordUpdateTimeDuration("UpdateBattlegroundMgr");
sOutdoorPvPMgr->Update(diff);
sWorldUpdateTime.RecordUpdateTimeDuration("UpdateOutdoorPvPMgr");
sBattlefieldMgr->Update(diff);
sWorldUpdateTime.RecordUpdateTimeDuration("BattlefieldMgr");
sLFGMgr->Update(diff, 2); // pussywizard: handle created proposals
sWorldUpdateTime.RecordUpdateTimeDuration("UpdateLFGMgr2");
// execute callbacks from sql queries that were queued recently
ProcessQueryCallbacks();
sWorldUpdateTime.RecordUpdateTimeDuration("ProcessQueryCallbacks");
/// <li> Update uptime table
if (m_timers[WUPDATE_UPTIME].Passed())
{
uint32 tmpDiff = uint32(m_gameTime - m_startTime);
uint32 tmpDiff = GameTime::GetUptime();
uint32 maxOnlinePlayers = GetMaxPlayerCount();
m_timers[WUPDATE_UPTIME].Reset();
@@ -2193,7 +2192,7 @@ void World::Update(uint32 diff)
stmt->setUInt32(0, tmpDiff);
stmt->setUInt16(1, uint16(maxOnlinePlayers));
stmt->setUInt32(2, realmID);
stmt->setUInt32(3, uint32(m_startTime));
stmt->setUInt32(3, uint32(GameTime::GetStartTime()));
LoginDatabase.Execute(stmt);
}
@@ -2497,7 +2496,7 @@ BanReturn World::BanAccount(BanMode mode, std::string const& nameOrIP, std::stri
PreparedStatement* stmtx = LoginDatabase.GetPreparedStatement(LOGIN_SEL_ACCOUNT_BANNED);
stmtx->setUInt32(0, account);
PreparedQueryResult banresultx = LoginDatabase.Query(stmtx);
if (banresultx && ((*banresultx)[0].GetUInt32() == (*banresultx)[1].GetUInt32() || ((*banresultx)[1].GetUInt32() > time(NULL)+duration_secs && duration_secs)))
if (banresultx && ((*banresultx)[0].GetUInt32() == (*banresultx)[1].GetUInt32() || ((*banresultx)[1].GetUInt32() > GameTime::GetGameTime()+duration_secs && duration_secs)))
return BAN_LONGER_EXISTS;
// make sure there is only one active ban
@@ -2616,10 +2615,10 @@ bool World::RemoveBanCharacter(std::string const& name)
void World::_UpdateGameTime()
{
///- update the time
time_t thisTime = time(NULL);
uint32 elapsed = uint32(thisTime - m_gameTime);
m_gameTime = thisTime;
m_gameMSTime = getMSTime();
time_t lastGameTime = GameTime::GetGameTime();
GameTime::UpdateGameTimers();
uint32 elapsed = uint32(GameTime::GetGameTime() - lastGameTime);
///- if there is a shutdown timer
if (!IsStopped() && m_ShutdownTimer > 0 && elapsed > 0)
@@ -2752,7 +2751,7 @@ void World::UpdateSessions(uint32 diff)
if (pSession->HandleSocketClosed())
{
if (!RemoveQueuedPlayer(pSession) && getIntConfig(CONFIG_INTERVAL_DISCONNECT_TOLERANCE))
m_disconnects[pSession->GetAccountId()] = time(NULL);
m_disconnects[pSession->GetAccountId()] = GameTime::GetGameTime();
m_sessions.erase(itr);
// there should be no offline session if current one is logged onto a character
SessionMap::iterator iter;
@@ -2763,7 +2762,7 @@ void World::UpdateSessions(uint32 diff)
tmp->SetShouldSetOfflineInDB(false);
delete tmp;
}
pSession->SetOfflineTime(time(NULL));
pSession->SetOfflineTime(GameTime::GetGameTime());
m_offlineSessions[pSession->GetAccountId()] = pSession;
continue;
}
@@ -2771,7 +2770,7 @@ void World::UpdateSessions(uint32 diff)
if (!pSession->Update(diff, updater))
{
if (!RemoveQueuedPlayer(pSession) && getIntConfig(CONFIG_INTERVAL_DISCONNECT_TOLERANCE))
m_disconnects[pSession->GetAccountId()] = time(NULL);
m_disconnects[pSession->GetAccountId()] = GameTime::GetGameTime();
m_sessions.erase(itr);
if (m_offlineSessions.find(pSession->GetAccountId()) != m_offlineSessions.end()) // pussywizard: don't set offline in db because offline session for that acc is present (character is in world)
pSession->SetShouldSetOfflineInDB(false);
@@ -2782,7 +2781,7 @@ void World::UpdateSessions(uint32 diff)
// pussywizard:
if (m_offlineSessions.empty())
return;
uint32 currTime = time(NULL);
uint32 currTime = GameTime::GetGameTime();
for (SessionMap::iterator itr = m_offlineSessions.begin(), next; itr != m_offlineSessions.end(); itr = next)
{
next = itr;
@@ -2920,7 +2919,7 @@ time_t World::GetNextTimeWithDayAndHour(int8 dayOfWeek, int8 hour)
{
if (hour < 0 || hour > 23)
hour = 0;
time_t curr = time(NULL);
time_t curr = GameTime::GetGameTime();
tm localTm;
ACE_OS::localtime_r(&curr, &localTm);
localTm.tm_hour = hour;
@@ -2941,7 +2940,7 @@ time_t World::GetNextTimeWithMonthAndHour(int8 month, int8 hour)
{
if (hour < 0 || hour > 23)
hour = 0;
time_t curr = time(NULL);
time_t curr = GameTime::GetGameTime();
tm localTm;
ACE_OS::localtime_r(&curr, &localTm);
localTm.tm_mday = 1;

View File

@@ -292,8 +292,6 @@ enum WorldIntConfigs
CONFIG_PVP_TOKEN_MAP_TYPE,
CONFIG_PVP_TOKEN_ID,
CONFIG_PVP_TOKEN_COUNT,
CONFIG_INTERVAL_LOG_UPDATE,
CONFIG_MIN_LOG_UPDATE,
CONFIG_ENABLE_SINFO_LOGIN,
CONFIG_PLAYER_ALLOW_COMMANDS,
CONFIG_NUMTHREADS,
@@ -620,18 +618,6 @@ class World
/// Get the path where data (dbc, maps) are stored on disk
std::string const& GetDataPath() const { return m_dataPath; }
/// When server started?
time_t const& GetStartTime() const { return m_startTime; }
/// What time is it?
time_t const& GetGameTime() const { return m_gameTime; }
/// What time is it? in ms
static uint32 GetGameTimeMS() { return m_gameMSTime; }
/// Uptime (in secs)
uint32 GetUptime() const { return uint32(m_gameTime - m_startTime); }
/// Update time
uint32 GetUpdateTime() const { return m_updateTime; }
void SetRecordDiffInterval(int32 t) { if (t >= 0) m_int_configs[CONFIG_INTERVAL_LOG_UPDATE] = (uint32)t; }
/// Next daily quests and random bg reset time
time_t GetNextDailyQuestsResetTime() const { return m_NextDailyQuestReset; }
time_t GetNextWeeklyQuestsResetTime() const { return m_NextWeeklyQuestReset; }
@@ -812,12 +798,8 @@ class World
bool m_isClosed;
time_t m_startTime;
time_t m_gameTime;
IntervalTimer m_timers[WUPDATE_COUNT];
time_t mail_expire_check_timer;
uint32 m_updateTime, m_updateTimeSum;
static uint32 m_gameMSTime;
SessionMap m_sessions;
SessionMap m_offlineSessions;