diff --git a/src/game/ChatCommands/BanAndKickCommands.cpp b/src/game/ChatCommands/BanAndKickCommands.cpp index 680d3296..8fd46e46 100644 --- a/src/game/ChatCommands/BanAndKickCommands.cpp +++ b/src/game/ChatCommands/BanAndKickCommands.cpp @@ -26,6 +26,7 @@ #include "Language.h" #include "World.h" #include "AccountMgr.h" +#include "Util.h" /********************************************************************** CommandTable : banCommandTable @@ -177,7 +178,7 @@ bool ChatHandler::HandleBanHelper(BanMode mode, char* args) case BAN_SUCCESS: if (duration_secs > 0) { - PSendSysMessage(LANG_BAN_YOUBANNED, nameOrIP.c_str(), secsToTimeString(duration_secs, true).c_str(), reason); + PSendSysMessage(LANG_BAN_YOUBANNED, nameOrIP.c_str(), secsToTimeString(duration_secs, TimeFormat::ShortText).c_str(), reason); } else { @@ -246,7 +247,7 @@ bool ChatHandler::HandleBanInfoHelper(uint32 accountid, char const* accountname) active = true; } bool permanent = (fields[1].GetUInt64() == (uint64)0); - std::string bantime = permanent ? GetMangosString(LANG_BANINFO_INFINITE) : secsToTimeString(fields[1].GetUInt64(), true); + std::string bantime = permanent ? GetMangosString(LANG_BANINFO_INFINITE) : secsToTimeString(fields[1].GetUInt64(), TimeFormat::ShortText); PSendSysMessage(LANG_BANINFO_HISTORYENTRY, fields[0].GetString(), bantime.c_str(), active ? GetMangosString(LANG_BANINFO_YES) : GetMangosString(LANG_BANINFO_NO), fields[4].GetString(), fields[5].GetString()); } @@ -288,7 +289,7 @@ bool ChatHandler::HandleBanInfoIPCommand(char* args) bool permanent = !fields[6].GetUInt64(); PSendSysMessage(LANG_BANINFO_IPENTRY, fields[0].GetString(), fields[1].GetString(), permanent ? GetMangosString(LANG_BANINFO_NEVER) : fields[2].GetString(), - permanent ? GetMangosString(LANG_BANINFO_INFINITE) : secsToTimeString(fields[3].GetUInt64(), true).c_str(), fields[4].GetString(), fields[5].GetString()); + permanent ? GetMangosString(LANG_BANINFO_INFINITE) : secsToTimeString(fields[3].GetUInt64(), TimeFormat::ShortText).c_str(), fields[4].GetString(), fields[5].GetString()); delete result; return true; } diff --git a/src/game/ChatCommands/CreatureCommands.cpp b/src/game/ChatCommands/CreatureCommands.cpp index 3aca2d4c..f8838dc1 100644 --- a/src/game/ChatCommands/CreatureCommands.cpp +++ b/src/game/ChatCommands/CreatureCommands.cpp @@ -1081,8 +1081,8 @@ bool ChatHandler::HandleNpcInfoCommand(char* /*args*/) { curRespawnDelay = 0; } - std::string curRespawnDelayStr = secsToTimeString(curRespawnDelay, true); - std::string defRespawnDelayStr = secsToTimeString(target->GetRespawnDelay(), true); + std::string curRespawnDelayStr = secsToTimeString(curRespawnDelay, TimeFormat::ShortText); + std::string defRespawnDelayStr = secsToTimeString(target->GetRespawnDelay(), TimeFormat::ShortText); PSendSysMessage(LANG_NPCINFO_CHAR, target->GetGuidStr().c_str(), faction, npcflags, Entry, displayid, nativeid); PSendSysMessage(LANG_NPCINFO_LEVEL, target->getLevel()); diff --git a/src/game/ChatCommands/GMCommands.cpp b/src/game/ChatCommands/GMCommands.cpp index 362be0b5..bc162ade 100644 --- a/src/game/ChatCommands/GMCommands.cpp +++ b/src/game/ChatCommands/GMCommands.cpp @@ -27,7 +27,7 @@ #include "World.h" #include "Weather.h" #include "SpellMgr.h" - +#include "Util.h" /********************************************************************** CommandTable : commandTable @@ -129,7 +129,7 @@ bool ChatHandler::HandlePInfoCommand(char* args) PSendSysMessage(LANG_PINFO_ACCOUNT, (target ? "" : GetMangosString(LANG_OFFLINE)), nameLink.c_str(), target_guid.GetCounter(), username.c_str(), accId, security, email.c_str(), last_ip.c_str(), last_login.c_str(), latency); - std::string timeStr = secsToTimeString(total_player_time, true, true); + std::string timeStr = secsToTimeString(total_player_time, TimeFormat::ShortText, true); uint32 gold = money / GOLD; uint32 silv = (money % GOLD) / SILVER; uint32 copp = (money % GOLD) % SILVER; diff --git a/src/game/ChatCommands/GameObjectCommands.cpp b/src/game/ChatCommands/GameObjectCommands.cpp index e3d3f18d..a8ed9793 100644 --- a/src/game/ChatCommands/GameObjectCommands.cpp +++ b/src/game/ChatCommands/GameObjectCommands.cpp @@ -601,8 +601,8 @@ bool ChatHandler::HandleGameObjectTargetCommand(char* args) curRespawnDelay = 0; } - std::string curRespawnDelayStr = secsToTimeString(curRespawnDelay, true); - std::string defRespawnDelayStr = secsToTimeString(target->GetRespawnDelay(), true); + std::string curRespawnDelayStr = secsToTimeString(curRespawnDelay, TimeFormat::ShortText); + std::string defRespawnDelayStr = secsToTimeString(target->GetRespawnDelay(), TimeFormat::ShortText); PSendSysMessage(LANG_COMMAND_RAWPAWNTIMES, defRespawnDelayStr.c_str(), curRespawnDelayStr.c_str()); diff --git a/src/game/ChatCommands/InstanceCommands.cpp b/src/game/ChatCommands/InstanceCommands.cpp index 2eccabed..61cd1749 100644 --- a/src/game/ChatCommands/InstanceCommands.cpp +++ b/src/game/ChatCommands/InstanceCommands.cpp @@ -44,18 +44,18 @@ bool ChatHandler::HandleInstanceListBindsCommand(char* /*args*/) for (Player::BoundInstancesMap::const_iterator itr = binds.begin(); itr != binds.end(); ++itr) { DungeonPersistentState* state = itr->second.state; - std::string timeleft = secsToTimeString(state->GetResetTime() - time(NULL), true); + std::string timeleft = secsToTimeString(state->GetResetTime() - time(NULL), TimeFormat::ShortText); if (const MapEntry* entry = sMapStore.LookupEntry(itr->first)) { PSendSysMessage("map: %d (%s) inst: %d perm: %s canReset: %s TTR: %s", - itr->first, entry->name[GetSessionDbcLocale()], state->GetInstanceId(), itr->second.perm ? "yes" : "no", - state->CanReset() ? "yes" : "no", timeleft.c_str()); + itr->first, entry->name[GetSessionDbcLocale()], state->GetInstanceId(), itr->second.perm ? "yes" : "no", + state->CanReset() ? "yes" : "no", timeleft.c_str()); } else { PSendSysMessage("bound for a nonexistent map %u", itr->first); } - counter++; + ++counter; } PSendSysMessage("player binds: %d", counter); @@ -67,13 +67,12 @@ bool ChatHandler::HandleInstanceListBindsCommand(char* /*args*/) for (Group::BoundInstancesMap::const_iterator itr = binds.begin(); itr != binds.end(); ++itr) { DungeonPersistentState* state = itr->second.state; - std::string timeleft = secsToTimeString(state->GetResetTime() - time(NULL), true); - + std::string timeleft = secsToTimeString(state->GetResetTime() - time(NULL), TimeFormat::ShortText); if (const MapEntry* entry = sMapStore.LookupEntry(itr->first)) { PSendSysMessage("map: %d (%s) inst: %d perm: %s canReset: %s TTR: %s", - itr->first, entry->name[GetSessionDbcLocale()], state->GetInstanceId(), itr->second.perm ? "yes" : "no", - state->CanReset() ? "yes" : "no", timeleft.c_str()); + itr->first, entry->name[GetSessionDbcLocale()], state->GetInstanceId(), itr->second.perm ? "yes" : "no", + state->CanReset() ? "yes" : "no", timeleft.c_str()); } else { @@ -125,13 +124,13 @@ bool ChatHandler::HandleInstanceUnbindCommand(char* args) if (itr->first != player->GetMapId()) { DungeonPersistentState* save = itr->second.state; - std::string timeleft = secsToTimeString(save->GetResetTime() - time(NULL), true); + std::string timeleft = secsToTimeString(save->GetResetTime() - time(NULL), TimeFormat::ShortText); if (const MapEntry* entry = sMapStore.LookupEntry(itr->first)) { PSendSysMessage("unbinding map: %d (%s) inst: %d perm: %s canReset: %s TTR: %s", - itr->first, entry->name[GetSessionDbcLocale()], save->GetInstanceId(), itr->second.perm ? "yes" : "no", - save->CanReset() ? "yes" : "no", timeleft.c_str()); + itr->first, entry->name[GetSessionDbcLocale()], save->GetInstanceId(), itr->second.perm ? "yes" : "no", + save->CanReset() ? "yes" : "no", timeleft.c_str()); } else { diff --git a/src/game/Warden/Warden.cpp b/src/game/Warden/Warden.cpp index 136ed626..c97b12e7 100644 --- a/src/game/Warden/Warden.cpp +++ b/src/game/Warden/Warden.cpp @@ -150,7 +150,7 @@ void Warden::Update() if (_clientResponseTimer > maxClientResponseDelay * IN_MILLISECONDS) { sLog.outWarden("%s (latency: %u, IP: %s) exceeded Warden module response delay on state %s for more than %s - disconnecting client", - _session->GetPlayerName(), _session->GetLatency(), _session->GetRemoteAddress().c_str(), WardenState::to_string(_state), secsToTimeString(maxClientResponseDelay, true).c_str()); + _session->GetPlayerName(), _session->GetLatency(), _session->GetRemoteAddress().c_str(), WardenState::to_string(_state), secsToTimeString(maxClientResponseDelay, TimeFormat::ShortText).c_str()); _session->KickPlayer(); } else diff --git a/src/game/WorldHandlers/World.cpp b/src/game/WorldHandlers/World.cpp index a35aff7a..70d11984 100644 --- a/src/game/WorldHandlers/World.cpp +++ b/src/game/WorldHandlers/World.cpp @@ -2163,7 +2163,7 @@ void World::ShutdownMsg(bool show /*= false*/, Player* player /*= NULL*/) (m_ShutdownTimer < 12 * HOUR && (m_ShutdownTimer % HOUR) == 0) || // < 12 h; every 1 h (m_ShutdownTimer >= 12 * HOUR && (m_ShutdownTimer % (12 * HOUR)) == 0)) // >= 12 h; every 12 h { - std::string str = secsToTimeString(m_ShutdownTimer); + std::string str = secsToTimeString(m_ShutdownTimer, TimeFormat::Numeric); ServerMessageType msgid = (m_ShutdownMask & SHUTDOWN_MASK_RESTART) ? SERVER_MSG_RESTART_TIME : SERVER_MSG_SHUTDOWN_TIME; diff --git a/src/shared/Utilities/Timer.h b/src/shared/Utilities/Timer.h index 156719d3..37942596 100644 --- a/src/shared/Utilities/Timer.h +++ b/src/shared/Utilities/Timer.h @@ -82,9 +82,18 @@ inline uint32 GetUnixTimeStamp() struct IntervalTimer { -public: - IntervalTimer() : _interval(0), _current(0) { } + public: + /** + * @brief + * + */ + IntervalTimer() : _interval(0), _current(0) {} + /** + * @brief + * + * @param diff + */ void Update(time_t diff) { _current += diff; @@ -93,12 +102,19 @@ public: _current = 0; } } - + /** + * @brief + * + * @return bool + */ bool Passed() { return _current >= _interval; } - + /** + * @brief + * + */ void Reset() { if (_current >= _interval) @@ -127,12 +143,15 @@ public: return _current; } -private: - - time_t _interval; - time_t _current; + private: + time_t _interval; /**< TODO */ + time_t _current; /**< TODO */ }; +/** + * @brief + * + */ struct TimeTracker { public: diff --git a/src/shared/Utilities/Util.cpp b/src/shared/Utilities/Util.cpp index 6928ffca..45d8a8d4 100644 --- a/src/shared/Utilities/Util.cpp +++ b/src/shared/Utilities/Util.cpp @@ -29,6 +29,8 @@ #include "RNGen.h" #include "Log/Log.h" +#include + ////////////////////////////////////////////////////////////////////////// int32 irand(int32 min, int32 max) { @@ -163,7 +165,7 @@ std::tm localtime_r(const time_t& time) return tm_snapshot; } -std::string secsToTimeString(time_t timeInSecs, bool shortText, bool hoursOnly) +std::string secsToTimeString(time_t timeInSecs, TimeFormat timeFormat, bool hoursOnly) { time_t secs = timeInSecs % MINUTE; time_t minutes = timeInSecs % HOUR / MINUTE; @@ -173,21 +175,107 @@ std::string secsToTimeString(time_t timeInSecs, bool shortText, bool hoursOnly) std::ostringstream ss; if (days) { - ss << days << (shortText ? "d" : " Day(s) "); + ss << days; + if (timeFormat == TimeFormat::Numeric) + { + ss << ":"; + } + else if (timeFormat == TimeFormat::ShortText) + { + ss << "d"; + } + else // if (timeFormat == TimeFormat::FullText) + { + if (days == 1) + { + ss << " Day "; + } + else + { + ss << " Days "; + } + } } + if (hours || hoursOnly) { - ss << hours << (shortText ? "h" : " Hour(s) "); + ss << hours; + if (timeFormat == TimeFormat::Numeric) + { + ss << ":"; + } + else if (timeFormat == TimeFormat::ShortText) + { + ss << "h"; + } + else // if (timeFormat == TimeFormat::FullText) + { + if (hours <= 1) + { + ss << " Hour "; + } + else + { + ss << " Hours "; + } + } } + if (!hoursOnly) { - if (minutes) + ss << minutes; + if (timeFormat == TimeFormat::Numeric) { - ss << minutes << (shortText ? "m" : " Minute(s) "); + ss << ":"; } - if (secs || (!days && !hours && !minutes)) + else if (timeFormat == TimeFormat::ShortText) { - ss << secs << (shortText ? "s" : " Second(s)."); + ss << "m"; + } + else // if (timeFormat == TimeFormat::FullText) + { + if (minutes == 1) + { + ss << " Minute "; + } + else + { + ss << " Minutes "; + } + } + } + else + { + if (timeFormat == TimeFormat::Numeric) + { + ss << "0:"; + } + } + + if (secs || (!days && !hours && !minutes)) + { + ss << std::setw(2) << std::setfill('0') << secs; + if (timeFormat == TimeFormat::ShortText) + { + ss << "s"; + } + else if (timeFormat == TimeFormat::FullText) + { + if (secs <= 1) + { + ss << " Second."; + } + else + { + ss << " Seconds."; + } + } + } + else + { + if (timeFormat == TimeFormat::Numeric) + { + ss << "00"; } } diff --git a/src/shared/Utilities/Util.h b/src/shared/Utilities/Util.h index 2e169b66..76725978 100644 --- a/src/shared/Utilities/Util.h +++ b/src/shared/Utilities/Util.h @@ -34,6 +34,13 @@ #include #include +enum class TimeFormat : uint8 +{ + FullText, // 1 Days 2 Hours 3 Minutes 4 Seconds + ShortText, // 1d 2h 3m 4s + Numeric // 1:2:3:4 +}; + /** * @brief * @@ -87,7 +94,7 @@ std::tm localtime_r(const time_t& time); * @param hoursOnly * @return std::string */ -std::string secsToTimeString(time_t timeInSecs, bool shortText = false, bool hoursOnly = false); +std::string secsToTimeString(time_t timeInSecs, TimeFormat timeFormat = TimeFormat::FullText, bool hoursOnly = false); /** * @brief *