aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/server/collision/Management/MMapManager.cpp63
-rw-r--r--src/server/collision/Management/MMapManager.h5
-rw-r--r--src/server/game/AI/CoreAI/UnitAI.h1
-rw-r--r--src/server/game/Battlegrounds/Battleground.h1
-rw-r--r--src/server/game/Entities/Player/Player.cpp8
-rw-r--r--src/server/game/Server/Packets/MovementPackets.cpp9
-rw-r--r--src/server/game/Server/Packets/MovementPackets.h11
-rw-r--r--src/server/game/Server/Protocol/Opcodes.cpp2
-rw-r--r--src/server/game/Server/WorldSocket.cpp2
-rw-r--r--src/server/game/World/World.cpp15
-rw-r--r--src/server/shared/PrecompiledHeaders/sharedPCH.h1
-rw-r--r--src/server/shared/Utilities/Duration.h39
-rw-r--r--src/server/shared/Utilities/EventMap.cpp136
-rw-r--r--src/server/shared/Utilities/EventMap.h272
-rw-r--r--src/server/shared/Utilities/StringFormat.h8
-rw-r--r--src/server/shared/Utilities/TaskScheduler.h13
-rw-r--r--src/server/shared/Utilities/Timer.h4
-rw-r--r--src/server/shared/Utilities/Util.cpp9
-rw-r--r--src/server/shared/Utilities/Util.h342
19 files changed, 545 insertions, 396 deletions
diff --git a/src/server/collision/Management/MMapManager.cpp b/src/server/collision/Management/MMapManager.cpp
index e0b1ed3b161..0b9c1b325b7 100644
--- a/src/server/collision/Management/MMapManager.cpp
+++ b/src/server/collision/Management/MMapManager.cpp
@@ -37,11 +37,41 @@ namespace MMAP
// if we had, tiles in MMapData->mmapLoadedTiles, their actual data is lost!
}
+ void MMapManager::InitializeThreadUnsafe(const std::vector<uint32>& mapIds)
+ {
+ // the caller must pass the list of all mapIds that will be used in the VMapManager2 lifetime
+ for (const uint32& mapId : mapIds)
+ loadedMMaps.insert(MMapDataSet::value_type(mapId, nullptr));
+
+ thread_safe_environment = false;
+ }
+
+ MMapDataSet::const_iterator MMapManager::GetMMapData(uint32 mapId) const
+ {
+ // return the iterator if found or end() if not found/NULL
+ MMapDataSet::const_iterator itr = loadedMMaps.find(mapId);
+ if (itr != loadedMMaps.cend() && !itr->second)
+ itr = loadedMMaps.cend();
+
+ return itr;
+ }
+
bool MMapManager::loadMapData(uint32 mapId)
{
// we already have this map loaded?
- if (loadedMMaps.find(mapId) != loadedMMaps.end())
- return true;
+ MMapDataSet::iterator itr = loadedMMaps.find(mapId);
+ if (itr != loadedMMaps.end())
+ {
+ if (itr->second)
+ return true;
+ }
+ else
+ {
+ if (thread_safe_environment)
+ itr = loadedMMaps.insert(MMapDataSet::value_type(mapId, nullptr)).first;
+ else
+ ASSERT(false, "Invalid mapId %u passed to MMapManager after startup in thread unsafe environment", mapId);
+ }
// load and init dtNavMesh - read parameters from file
std::string fileName = Trinity::StringFormat(MAP_FILE_NAME_FORMAT, sWorld->GetDataPath().c_str(), mapId);
@@ -75,7 +105,7 @@ namespace MMAP
// store inside our map list
MMapData* mmap_data = new MMapData(mesh, mapId);
- loadedMMaps.insert(std::pair<uint32, MMapData*>(mapId, mmap_data));
+ itr->second = mmap_data;
return true;
}
@@ -252,14 +282,15 @@ namespace MMAP
bool MMapManager::unloadMap(uint32 mapId, int32 x, int32 y)
{
// check if we have this map loaded
- if (loadedMMaps.find(mapId) == loadedMMaps.end())
+ MMapDataSet::const_iterator itr = GetMMapData(mapId);
+ if (itr == loadedMMaps.end())
{
// file may not exist, therefore not loaded
TC_LOG_DEBUG("maps", "MMAP:unloadMap: Asked to unload not loaded navmesh map. %04u%02i%02i.mmtile", mapId, x, y);
return false;
}
- MMapData* mmap = loadedMMaps[mapId];
+ MMapData* mmap = itr->second;
// check if we have this tile loaded
uint32 packedGridPos = packTileID(x, y);
@@ -296,7 +327,8 @@ namespace MMAP
bool MMapManager::unloadMap(uint32 mapId)
{
- if (loadedMMaps.find(mapId) == loadedMMaps.end())
+ MMapDataSet::iterator itr = loadedMMaps.find(mapId);
+ if (itr == loadedMMaps.end() || !itr->second)
{
// file may not exist, therefore not loaded
TC_LOG_DEBUG("maps", "MMAP:unloadMap: Asked to unload not loaded navmesh map %04u", mapId);
@@ -304,7 +336,7 @@ namespace MMAP
}
// unload all tiles from given map
- MMapData* mmap = loadedMMaps[mapId];
+ MMapData* mmap = itr->second;
for (MMapTileSet::iterator i = mmap->loadedTileRefs.begin(); i != mmap->loadedTileRefs.end(); ++i)
{
uint32 x = (i->first >> 16);
@@ -320,7 +352,7 @@ namespace MMAP
}
delete mmap;
- loadedMMaps.erase(mapId);
+ itr->second = nullptr;
TC_LOG_DEBUG("maps", "MMAP:unloadMap: Unloaded %04i.mmap", mapId);
return true;
@@ -329,14 +361,15 @@ namespace MMAP
bool MMapManager::unloadMapInstance(uint32 mapId, uint32 instanceId)
{
// check if we have this map loaded
- if (loadedMMaps.find(mapId) == loadedMMaps.end())
+ MMapDataSet::const_iterator itr = GetMMapData(mapId);
+ if (itr == loadedMMaps.end())
{
// file may not exist, therefore not loaded
TC_LOG_DEBUG("maps", "MMAP:unloadMapInstance: Asked to unload not loaded navmesh map %04u", mapId);
return false;
}
- MMapData* mmap = loadedMMaps[mapId];
+ MMapData* mmap = itr->second;
if (mmap->navMeshQueries.find(instanceId) == mmap->navMeshQueries.end())
{
TC_LOG_DEBUG("maps", "MMAP:unloadMapInstance: Asked to unload not loaded dtNavMeshQuery mapId %04u instanceId %u", mapId, instanceId);
@@ -354,18 +387,20 @@ namespace MMAP
dtNavMesh const* MMapManager::GetNavMesh(uint32 mapId, TerrainSet swaps)
{
- if (loadedMMaps.find(mapId) == loadedMMaps.end())
+ MMapDataSet::const_iterator itr = GetMMapData(mapId);
+ if (itr == loadedMMaps.end())
return NULL;
- return loadedMMaps[mapId]->GetNavMesh(swaps);
+ return itr->second->GetNavMesh(swaps);
}
dtNavMeshQuery const* MMapManager::GetNavMeshQuery(uint32 mapId, uint32 instanceId, TerrainSet swaps)
{
- if (loadedMMaps.find(mapId) == loadedMMaps.end())
+ MMapDataSet::const_iterator itr = GetMMapData(mapId);
+ if (itr == loadedMMaps.end())
return NULL;
- MMapData* mmap = loadedMMaps[mapId];
+ MMapData* mmap = itr->second;
if (mmap->navMeshQueries.find(instanceId) == mmap->navMeshQueries.end())
{
// allocate mesh query
diff --git a/src/server/collision/Management/MMapManager.h b/src/server/collision/Management/MMapManager.h
index b7356716a9d..2b3818601af 100644
--- a/src/server/collision/Management/MMapManager.h
+++ b/src/server/collision/Management/MMapManager.h
@@ -92,9 +92,10 @@ namespace MMAP
class MMapManager
{
public:
- MMapManager() : loadedTiles(0) { }
+ MMapManager() : loadedTiles(0), thread_safe_environment(true) {}
~MMapManager();
+ void InitializeThreadUnsafe(const std::vector<uint32>& mapIds);
bool loadMap(const std::string& basePath, uint32 mapId, int32 x, int32 y);
bool unloadMap(uint32 mapId, int32 x, int32 y);
bool unloadMap(uint32 mapId);
@@ -115,8 +116,10 @@ namespace MMAP
bool loadMapData(uint32 mapId);
uint32 packTileID(int32 x, int32 y);
+ MMapDataSet::const_iterator GetMMapData(uint32 mapId) const;
MMapDataSet loadedMMaps;
uint32 loadedTiles;
+ bool thread_safe_environment;
PhasedTile* LoadTile(uint32 mapId, int32 x, int32 y);
PhaseTileMap _phaseTiles;
diff --git a/src/server/game/AI/CoreAI/UnitAI.h b/src/server/game/AI/CoreAI/UnitAI.h
index 3ea18f272ae..d98f791421b 100644
--- a/src/server/game/AI/CoreAI/UnitAI.h
+++ b/src/server/game/AI/CoreAI/UnitAI.h
@@ -22,6 +22,7 @@
#include "Define.h"
#include "Unit.h"
#include "Containers.h"
+#include "EventMap.h"
#include <list>
class Player;
diff --git a/src/server/game/Battlegrounds/Battleground.h b/src/server/game/Battlegrounds/Battleground.h
index 43ef7d9511b..51769ecdaac 100644
--- a/src/server/game/Battlegrounds/Battleground.h
+++ b/src/server/game/Battlegrounds/Battleground.h
@@ -28,6 +28,7 @@
#include "GameObject.h"
#include "Packets/WorldStatePackets.h"
#include "Packets/BattlegroundPackets.h"
+#include "EventMap.h"
class Creature;
class GameObject;
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index d121e5bb70b..9392f8ab924 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -23811,10 +23811,10 @@ void Player::ResurrectUsingRequestData()
void Player::SetClientControl(Unit* target, bool allowMove)
{
- WorldPacket data(SMSG_CONTROL_UPDATE, target->GetPackGUID().size()+1);
- data << target->GetPackGUID();
- data << uint8(allowMove ? 1 : 0);
- GetSession()->SendPacket(&data);
+ WorldPackets::Movement::ControlUpdate data;
+ data.Guid = target->GetGUID();
+ data.On = allowMove;
+ GetSession()->SendPacket(data.Write());
if (this != target)
SetViewpoint(target, allowMove);
diff --git a/src/server/game/Server/Packets/MovementPackets.cpp b/src/server/game/Server/Packets/MovementPackets.cpp
index 65847ccfa6e..c8c26af2be2 100644
--- a/src/server/game/Server/Packets/MovementPackets.cpp
+++ b/src/server/game/Server/Packets/MovementPackets.cpp
@@ -680,3 +680,12 @@ void WorldPackets::Movement::SummonResponse::Read()
_worldPacket >> SummonerGUID;
Accept = _worldPacket.ReadBit();
}
+
+WorldPacket const* WorldPackets::Movement::ControlUpdate::Write()
+{
+ _worldPacket << Guid;
+ _worldPacket.WriteBit(On);
+ _worldPacket.FlushBits();
+
+ return &_worldPacket;
+}
diff --git a/src/server/game/Server/Packets/MovementPackets.h b/src/server/game/Server/Packets/MovementPackets.h
index 22d1b62a08c..b00d29f5501 100644
--- a/src/server/game/Server/Packets/MovementPackets.h
+++ b/src/server/game/Server/Packets/MovementPackets.h
@@ -412,6 +412,17 @@ namespace WorldPackets
bool Accept = false;
ObjectGuid SummonerGUID;
};
+
+ class ControlUpdate final : public ServerPacket
+ {
+ public:
+ ControlUpdate() : ServerPacket(SMSG_CONTROL_UPDATE, 16 + 1) { }
+
+ WorldPacket const* Write() override;
+
+ ObjectGuid Guid;
+ bool On = false;
+ };
}
ByteBuffer& operator<<(ByteBuffer& data, Movement::MonsterSplineFilterKey const& monsterSplineFilterKey);
diff --git a/src/server/game/Server/Protocol/Opcodes.cpp b/src/server/game/Server/Protocol/Opcodes.cpp
index 8ab053f2296..38248b9daf6 100644
--- a/src/server/game/Server/Protocol/Opcodes.cpp
+++ b/src/server/game/Server/Protocol/Opcodes.cpp
@@ -1032,7 +1032,7 @@ void OpcodeTable::Initialize()
DEFINE_SERVER_OPCODE_HANDLER(SMSG_CONQUEST_FORMULA_CONSTANTS, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_CONSOLE_WRITE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_CONTACT_LIST, STATUS_NEVER, CONNECTION_TYPE_REALM);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_CONTROL_UPDATE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_CONTROL_UPDATE, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_CONVERT_RUNE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_COOLDOWN_CHEAT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_COOLDOWN_EVENT, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
diff --git a/src/server/game/Server/WorldSocket.cpp b/src/server/game/Server/WorldSocket.cpp
index 027c35dfd7f..372f31d1e97 100644
--- a/src/server/game/Server/WorldSocket.cpp
+++ b/src/server/game/Server/WorldSocket.cpp
@@ -881,6 +881,8 @@ void WorldSocket::SendAuthResponseError(uint8 code)
bool WorldSocket::HandlePing(WorldPacket& recvPacket)
{
+ using namespace std::chrono;
+
uint32 ping;
uint32 latency;
diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp
index 948729c6d70..2fdb8a52aa2 100644
--- a/src/server/game/World/World.cpp
+++ b/src/server/game/World/World.cpp
@@ -1471,15 +1471,16 @@ void World::SetInitialWorldSettings()
sSpellMgr->LoadPetFamilySpellsStore();
- if (VMAP::VMapManager2* vmmgr2 = dynamic_cast<VMAP::VMapManager2*>(VMAP::VMapFactory::createOrGetVMapManager()))
- {
- std::vector<uint32> mapIds;
- for (uint32 mapId = 0; mapId < sMapStore.GetNumRows(); mapId++)
- if (sMapStore.LookupEntry(mapId))
- mapIds.push_back(mapId);
+ std::vector<uint32> mapIds;
+ for (uint32 mapId = 0; mapId < sMapStore.GetNumRows(); mapId++)
+ if (sMapStore.LookupEntry(mapId))
+ mapIds.push_back(mapId);
+ if (VMAP::VMapManager2* vmmgr2 = dynamic_cast<VMAP::VMapManager2*>(VMAP::VMapFactory::createOrGetVMapManager()))
vmmgr2->InitializeThreadUnsafe(mapIds);
- }
+
+ MMAP::MMapManager* mmmgr = MMAP::MMapFactory::createOrGetMMapManager();
+ mmmgr->InitializeThreadUnsafe(mapIds);
TC_LOG_INFO("server.loading", "Loading SpellInfo store...");
sSpellMgr->LoadSpellInfoStore();
diff --git a/src/server/shared/PrecompiledHeaders/sharedPCH.h b/src/server/shared/PrecompiledHeaders/sharedPCH.h
index 87af9f44eb7..d99476bc7a8 100644
--- a/src/server/shared/PrecompiledHeaders/sharedPCH.h
+++ b/src/server/shared/PrecompiledHeaders/sharedPCH.h
@@ -7,3 +7,4 @@
#include "Errors.h"
#include "TypeList.h"
#include "TaskScheduler.h"
+#include "EventMap.h"
diff --git a/src/server/shared/Utilities/Duration.h b/src/server/shared/Utilities/Duration.h
new file mode 100644
index 00000000000..58a08e5842f
--- /dev/null
+++ b/src/server/shared/Utilities/Duration.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * 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/>.
+ */
+
+#ifndef _DURATION_H_
+#define _DURATION_H_
+
+#include <chrono>
+
+/// Milliseconds shorthand typedef.
+typedef std::chrono::milliseconds Milliseconds;
+
+/// Seconds shorthand typedef.
+typedef std::chrono::seconds Seconds;
+
+/// Minutes shorthand typedef.
+typedef std::chrono::minutes Minutes;
+
+/// Hours shorthand typedef.
+typedef std::chrono::hours Hours;
+
+/// Makes std::chrono_literals globally available.
+// ToDo: Enable this when TC supports C++14.
+// using namespace std::chrono_literals;
+
+#endif // _DURATION_H_
diff --git a/src/server/shared/Utilities/EventMap.cpp b/src/server/shared/Utilities/EventMap.cpp
new file mode 100644
index 00000000000..8c3f60afe82
--- /dev/null
+++ b/src/server/shared/Utilities/EventMap.cpp
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * 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/>.
+ */
+
+#include "EventMap.h"
+
+void EventMap::Reset()
+{
+ _eventMap.clear();
+ _time = 0;
+ _phase = 0;
+}
+
+void EventMap::SetPhase(uint8 phase)
+{
+ if (!phase)
+ _phase = 0;
+ else if (phase <= 8)
+ _phase = uint8(1 << (phase - 1));
+}
+
+void EventMap::ScheduleEvent(uint32 eventId, uint32 time, uint32 group /*= 0*/, uint8 phase /*= 0*/)
+{
+ if (group && group <= 8)
+ eventId |= (1 << (group + 15));
+
+ if (phase && phase <= 8)
+ eventId |= (1 << (phase + 23));
+
+ _eventMap.insert(EventStore::value_type(_time + time, eventId));
+}
+
+uint32 EventMap::ExecuteEvent()
+{
+ while (!Empty())
+ {
+ EventStore::iterator itr = _eventMap.begin();
+
+ if (itr->first > _time)
+ return 0;
+ else if (_phase && (itr->second & 0xFF000000) && !((itr->second >> 24) & _phase))
+ _eventMap.erase(itr);
+ else
+ {
+ uint32 eventId = (itr->second & 0x0000FFFF);
+ _lastEvent = itr->second; // include phase/group
+ _eventMap.erase(itr);
+ return eventId;
+ }
+ }
+
+ return 0;
+}
+
+void EventMap::DelayEvents(uint32 delay, uint32 group)
+{
+ if (!group || group > 8 || Empty())
+ return;
+
+ EventStore delayed;
+
+ for (EventStore::iterator itr = _eventMap.begin(); itr != _eventMap.end();)
+ {
+ if (itr->second & (1 << (group + 15)))
+ {
+ delayed.insert(EventStore::value_type(itr->first + delay, itr->second));
+ _eventMap.erase(itr++);
+ }
+ else
+ ++itr;
+ }
+
+ _eventMap.insert(delayed.begin(), delayed.end());
+}
+
+void EventMap::CancelEvent(uint32 eventId)
+{
+ if (Empty())
+ return;
+
+ for (EventStore::iterator itr = _eventMap.begin(); itr != _eventMap.end();)
+ {
+ if (eventId == (itr->second & 0x0000FFFF))
+ _eventMap.erase(itr++);
+ else
+ ++itr;
+ }
+}
+
+void EventMap::CancelEventGroup(uint32 group)
+{
+ if (!group || group > 8 || Empty())
+ return;
+
+ for (EventStore::iterator itr = _eventMap.begin(); itr != _eventMap.end();)
+ {
+ if (itr->second & (1 << (group + 15)))
+ _eventMap.erase(itr++);
+ else
+ ++itr;
+ }
+}
+
+uint32 EventMap::GetNextEventTime(uint32 eventId) const
+{
+ if (Empty())
+ return 0;
+
+ for (EventStore::const_iterator itr = _eventMap.begin(); itr != _eventMap.end(); ++itr)
+ if (eventId == (itr->second & 0x0000FFFF))
+ return itr->first;
+
+ return 0;
+}
+
+uint32 EventMap::GetTimeUntilEvent(uint32 eventId) const
+{
+ for (EventStore::const_iterator itr = _eventMap.begin(); itr != _eventMap.end(); ++itr)
+ if (eventId == (itr->second & 0x0000FFFF))
+ return itr->first - _time;
+
+ return std::numeric_limits<uint32>::max();
+}
diff --git a/src/server/shared/Utilities/EventMap.h b/src/server/shared/Utilities/EventMap.h
new file mode 100644
index 00000000000..a12cfc0cb4d
--- /dev/null
+++ b/src/server/shared/Utilities/EventMap.h
@@ -0,0 +1,272 @@
+/*
+ * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * 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/>.
+ */
+
+#ifndef _EVENT_MAP_H_
+#define _EVENT_MAP_H_
+
+#include "Common.h"
+
+class EventMap
+{
+ /**
+ * Internal storage type.
+ * Key: Time as uint32 when the event should occur.
+ * Value: The event data as uint32.
+ *
+ * Structure of event data:
+ * - Bit 0 - 15: Event Id.
+ * - Bit 16 - 23: Group
+ * - Bit 24 - 31: Phase
+ * - Pattern: 0xPPGGEEEE
+ */
+ typedef std::multimap<uint32, uint32> EventStore;
+
+public:
+ EventMap() : _time(0), _phase(0), _lastEvent(0) { }
+
+ /**
+ * @name Reset
+ * @brief Removes all scheduled events and resets time and phase.
+ */
+ void Reset();
+
+ /**
+ * @name Update
+ * @brief Updates the timer of the event map.
+ * @param time Value to be added to time.
+ */
+ void Update(uint32 time)
+ {
+ _time += time;
+ }
+
+ /**
+ * @name GetTimer
+ * @return Current timer value.
+ */
+ uint32 GetTimer() const
+ {
+ return _time;
+ }
+
+ /**
+ * @name GetPhaseMask
+ * @return Active phases as mask.
+ */
+ uint8 GetPhaseMask() const
+ {
+ return _phase;
+ }
+
+ /**
+ * @name Empty
+ * @return True, if there are no events scheduled.
+ */
+ bool Empty() const
+ {
+ return _eventMap.empty();
+ }
+
+ /**
+ * @name SetPhase
+ * @brief Sets the phase of the map (absolute).
+ * @param phase Phase which should be set. Values: 1 - 8. 0 resets phase.
+ */
+ void SetPhase(uint8 phase);
+
+ /**
+ * @name AddPhase
+ * @brief Activates the given phase (bitwise).
+ * @param phase Phase which should be activated. Values: 1 - 8
+ */
+ void AddPhase(uint8 phase)
+ {
+ if (phase && phase <= 8)
+ _phase |= uint8(1 << (phase - 1));
+ }
+
+ /**
+ * @name RemovePhase
+ * @brief Deactivates the given phase (bitwise).
+ * @param phase Phase which should be deactivated. Values: 1 - 8.
+ */
+ void RemovePhase(uint8 phase)
+ {
+ if (phase && phase <= 8)
+ _phase &= uint8(~(1 << (phase - 1)));
+ }
+
+ /**
+ * @name ScheduleEvent
+ * @brief Creates new event entry in map.
+ * @param eventId The id of the new event.
+ * @param time The time in milliseconds until the event occurs.
+ * @param group The group which the event is associated to. Has to be between 1 and 8. 0 means it has no group.
+ * @param phase The phase in which the event can occur. Has to be between 1 and 8. 0 means it can occur in all phases.
+ */
+ void ScheduleEvent(uint32 eventId, uint32 time, uint32 group = 0, uint8 phase = 0);
+
+ /**
+ * @name RescheduleEvent
+ * @brief Cancels the given event and reschedules it.
+ * @param eventId The id of the event.
+ * @param time The time in milliseconds until the event occurs.
+ * @param group The group which the event is associated to. Has to be between 1 and 8. 0 means it has no group.
+ * @param phase The phase in which the event can occur. Has to be between 1 and 8. 0 means it can occur in all phases.
+ */
+ void RescheduleEvent(uint32 eventId, uint32 time, uint32 group = 0, uint8 phase = 0)
+ {
+ CancelEvent(eventId);
+ ScheduleEvent(eventId, time, group, phase);
+ }
+
+ /**
+ * @name RepeatEvent
+ * @brief Repeats the mostly recently executed event.
+ * @param time Time until the event occurs.
+ */
+ void Repeat(uint32 time)
+ {
+ _eventMap.insert(EventStore::value_type(_time + time, _lastEvent));
+ }
+
+ /**
+ * @name RepeatEvent
+ * @brief Repeats the mostly recently executed event, Equivalent to Repeat(urand(minTime, maxTime).
+ * @param minTime Minimum time until the event occurs.
+ * @param maxTime Maximum time until the event occurs.
+ */
+ void Repeat(uint32 minTime, uint32 maxTime)
+ {
+ Repeat(urand(minTime, maxTime));
+ }
+
+ /**
+ * @name ExecuteEvent
+ * @brief Returns the next event to execute and removes it from map.
+ * @return Id of the event to execute.
+ */
+ uint32 ExecuteEvent();
+
+ /**
+ * @name DelayEvents
+ * @brief Delays all events in the map. If delay is greater than or equal internal timer, delay will be 0.
+ * @param delay Amount of delay.
+ */
+ void DelayEvents(uint32 delay)
+ {
+ _time = delay < _time ? _time - delay : 0;
+ }
+
+ /**
+ * @name DelayEvents
+ * @brief Delay all events of the same group.
+ * @param delay Amount of delay.
+ * @param group Group of the events.
+ */
+ void DelayEvents(uint32 delay, uint32 group);
+
+ /**
+ * @name CancelEvent
+ * @brief Cancels all events of the specified id.
+ * @param eventId Event id to cancel.
+ */
+ void CancelEvent(uint32 eventId);
+
+ /**
+ * @name CancelEventGroup
+ * @brief Cancel events belonging to specified group.
+ * @param group Group to cancel.
+ */
+ void CancelEventGroup(uint32 group);
+
+ /**
+ * @name GetNextEventTime
+ * @brief Returns closest occurence of specified event.
+ * @param eventId Wanted event id.
+ * @return Time of found event.
+ */
+ uint32 GetNextEventTime(uint32 eventId) const;
+
+ /**
+ * @name GetNextEventTime
+ * @return Time of next event.
+ */
+ uint32 GetNextEventTime() const
+ {
+ return Empty() ? 0 : _eventMap.begin()->first;
+ }
+
+ /**
+ * @name IsInPhase
+ * @brief Returns whether event map is in specified phase or not.
+ * @param phase Wanted phase.
+ * @return True, if phase of event map contains specified phase.
+ */
+ bool IsInPhase(uint8 phase) const
+ {
+ return phase <= 8 && (!phase || _phase & (1 << (phase - 1)));
+ }
+
+ /**
+ * @name GetTimeUntilEvent
+ * @brief Returns time in milliseconds until next event.
+ * @param eventId of the event.
+ * @return Time of next event.
+ */
+ uint32 GetTimeUntilEvent(uint32 eventId) const;
+
+private:
+ /**
+ * @name _time
+ * @brief Internal timer.
+ *
+ * This does not represent the real date/time value.
+ * It's more like a stopwatch: It can run, it can be stopped,
+ * it can be resetted and so on. Events occur when this timer
+ * has reached their time value. Its value is changed in the
+ * Update method.
+ */
+ uint32 _time;
+
+ /**
+ * @name _phase
+ * @brief Phase mask of the event map.
+ *
+ * Contains the phases the event map is in. Multiple
+ * phases from 1 to 8 can be set with SetPhase or
+ * AddPhase. RemovePhase deactives a phase.
+ */
+ uint8 _phase;
+
+ /**
+ * @name _eventMap
+ * @brief Internal event storage map. Contains the scheduled events.
+ *
+ * See typedef at the beginning of the class for more
+ * details.
+ */
+ EventStore _eventMap;
+
+ /**
+ * @name _lastEvent
+ * @brief Stores information on the most recently executed event
+ */
+ uint32 _lastEvent;
+};
+
+#endif // _EVENT_MAP_H_
diff --git a/src/server/shared/Utilities/StringFormat.h b/src/server/shared/Utilities/StringFormat.h
index 70d9aefb14d..0e9dde471da 100644
--- a/src/server/shared/Utilities/StringFormat.h
+++ b/src/server/shared/Utilities/StringFormat.h
@@ -23,11 +23,11 @@
namespace Trinity
{
- //! Default TC string format function
- template<typename... Args>
- inline std::string StringFormat(const char* fmt, Args const&... args)
+ /// Default TC string format function.
+ template<typename Format, typename... Args>
+ inline std::string StringFormat(Format&& fmt, Args&&... args)
{
- return fmt::sprintf(fmt, args...);
+ return fmt::sprintf(std::forward<Format>(fmt), std::forward<Args>(args)...);
}
}
diff --git a/src/server/shared/Utilities/TaskScheduler.h b/src/server/shared/Utilities/TaskScheduler.h
index d45835b5f17..f1fe7ea0a21 100644
--- a/src/server/shared/Utilities/TaskScheduler.h
+++ b/src/server/shared/Utilities/TaskScheduler.h
@@ -29,6 +29,7 @@
#include <boost/optional.hpp>
#include "Util.h"
+#include "Duration.h"
class TaskContext;
@@ -646,16 +647,4 @@ private:
void Invoke();
};
-/// Milliseconds shorthand typedef.
-typedef std::chrono::milliseconds Milliseconds;
-
-/// Seconds shorthand typedef.
-typedef std::chrono::seconds Seconds;
-
-/// Minutes shorthand typedef.
-typedef std::chrono::minutes Minutes;
-
-/// Hours shorthand typedef.
-typedef std::chrono::hours Hours;
-
#endif /// _TASK_SCHEDULER_H_
diff --git a/src/server/shared/Utilities/Timer.h b/src/server/shared/Utilities/Timer.h
index b7d2fa1b5ad..c54903d7be2 100644
--- a/src/server/shared/Utilities/Timer.h
+++ b/src/server/shared/Utilities/Timer.h
@@ -21,10 +21,10 @@
#include <chrono>
-using namespace std::chrono;
-
inline uint32 getMSTime()
{
+ using namespace std::chrono;
+
static const system_clock::time_point ApplicationStartTime = system_clock::now();
return uint32(duration_cast<milliseconds>(system_clock::now() - ApplicationStartTime).count());
diff --git a/src/server/shared/Utilities/Util.cpp b/src/server/shared/Utilities/Util.cpp
index 9a3d612a54b..ec67968f11e 100644
--- a/src/server/shared/Utilities/Util.cpp
+++ b/src/server/shared/Utilities/Util.cpp
@@ -573,15 +573,6 @@ std::string ByteArrayToHexStr(uint8 const* bytes, uint32 arrayLen, bool reverse
return ss.str();
}
-uint32 EventMap::GetTimeUntilEvent(uint32 eventId) const
-{
- for (EventStore::const_iterator itr = _eventMap.begin(); itr != _eventMap.end(); ++itr)
- if (eventId == (itr->second & 0x0000FFFF))
- return itr->first - _time;
-
- return std::numeric_limits<uint32>::max();
-}
-
void HexStrToByteArray(std::string const& str, uint8* out, bool reverse /*= false*/)
{
// string must have even number of characters
diff --git a/src/server/shared/Utilities/Util.h b/src/server/shared/Utilities/Util.h
index 9605efe18ec..a96fd21058f 100644
--- a/src/server/shared/Utilities/Util.h
+++ b/src/server/shared/Utilities/Util.h
@@ -555,346 +555,4 @@ bool CompareValues(ComparisionType type, T val1, T val2)
}
}
-class EventMap
-{
- /**
- * Internal storage type.
- * Key: Time as uint32 when the event should occur.
- * Value: The event data as uint32.
- *
- * Structure of event data:
- * - Bit 0 - 15: Event Id.
- * - Bit 16 - 23: Group
- * - Bit 24 - 31: Phase
- * - Pattern: 0xPPGGEEEE
- */
- typedef std::multimap<uint32, uint32> EventStore;
-
- public:
- EventMap() : _time(0), _phase(0), _lastEvent(0) { }
-
- /**
- * @name Reset
- * @brief Removes all scheduled events and resets time and phase.
- */
- void Reset()
- {
- _eventMap.clear();
- _time = 0;
- _phase = 0;
- }
-
- /**
- * @name Update
- * @brief Updates the timer of the event map.
- * @param time Value to be added to time.
- */
- void Update(uint32 time)
- {
- _time += time;
- }
-
- /**
- * @name GetTimer
- * @return Current timer value.
- */
- uint32 GetTimer() const
- {
- return _time;
- }
-
- /**
- * @name GetPhaseMask
- * @return Active phases as mask.
- */
- uint8 GetPhaseMask() const
- {
- return _phase;
- }
-
- /**
- * @name Empty
- * @return True, if there are no events scheduled.
- */
- bool Empty() const
- {
- return _eventMap.empty();
- }
-
- /**
- * @name SetPhase
- * @brief Sets the phase of the map (absolute).
- * @param phase Phase which should be set. Values: 1 - 8. 0 resets phase.
- */
- void SetPhase(uint8 phase)
- {
- if (!phase)
- _phase = 0;
- else if (phase <= 8)
- _phase = uint8(1 << (phase - 1));
- }
-
- /**
- * @name AddPhase
- * @brief Activates the given phase (bitwise).
- * @param phase Phase which should be activated. Values: 1 - 8
- */
- void AddPhase(uint8 phase)
- {
- if (phase && phase <= 8)
- _phase |= uint8(1 << (phase - 1));
- }
-
- /**
- * @name RemovePhase
- * @brief Deactivates the given phase (bitwise).
- * @param phase Phase which should be deactivated. Values: 1 - 8.
- */
- void RemovePhase(uint8 phase)
- {
- if (phase && phase <= 8)
- _phase &= uint8(~(1 << (phase - 1)));
- }
-
- /**
- * @name ScheduleEvent
- * @brief Creates new event entry in map.
- * @param eventId The id of the new event.
- * @param time The time in milliseconds until the event occurs.
- * @param group The group which the event is associated to. Has to be between 1 and 8. 0 means it has no group.
- * @param phase The phase in which the event can occur. Has to be between 1 and 8. 0 means it can occur in all phases.
- */
- void ScheduleEvent(uint32 eventId, uint32 time, uint32 group = 0, uint8 phase = 0)
- {
- if (group && group <= 8)
- eventId |= (1 << (group + 15));
-
- if (phase && phase <= 8)
- eventId |= (1 << (phase + 23));
-
- _eventMap.insert(EventStore::value_type(_time + time, eventId));
- }
-
- /**
- * @name RescheduleEvent
- * @brief Cancels the given event and reschedules it.
- * @param eventId The id of the event.
- * @param time The time in milliseconds until the event occurs.
- * @param group The group which the event is associated to. Has to be between 1 and 8. 0 means it has no group.
- * @param phase The phase in which the event can occur. Has to be between 1 and 8. 0 means it can occur in all phases.
- */
- void RescheduleEvent(uint32 eventId, uint32 time, uint32 group = 0, uint8 phase = 0)
- {
- CancelEvent(eventId);
- ScheduleEvent(eventId, time, group, phase);
- }
-
- /**
- * @name RepeatEvent
- * @brief Repeats the mostly recently executed event.
- * @param time Time until the event occurs.
- */
- void Repeat(uint32 time)
- {
- _eventMap.insert(EventStore::value_type(_time + time, _lastEvent));
- }
-
- /**
- * @name RepeatEvent
- * @brief Repeats the mostly recently executed event, Equivalent to Repeat(urand(minTime, maxTime).
- * @param minTime Minimum time until the event occurs.
- * @param maxTime Maximum time until the event occurs.
- */
- void Repeat(uint32 minTime, uint32 maxTime)
- {
- Repeat(urand(minTime, maxTime));
- }
-
- /**
- * @name ExecuteEvent
- * @brief Returns the next event to execute and removes it from map.
- * @return Id of the event to execute.
- */
- uint32 ExecuteEvent()
- {
- while (!Empty())
- {
- EventStore::iterator itr = _eventMap.begin();
-
- if (itr->first > _time)
- return 0;
- else if (_phase && (itr->second & 0xFF000000) && !((itr->second >> 24) & _phase))
- _eventMap.erase(itr);
- else
- {
- uint32 eventId = (itr->second & 0x0000FFFF);
- _lastEvent = itr->second; // include phase/group
- _eventMap.erase(itr);
- return eventId;
- }
- }
-
- return 0;
- }
-
- /**
- * @name DelayEvents
- * @brief Delays all events in the map. If delay is greater than or equal internal timer, delay will be 0.
- * @param delay Amount of delay.
- */
- void DelayEvents(uint32 delay)
- {
- _time = delay < _time ? _time - delay : 0;
- }
-
- /**
- * @name DelayEvents
- * @brief Delay all events of the same group.
- * @param delay Amount of delay.
- * @param group Group of the events.
- */
- void DelayEvents(uint32 delay, uint32 group)
- {
- if (!group || group > 8 || Empty())
- return;
-
- EventStore delayed;
-
- for (EventStore::iterator itr = _eventMap.begin(); itr != _eventMap.end();)
- {
- if (itr->second & (1 << (group + 15)))
- {
- delayed.insert(EventStore::value_type(itr->first + delay, itr->second));
- _eventMap.erase(itr++);
- }
- else
- ++itr;
- }
-
- _eventMap.insert(delayed.begin(), delayed.end());
- }
-
- /**
- * @name CancelEvent
- * @brief Cancels all events of the specified id.
- * @param eventId Event id to cancel.
- */
- void CancelEvent(uint32 eventId)
- {
- if (Empty())
- return;
-
- for (EventStore::iterator itr = _eventMap.begin(); itr != _eventMap.end();)
- {
- if (eventId == (itr->second & 0x0000FFFF))
- _eventMap.erase(itr++);
- else
- ++itr;
- }
- }
-
- /**
- * @name CancelEventGroup
- * @brief Cancel events belonging to specified group.
- * @param group Group to cancel.
- */
- void CancelEventGroup(uint32 group)
- {
- if (!group || group > 8 || Empty())
- return;
-
- for (EventStore::iterator itr = _eventMap.begin(); itr != _eventMap.end();)
- {
- if (itr->second & (1 << (group + 15)))
- _eventMap.erase(itr++);
- else
- ++itr;
- }
- }
-
- /**
- * @name GetNextEventTime
- * @brief Returns closest occurence of specified event.
- * @param eventId Wanted event id.
- * @return Time of found event.
- */
- uint32 GetNextEventTime(uint32 eventId) const
- {
- if (Empty())
- return 0;
-
- for (EventStore::const_iterator itr = _eventMap.begin(); itr != _eventMap.end(); ++itr)
- if (eventId == (itr->second & 0x0000FFFF))
- return itr->first;
-
- return 0;
- }
-
- /**
- * @name GetNextEventTime
- * @return Time of next event.
- */
- uint32 GetNextEventTime() const
- {
- return Empty() ? 0 : _eventMap.begin()->first;
- }
-
- /**
- * @name IsInPhase
- * @brief Returns wether event map is in specified phase or not.
- * @param phase Wanted phase.
- * @return True, if phase of event map contains specified phase.
- */
- bool IsInPhase(uint8 phase)
- {
- return phase <= 8 && (!phase || _phase & (1 << (phase - 1)));
- }
-
- /**
- * @name GetTimeUntilEvent
- * @brief Returns time in milliseconds until next event.
- * @param eventId of the event.
- * @return Time of next event.
- */
- uint32 GetTimeUntilEvent(uint32 eventId) const;
-
- private:
- /**
- * @name _time
- * @brief Internal timer.
- *
- * This does not represent the real date/time value.
- * It's more like a stopwatch: It can run, it can be stopped,
- * it can be resetted and so on. Events occur when this timer
- * has reached their time value. Its value is changed in the
- * Update method.
- */
- uint32 _time;
-
- /**
- * @name _phase
- * @brief Phase mask of the event map.
- *
- * Contains the phases the event map is in. Multiple
- * phases from 1 to 8 can be set with SetPhase or
- * AddPhase. RemovePhase deactives a phase.
- */
- uint8 _phase;
-
- /**
- * @name _eventMap
- * @brief Internal event storage map. Contains the scheduled events.
- *
- * See typedef at the beginning of the class for more
- * details.
- */
- EventStore _eventMap;
-
- /**
- * @name _lastEvent
- * @brief Stores information on the most recently executed event
- */
- uint32 _lastEvent;
-};
-
#endif