Advertisement
Guest User

MiLk

a guest
Dec 22nd, 2009
327
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 178.12 KB | None | 0 0
  1. [quote]From 19328e7d4f883ed6dff07efb287ed5c968e337b0 Mon Sep 17 00:00:00 2001
  2. From: Opterman <fasteruo@gmail.com>
  3. Date: Sun, 22 Nov 2009 13:57:40 +0100
  4. Subject: [PATCH] Map Updater v.07
  5.  
  6. ---
  7. src/game/BattleGround.cpp | 16 +-
  8. src/game/BattleGround.h | 62 ++---
  9. src/game/BattleGroundBE.cpp | 6 +-
  10. src/game/BattleGroundDS.cpp | 42 +++-
  11. src/game/BattleGroundDS.h | 1 +
  12. src/game/BattleGroundHandler.cpp | 18 +-
  13. src/game/BattleGroundMgr.cpp | 398 +++++++++++++++++---------------
  14. src/game/BattleGroundMgr.h | 60 +++--
  15. src/game/BattleGroundNA.cpp | 6 +-
  16. src/game/BattleGroundRL.cpp | 5 +-
  17. src/game/BattleGroundRV.cpp | 33 +++-
  18. src/game/BattleGroundRV.h | 1 +
  19. src/game/CharacterHandler.cpp | 21 ++
  20. src/game/DBCStructure.h | 12 +-
  21. src/game/DBCfmt.h | 2 +-
  22. src/game/GameEventMgr.cpp | 363 +++++++++++++----------------
  23. src/game/GameEventMgr.h | 42 ++--
  24. src/game/GridDefines.h | 2 +-
  25. src/game/Group.cpp | 4 +-
  26. src/game/InstanceData.cpp | 10 +-
  27. src/game/Level2.cpp | 102 +++-----
  28. src/game/Map.cpp | 208 +++++++++++++++--
  29. src/game/Map.h | 23 ++-
  30. src/game/MapInstanced.cpp | 4 +-
  31. src/game/MapManager.cpp | 60 ++++--
  32. src/game/MapManager.h | 9 +-
  33. src/game/MovementHandler.cpp | 22 ++-
  34. src/game/Object.cpp | 5 +-
  35. src/game/ObjectMgr.cpp | 9 +-
  36. src/game/Player.cpp | 44 +++-
  37. src/game/Player.h | 4 +-
  38. src/game/Spell.cpp | 10 +
  39. src/game/Spell.h | 2 +-
  40. src/game/World.cpp | 38 ++--
  41. src/game/World.h | 6 +-
  42. src/game/WorldSession.cpp | 8 +-
  43. src/game/WorldSession.h | 14 ++
  44. src/mangosd/Master.cpp | 81 +++++--
  45. src/mangosd/WorldRunnable.cpp | 1 +
  46. src/mangosd/mangosd.conf.dist.in | 33 +++-
  47. src/shared/Database/Database.cpp | 10 +
  48. src/shared/Database/Database.h | 29 ++--
  49. src/shared/Database/DatabaseImpl.h | 64 +++---
  50. src/shared/Database/SqlDelayThread.cpp | 4 +-
  51. src/shared/Database/SqlDelayThread.h | 4 +-
  52. src/shared/Threading.cpp | 22 ++
  53. src/shared/Threading.h | 6 +-
  54. 47 files changed, 1195 insertions(+), 731 deletions(-)
  55.  
  56. diff --git a/src/game/BattleGround.cpp b/src/game/BattleGround.cpp
  57. index 9034853..35eafcc 100644
  58. --- a/src/game/BattleGround.cpp
  59. +++ b/src/game/BattleGround.cpp
  60. @@ -212,7 +212,7 @@ BattleGround::BattleGround()
  61. m_Status = STATUS_NONE;
  62. m_ClientInstanceID = 0;
  63. m_EndTime = 0;
  64. - m_QueueId = QUEUE_ID_MAX_LEVEL_19;
  65. + m_QueueId = 0;
  66. m_InvitedAlliance = 0;
  67. m_InvitedHorde = 0;
  68. m_ArenaType = 0;
  69. @@ -304,7 +304,7 @@ BattleGround::~BattleGround()
  70. m_Map->SetUnload();
  71.  
  72. // remove from bg free slot queue
  73. - this->RemoveFromBGFreeSlotQueue();
  74. + RemoveFromBGFreeSlotQueue();
  75.  
  76. for(BattleGroundScoreMap::const_iterator itr = m_PlayerScores.begin(); itr != m_PlayerScores.end(); ++itr)
  77. delete itr->second;
  78. @@ -984,6 +984,14 @@ void BattleGround::BlockMovement(Player *plr)
  79. plr->SetClientControl(plr, 0); // movement disabled NOTE: the effect will be automatically removed by client when the player is teleported from the battleground, so no need to send with uint8(1) in RemovePlayerAtLeave()
  80. }
  81.  
  82. +void BattleGround::RemovePlayer(Player * /*player */, uint64 /*guid*/)
  83. +{
  84. + if(!isArena() || GetStatus() != STATUS_WAIT_LEAVE)
  85. + return;
  86. +
  87. + CheckArenaWinConditions();
  88. +}
  89. +
  90. void BattleGround::RemovePlayerAtLeave(uint64 guid, bool Transport, bool SendPacket)
  91. {
  92. uint32 team = GetPlayerTeam(guid);
  93. @@ -1114,7 +1122,7 @@ void BattleGround::RemovePlayerAtLeave(uint64 guid, bool Transport, bool SendPac
  94. // this method is called when no players remains in battleground
  95. void BattleGround::Reset()
  96. {
  97. - SetQueueId(QUEUE_ID_MAX_LEVEL_19);
  98. + SetQueueId(0);
  99. SetWinner(WINNER_NONE);
  100. SetStatus(STATUS_WAIT_QUEUE);
  101. SetStartTime(0);
  102. @@ -1742,6 +1750,8 @@ void BattleGround::HandleKillPlayer( Player *player, Player *killer )
  103. // to be able to remove insignia -- ONLY IN BattleGrounds
  104. if (!isArena())
  105. player->SetFlag( UNIT_FIELD_FLAGS, UNIT_FLAG_SKINNABLE );
  106. + else if(GetStatus() == STATUS_IN_PROGRESS && killer)
  107. + CheckArenaWinConditions();
  108. }
  109.  
  110. // return the player's team based on battlegroundplayer info
  111. diff --git a/src/game/BattleGround.h b/src/game/BattleGround.h
  112. index d35e114..bd0d4b3 100644
  113. --- a/src/game/BattleGround.h
  114. +++ b/src/game/BattleGround.h
  115. @@ -165,19 +165,6 @@ enum BattleGroundQueueTypeId
  116. };
  117. #define MAX_BATTLEGROUND_QUEUE_TYPES 10
  118.  
  119. -enum BGQueueIdBasedOnLevel // queue_id for level ranges
  120. -{
  121. - QUEUE_ID_MAX_LEVEL_19 = 0,
  122. - QUEUE_ID_MAX_LEVEL_29 = 1,
  123. - QUEUE_ID_MAX_LEVEL_39 = 2,
  124. - QUEUE_ID_MAX_LEVEL_49 = 3,
  125. - QUEUE_ID_MAX_LEVEL_59 = 4,
  126. - QUEUE_ID_MAX_LEVEL_69 = 5,
  127. - QUEUE_ID_MAX_LEVEL_79 = 6,
  128. - QUEUE_ID_MAX_LEVEL_80 = 7
  129. -};
  130. -#define MAX_BATTLEGROUND_QUEUES 8
  131. -
  132. enum ScoreType
  133. {
  134. SCORE_KILLING_BLOWS = 1,
  135. @@ -307,26 +294,26 @@ class BattleGround
  136.  
  137. /* Battleground */
  138. // Get methods:
  139. - char const* GetName() const { return m_Name; }
  140. - BattleGroundTypeId GetTypeID() const { return m_TypeID; }
  141. - BGQueueIdBasedOnLevel GetQueueId() const { return m_QueueId; }
  142. - uint32 GetInstanceID() const { return m_InstanceID; }
  143. - BattleGroundStatus GetStatus() const { return m_Status; }
  144. - uint32 GetClientInstanceID() const { return m_ClientInstanceID; }
  145. - uint32 GetStartTime() const { return m_StartTime; }
  146. - uint32 GetEndTime() const { return m_EndTime; }
  147. - uint32 GetMaxPlayers() const { return m_MaxPlayers; }
  148. - uint32 GetMinPlayers() const { return m_MinPlayers; }
  149. -
  150. - uint32 GetMinLevel() const { return m_LevelMin; }
  151. - uint32 GetMaxLevel() const { return m_LevelMax; }
  152. -
  153. - uint32 GetMaxPlayersPerTeam() const { return m_MaxPlayersPerTeam; }
  154. - uint32 GetMinPlayersPerTeam() const { return m_MinPlayersPerTeam; }
  155. -
  156. - int32 GetStartDelayTime() const { return m_StartDelayTime; }
  157. - uint8 GetArenaType() const { return m_ArenaType; }
  158. - uint8 GetWinner() const { return m_Winner; }
  159. + char const* GetName() const { return m_Name; }
  160. + BattleGroundTypeId GetTypeID() const { return m_TypeID; }
  161. + uint8 GetQueueId() const { return m_QueueId; }
  162. + uint32 GetInstanceID() const { return m_InstanceID; }
  163. + BattleGroundStatus GetStatus() const { return m_Status; }
  164. + uint32 GetClientInstanceID() const { return m_ClientInstanceID; }
  165. + uint32 GetStartTime() const { return m_StartTime; }
  166. + uint32 GetEndTime() const { return m_EndTime; }
  167. + uint32 GetMaxPlayers() const { return m_MaxPlayers; }
  168. + uint32 GetMinPlayers() const { return m_MinPlayers; }
  169. +
  170. + uint32 GetMinLevel() const { return m_LevelMin; }
  171. + uint32 GetMaxLevel() const { return m_LevelMax; }
  172. +
  173. + uint32 GetMaxPlayersPerTeam() const { return m_MaxPlayersPerTeam; }
  174. + uint32 GetMinPlayersPerTeam() const { return m_MinPlayersPerTeam; }
  175. +
  176. + int32 GetStartDelayTime() const { return m_StartDelayTime; }
  177. + uint8 GetArenaType() const { return m_ArenaType; }
  178. + uint8 GetWinner() const { return m_Winner; }
  179. uint32 GetBattlemasterEntry() const;
  180. uint32 GetBonusHonorFromKill(uint32 kills) const;
  181.  
  182. @@ -334,11 +321,11 @@ class BattleGround
  183. void SetName(char const* Name) { m_Name = Name; }
  184. void SetTypeID(BattleGroundTypeId TypeID) { m_TypeID = TypeID; }
  185. //here we can count minlevel and maxlevel for players
  186. - void SetQueueId(BGQueueIdBasedOnLevel ID)
  187. + void SetQueueId(uint8 ID)
  188. {
  189. m_QueueId = ID;
  190. uint8 diff = (m_TypeID == BATTLEGROUND_AV) ? 1 : 0;
  191. - this->SetLevelRange((ID + 1) * 10 + diff, (ID + 2) * 10 - ((diff + 1) % 2));
  192. + SetLevelRange((ID + 1) * 10 + diff, (ID + 2) * 10 - ((diff + 1) % 2));
  193. }
  194. void SetInstanceID(uint32 InstanceID) { m_InstanceID = InstanceID; }
  195. void SetStatus(BattleGroundStatus Status) { m_Status = Status; }
  196. @@ -372,6 +359,7 @@ class BattleGround
  197. return m_InvitedHorde;
  198. }
  199. bool HasFreeSlots() const;
  200. + bool CanUnload(){ return m_SetDeleteThis; }
  201. uint32 GetFreeSlotsForTeam(uint32 Team) const;
  202.  
  203. bool isArena() const { return m_IsArena; }
  204. @@ -561,7 +549,7 @@ class BattleGround
  205.  
  206. BattleGroundScoreMap m_PlayerScores; // Player scores
  207. // must be implemented in BG subclass
  208. - virtual void RemovePlayer(Player * /*player*/, uint64 /*guid*/) {}
  209. + virtual void RemovePlayer(Player *player, uint64 guid);
  210.  
  211. /* Player lists, those need to be accessible by inherited classes */
  212. BattleGroundPlayerMap m_Players;
  213. @@ -585,7 +573,7 @@ class BattleGround
  214. uint32 m_StartTime;
  215. bool m_ArenaBuffSpawned; // to cache if arenabuff event is started (cause bool is faster than checking IsActiveEvent)
  216. int32 m_EndTime; // it is set to 120000 when bg is ending and it decreases itself
  217. - BGQueueIdBasedOnLevel m_QueueId;
  218. + uint8 m_QueueId;
  219. uint8 m_ArenaType; // 2=2v2, 3=3v3, 5=5v5
  220. bool m_InBGFreeSlotQueue; // used to make sure that BG is only once inserted into the BattleGroundMgr.BGFreeSlotQueue[bgTypeId] deque
  221. bool m_SetDeleteThis; // used for safe deletion of the bg after end / all players leave
  222. diff --git a/src/game/BattleGroundBE.cpp b/src/game/BattleGroundBE.cpp
  223. index fddc8bc..50fa9ad 100644
  224. --- a/src/game/BattleGroundBE.cpp
  225. +++ b/src/game/BattleGroundBE.cpp
  226. @@ -73,7 +73,7 @@ void BattleGroundBE::AddPlayer(Player *plr)
  227. UpdateWorldState(0x9f0, GetAlivePlayersCountByTeam(HORDE));
  228. }
  229.  
  230. -void BattleGroundBE::RemovePlayer(Player* /*plr*/, uint64 /*guid*/)
  231. +void BattleGroundBE::RemovePlayer(Player* player, uint64 guid)
  232. {
  233. if (GetStatus() == STATUS_WAIT_LEAVE)
  234. return;
  235. @@ -81,7 +81,7 @@ void BattleGroundBE::RemovePlayer(Player* /*plr*/, uint64 /*guid*/)
  236. UpdateWorldState(0x9f1, GetAlivePlayersCountByTeam(ALLIANCE));
  237. UpdateWorldState(0x9f0, GetAlivePlayersCountByTeam(HORDE));
  238.  
  239. - CheckArenaWinConditions();
  240. + BattleGround::RemovePlayer(player, guid);
  241. }
  242.  
  243. void BattleGroundBE::HandleKillPlayer(Player *player, Player *killer)
  244. @@ -99,8 +99,6 @@ void BattleGroundBE::HandleKillPlayer(Player *player, Player *killer)
  245.  
  246. UpdateWorldState(0x9f1, GetAlivePlayersCountByTeam(ALLIANCE));
  247. UpdateWorldState(0x9f0, GetAlivePlayersCountByTeam(HORDE));
  248. -
  249. - CheckArenaWinConditions();
  250. }
  251.  
  252. bool BattleGroundBE::HandlePlayerUnderMap(Player *player)
  253. diff --git a/src/game/BattleGroundDS.cpp b/src/game/BattleGroundDS.cpp
  254. index 78360b9..43c6f53 100644
  255. --- a/src/game/BattleGroundDS.cpp
  256. +++ b/src/game/BattleGroundDS.cpp
  257. @@ -19,6 +19,7 @@
  258. #include "Player.h"
  259. #include "BattleGround.h"
  260. #include "BattleGroundDS.h"
  261. +#include "WorldPacket.h"
  262. #include "Language.h"
  263.  
  264. BattleGroundDS::BattleGroundDS()
  265. @@ -51,6 +52,7 @@ void BattleGroundDS::StartingEventCloseDoors()
  266.  
  267. void BattleGroundDS::StartingEventOpenDoors()
  268. {
  269. + OpenDoorEvent(BG_EVENT_DOOR);
  270. }
  271.  
  272. void BattleGroundDS::AddPlayer(Player *plr)
  273. @@ -60,21 +62,49 @@ void BattleGroundDS::AddPlayer(Player *plr)
  274. BattleGroundDSScore* sc = new BattleGroundDSScore;
  275.  
  276. m_PlayerScores[plr->GetGUID()] = sc;
  277. -}
  278.  
  279. -void BattleGroundDS::RemovePlayer(Player * /*plr*/, uint64 /*guid*/)
  280. -{
  281. + UpdateWorldState(0xe11, GetAlivePlayersCountByTeam(ALLIANCE));
  282. + UpdateWorldState(0xe10, GetAlivePlayersCountByTeam(HORDE));
  283. }
  284.  
  285. -void BattleGroundDS::HandleKillPlayer(Player* player, Player* killer)
  286. -{
  287. +void BattleGroundDS::RemovePlayer(Player * player, uint64 guid)
  288. + {
  289. + if (GetStatus() == STATUS_WAIT_LEAVE)
  290. + return;
  291. +
  292. + UpdateWorldState(0xe11, GetAlivePlayersCountByTeam(ALLIANCE));
  293. + UpdateWorldState(0xe10, GetAlivePlayersCountByTeam(HORDE));
  294. +
  295. + BattleGround::RemovePlayer(player, guid);
  296. + }
  297. +
  298. + void BattleGroundDS::HandleKillPlayer(Player* player, Player* killer)
  299. + {
  300. + if (GetStatus() != STATUS_IN_PROGRESS)
  301. + return;
  302. +
  303. + if (!killer)
  304. + {
  305. + sLog.outError("BattleGroundDS: Killer player not found");
  306. + return;
  307. + }
  308. +
  309. BattleGround::HandleKillPlayer(player, killer);
  310. -}
  311. + UpdateWorldState(0xe11, GetAlivePlayersCountByTeam(ALLIANCE));
  312. + UpdateWorldState(0xe10, GetAlivePlayersCountByTeam(HORDE));
  313. + }
  314.  
  315. void BattleGroundDS::HandleAreaTrigger(Player * /*Source*/, uint32 /*Trigger*/)
  316. {
  317. }
  318.  
  319. +void BattleGroundDS::FillInitialWorldStates(WorldPacket &data)
  320. +{
  321. + data << uint32(0xe11) << uint32(GetAlivePlayersCountByTeam(ALLIANCE)); // 7
  322. + data << uint32(0xe10) << uint32(GetAlivePlayersCountByTeam(HORDE)); // 8
  323. + data << uint32(0xe1a) << uint32(1); // 9
  324. +}
  325. +
  326. bool BattleGroundDS::SetupBattleGround()
  327. {
  328. return true;
  329. diff --git a/src/game/BattleGroundDS.h b/src/game/BattleGroundDS.h
  330. index 44a6cfb..3097e4f 100644
  331. --- a/src/game/BattleGroundDS.h
  332. +++ b/src/game/BattleGroundDS.h
  333. @@ -45,6 +45,7 @@ class BattleGroundDS : public BattleGround
  334. void RemovePlayer(Player *plr, uint64 guid);
  335. void HandleAreaTrigger(Player *Source, uint32 Trigger);
  336. bool SetupBattleGround();
  337. + virtual void FillInitialWorldStates(WorldPacket &d);
  338. void HandleKillPlayer(Player* player, Player *killer);
  339. };
  340. #endif
  341. diff --git a/src/game/BattleGroundHandler.cpp b/src/game/BattleGroundHandler.cpp
  342. index f6d3229..8f83701 100644
  343. --- a/src/game/BattleGroundHandler.cpp
  344. +++ b/src/game/BattleGroundHandler.cpp
  345. @@ -104,7 +104,7 @@ void WorldSession::HandleBattlemasterJoinOpcode( WorldPacket & recv_data )
  346. // get bg instance or bg template if instance not found
  347. BattleGround *bg = NULL;
  348. if (instanceId)
  349. - bg = sBattleGroundMgr.GetBattleGroundThroughClientInstance(instanceId, bgTypeId);
  350. + bg = sBattleGroundMgr.GetBattleGround(instanceId, bgTypeId, _player->GetBGLevelQueueId());
  351.  
  352. if (!bg && !(bg = sBattleGroundMgr.GetBattleGroundTemplate(bgTypeId)))
  353. {
  354. @@ -153,7 +153,7 @@ void WorldSession::HandleBattlemasterJoinOpcode( WorldPacket & recv_data )
  355. {
  356. sLog.outDebug("Battleground: the following players are joining as group:");
  357. GroupQueueInfo * ginfo = bgQueue.AddGroup(_player, grp, bgTypeId, 0, false, isPremade, 0);
  358. - uint32 avgTime = bgQueue.GetAverageQueueWaitTime(ginfo, _player->GetBattleGroundQueueIdFromLevel());
  359. + uint32 avgTime = bgQueue.GetAverageQueueWaitTime(ginfo, _player->GetBGLevelQueueId());
  360. for(GroupReference *itr = grp->GetFirstMember(); itr != NULL; itr = itr->next())
  361. {
  362. Player *member = itr->getSource();
  363. @@ -174,7 +174,7 @@ void WorldSession::HandleBattlemasterJoinOpcode( WorldPacket & recv_data )
  364. else
  365. {
  366. GroupQueueInfo * ginfo = bgQueue.AddGroup(_player, NULL, bgTypeId, 0, false, isPremade, 0);
  367. - uint32 avgTime = bgQueue.GetAverageQueueWaitTime(ginfo, _player->GetBattleGroundQueueIdFromLevel());
  368. + uint32 avgTime = bgQueue.GetAverageQueueWaitTime(ginfo, _player->GetBGLevelQueueId());
  369. // already checked if queueSlot is valid, now just get it
  370. uint32 queueSlot = _player->AddBattleGroundQueueId(bgQueueTypeId);
  371.  
  372. @@ -184,7 +184,7 @@ void WorldSession::HandleBattlemasterJoinOpcode( WorldPacket & recv_data )
  373. SendPacket(&data);
  374. sLog.outDebug("Battleground: player joined queue for bg queue type %u bg type %u: GUID %u, NAME %s",bgQueueTypeId,bgTypeId,_player->GetGUIDLow(), _player->GetName());
  375. }
  376. - sBattleGroundMgr.ScheduleQueueUpdate(0, 0, bgQueueTypeId, bgTypeId, _player->GetBattleGroundQueueIdFromLevel());
  377. + sBattleGroundMgr.ScheduleQueueUpdate(0, 0, bgQueueTypeId, bgTypeId, _player->GetBGLevelQueueId());
  378. }
  379.  
  380. void WorldSession::HandleBattleGroundPlayerPositionsOpcode( WorldPacket & /*recv_data*/ )
  381. @@ -427,7 +427,7 @@ void WorldSession::HandleBattleFieldPortOpcode( WorldPacket &recv_data )
  382. bgQueue.RemovePlayer(_player->GetGUID(), true);
  383. // player left queue, we should update it - do not update Arena Queue
  384. if (!ginfo.ArenaType)
  385. - sBattleGroundMgr.ScheduleQueueUpdate(ginfo.ArenaTeamRating, ginfo.ArenaType, bgQueueTypeId, bgTypeId, _player->GetBattleGroundQueueIdFromLevel());
  386. + sBattleGroundMgr.ScheduleQueueUpdate(ginfo.ArenaTeamRating, ginfo.ArenaType, bgQueueTypeId, bgTypeId, _player->GetBGLevelQueueId());
  387. SendPacket(&data);
  388. sLog.outDebug("Battleground: player %s (%u) left queue for bgtype %u, queue type %u.", _player->GetName(), _player->GetGUIDLow(), bg->GetTypeID(), bgQueueTypeId);
  389. break;
  390. @@ -509,7 +509,7 @@ void WorldSession::HandleBattlefieldStatusOpcode( WorldPacket & /*recv_data*/ )
  391. bg = sBattleGroundMgr.GetBattleGroundTemplate(bgTypeId);
  392. if (!bg)
  393. continue;
  394. - uint32 avgTime = bgQueue.GetAverageQueueWaitTime(&ginfo, _player->GetBattleGroundQueueIdFromLevel());
  395. + uint32 avgTime = bgQueue.GetAverageQueueWaitTime(&ginfo, _player->GetBGLevelQueueId());
  396. // send status in BattleGround Queue
  397. sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, i, STATUS_WAIT_QUEUE, avgTime, getMSTimeDiff(ginfo.JoinTime, getMSTime()), arenaType);
  398. SendPacket(&data);
  399. @@ -679,7 +679,7 @@ void WorldSession::HandleBattlemasterJoinArena( WorldPacket & recv_data )
  400. sLog.outDebug("Battleground: arena team id %u, leader %s queued with rating %u for type %u",_player->GetArenaTeamId(arenaslot),_player->GetName(),arenaRating,arenatype);
  401.  
  402. GroupQueueInfo * ginfo = bgQueue.AddGroup(_player, grp, bgTypeId, arenatype, isRated, false, arenaRating, ateamId);
  403. - uint32 avgTime = bgQueue.GetAverageQueueWaitTime(ginfo, _player->GetBattleGroundQueueIdFromLevel());
  404. + uint32 avgTime = bgQueue.GetAverageQueueWaitTime(ginfo, _player->GetBGLevelQueueId());
  405. for(GroupReference *itr = grp->GetFirstMember(); itr != NULL; itr = itr->next())
  406. {
  407. Player *member = itr->getSource();
  408. @@ -701,7 +701,7 @@ void WorldSession::HandleBattlemasterJoinArena( WorldPacket & recv_data )
  409. else
  410. {
  411. GroupQueueInfo * ginfo = bgQueue.AddGroup(_player, NULL, bgTypeId, arenatype, isRated, false, arenaRating, ateamId);
  412. - uint32 avgTime = bgQueue.GetAverageQueueWaitTime(ginfo, _player->GetBattleGroundQueueIdFromLevel());
  413. + uint32 avgTime = bgQueue.GetAverageQueueWaitTime(ginfo, _player->GetBGLevelQueueId());
  414. uint32 queueSlot = _player->AddBattleGroundQueueId(bgQueueTypeId);
  415.  
  416. WorldPacket data;
  417. @@ -710,7 +710,7 @@ void WorldSession::HandleBattlemasterJoinArena( WorldPacket & recv_data )
  418. SendPacket(&data);
  419. sLog.outDebug("Battleground: player joined queue for arena, skirmish, bg queue type %u bg type %u: GUID %u, NAME %s",bgQueueTypeId,bgTypeId,_player->GetGUIDLow(), _player->GetName());
  420. }
  421. - sBattleGroundMgr.ScheduleQueueUpdate(arenaRating, arenatype, bgQueueTypeId, bgTypeId, _player->GetBattleGroundQueueIdFromLevel());
  422. + sBattleGroundMgr.ScheduleQueueUpdate(arenaRating, arenatype, bgQueueTypeId, bgTypeId, _player->GetBGLevelQueueId());
  423. }
  424.  
  425. void WorldSession::HandleReportPvPAFK( WorldPacket & recv_data )
  426. diff --git a/src/game/BattleGroundMgr.cpp b/src/game/BattleGroundMgr.cpp
  427. index 44014c4..66f16f3 100644
  428. --- a/src/game/BattleGroundMgr.cpp
  429. +++ b/src/game/BattleGroundMgr.cpp
  430. @@ -54,12 +54,19 @@ INSTANTIATE_SINGLETON_1( BattleGroundMgr );
  431.  
  432. BattleGroundQueue::BattleGroundQueue()
  433. {
  434. + uint8 MaxQueueId = BattleGroundMgr::GetMaxQueueId();
  435. +
  436. + m_QueuedGroups.resize(MaxQueueId);
  437. + for(uint8 p = 0; p < MaxQueueId; p++)
  438. + m_QueuedGroups[p].resize(BG_QUEUE_GROUP_TYPES_COUNT);
  439. +
  440. for(uint32 i = 0; i < BG_TEAMS_COUNT; i++)
  441. {
  442. - for(uint32 j = 0; j < MAX_BATTLEGROUND_QUEUES; j++)
  443. + for(uint32 j = 0; j < MaxQueueId; j++)
  444. {
  445. m_SumOfWaitTimes[i][j] = 0;
  446. m_WaitTimeLastPlayer[i][j] = 0;
  447. + m_WaitTimes[i][j].resize(COUNT_OF_PLAYERS_TO_AVERAGE_WAIT_TIME);
  448. for(uint32 k = 0; k < COUNT_OF_PLAYERS_TO_AVERAGE_WAIT_TIME; k++)
  449. m_WaitTimes[i][j][k] = 0;
  450. }
  451. @@ -69,16 +76,20 @@ BattleGroundQueue::BattleGroundQueue()
  452. BattleGroundQueue::~BattleGroundQueue()
  453. {
  454. m_QueuedPlayers.clear();
  455. - for (int i = 0; i < MAX_BATTLEGROUND_QUEUES; i++)
  456. +
  457. + uint32 MaxQueueId = sBattleGroundMgr.GetMaxQueueId();
  458. + for (int i = 0; i < MaxQueueId; i++)
  459. {
  460. for(uint32 j = 0; j < BG_QUEUE_GROUP_TYPES_COUNT; j++)
  461. {
  462. - for(GroupsQueueType::iterator itr = m_QueuedGroups[i][j].begin(); itr!= m_QueuedGroups[i][j].end(); ++itr)
  463. + for(GroupQueueInfoList::iterator itr = m_QueuedGroups[i][j].begin(); itr!= m_QueuedGroups[i][j].end(); ++itr)
  464. delete (*itr);
  465. m_QueuedGroups[i][j].clear();
  466. }
  467. - }
  468. -}
  469. + m_QueuedGroups[i].clear();
  470. + }
  471. + m_QueuedGroups.clear();
  472. + }
  473.  
  474. /*********************************************************/
  475. /*** BATTLEGROUND QUEUE SELECTION POOLS ***/
  476. @@ -99,8 +110,8 @@ bool BattleGroundQueue::SelectionPool::KickGroup(uint32 size)
  477. {
  478. //find maxgroup or LAST group with size == size and kick it
  479. bool found = false;
  480. - GroupsQueueType::iterator groupToKick = SelectedGroups.begin();
  481. - for (GroupsQueueType::iterator itr = groupToKick; itr != SelectedGroups.end(); ++itr)
  482. + GroupQueueInfoList::iterator groupToKick = SelectedGroups.begin();
  483. + for (GroupQueueInfoList::iterator itr = groupToKick; itr != SelectedGroups.end(); ++itr)
  484. {
  485. if (abs((int32)((*itr)->Players.size() - size)) <= 1)
  486. {
  487. @@ -150,7 +161,7 @@ bool BattleGroundQueue::SelectionPool::AddGroup(GroupQueueInfo *ginfo, uint32 de
  488. // add group or player (grp == NULL) to bg queue with the given leader and bg specifications
  489. GroupQueueInfo * BattleGroundQueue::AddGroup(Player *leader, Group* grp, BattleGroundTypeId BgTypeId, uint8 ArenaType, bool isRated, bool isPremade, uint32 arenaRating, uint32 arenateamid)
  490. {
  491. - BGQueueIdBasedOnLevel queue_id = leader->GetBattleGroundQueueIdFromLevel();
  492. + uint8 queue_id = leader->GetBGLevelQueueId();
  493.  
  494. // create new ginfo
  495. GroupQueueInfo* ginfo = new GroupQueueInfo;
  496. @@ -222,7 +233,7 @@ GroupQueueInfo * BattleGroundQueue::AddGroup(Player *leader, Group* grp, BattleG
  497. uint32 qHorde = 0;
  498. uint32 qAlliance = 0;
  499. uint32 q_min_level = (queue_id + 1) * 10;
  500. - GroupsQueueType::const_iterator itr;
  501. + GroupQueueInfoList::const_iterator itr;
  502. for(itr = m_QueuedGroups[queue_id][BG_QUEUE_NORMAL_ALLIANCE].begin(); itr != m_QueuedGroups[queue_id][BG_QUEUE_NORMAL_ALLIANCE].end(); ++itr)
  503. if (!(*itr)->IsInvitedToBGInstanceGUID)
  504. qAlliance += (*itr)->Players.size();
  505. @@ -250,7 +261,7 @@ GroupQueueInfo * BattleGroundQueue::AddGroup(Player *leader, Group* grp, BattleG
  506. return ginfo;
  507. }
  508.  
  509. -void BattleGroundQueue::PlayerInvitedToBGUpdateAverageWaitTime(GroupQueueInfo* ginfo, BGQueueIdBasedOnLevel queue_id)
  510. +void BattleGroundQueue::PlayerInvitedToBGUpdateAverageWaitTime(GroupQueueInfo* ginfo, uint8 queue_id)
  511. {
  512. uint32 timeInQueue = getMSTimeDiff(ginfo->JoinTime, getMSTime());
  513. uint8 team_index = BG_TEAM_ALLIANCE; //default set to BG_TEAM_ALLIANCE - or non rated arenas!
  514. @@ -278,7 +289,7 @@ void BattleGroundQueue::PlayerInvitedToBGUpdateAverageWaitTime(GroupQueueInfo* g
  515. (*lastPlayerAddedPointer) %= COUNT_OF_PLAYERS_TO_AVERAGE_WAIT_TIME;
  516. }
  517.  
  518. -uint32 BattleGroundQueue::GetAverageQueueWaitTime(GroupQueueInfo* ginfo, BGQueueIdBasedOnLevel queue_id)
  519. +uint32 BattleGroundQueue::GetAverageQueueWaitTime(GroupQueueInfo* ginfo, uint8 queue_id)
  520. {
  521. uint8 team_index = BG_TEAM_ALLIANCE; //default set to BG_TEAM_ALLIANCE - or non rated arenas!
  522. if (!ginfo->ArenaType)
  523. @@ -317,13 +328,13 @@ void BattleGroundQueue::RemovePlayer(const uint64& guid, bool decreaseInvitedCou
  524. }
  525.  
  526. GroupQueueInfo* group = itr->second.GroupInfo;
  527. - GroupsQueueType::iterator group_itr, group_itr_tmp;
  528. + GroupQueueInfoList::iterator group_itr, group_itr_tmp;
  529. // mostly people with the highest levels are in battlegrounds, thats why
  530. // we count from MAX_BATTLEGROUND_QUEUES - 1 to 0
  531. // variable index removes useless searching in other team's queue
  532. uint32 index = (group->Team == HORDE) ? BG_TEAM_HORDE : BG_TEAM_ALLIANCE;
  533.  
  534. - for (int32 queue_id_tmp = MAX_BATTLEGROUND_QUEUES - 1; queue_id_tmp >= 0 && queue_id == -1; --queue_id_tmp)
  535. + for (int32 queue_id_tmp = sBattleGroundMgr.GetMaxQueueId() - 1; queue_id_tmp >= 0 && queue_id == -1; --queue_id_tmp)
  536. {
  537. //we must check premade and normal team's queue - because when players from premade are joining bg,
  538. //they leave groupinfo so we can't use its players size to find out index
  539. @@ -453,7 +464,7 @@ bool BattleGroundQueue::InviteGroupToBG(GroupQueueInfo * ginfo, BattleGround * b
  540. ginfo->IsInvitedToBGInstanceGUID = bg->GetInstanceID();
  541. BattleGroundTypeId bgTypeId = bg->GetTypeID();
  542. BattleGroundQueueTypeId bgQueueTypeId = BattleGroundMgr::BGQueueTypeId(bgTypeId, bg->GetArenaType());
  543. - BGQueueIdBasedOnLevel queue_id = bg->GetQueueId();
  544. + uint8 queue_id = bg->GetQueueId();
  545.  
  546. // set ArenaTeamId for rated matches
  547. if (bg->isArena() && bg->isRated())
  548. @@ -507,13 +518,13 @@ This function is inviting players to already running battlegrounds
  549. Invitation type is based on config file
  550. large groups are disadvantageous, because they will be kicked first if invitation type = 1
  551. */
  552. -void BattleGroundQueue::FillPlayersToBG(BattleGround* bg, BGQueueIdBasedOnLevel queue_id)
  553. +void BattleGroundQueue::FillPlayersToBG(BattleGround* bg, uint8 queue_id)
  554. {
  555. int32 hordeFree = bg->GetFreeSlotsForTeam(HORDE);
  556. int32 aliFree = bg->GetFreeSlotsForTeam(ALLIANCE);
  557.  
  558. //iterator for iterating through bg queue
  559. - GroupsQueueType::const_iterator Ali_itr = m_QueuedGroups[queue_id][BG_QUEUE_NORMAL_ALLIANCE].begin();
  560. + GroupQueueInfoList::const_iterator Ali_itr = m_QueuedGroups[queue_id][BG_QUEUE_NORMAL_ALLIANCE].begin();
  561. //count of groups in queue - used to stop cycles
  562. uint32 aliCount = m_QueuedGroups[queue_id][BG_QUEUE_NORMAL_ALLIANCE].size();
  563. //index to queue which group is current
  564. @@ -521,7 +532,7 @@ void BattleGroundQueue::FillPlayersToBG(BattleGround* bg, BGQueueIdBasedOnLevel
  565. for (; aliIndex < aliCount && m_SelectionPools[BG_TEAM_ALLIANCE].AddGroup((*Ali_itr), aliFree); aliIndex++)
  566. ++Ali_itr;
  567. //the same thing for horde
  568. - GroupsQueueType::const_iterator Horde_itr = m_QueuedGroups[queue_id][BG_QUEUE_NORMAL_HORDE].begin();
  569. + GroupQueueInfoList::const_iterator Horde_itr = m_QueuedGroups[queue_id][BG_QUEUE_NORMAL_HORDE].begin();
  570. uint32 hordeCount = m_QueuedGroups[queue_id][BG_QUEUE_NORMAL_HORDE].size();
  571. uint32 hordeIndex = 0;
  572. for (; hordeIndex < hordeCount && m_SelectionPools[BG_TEAM_HORDE].AddGroup((*Horde_itr), hordeFree); hordeIndex++)
  573. @@ -585,14 +596,14 @@ void BattleGroundQueue::FillPlayersToBG(BattleGround* bg, BGQueueIdBasedOnLevel
  574. // this method checks if premade versus premade battleground is possible
  575. // then after 30 mins (default) in queue it moves premade group to normal queue
  576. // it tries to invite as much players as it can - to MaxPlayersPerTeam, because premade groups have more than MinPlayersPerTeam players
  577. -bool BattleGroundQueue::CheckPremadeMatch(BGQueueIdBasedOnLevel queue_id, uint32 MinPlayersPerTeam, uint32 MaxPlayersPerTeam)
  578. +bool BattleGroundQueue::CheckPremadeMatch(uint8 queue_id, uint32 MinPlayersPerTeam, uint32 MaxPlayersPerTeam)
  579. {
  580. //check match
  581. if (!m_QueuedGroups[queue_id][BG_QUEUE_PREMADE_ALLIANCE].empty() && !m_QueuedGroups[queue_id][BG_QUEUE_PREMADE_HORDE].empty())
  582. {
  583. //start premade match
  584. //if groups aren't invited
  585. - GroupsQueueType::const_iterator ali_group, horde_group;
  586. + GroupQueueInfoList::const_iterator ali_group, horde_group;
  587. for( ali_group = m_QueuedGroups[queue_id][BG_QUEUE_PREMADE_ALLIANCE].begin(); ali_group != m_QueuedGroups[queue_id][BG_QUEUE_PREMADE_ALLIANCE].end(); ++ali_group)
  588. if (!(*ali_group)->IsInvitedToBGInstanceGUID)
  589. break;
  590. @@ -606,7 +617,7 @@ bool BattleGroundQueue::CheckPremadeMatch(BGQueueIdBasedOnLevel queue_id, uint32
  591. m_SelectionPools[BG_TEAM_HORDE].AddGroup((*horde_group), MaxPlayersPerTeam);
  592. //add groups/players from normal queue to size of bigger group
  593. uint32 maxPlayers = std::max(m_SelectionPools[BG_TEAM_ALLIANCE].GetPlayerCount(), m_SelectionPools[BG_TEAM_HORDE].GetPlayerCount());
  594. - GroupsQueueType::const_iterator itr;
  595. + GroupQueueInfoList::const_iterator itr;
  596. for(uint32 i = 0; i < BG_TEAMS_COUNT; i++)
  597. {
  598. for(itr = m_QueuedGroups[queue_id][BG_QUEUE_NORMAL_ALLIANCE + i].begin(); itr != m_QueuedGroups[queue_id][BG_QUEUE_NORMAL_ALLIANCE + i].end(); ++itr)
  599. @@ -629,7 +640,7 @@ bool BattleGroundQueue::CheckPremadeMatch(BGQueueIdBasedOnLevel queue_id, uint32
  600. {
  601. if (!m_QueuedGroups[queue_id][BG_QUEUE_PREMADE_ALLIANCE + i].empty())
  602. {
  603. - GroupsQueueType::iterator itr = m_QueuedGroups[queue_id][BG_QUEUE_PREMADE_ALLIANCE + i].begin();
  604. + GroupQueueInfoList::iterator itr = m_QueuedGroups[queue_id][BG_QUEUE_PREMADE_ALLIANCE + i].begin();
  605. if (!(*itr)->IsInvitedToBGInstanceGUID && ((*itr)->JoinTime < time_before || (*itr)->Players.size() < MinPlayersPerTeam))
  606. {
  607. //we must insert group to normal queue and erase pointer from premade queue
  608. @@ -643,9 +654,9 @@ bool BattleGroundQueue::CheckPremadeMatch(BGQueueIdBasedOnLevel queue_id, uint32
  609. }
  610.  
  611. // this method tries to create battleground or arena with MinPlayersPerTeam against MinPlayersPerTeam
  612. -bool BattleGroundQueue::CheckNormalMatch(BattleGround* bg_template, BGQueueIdBasedOnLevel queue_id, uint32 minPlayers, uint32 maxPlayers)
  613. +bool BattleGroundQueue::CheckNormalMatch(BattleGround* bg_template, uint8 queue_id, uint32 minPlayers, uint32 maxPlayers)
  614. {
  615. - GroupsQueueType::const_iterator itr_team[BG_TEAMS_COUNT];
  616. + GroupQueueInfoList::const_iterator itr_team[BG_TEAMS_COUNT];
  617. for(uint32 i = 0; i < BG_TEAMS_COUNT; i++)
  618. {
  619. itr_team[i] = m_QueuedGroups[queue_id][BG_QUEUE_NORMAL_ALLIANCE + i].begin();
  620. @@ -686,7 +697,7 @@ bool BattleGroundQueue::CheckNormalMatch(BattleGround* bg_template, BGQueueIdBas
  621. }
  622.  
  623. // this method will check if we can invite players to same faction skirmish match
  624. -bool BattleGroundQueue::CheckSkirmishForSameFaction(BGQueueIdBasedOnLevel queue_id, uint32 minPlayersPerTeam)
  625. +bool BattleGroundQueue::CheckSkirmishForSameFaction(uint8 queue_id, uint32 minPlayersPerTeam)
  626. {
  627. if (m_SelectionPools[BG_TEAM_ALLIANCE].GetPlayerCount() < minPlayersPerTeam && m_SelectionPools[BG_TEAM_HORDE].GetPlayerCount() < minPlayersPerTeam)
  628. return false;
  629. @@ -704,13 +715,13 @@ bool BattleGroundQueue::CheckSkirmishForSameFaction(BGQueueIdBasedOnLevel queue_
  630. //store last ginfo pointer
  631. GroupQueueInfo* ginfo = m_SelectionPools[teamIndex].SelectedGroups.back();
  632. //set itr_team to group that was added to selection pool latest
  633. - GroupsQueueType::iterator itr_team = m_QueuedGroups[queue_id][BG_QUEUE_NORMAL_ALLIANCE + teamIndex].begin();
  634. + GroupQueueInfoList::iterator itr_team = m_QueuedGroups[queue_id][BG_QUEUE_NORMAL_ALLIANCE + teamIndex].begin();
  635. for(; itr_team != m_QueuedGroups[queue_id][BG_QUEUE_NORMAL_ALLIANCE + teamIndex].end(); ++itr_team)
  636. if (ginfo == *itr_team)
  637. break;
  638. if (itr_team == m_QueuedGroups[queue_id][BG_QUEUE_NORMAL_ALLIANCE + teamIndex].end())
  639. return false;
  640. - GroupsQueueType::iterator itr_team2 = itr_team;
  641. + GroupQueueInfoList::iterator itr_team2 = itr_team;
  642. ++itr_team2;
  643. //invite players to other selection pool
  644. for(; itr_team2 != m_QueuedGroups[queue_id][BG_QUEUE_NORMAL_ALLIANCE + teamIndex].end(); ++itr_team2)
  645. @@ -723,14 +734,14 @@ bool BattleGroundQueue::CheckSkirmishForSameFaction(BGQueueIdBasedOnLevel queue_
  646. return false;
  647.  
  648. //here we have correct 2 selections and we need to change one teams team and move selection pool teams to other team's queue
  649. - for(GroupsQueueType::iterator itr = m_SelectionPools[otherTeam].SelectedGroups.begin(); itr != m_SelectionPools[otherTeam].SelectedGroups.end(); ++itr)
  650. + for(GroupQueueInfoList::iterator itr = m_SelectionPools[otherTeam].SelectedGroups.begin(); itr != m_SelectionPools[otherTeam].SelectedGroups.end(); ++itr)
  651. {
  652. //set correct team
  653. (*itr)->Team = otherTeamId;
  654. //add team to other queue
  655. m_QueuedGroups[queue_id][BG_QUEUE_NORMAL_ALLIANCE + otherTeam].push_front(*itr);
  656. //remove team from old queue
  657. - GroupsQueueType::iterator itr2 = itr_team;
  658. + GroupQueueInfoList::iterator itr2 = itr_team;
  659. ++itr2;
  660. for(; itr2 != m_QueuedGroups[queue_id][BG_QUEUE_NORMAL_ALLIANCE + teamIndex].end(); ++itr2)
  661. {
  662. @@ -749,7 +760,7 @@ this method is called when group is inserted, or player / group is removed from
  663. it must be called after fully adding the members of a group to ensure group joining
  664. should be called from BattleGround::RemovePlayer function in some cases
  665. */
  666. -void BattleGroundQueue::Update(BattleGroundTypeId bgTypeId, BGQueueIdBasedOnLevel queue_id, uint8 arenaType, bool isRated, uint32 arenaRating)
  667. +void BattleGroundQueue::Update(BattleGroundTypeId bgTypeId, uint8 queue_id, uint8 arenaType, bool isRated, uint32 arenaRating)
  668. {
  669. //ACE_Guard<ACE_Recursive_Thread_Mutex> guard(m_Lock);
  670. //if no players in queue - do nothing
  671. @@ -781,9 +792,9 @@ void BattleGroundQueue::Update(BattleGroundTypeId bgTypeId, BGQueueIdBasedOnLeve
  672. FillPlayersToBG(bg, queue_id);
  673.  
  674. // now everything is set, invite players
  675. - for(GroupsQueueType::const_iterator citr = m_SelectionPools[BG_TEAM_ALLIANCE].SelectedGroups.begin(); citr != m_SelectionPools[BG_TEAM_ALLIANCE].SelectedGroups.end(); ++citr)
  676. + for(GroupQueueInfoList::const_iterator citr = m_SelectionPools[BG_TEAM_ALLIANCE].SelectedGroups.begin(); citr != m_SelectionPools[BG_TEAM_ALLIANCE].SelectedGroups.end(); ++citr)
  677. InviteGroupToBG((*citr), bg, (*citr)->Team);
  678. - for(GroupsQueueType::const_iterator citr = m_SelectionPools[BG_TEAM_HORDE].SelectedGroups.begin(); citr != m_SelectionPools[BG_TEAM_HORDE].SelectedGroups.end(); ++citr)
  679. + for(GroupQueueInfoList::const_iterator citr = m_SelectionPools[BG_TEAM_HORDE].SelectedGroups.begin(); citr != m_SelectionPools[BG_TEAM_HORDE].SelectedGroups.end(); ++citr)
  680. InviteGroupToBG((*citr), bg, (*citr)->Team);
  681.  
  682. if (!bg->HasFreeSlots())
  683. @@ -810,31 +821,9 @@ void BattleGroundQueue::Update(BattleGroundTypeId bgTypeId, BGQueueIdBasedOnLeve
  684. if (bg_template->isArena())
  685. {
  686. if (sBattleGroundMgr.isArenaTesting())
  687. - {
  688. - MaxPlayersPerTeam = 1;
  689. - MinPlayersPerTeam = 1;
  690. - }
  691. + MaxPlayersPerTeam = MinPlayersPerTeam = 1;
  692. else
  693. - {
  694. - //this switch can be much shorter
  695. - MaxPlayersPerTeam = arenaType;
  696. - MinPlayersPerTeam = arenaType;
  697. - /*switch(arenaType)
  698. - {
  699. - case ARENA_TYPE_2v2:
  700. - MaxPlayersPerTeam = 2;
  701. - MinPlayersPerTeam = 2;
  702. - break;
  703. - case ARENA_TYPE_3v3:
  704. - MaxPlayersPerTeam = 3;
  705. - MinPlayersPerTeam = 3;
  706. - break;
  707. - case ARENA_TYPE_5v5:
  708. - MaxPlayersPerTeam = 5;
  709. - MinPlayersPerTeam = 5;
  710. - break;
  711. - }*/
  712. - }
  713. + MaxPlayersPerTeam = MinPlayersPerTeam = arenaType;
  714. }
  715.  
  716. m_SelectionPools[BG_TEAM_ALLIANCE].Init();
  717. @@ -854,7 +843,7 @@ void BattleGroundQueue::Update(BattleGroundTypeId bgTypeId, BGQueueIdBasedOnLeve
  718. }
  719. //invite those selection pools
  720. for(uint32 i = 0; i < BG_TEAMS_COUNT; i++)
  721. - for(GroupsQueueType::const_iterator citr = m_SelectionPools[BG_TEAM_ALLIANCE + i].SelectedGroups.begin(); citr != m_SelectionPools[BG_TEAM_ALLIANCE + i].SelectedGroups.end(); ++citr)
  722. + for(GroupQueueInfoList::const_iterator citr = m_SelectionPools[BG_TEAM_ALLIANCE + i].SelectedGroups.begin(); citr != m_SelectionPools[BG_TEAM_ALLIANCE + i].SelectedGroups.end(); ++citr)
  723. InviteGroupToBG((*citr), bg2, (*citr)->Team);
  724. //start bg
  725. bg2->StartBattleGround();
  726. @@ -881,7 +870,7 @@ void BattleGroundQueue::Update(BattleGroundTypeId bgTypeId, BGQueueIdBasedOnLeve
  727.  
  728. // invite those selection pools
  729. for(uint32 i = 0; i < BG_TEAMS_COUNT; i++)
  730. - for(GroupsQueueType::const_iterator citr = m_SelectionPools[BG_TEAM_ALLIANCE + i].SelectedGroups.begin(); citr != m_SelectionPools[BG_TEAM_ALLIANCE + i].SelectedGroups.end(); ++citr)
  731. + for(GroupQueueInfoList::const_iterator citr = m_SelectionPools[BG_TEAM_ALLIANCE + i].SelectedGroups.begin(); citr != m_SelectionPools[BG_TEAM_ALLIANCE + i].SelectedGroups.end(); ++citr)
  732. InviteGroupToBG((*citr), bg2, (*citr)->Team);
  733. // start bg
  734. bg2->StartBattleGround();
  735. @@ -926,7 +915,7 @@ void BattleGroundQueue::Update(BattleGroundTypeId bgTypeId, BGQueueIdBasedOnLeve
  736.  
  737. // we need to find 2 teams which will play next game
  738.  
  739. - GroupsQueueType::iterator itr_team[BG_TEAMS_COUNT];
  740. + GroupQueueInfoList::iterator itr_team[BG_TEAMS_COUNT];
  741.  
  742. //optimalization : --- we dont need to use selection_pools - each update we select max 2 groups
  743.  
  744. @@ -1117,8 +1106,6 @@ void BGQueueRemoveEvent::Abort(uint64 /*e_time*/)
  745.  
  746. BattleGroundMgr::BattleGroundMgr() : m_AutoDistributionTimeChecker(0), m_ArenaTesting(false)
  747. {
  748. - for(uint32 i = BATTLEGROUND_TYPE_NONE; i < MAX_BATTLEGROUND_TYPE_ID; i++)
  749. - m_BattleGrounds[i].clear();
  750. m_NextRatingDiscardUpdate = sWorld.getConfig(CONFIG_ARENA_RATING_DISCARD_TIMER);
  751. m_Testing=false;
  752. }
  753. @@ -1130,54 +1117,63 @@ BattleGroundMgr::~BattleGroundMgr()
  754.  
  755. void BattleGroundMgr::DeleteAllBattleGrounds()
  756. {
  757. - for(uint32 i = BATTLEGROUND_TYPE_NONE; i < MAX_BATTLEGROUND_TYPE_ID; i++)
  758. + // destroy template battlegrounds that listed only in queues (other already terminated)
  759. +
  760. + for(MapBattleGround::iterator itr = m_BattleGrounds.begin(); itr != m_BattleGrounds.end(); itr++)
  761. {
  762. - for(BattleGroundSet::iterator itr = m_BattleGrounds[i].begin(); itr != m_BattleGrounds[i].end();)
  763. + for(BattleGroundSet::iterator itr_bg = itr->second.begin(); itr_bg != itr->second.end(); itr_bg++)
  764. {
  765. - BattleGround * bg = itr->second;
  766. - m_BattleGrounds[i].erase(itr++);
  767. - if (!m_ClientBattleGroundIds[i][bg->GetQueueId()].empty())
  768. - m_ClientBattleGroundIds[i][bg->GetQueueId()].erase(bg->GetClientInstanceID());
  769. + BattleGround * bg = itr_bg->second;
  770. + uint8 BgQueueId = bg->GetQueueId();
  771. + BattleGroundTypeId bgTypeId = bg->GetTypeID();
  772. +
  773. + itr->second.erase(itr_bg);
  774. + if (m_ClientBattleGroundIds.find(bgTypeId) != m_ClientBattleGroundIds.end() &&
  775. + m_ClientBattleGroundIds[bgTypeId].find(BgQueueId) != m_ClientBattleGroundIds[bgTypeId].end())
  776. + {
  777. + m_ClientBattleGroundIds[bgTypeId][BgQueueId].erase(bg->GetClientInstanceID());
  778. + MapBGClientId::iterator iterInst = m_ClientBattleGroundIds[bgTypeId][BgQueueId].find(bg->GetClientInstanceID());
  779. + if(iterInst != m_ClientBattleGroundIds[bgTypeId][BgQueueId].end())
  780. + m_ClientBattleGroundIds[bgTypeId][BgQueueId].erase(iterInst);
  781. + }
  782. +
  783. + // ~BattleGround call unregistring BG from queue
  784. + if(BGFreeSlotQueue.find(bgTypeId) != BGFreeSlotQueue.end())
  785. + {
  786. + while(!BGFreeSlotQueue[bgTypeId].empty())
  787. + delete BGFreeSlotQueue[bgTypeId].front();
  788. + }
  789. +
  790. delete bg;
  791. }
  792. - }
  793. + }
  794. +}
  795.  
  796. - // destroy template battlegrounds that listed only in queues (other already terminated)
  797. - for(uint32 bgTypeId = 0; bgTypeId < MAX_BATTLEGROUND_TYPE_ID; ++bgTypeId)
  798. - {
  799. - // ~BattleGround call unregistring BG from queue
  800. - while(!BGFreeSlotQueue[bgTypeId].empty())
  801. - delete BGFreeSlotQueue[bgTypeId].front();
  802. - }
  803. +void BattleGroundMgr::DestroyBattleGround(BattleGround *BG)
  804. +{
  805. + uint8 QueueId = BG->GetQueueId();
  806. + BattleGroundTypeId bgTypeId = BG->GetTypeID();
  807. +
  808. + if(m_BattleGrounds.find(bgTypeId) == m_BattleGrounds.end())
  809. + return;
  810. +
  811. + BattleGroundSet::iterator itr = m_BattleGrounds[bgTypeId].find(BG->GetInstanceID());
  812. +
  813. + if(itr != m_BattleGrounds[bgTypeId].end())
  814. + m_BattleGrounds[bgTypeId].erase(itr);
  815. +
  816. + MapBGClientId BgMap = m_ClientBattleGroundIds[bgTypeId][QueueId];
  817. + MapBGClientId::iterator iter = BgMap.find(BG->GetClientInstanceID());
  818. +
  819. + if(BgMap.end() != iter)
  820. + BgMap.erase(iter);
  821. +
  822. + delete BG;
  823. }
  824.  
  825. // used to update running battlegrounds, and delete finished ones
  826. void BattleGroundMgr::Update(uint32 diff)
  827. {
  828. - BattleGroundSet::iterator itr, next;
  829. - for(uint32 i = BATTLEGROUND_TYPE_NONE; i < MAX_BATTLEGROUND_TYPE_ID; i++)
  830. - {
  831. - itr = m_BattleGrounds[i].begin();
  832. - // skip updating battleground template
  833. - if (itr != m_BattleGrounds[i].end())
  834. - ++itr;
  835. - for(; itr != m_BattleGrounds[i].end(); itr = next)
  836. - {
  837. - next = itr;
  838. - ++next;
  839. - itr->second->Update(diff);
  840. - // use the SetDeleteThis variable
  841. - // direct deletion caused crashes
  842. - if (itr->second->m_SetDeleteThis)
  843. - {
  844. - BattleGround * bg = itr->second;
  845. - m_BattleGrounds[i].erase(itr);
  846. - if (!m_ClientBattleGroundIds[i][bg->GetQueueId()].empty())
  847. - m_ClientBattleGroundIds[i][bg->GetQueueId()].erase(bg->GetClientInstanceID());
  848. - delete bg;
  849. - }
  850. - }
  851. - }
  852.  
  853. // update scheduled queues
  854. if (!m_QueueUpdateScheduler.empty())
  855. @@ -1194,11 +1190,11 @@ void BattleGroundMgr::Update(uint32 diff)
  856.  
  857. for (uint8 i = 0; i < scheduled.size(); i++)
  858. {
  859. - uint32 arenaRating = scheduled[i] >> 32;
  860. - uint8 arenaType = scheduled[i] >> 24 & 255;
  861. - BattleGroundQueueTypeId bgQueueTypeId = BattleGroundQueueTypeId(scheduled[i] >> 16 & 255);
  862. - BattleGroundTypeId bgTypeId = BattleGroundTypeId((scheduled[i] >> 8) & 255);
  863. - BGQueueIdBasedOnLevel queue_id = BGQueueIdBasedOnLevel(scheduled[i] & 255);
  864. + uint8 queue_id = scheduled[i] & 0xFF;
  865. + uint32 arenaRating = scheduled[i] >> 0x20;
  866. + uint8 arenaType = scheduled[i] >> 0x18 & 0xFF;
  867. + BattleGroundQueueTypeId bgQueueTypeId = BattleGroundQueueTypeId(scheduled[i] >> 0x10 & 0xFF);
  868. + BattleGroundTypeId bgTypeId = BattleGroundTypeId((scheduled[i] >> 0x08) & 0xFF);
  869. m_BattleGroundQueues[bgQueueTypeId].Update(bgTypeId, queue_id, arenaType, arenaRating > 0, arenaRating);
  870. }
  871. }
  872. @@ -1209,14 +1205,15 @@ void BattleGroundMgr::Update(uint32 diff)
  873. // it's time to force update
  874. if (m_NextRatingDiscardUpdate < diff)
  875. {
  876. - // forced update for level 70 rated arenas
  877. - sLog.outDebug("BattleGroundMgr: UPDATING ARENA QUEUES");
  878. - m_BattleGroundQueues[BATTLEGROUND_QUEUE_2v2].Update(BATTLEGROUND_AA, QUEUE_ID_MAX_LEVEL_79, ARENA_TYPE_2v2, true, 0);
  879. - m_BattleGroundQueues[BATTLEGROUND_QUEUE_2v2].Update(BATTLEGROUND_AA, QUEUE_ID_MAX_LEVEL_80, ARENA_TYPE_2v2, true, 0);
  880. - m_BattleGroundQueues[BATTLEGROUND_QUEUE_3v3].Update(BATTLEGROUND_AA, QUEUE_ID_MAX_LEVEL_79, ARENA_TYPE_3v3, true, 0);
  881. - m_BattleGroundQueues[BATTLEGROUND_QUEUE_3v3].Update(BATTLEGROUND_AA, QUEUE_ID_MAX_LEVEL_80, ARENA_TYPE_3v3, true, 0);
  882. - m_BattleGroundQueues[BATTLEGROUND_QUEUE_5v5].Update(BATTLEGROUND_AA, QUEUE_ID_MAX_LEVEL_79, ARENA_TYPE_5v5, true, 0);
  883. - m_BattleGroundQueues[BATTLEGROUND_QUEUE_5v5].Update(BATTLEGROUND_AA, QUEUE_ID_MAX_LEVEL_80, ARENA_TYPE_5v5, true, 0);
  884. + // forced update for max level rated arenas
  885. +
  886. + uint8 MaxQueueId = GetMaxQueueId() - 1;
  887. + m_BattleGroundQueues[BATTLEGROUND_QUEUE_2v2].Update(BATTLEGROUND_AA, MaxQueueId-1, ARENA_TYPE_2v2, true, 0);
  888. + m_BattleGroundQueues[BATTLEGROUND_QUEUE_2v2].Update(BATTLEGROUND_AA, MaxQueueId, ARENA_TYPE_2v2, true, 0);
  889. + m_BattleGroundQueues[BATTLEGROUND_QUEUE_3v3].Update(BATTLEGROUND_AA, MaxQueueId-1, ARENA_TYPE_3v3, true, 0);
  890. + m_BattleGroundQueues[BATTLEGROUND_QUEUE_3v3].Update(BATTLEGROUND_AA, MaxQueueId, ARENA_TYPE_3v3, true, 0);
  891. + m_BattleGroundQueues[BATTLEGROUND_QUEUE_5v5].Update(BATTLEGROUND_AA, MaxQueueId-1, ARENA_TYPE_5v5, true, 0);
  892. + m_BattleGroundQueues[BATTLEGROUND_QUEUE_5v5].Update(BATTLEGROUND_AA, MaxQueueId, ARENA_TYPE_5v5, true, 0);
  893. m_NextRatingDiscardUpdate = sWorld.getConfig(CONFIG_ARENA_RATING_DISCARD_TIMER);
  894. }
  895. else
  896. @@ -1479,75 +1476,102 @@ void BattleGroundMgr::BuildPlayerJoinedBattleGroundPacket(WorldPacket *data, Pla
  897. *data << uint64(plr->GetGUID());
  898. }
  899.  
  900. -BattleGround * BattleGroundMgr::GetBattleGroundThroughClientInstance(uint32 instanceId, BattleGroundTypeId bgTypeId)
  901. +BattleGround * BattleGroundMgr::GetBattleGround(uint32 InstanceID, BattleGroundTypeId bgTypeId, int16 QueueId)
  902. {
  903. - //cause at HandleBattleGroundJoinOpcode the clients sends the instanceid he gets from
  904. - //SMSG_BATTLEFIELD_LIST we need to find the battleground with this clientinstance-id
  905. - BattleGround* bg = GetBattleGroundTemplate(bgTypeId);
  906. - if (!bg)
  907. - return NULL;
  908. + if(!IsValidBattleGround(bgTypeId,QueueId))
  909. + return NULL;
  910.  
  911. - if (bg->isArena())
  912. - return GetBattleGround(instanceId, bgTypeId);
  913. -
  914. - for(BattleGroundSet::iterator itr = m_BattleGrounds[bgTypeId].begin(); itr != m_BattleGrounds[bgTypeId].end(); ++itr)
  915. + //If QueueId != -1 then InstanceID is Client Instance ID , so we convert it to Map instance Id
  916. + if(QueueId != -1 && !IsArenaType(bgTypeId))
  917. {
  918. - if (itr->second->GetClientInstanceID() == instanceId)
  919. - return itr->second;
  920. + MapBGClientId::iterator itr = m_ClientBattleGroundIds[bgTypeId][uint8(QueueId)].find(InstanceID);
  921. + if(itr != m_ClientBattleGroundIds[bgTypeId][uint8(QueueId)].end())
  922. + InstanceID = itr->second;
  923. }
  924. - return NULL;
  925. -}
  926.  
  927. -BattleGround * BattleGroundMgr::GetBattleGround(uint32 InstanceID, BattleGroundTypeId bgTypeId)
  928. -{
  929. - //search if needed
  930. - BattleGroundSet::iterator itr;
  931. if (bgTypeId == BATTLEGROUND_TYPE_NONE)
  932. {
  933. - for(uint32 i = BATTLEGROUND_AV; i < MAX_BATTLEGROUND_TYPE_ID; i++)
  934. - {
  935. - itr = m_BattleGrounds[i].find(InstanceID);
  936. - if (itr != m_BattleGrounds[i].end())
  937. - return itr->second;
  938. - }
  939. + for(MapBattleGround::iterator itr = m_BattleGrounds.begin(); itr != m_BattleGrounds.end(); itr++)
  940. + if(itr->second.find(InstanceID) != itr->second.end())
  941. + return itr->second[InstanceID];
  942. +
  943. return NULL;
  944. }
  945. - itr = m_BattleGrounds[bgTypeId].find(InstanceID);
  946. - return ( (itr != m_BattleGrounds[bgTypeId].end()) ? itr->second : NULL );
  947. +
  948. + if(m_BattleGrounds.find(bgTypeId) != m_BattleGrounds.end() && m_BattleGrounds[bgTypeId].find(InstanceID) != m_BattleGrounds[bgTypeId].end())
  949. + return m_BattleGrounds[bgTypeId][InstanceID];
  950. +
  951. + return NULL;
  952. }
  953.  
  954. BattleGround * BattleGroundMgr::GetBattleGroundTemplate(BattleGroundTypeId bgTypeId)
  955. {
  956. - //map is sorted and we can be sure that lowest instance id has only BG template
  957. - return m_BattleGrounds[bgTypeId].empty() ? NULL : m_BattleGrounds[bgTypeId].begin()->second;
  958. + return m_BGTemplates.find(bgTypeId) == m_BGTemplates.end() ? NULL : m_BGTemplates[bgTypeId];
  959. }
  960.  
  961. -uint32 BattleGroundMgr::CreateClientVisibleInstanceId(BattleGroundTypeId bgTypeId, BGQueueIdBasedOnLevel queue_id)
  962. +uint32 BattleGroundMgr::CreateClientInstId(BattleGroundTypeId bgTypeId, uint8 QueueId, uint32 InstanceID)
  963. {
  964. - if (IsArenaType(bgTypeId))
  965. - return 0; //arenas don't have client-instanceids
  966. -
  967. - // we create here an instanceid, which is just for
  968. - // displaying this to the client and without any other use..
  969. - // the client-instanceIds are unique for each battleground-type
  970. - // the instance-id just needs to be as low as possible, beginning with 1
  971. - // the following works, because std::set is default ordered with "<"
  972. - // the optimalization would be to use as bitmask std::vector<uint32> - but that would only make code unreadable
  973. - uint32 lastId = 0;
  974. - for(std::set<uint32>::iterator itr = m_ClientBattleGroundIds[bgTypeId][queue_id].begin(); itr != m_ClientBattleGroundIds[bgTypeId][queue_id].end();)
  975. - {
  976. - if( (++lastId) != *itr) //if there is a gap between the ids, we will break..
  977. - break;
  978. - lastId = *itr;
  979. + if (IsArenaType(bgTypeId) || IsValidBattleGround(bgTypeId,QueueId))
  980. + return 0; //arenas don't have client-instanceids
  981. +
  982. + uint32 NewId = 0;
  983. +
  984. + for(uint8 i = 1; i <= 0xFF; i++)
  985. + {
  986. + if(m_ClientBattleGroundIds[bgTypeId][QueueId].find(i)==m_ClientBattleGroundIds[bgTypeId][QueueId].end())
  987. + {
  988. + m_ClientBattleGroundIds[bgTypeId][QueueId][i] = InstanceID;
  989. + return i;
  990. + }
  991. }
  992. - m_ClientBattleGroundIds[bgTypeId][queue_id].insert(lastId + 1);
  993. - return lastId + 1;
  994. +
  995. + return 0;
  996. +}
  997. +
  998. +bool BattleGroundMgr::IsValidBattleGround(BattleGroundTypeId bgType,int16 QueueId)
  999. +{
  1000. + if(QueueId != -1 && uint8(QueueId) >= GetMaxQueueId())
  1001. + return false;
  1002. +
  1003. + if(!sBattlemasterListStore.LookupEntry(uint32(bgType)))
  1004. + return false;
  1005. +
  1006. + return true;
  1007. +}
  1008. +
  1009. +BattleGroundTypeId BattleGroundMgr::GetBgTypeByMap(uint32 MapId)
  1010. +{
  1011. + for(uint8 i = 0; i < sBattlemasterListStore.GetNumRows(); i++)
  1012. + if(BattlemasterListEntry const* bl = sBattlemasterListStore.LookupEntry(i))
  1013. + if(bl->GetMapCount() == 1 && bl->mapid[0] == MapId)
  1014. + return BattleGroundTypeId(bl->id);
  1015. +
  1016. + return BATTLEGROUND_TYPE_NONE;
  1017. +}
  1018. +
  1019. +BattleGroundTypeId BattleGroundMgr::GetArenaType()
  1020. +{
  1021. + for(uint8 i = 0; i < sBattlemasterListStore.GetNumRows(); i++)
  1022. + if(BattlemasterListEntry const* bl = sBattlemasterListStore.LookupEntry(i))
  1023. + if(bl->GetMapCount() > 1 && bl->type == TYPE_ARENA)
  1024. + return GetBgTypeByMap(bl->mapid[urand(0,bl->GetMapCount())]);
  1025. +
  1026. + return BATTLEGROUND_NA;
  1027. +}
  1028. +
  1029. +uint8 BattleGroundMgr::GetMaxQueueId()
  1030. +{
  1031. + return uint8(sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL) / 0x0A);
  1032. }
  1033.  
  1034. // create a new battleground that will really be used to play
  1035. -BattleGround * BattleGroundMgr::CreateNewBattleGround(BattleGroundTypeId bgTypeId, BGQueueIdBasedOnLevel queue_id, uint8 arenaType, bool isRated)
  1036. +BattleGround * BattleGroundMgr::CreateNewBattleGround(BattleGroundTypeId bgTypeId, uint8 queue_id, uint8 arenaType, bool isRated)
  1037. {
  1038. // get the template BG
  1039. +
  1040. + if(IsArenaType(bgTypeId))
  1041. + bgTypeId = GetArenaType();
  1042. +
  1043. BattleGround *bg_template = GetBattleGroundTemplate(bgTypeId);
  1044. if (!bg_template)
  1045. {
  1046. @@ -1555,20 +1579,6 @@ BattleGround * BattleGroundMgr::CreateNewBattleGround(BattleGroundTypeId bgTypeI
  1047. return NULL;
  1048. }
  1049.  
  1050. - //for arenas there is random map used
  1051. - if (bg_template->isArena())
  1052. - {
  1053. - BattleGroundTypeId arenas[] = {BATTLEGROUND_NA, BATTLEGROUND_BE, BATTLEGROUND_RL};
  1054. - uint32 arena_num = urand(0,2);
  1055. - bgTypeId = arenas[arena_num];
  1056. - bg_template = GetBattleGroundTemplate(bgTypeId);
  1057. - if (!bg_template)
  1058. - {
  1059. - sLog.outError("BattleGround: CreateNewBattleGround - bg template not found for %u", bgTypeId);
  1060. - return NULL;
  1061. - }
  1062. - }
  1063. -
  1064. BattleGround *bg = NULL;
  1065. // create a copy of the BG template
  1066. switch(bgTypeId)
  1067. @@ -1618,8 +1628,11 @@ BattleGround * BattleGroundMgr::CreateNewBattleGround(BattleGroundTypeId bgTypeI
  1068. }
  1069.  
  1070. // generate a new instance id
  1071. - bg->SetInstanceID(sMapMgr.GenerateInstanceId()); // set instance id
  1072. - bg->SetClientInstanceID(CreateClientVisibleInstanceId(bgTypeId, queue_id));
  1073. + uint32 InstanceID = MapManager::Instance().GenerateInstanceId();
  1074. + uint32 ClientID = CreateClientInstId(bgTypeId, queue_id, InstanceID);
  1075. +
  1076. + bg->SetInstanceID(InstanceID);
  1077. + bg->SetClientInstanceID(ClientID);
  1078.  
  1079. // reset the new bg (set status to status_wait_queue from status_none)
  1080. bg->Reset();
  1081. @@ -1669,8 +1682,7 @@ uint32 BattleGroundMgr::CreateBattleGround(BattleGroundTypeId bgTypeId, bool IsA
  1082. bg->SetTeamStartLoc(HORDE, Team2StartLocX, Team2StartLocY, Team2StartLocZ, Team2StartLocO);
  1083. bg->SetLevelRange(LevelMin, LevelMax);
  1084.  
  1085. - // add bg to update list
  1086. - AddBattleGround(bg->GetInstanceID(), bg->GetTypeID(), bg);
  1087. + m_BGTemplates[bgTypeId] = bg;
  1088.  
  1089. // return some not-null value, bgTypeId is good enough for me
  1090. return bgTypeId;
  1091. @@ -1872,8 +1884,7 @@ void BattleGroundMgr::BuildBattleGroundListPacket(WorldPacket *data, const uint6
  1092. if (!plr)
  1093. return;
  1094.  
  1095. - uint32 PlayerLevel = 10;
  1096. - PlayerLevel = plr->getLevel();
  1097. + uint32 PlayerLevel = plr->getLevel();
  1098.  
  1099. data->Initialize(SMSG_BATTLEFIELD_LIST);
  1100. *data << uint64(guid); // battlemaster guid
  1101. @@ -1892,11 +1903,13 @@ void BattleGroundMgr::BuildBattleGroundListPacket(WorldPacket *data, const uint6
  1102. uint32 count = 0;
  1103. *data << uint32(0x00); // number of bg instances
  1104.  
  1105. - uint32 queue_id = plr->GetBattleGroundQueueIdFromLevel();
  1106. - for(std::set<uint32>::iterator itr = m_ClientBattleGroundIds[bgTypeId][queue_id].begin(); itr != m_ClientBattleGroundIds[bgTypeId][queue_id].end();++itr)
  1107. + MapBGClientId ClientIDs = m_ClientBattleGroundIds[bgTypeId][plr->GetBGLevelQueueId()];
  1108. +
  1109. + for(MapBGClientId::iterator itr = ClientIDs.begin(), next; itr != ClientIDs.end(); itr = next)
  1110. {
  1111. - *data << uint32(*itr);
  1112. - ++count;
  1113. + next = itr; ++next;
  1114. + *data << uint32(itr->first);
  1115. + ++count;
  1116. }
  1117. data->put<uint32>( count_pos , count);
  1118. }
  1119. @@ -1925,10 +1938,9 @@ void BattleGroundMgr::SendToBattleGround(Player *pl, uint32 instanceId, BattleGr
  1120.  
  1121. bool BattleGroundMgr::IsArenaType(BattleGroundTypeId bgTypeId)
  1122. {
  1123. - return ( bgTypeId == BATTLEGROUND_AA ||
  1124. - bgTypeId == BATTLEGROUND_BE ||
  1125. - bgTypeId == BATTLEGROUND_NA ||
  1126. - bgTypeId == BATTLEGROUND_RL );
  1127. + if(BattlemasterListEntry const* bl = sBattlemasterListStore.LookupEntry(bgTypeId))
  1128. + return(bl->type == TYPE_ARENA);
  1129. + return false;
  1130. }
  1131.  
  1132. BattleGroundQueueTypeId BattleGroundMgr::BGQueueTypeId(BattleGroundTypeId bgTypeId, uint8 arenaType)
  1133. @@ -2029,11 +2041,11 @@ void BattleGroundMgr::ToggleArenaTesting()
  1134. sWorld.SendWorldText(LANG_DEBUG_ARENA_OFF);
  1135. }
  1136.  
  1137. -void BattleGroundMgr::ScheduleQueueUpdate(uint32 arenaRating, uint8 arenaType, BattleGroundQueueTypeId bgQueueTypeId, BattleGroundTypeId bgTypeId, BGQueueIdBasedOnLevel queue_id)
  1138. +void BattleGroundMgr::ScheduleQueueUpdate(uint32 arenaRating, uint8 arenaType, BattleGroundQueueTypeId bgQueueTypeId, BattleGroundTypeId bgTypeId, uint8 queue_id)
  1139. {
  1140. //ACE_Guard<ACE_Thread_Mutex> guard(SchedulerLock);
  1141. //we will use only 1 number created of bgTypeId and queue_id
  1142. - uint64 schedule_id = ((uint64)arenaRating << 32) | (arenaType << 24) | (bgQueueTypeId << 16) | (bgTypeId << 8) | queue_id;
  1143. + uint64 schedule_id = ((uint64)arenaRating << 0x20) | (arenaType << 0x18) | (bgQueueTypeId << 0x10) | (bgTypeId << 8) | queue_id;
  1144. bool found = false;
  1145. for (uint8 i = 0; i < m_QueueUpdateScheduler.size(); i++)
  1146. {
  1147. @@ -2117,12 +2129,16 @@ bool BattleGroundMgr::IsBGWeekend(BattleGroundTypeId bgTypeId)
  1148. {
  1149. case BATTLEGROUND_AV:
  1150. return IsHolidayActive(HOLIDAY_CALL_TO_ARMS_AV);
  1151. - case BATTLEGROUND_EY:
  1152. - return IsHolidayActive(HOLIDAY_CALL_TO_ARMS_EY);
  1153. case BATTLEGROUND_WS:
  1154. return IsHolidayActive(HOLIDAY_CALL_TO_ARMS_WS);
  1155. + case BATTLEGROUND_AB:
  1156. + return IsHolidayActive(HOLIDAY_CALL_TO_ARMS_AB);
  1157. + case BATTLEGROUND_EY:
  1158. + return IsHolidayActive(HOLIDAY_CALL_TO_ARMS_EY);
  1159. case BATTLEGROUND_SA:
  1160. - return IsHolidayActive(HOLIDAY_CALL_TO_ARMS_SA);
  1161. + return IsHolidayActive(HOLIDAY_CALL_TO_ARMS_SA);
  1162. + case BATTLEGROUND_IC:
  1163. + return IsHolidayActive(HOLIDAY_CALL_TO_ARMS_ISLE_OF_C);
  1164. default:
  1165. return false;
  1166. }
  1167. diff --git a/src/game/BattleGroundMgr.h b/src/game/BattleGroundMgr.h
  1168. index 7b646c6..838046c 100644
  1169. --- a/src/game/BattleGroundMgr.h
  1170. +++ b/src/game/BattleGroundMgr.h
  1171. @@ -26,7 +26,9 @@
  1172. #include "ace/Recursive_Thread_Mutex.h"
  1173.  
  1174. typedef std::map<uint32, BattleGround*> BattleGroundSet;
  1175. +typedef std::map<uint32, BattleGroundSet> MapBattleGround;
  1176.  
  1177. +typedef std::map<uint8, uint32> MapBGClientId;
  1178. //this container can't be deque, because deque doesn't like removing the last element - if you remove it, it invalidates next iterator and crash appears
  1179. typedef std::list<BattleGround*> BGFreeSlotQueueType;
  1180.  
  1181. @@ -75,18 +77,18 @@ class BattleGroundQueue
  1182. BattleGroundQueue();
  1183. ~BattleGroundQueue();
  1184.  
  1185. - void Update(BattleGroundTypeId bgTypeId, BGQueueIdBasedOnLevel queue_id, uint8 arenaType = 0, bool isRated = false, uint32 minRating = 0);
  1186. + void Update(BattleGroundTypeId bgTypeId, uint8 queue_id, uint8 arenaType = 0, bool isRated = false, uint32 minRating = 0);
  1187.  
  1188. - void FillPlayersToBG(BattleGround* bg, BGQueueIdBasedOnLevel queue_id);
  1189. - bool CheckPremadeMatch(BGQueueIdBasedOnLevel queue_id, uint32 MinPlayersPerTeam, uint32 MaxPlayersPerTeam);
  1190. - bool CheckNormalMatch(BattleGround* bg_template, BGQueueIdBasedOnLevel queue_id, uint32 minPlayers, uint32 maxPlayers);
  1191. - bool CheckSkirmishForSameFaction(BGQueueIdBasedOnLevel queue_id, uint32 minPlayersPerTeam);
  1192. + void FillPlayersToBG(BattleGround* bg, uint8 queue_id);
  1193. + bool CheckPremadeMatch(uint8 queue_id, uint32 MinPlayersPerTeam, uint32 MaxPlayersPerTeam);
  1194. + bool CheckNormalMatch(BattleGround* bg_template, uint8 queue_id, uint32 minPlayers, uint32 maxPlayers);
  1195. + bool CheckSkirmishForSameFaction(uint8 queue_id, uint32 minPlayersPerTeam);
  1196. GroupQueueInfo * AddGroup(Player* leader, Group* group, BattleGroundTypeId bgTypeId, uint8 ArenaType, bool isRated, bool isPremade, uint32 ArenaRating, uint32 ArenaTeamId = 0);
  1197. void RemovePlayer(const uint64& guid, bool decreaseInvitedCount);
  1198. bool IsPlayerInvited(const uint64& pl_guid, const uint32 bgInstanceGuid, const uint32 removeTime);
  1199. bool GetPlayerGroupInfoData(const uint64& guid, GroupQueueInfo* ginfo);
  1200. - void PlayerInvitedToBGUpdateAverageWaitTime(GroupQueueInfo* ginfo, BGQueueIdBasedOnLevel queue_id);
  1201. - uint32 GetAverageQueueWaitTime(GroupQueueInfo* ginfo, BGQueueIdBasedOnLevel queue_id);
  1202. + void PlayerInvitedToBGUpdateAverageWaitTime(GroupQueueInfo* ginfo, uint8 queue_id);
  1203. + uint32 GetAverageQueueWaitTime(GroupQueueInfo* ginfo, uint8 queue_id);
  1204.  
  1205. private:
  1206. //mutex that should not allow changing private data, nor allowing to update Queue during private data change.
  1207. @@ -97,8 +99,8 @@ class BattleGroundQueue
  1208. QueuedPlayersMap m_QueuedPlayers;
  1209.  
  1210. //we need constant add to begin and constant remove / add from the end, therefore deque suits our problem well
  1211. - typedef std::list<GroupQueueInfo*> GroupsQueueType;
  1212. -
  1213. + typedef std::list<GroupQueueInfo*> GroupQueueInfoList;
  1214. + typedef std::vector < std::vector< GroupQueueInfoList > > GroupsQueueType;
  1215. /*
  1216. This two dimensional array is used to store All queued groups
  1217. First dimension specifies the bgTypeId
  1218. @@ -108,7 +110,7 @@ class BattleGroundQueue
  1219. BG_QUEUE_NORMAL_ALLIANCE is used for normal (or small) alliance groups or non-rated arena matches
  1220. BG_QUEUE_NORMAL_HORDE is used for normal (or small) horde groups or non-rated arena matches
  1221. */
  1222. - GroupsQueueType m_QueuedGroups[MAX_BATTLEGROUND_QUEUES][BG_QUEUE_GROUP_TYPES_COUNT];
  1223. + GroupsQueueType m_QueuedGroups;
  1224.  
  1225. // class to select and invite groups to bg
  1226. class SelectionPool
  1227. @@ -119,7 +121,7 @@ class BattleGroundQueue
  1228. bool KickGroup(uint32 size);
  1229. uint32 GetPlayerCount() const {return PlayerCount;}
  1230. public:
  1231. - GroupsQueueType SelectedGroups;
  1232. + GroupQueueInfoList SelectedGroups;
  1233. private:
  1234. uint32 PlayerCount;
  1235. };
  1236. @@ -128,9 +130,9 @@ class BattleGroundQueue
  1237. SelectionPool m_SelectionPools[BG_TEAMS_COUNT];
  1238.  
  1239. bool InviteGroupToBG(GroupQueueInfo * ginfo, BattleGround * bg, uint32 side);
  1240. - uint32 m_WaitTimes[BG_TEAMS_COUNT][MAX_BATTLEGROUND_QUEUES][COUNT_OF_PLAYERS_TO_AVERAGE_WAIT_TIME];
  1241. - uint32 m_WaitTimeLastPlayer[BG_TEAMS_COUNT][MAX_BATTLEGROUND_QUEUES];
  1242. - uint32 m_SumOfWaitTimes[BG_TEAMS_COUNT][MAX_BATTLEGROUND_QUEUES];
  1243. + std::map<uint8, std::vector<uint32> > m_WaitTimes[BG_TEAMS_COUNT];
  1244. + std::map<uint8, uint32> m_WaitTimeLastPlayer[BG_TEAMS_COUNT];
  1245. + std::map<uint8, uint32> m_SumOfWaitTimes[BG_TEAMS_COUNT];
  1246. };
  1247.  
  1248. /*
  1249. @@ -199,17 +201,23 @@ class BattleGroundMgr
  1250. void BuildPlaySoundPacket(WorldPacket *data, uint32 soundid);
  1251.  
  1252. /* Battlegrounds */
  1253. - BattleGround* GetBattleGroundThroughClientInstance(uint32 instanceId, BattleGroundTypeId bgTypeId);
  1254. - BattleGround* GetBattleGround(uint32 InstanceID, BattleGroundTypeId bgTypeId); //there must be uint32 because MAX_BATTLEGROUND_TYPE_ID means unknown
  1255. + static uint8 GetMaxQueueId();
  1256. + BattleGroundTypeId GetArenaType();
  1257. + uint32 GetBgMapByType(BattleGroundTypeId type);
  1258. + BattleGroundTypeId GetBgTypeByMap(uint32 MapId);
  1259. + Map *GetBgMapPtrByType(BattleGroundTypeId type);
  1260. + bool IsValidBattleGround(BattleGroundTypeId bgType, int16 QueueId = -1);
  1261. + BattleGround* GetBattleGround(uint32 InstanceID, BattleGroundTypeId bgTypeId, int16 QueueId = -1);
  1262.  
  1263. BattleGround* GetBattleGroundTemplate(BattleGroundTypeId bgTypeId);
  1264. - BattleGround* CreateNewBattleGround(BattleGroundTypeId bgTypeId, BGQueueIdBasedOnLevel queue_id, uint8 arenaType, bool isRated);
  1265. + BattleGround* CreateNewBattleGround(BattleGroundTypeId bgTypeId, uint8 queue_id, uint8 arenaType, bool isRated);
  1266.  
  1267. uint32 CreateBattleGround(BattleGroundTypeId bgTypeId, bool IsArena, uint32 MinPlayersPerTeam, uint32 MaxPlayersPerTeam, uint32 LevelMin, uint32 LevelMax, char* BattleGroundName, uint32 MapID, float Team1StartLocX, float Team1StartLocY, float Team1StartLocZ, float Team1StartLocO, float Team2StartLocX, float Team2StartLocY, float Team2StartLocZ, float Team2StartLocO);
  1268.  
  1269. void AddBattleGround(uint32 InstanceID, BattleGroundTypeId bgTypeId, BattleGround* BG) { m_BattleGrounds[bgTypeId][InstanceID] = BG; };
  1270. - void RemoveBattleGround(uint32 instanceID, BattleGroundTypeId bgTypeId) { m_BattleGrounds[bgTypeId].erase(instanceID); }
  1271. - uint32 CreateClientVisibleInstanceId(BattleGroundTypeId bgTypeId, BGQueueIdBasedOnLevel queue_id);
  1272. + void RemoveBattleGround(uint32 InstanceID, BattleGroundTypeId bgTypeId) { m_BattleGrounds[bgTypeId].erase(InstanceID); }
  1273. + uint32 CreateClientInstId(BattleGroundTypeId bgTypeId, uint8 queue_id, uint32 InstanceID);
  1274. + void DestroyBattleGround(BattleGround *BG);
  1275.  
  1276. void CreateInitialBattleGrounds();
  1277. void DeleteAllBattleGrounds();
  1278. @@ -220,9 +228,9 @@ class BattleGroundMgr
  1279. //these queues are instantiated when creating BattlegroundMrg
  1280. BattleGroundQueue m_BattleGroundQueues[MAX_BATTLEGROUND_QUEUE_TYPES]; // public, because we need to access them in BG handler code
  1281.  
  1282. - BGFreeSlotQueueType BGFreeSlotQueue[MAX_BATTLEGROUND_TYPE_ID];
  1283. + std::map<uint32,BGFreeSlotQueueType> BGFreeSlotQueue;
  1284.  
  1285. - void ScheduleQueueUpdate(uint32 arenaRating, uint8 arenaType, BattleGroundQueueTypeId bgQueueTypeId, BattleGroundTypeId bgTypeId, BGQueueIdBasedOnLevel queue_id);
  1286. + void ScheduleQueueUpdate(uint32 arenaRating, uint8 arenaType, BattleGroundQueueTypeId bgQueueTypeId, BattleGroundTypeId bgTypeId, uint8 queue_id);
  1287. uint32 GetMaxRatingDifference() const;
  1288. uint32 GetRatingDiscardTimer() const;
  1289. uint32 GetPrematureFinishTime() const;
  1290. @@ -274,12 +282,16 @@ class BattleGroundMgr
  1291. GameObjectBattleEventIndexesMap m_GameObjectBattleEventIndexMap;
  1292.  
  1293. /* Battlegrounds */
  1294. - BattleGroundSet m_BattleGrounds[MAX_BATTLEGROUND_TYPE_ID];
  1295. - std::vector<uint64> m_QueueUpdateScheduler;
  1296. - std::set<uint32> m_ClientBattleGroundIds[MAX_BATTLEGROUND_TYPE_ID][MAX_BATTLEGROUND_QUEUES]; //the instanceids just visible for the client
  1297. +
  1298. uint32 m_NextRatingDiscardUpdate;
  1299. time_t m_NextAutoDistributionTime;
  1300. uint32 m_AutoDistributionTimeChecker;
  1301. + std::vector<uint64>m_QueueUpdateScheduler;
  1302. +
  1303. + MapBattleGround m_BattleGrounds;
  1304. + std::map<BattleGroundTypeId,BattleGround *> m_BGTemplates;
  1305. + std::map<uint32, std::map<uint8,MapBGClientId> > m_ClientBattleGroundIds;
  1306. +
  1307. bool m_ArenaTesting;
  1308. bool m_Testing;
  1309. };
  1310. diff --git a/src/game/BattleGroundNA.cpp b/src/game/BattleGroundNA.cpp
  1311. index ba7e18f..23baffb 100644
  1312. --- a/src/game/BattleGroundNA.cpp
  1313. +++ b/src/game/BattleGroundNA.cpp
  1314. @@ -73,7 +73,7 @@ void BattleGroundNA::AddPlayer(Player *plr)
  1315. UpdateWorldState(0xa10, GetAlivePlayersCountByTeam(HORDE));
  1316. }
  1317.  
  1318. -void BattleGroundNA::RemovePlayer(Player* /*plr*/, uint64 /*guid*/)
  1319. +void BattleGroundNA::RemovePlayer(Player* player, uint64 guid)
  1320. {
  1321. if (GetStatus() == STATUS_WAIT_LEAVE)
  1322. return;
  1323. @@ -81,7 +81,7 @@ void BattleGroundNA::RemovePlayer(Player* /*plr*/, uint64 /*guid*/)
  1324. UpdateWorldState(0xa0f, GetAlivePlayersCountByTeam(ALLIANCE));
  1325. UpdateWorldState(0xa10, GetAlivePlayersCountByTeam(HORDE));
  1326.  
  1327. - CheckArenaWinConditions();
  1328. + BattleGround::RemovePlayer(player, guid);
  1329. }
  1330.  
  1331. void BattleGroundNA::HandleKillPlayer(Player *player, Player *killer)
  1332. @@ -99,8 +99,6 @@ void BattleGroundNA::HandleKillPlayer(Player *player, Player *killer)
  1333.  
  1334. UpdateWorldState(0xa0f, GetAlivePlayersCountByTeam(ALLIANCE));
  1335. UpdateWorldState(0xa10, GetAlivePlayersCountByTeam(HORDE));
  1336. -
  1337. - CheckArenaWinConditions();
  1338. }
  1339.  
  1340. bool BattleGroundNA::HandlePlayerUnderMap(Player *player)
  1341. diff --git a/src/game/BattleGroundRL.cpp b/src/game/BattleGroundRL.cpp
  1342. index 009e0e9..6198bf0 100644
  1343. --- a/src/game/BattleGroundRL.cpp
  1344. +++ b/src/game/BattleGroundRL.cpp
  1345. @@ -73,7 +73,7 @@ void BattleGroundRL::AddPlayer(Player *plr)
  1346. UpdateWorldState(0xbb9, GetAlivePlayersCountByTeam(HORDE));
  1347. }
  1348.  
  1349. -void BattleGroundRL::RemovePlayer(Player* /*plr*/, uint64 /*guid*/)
  1350. +void BattleGroundRL::RemovePlayer(Player* player, uint64 guid)
  1351. {
  1352. if (GetStatus() == STATUS_WAIT_LEAVE)
  1353. return;
  1354. @@ -81,7 +81,7 @@ void BattleGroundRL::RemovePlayer(Player* /*plr*/, uint64 /*guid*/)
  1355. UpdateWorldState(0xbb8, GetAlivePlayersCountByTeam(ALLIANCE));
  1356. UpdateWorldState(0xbb9, GetAlivePlayersCountByTeam(HORDE));
  1357.  
  1358. - CheckArenaWinConditions();
  1359. + BattleGround::RemovePlayer(player, guid);
  1360. }
  1361.  
  1362. void BattleGroundRL::HandleKillPlayer(Player *player, Player *killer)
  1363. @@ -100,7 +100,6 @@ void BattleGroundRL::HandleKillPlayer(Player *player, Player *killer)
  1364. UpdateWorldState(0xbb8, GetAlivePlayersCountByTeam(ALLIANCE));
  1365. UpdateWorldState(0xbb9, GetAlivePlayersCountByTeam(HORDE));
  1366.  
  1367. - CheckArenaWinConditions();
  1368. }
  1369.  
  1370. bool BattleGroundRL::HandlePlayerUnderMap(Player *player)
  1371. diff --git a/src/game/BattleGroundRV.cpp b/src/game/BattleGroundRV.cpp
  1372. index 8c252c3..2993ffc 100644
  1373. --- a/src/game/BattleGroundRV.cpp
  1374. +++ b/src/game/BattleGroundRV.cpp
  1375. @@ -19,6 +19,7 @@
  1376. #include "Player.h"
  1377. #include "BattleGround.h"
  1378. #include "BattleGroundRV.h"
  1379. +#include "WorldPacket.h"
  1380. #include "Language.h"
  1381.  
  1382. BattleGroundRV::BattleGroundRV()
  1383. @@ -60,21 +61,49 @@ void BattleGroundRV::AddPlayer(Player *plr)
  1384. BattleGroundRVScore* sc = new BattleGroundRVScore;
  1385.  
  1386. m_PlayerScores[plr->GetGUID()] = sc;
  1387. +
  1388. + UpdateWorldState(0xe11, GetAlivePlayersCountByTeam(ALLIANCE));
  1389. + UpdateWorldState(0xe10, GetAlivePlayersCountByTeam(HORDE));
  1390. }
  1391.  
  1392. -void BattleGroundRV::RemovePlayer(Player * /*plr*/, uint64 /*guid*/)
  1393. +void BattleGroundRV::RemovePlayer(Player * player, uint64 guid)
  1394. {
  1395. + if (GetStatus() == STATUS_WAIT_LEAVE)
  1396. + return;
  1397. +
  1398. + UpdateWorldState(0xe11, GetAlivePlayersCountByTeam(ALLIANCE));
  1399. + UpdateWorldState(0xe10, GetAlivePlayersCountByTeam(HORDE));
  1400. +
  1401. + BattleGround::RemovePlayer(player, guid);
  1402. }
  1403.  
  1404. void BattleGroundRV::HandleKillPlayer(Player* player, Player* killer)
  1405. -{
  1406. +{
  1407. + if (GetStatus() != STATUS_IN_PROGRESS)
  1408. + return;
  1409. +
  1410. + if (!killer)
  1411. + {
  1412. + sLog.outError("BattleGroundRV: Killer player not found");
  1413. + return;
  1414. + }
  1415. +
  1416. BattleGround::HandleKillPlayer(player, killer);
  1417. + UpdateWorldState(0xe11, GetAlivePlayersCountByTeam(ALLIANCE));
  1418. + UpdateWorldState(0xe10, GetAlivePlayersCountByTeam(HORDE));
  1419. }
  1420.  
  1421. void BattleGroundRV::HandleAreaTrigger(Player * /*Source*/, uint32 /*Trigger*/)
  1422. {
  1423. }
  1424.  
  1425. +void BattleGroundRV::FillInitialWorldStates(WorldPacket &data)
  1426. +{
  1427. + data << uint32(0xe11) << uint32(GetAlivePlayersCountByTeam(ALLIANCE)); // 7
  1428. + data << uint32(0xe10) << uint32(GetAlivePlayersCountByTeam(HORDE)); // 8
  1429. + data << uint32(0xe1a) << uint32(1); // 9
  1430. +}
  1431. +
  1432. bool BattleGroundRV::SetupBattleGround()
  1433. {
  1434. return true;
  1435. diff --git a/src/game/BattleGroundRV.h b/src/game/BattleGroundRV.h
  1436. index e3e94ba..bf612b8 100644
  1437. --- a/src/game/BattleGroundRV.h
  1438. +++ b/src/game/BattleGroundRV.h
  1439. @@ -45,6 +45,7 @@ class BattleGroundRV : public BattleGround
  1440. void RemovePlayer(Player *plr, uint64 guid);
  1441. void HandleAreaTrigger(Player *Source, uint32 Trigger);
  1442. bool SetupBattleGround();
  1443. + virtual void FillInitialWorldStates(WorldPacket &d);
  1444. void HandleKillPlayer(Player* player, Player *killer);
  1445. };
  1446. #endif
  1447. diff --git a/src/game/CharacterHandler.cpp b/src/game/CharacterHandler.cpp
  1448. index 69cd034..97e3be2 100644
  1449. --- a/src/game/CharacterHandler.cpp
  1450. +++ b/src/game/CharacterHandler.cpp
  1451. @@ -30,6 +30,7 @@
  1452. #include "Guild.h"
  1453. #include "UpdateMask.h"
  1454. #include "Auth/md5.h"
  1455. +#include "MapManager.h"
  1456. #include "ObjectAccessor.h"
  1457. #include "Group.h"
  1458. #include "Database/DatabaseImpl.h"
  1459. @@ -552,6 +553,7 @@ void WorldSession::HandlePlayerLoginOpcode( WorldPacket & recv_data )
  1460.  
  1461. void WorldSession::HandlePlayerLogin(LoginQueryHolder *holder)
  1462. {
  1463. + SetUpdating(true);
  1464. uint64 playerGuid = holder->GetGuid();
  1465.  
  1466. Player *pCurrChar = new Player(this);
  1467. @@ -566,6 +568,22 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder *holder)
  1468. m_playerLoading = false;
  1469. return;
  1470. }
  1471. + //Map is being restarted so we cant enter
  1472. + if(Map *map = sMapMgr.FindMap(pCurrChar->GetMapId()))
  1473. + {
  1474. + if(map->GetUpdaterStatus() != UPDATER_ACTIVE)
  1475. + {
  1476. + WorldPacket data(SMSG_CHARACTER_LOGIN_FAILED, 9);
  1477. + data << uint64(pCurrChar->GetGUID());
  1478. + data << uint8(CHAR_LOGIN_NO_WORLD);
  1479. + m_playerRecentlyLogout = true;
  1480. + m_playerLoading = false;
  1481. + SendPacket(&data);
  1482. + delete pCurrChar; // delete it manually
  1483. + delete holder; // delete all unprocessed queries
  1484. + return;
  1485. + }
  1486. + }
  1487.  
  1488. SetPlayer(pCurrChar);
  1489.  
  1490. @@ -782,6 +800,9 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder *holder)
  1491.  
  1492. m_playerLoading = false;
  1493. delete holder;
  1494. +
  1495. + SetUpdating(false);
  1496. + SetUpdateStatus(SESSION_UPDATE_MAP);
  1497. }
  1498.  
  1499. void WorldSession::HandleSetFactionAtWar( WorldPacket & recv_data )
  1500. diff --git a/src/game/DBCStructure.h b/src/game/DBCStructure.h
  1501. index e799e99..514afa4 100644
  1502. --- a/src/game/DBCStructure.h
  1503. +++ b/src/game/DBCStructure.h
  1504. @@ -572,11 +572,21 @@ struct BattlemasterListEntry
  1505. uint32 maxplayersperteam; // 12
  1506. // 13 minplayers
  1507. // 14 0 or 9
  1508. - // 15
  1509. + uint32 IsActive; // 15 Is bg active?
  1510. char* name[16]; // 16-31
  1511. // 32 string flag, unused
  1512. // 33 unused
  1513. //uint32 unk; // 34 new 3.1
  1514. +
  1515. + uint8 GetMapCount() const
  1516. + {
  1517. + if(!IsActive)
  1518. + return 0;
  1519. +
  1520. + uint8 i = 0;
  1521. + while(i < 8 && mapid[i] != -1)i++;
  1522. + return i;
  1523. + }
  1524. };
  1525.  
  1526. #define MAX_OUTFIT_ITEMS 24
  1527. diff --git a/src/game/DBCfmt.h b/src/game/DBCfmt.h
  1528. index aa51050..fc96ca2 100644
  1529. --- a/src/game/DBCfmt.h
  1530. +++ b/src/game/DBCfmt.h
  1531. @@ -27,7 +27,7 @@ const char AreaTriggerEntryfmt[]="niffffffff";
  1532. const char AuctionHouseEntryfmt[]="niiixxxxxxxxxxxxxxxxx";
  1533. const char BankBagSlotPricesEntryfmt[]="ni";
  1534. const char BarberShopStyleEntryfmt[]="nixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxiii";
  1535. -const char BattlemasterListEntryfmt[]="niiiiiiiiiiiixxxssssssssssssssssxxx";
  1536. +const char BattlemasterListEntryfmt[]="niiiiiiiiiiiixxissssssssssssssssxxx";
  1537. const char CharStartOutfitEntryfmt[]="diiiiiiiiiiiiiiiiiiiiiiiiixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
  1538. const char CharTitlesEntryfmt[]="nxssssssssssssssssxxxxxxxxxxxxxxxxxxi";
  1539. const char ChatChannelsEntryfmt[]="iixssssssssssssssssxxxxxxxxxxxxxxxxxx";
  1540. diff --git a/src/game/GameEventMgr.cpp b/src/game/GameEventMgr.cpp
  1541. index 2249b94..8ad5b53 100644
  1542. --- a/src/game/GameEventMgr.cpp
  1543. +++ b/src/game/GameEventMgr.cpp
  1544. @@ -24,92 +24,80 @@
  1545. #include "ProgressBar.h"
  1546. #include "Language.h"
  1547. #include "Log.h"
  1548. +#include "WorldPacket.h"
  1549. #include "MapManager.h"
  1550. #include "Policies/SingletonImp.h"
  1551.  
  1552. INSTANTIATE_SINGLETON_1(GameEventMgr);
  1553.  
  1554. -bool GameEventMgr::CheckOneGameEvent(uint16 entry) const
  1555. +bool GameEventMgr::CheckOneGameEvent(GameEventData Event) const
  1556. {
  1557. // Get the event information
  1558. time_t currenttime = time(NULL);
  1559. - if( mGameEvent[entry].start < currenttime && currenttime < mGameEvent[entry].end &&
  1560. - ((currenttime - mGameEvent[entry].start) % (mGameEvent[entry].occurence * MINUTE)) < (mGameEvent[entry].length * MINUTE) )
  1561. + if( Event.start < currenttime && currenttime < Event.end &&
  1562. + ((currenttime - Event.start) % (Event.occurence * MINUTE)) < (Event.length * MINUTE) )
  1563. return true;
  1564. else
  1565. return false;
  1566. }
  1567.  
  1568. -uint32 GameEventMgr::NextCheck(uint16 entry) const
  1569. +uint32 GameEventMgr::NextCheck(GameEventData Event) const
  1570. {
  1571. time_t currenttime = time(NULL);
  1572.  
  1573. // outdated event: we return max
  1574. - if (currenttime > mGameEvent[entry].end)
  1575. + if (currenttime > Event.end)
  1576. return max_ge_check_delay;
  1577.  
  1578. // never started event, we return delay before start
  1579. - if (mGameEvent[entry].start > currenttime)
  1580. - return (mGameEvent[entry].start - currenttime);
  1581. + if (Event.start > currenttime)
  1582. + return (Event.start - currenttime);
  1583.  
  1584. uint32 delay;
  1585. // in event, we return the end of it
  1586. - if ((((currenttime - mGameEvent[entry].start) % (mGameEvent[entry].occurence * 60)) < (mGameEvent[entry].length * 60)))
  1587. + if ((((currenttime - Event.start) % (Event.occurence * 60)) < (Event.length * 60)))
  1588. // we return the delay before it ends
  1589. - delay = (mGameEvent[entry].length * MINUTE) - ((currenttime - mGameEvent[entry].start) % (mGameEvent[entry].occurence * MINUTE));
  1590. + delay = (Event.length * MINUTE) - ((currenttime - Event.start) % (Event.occurence * MINUTE));
  1591. else // not in window, we return the delay before next start
  1592. - delay = (mGameEvent[entry].occurence * MINUTE) - ((currenttime - mGameEvent[entry].start) % (mGameEvent[entry].occurence * MINUTE));
  1593. + delay = (Event.occurence * MINUTE) - ((currenttime - Event.start) % (Event.occurence * MINUTE));
  1594. // In case the end is before next check
  1595. - if (mGameEvent[entry].end < time_t(currenttime + delay))
  1596. - return (mGameEvent[entry].end - currenttime);
  1597. + if (Event.end < time_t(currenttime + delay))
  1598. + return (Event.end - currenttime);
  1599. else
  1600. return delay;
  1601. }
  1602.  
  1603. -void GameEventMgr::StartEvent( uint16 event_id, bool overwrite )
  1604. +void GameEventMgr::StartEvent( uint16 EventId, bool OverWrite )
  1605. {
  1606. - AddActiveEvent(event_id);
  1607. - ApplyNewEvent(event_id);
  1608. - if(overwrite)
  1609. + GameEventData *Event = &mGameEvent[EventId];
  1610. + Event->active = true;
  1611. + ApplyNewEvent(EventId);
  1612. +
  1613. + if(OverWrite)
  1614. {
  1615. - mGameEvent[event_id].start = time(NULL);
  1616. - if(mGameEvent[event_id].end <= mGameEvent[event_id].start)
  1617. - mGameEvent[event_id].end = mGameEvent[event_id].start+mGameEvent[event_id].length;
  1618. + Event->start = time(NULL);
  1619. + if(Event->end <= Event->start)
  1620. + Event->end = time_t(Event->start+Event->length);
  1621. }
  1622. }
  1623.  
  1624. -void GameEventMgr::StopEvent( uint16 event_id, bool overwrite )
  1625. +void GameEventMgr::StopEvent( uint16 EventId, bool OverWrite )
  1626. {
  1627. - RemoveActiveEvent(event_id);
  1628. - UnApplyEvent(event_id);
  1629. - if(overwrite)
  1630. + GameEventData *Event = &mGameEvent[EventId];
  1631. + Event->active = false;
  1632. + UnApplyEvent(EventId);
  1633. +
  1634. + if(OverWrite)
  1635. {
  1636. - mGameEvent[event_id].start = time(NULL) - mGameEvent[event_id].length * MINUTE;
  1637. - if(mGameEvent[event_id].end <= mGameEvent[event_id].start)
  1638. - mGameEvent[event_id].end = mGameEvent[event_id].start+mGameEvent[event_id].length;
  1639. + Event->start = time(NULL) - Event->length * MINUTE;
  1640. + if(Event->end <= Event->start)
  1641. + Event->end = time_t(Event->start+Event->length);
  1642. }
  1643. }
  1644.  
  1645. void GameEventMgr::LoadFromDB()
  1646. {
  1647. - {
  1648. - QueryResult *result = WorldDatabase.Query("SELECT MAX(entry) FROM game_event");
  1649. - if( !result )
  1650. - {
  1651. - sLog.outString(">> Table game_event is empty.");
  1652. - sLog.outString();
  1653. - return;
  1654. - }
  1655. -
  1656. - Field *fields = result->Fetch();
  1657. -
  1658. - uint32 max_event_id = fields[0].GetUInt16();
  1659. - delete result;
  1660. -
  1661. - mGameEvent.resize(max_event_id+1);
  1662. - }
  1663. -
  1664. - QueryResult *result = WorldDatabase.Query("SELECT entry,UNIX_TIMESTAMP(start_time),UNIX_TIMESTAMP(end_time),occurence,length,holiday,description FROM game_event");
  1665. + QueryResult *result = WorldDatabase.Query("SELECT entry,UNIX_TIMESTAMP(start_time),UNIX_TIMESTAMP(end_time),occurence,length,holiday,node,description FROM game_event");
  1666. if( !result )
  1667. {
  1668. mGameEvent.clear();
  1669. @@ -144,7 +132,7 @@ void GameEventMgr::LoadFromDB()
  1670. pGameEvent.occurence = fields[3].GetUInt32();
  1671. pGameEvent.length = fields[4].GetUInt32();
  1672. pGameEvent.holiday_id = fields[5].GetUInt32();
  1673. -
  1674. + pGameEvent.node = fields[6].GetUInt32();
  1675.  
  1676. if(pGameEvent.length==0) // length>0 is validity check
  1677. {
  1678. @@ -161,7 +149,7 @@ void GameEventMgr::LoadFromDB()
  1679. }
  1680. }
  1681.  
  1682. - pGameEvent.description = fields[6].GetCppString();
  1683. + pGameEvent.description = fields[7].GetCppString();
  1684.  
  1685. } while( result->NextRow() );
  1686. delete result;
  1687. @@ -170,7 +158,6 @@ void GameEventMgr::LoadFromDB()
  1688. sLog.outString( ">> Loaded %u game events", count );
  1689. }
  1690.  
  1691. - mGameEventCreatureGuids.resize(mGameEvent.size()*2-1);
  1692. // 1 2
  1693. result = WorldDatabase.Query("SELECT creature.guid, game_event_creature.event "
  1694. "FROM creature JOIN game_event_creature ON creature.guid = game_event_creature.guid");
  1695. @@ -193,21 +180,17 @@ void GameEventMgr::LoadFromDB()
  1696. Field *fields = result->Fetch();
  1697.  
  1698. bar.step();
  1699. -
  1700. - uint32 guid = fields[0].GetUInt32();
  1701. - int16 event_id = fields[1].GetInt16();
  1702. -
  1703. - int32 internal_event_id = mGameEvent.size() + event_id - 1;
  1704. -
  1705. - if(internal_event_id < 0 || (size_t)internal_event_id >= mGameEventCreatureGuids.size())
  1706. + uint32 Guid = fields[0].GetUInt32();
  1707. + int16 EventId = fields[1].GetInt16 ();
  1708. + uint16 RealEventId = uint16(EventId < 0 ? EventId * -1 : EventId);
  1709. + if(mGameEvent.find(RealEventId)==mGameEvent.end())
  1710. {
  1711. - sLog.outErrorDb("`game_event_creature` game event id (%i) is out of range compared to max event id in `game_event`",event_id);
  1712. + sLog.outErrorDb("`game_event_creature` game event id (%u) is out of range compared to max event id in `game_event`",RealEventId);
  1713. continue;
  1714. }
  1715.  
  1716. ++count;
  1717. - GuidList& crelist = mGameEventCreatureGuids[internal_event_id];
  1718. - crelist.push_back(guid);
  1719. + mGameEventCreatureGuids[EventId].push_back(Guid);
  1720.  
  1721. } while( result->NextRow() );
  1722. delete result;
  1723. @@ -216,7 +199,6 @@ void GameEventMgr::LoadFromDB()
  1724. sLog.outString( ">> Loaded %u creatures in game events", count );
  1725. }
  1726.  
  1727. - mGameEventGameobjectGuids.resize(mGameEvent.size()*2-1);
  1728. // 1 2
  1729. result = WorldDatabase.Query("SELECT gameobject.guid, game_event_gameobject.event "
  1730. "FROM gameobject JOIN game_event_gameobject ON gameobject.guid=game_event_gameobject.guid");
  1731. @@ -240,20 +222,18 @@ void GameEventMgr::LoadFromDB()
  1732.  
  1733. bar.step();
  1734.  
  1735. - uint32 guid = fields[0].GetUInt32();
  1736. - int16 event_id = fields[1].GetInt16();
  1737. -
  1738. - int32 internal_event_id = mGameEvent.size() + event_id - 1;
  1739. + uint32 Guid = fields[0].GetUInt32();
  1740. + uint16 EventId = fields[1].GetUInt16();
  1741. + uint16 RealEventId = uint16(EventId < 0 ? EventId * -1 : EventId);
  1742.  
  1743. - if(internal_event_id < 0 || (size_t)internal_event_id >= mGameEventGameobjectGuids.size())
  1744. + if(mGameEvent.find(EventId)==mGameEvent.end())
  1745. {
  1746. - sLog.outErrorDb("`game_event_gameobject` game event id (%i) is out of range compared to max event id in `game_event`",event_id);
  1747. + sLog.outErrorDb("`game_event_gameobject` game event id (%u) not exist in `game_event`",RealEventId);
  1748. continue;
  1749. }
  1750.  
  1751. ++count;
  1752. - GuidList& golist = mGameEventGameobjectGuids[internal_event_id];
  1753. - golist.push_back(guid);
  1754. + mGameEventGameobjectGuids[EventId].push_back(Guid);
  1755.  
  1756. } while( result->NextRow() );
  1757. delete result;
  1758. @@ -262,7 +242,6 @@ void GameEventMgr::LoadFromDB()
  1759. sLog.outString( ">> Loaded %u gameobjects in game events", count );
  1760. }
  1761.  
  1762. - mGameEventModelEquip.resize(mGameEvent.size());
  1763. // 0 1 2
  1764. result = WorldDatabase.Query("SELECT creature.guid, game_event_model_equip.event, game_event_model_equip.modelid,"
  1765. // 3
  1766. @@ -287,17 +266,16 @@ void GameEventMgr::LoadFromDB()
  1767. Field *fields = result->Fetch();
  1768.  
  1769. bar.step();
  1770. - uint32 guid = fields[0].GetUInt32();
  1771. - uint16 event_id = fields[1].GetUInt16();
  1772. + uint32 Guid = fields[0].GetUInt32();
  1773. + uint16 EventId = fields[1].GetUInt16();
  1774.  
  1775. - if(event_id >= mGameEventModelEquip.size())
  1776. + if(mGameEvent.find(EventId)==mGameEvent.end())
  1777. {
  1778. - sLog.outErrorDb("`game_event_model_equip` game event id (%u) is out of range compared to max event id in `game_event`",event_id);
  1779. + sLog.outErrorDb("`game_event_model_equip` game event id (%u) is out of range compared to max event id in `game_event`",EventId);
  1780. continue;
  1781. }
  1782.  
  1783. ++count;
  1784. - ModelEquipList& equiplist = mGameEventModelEquip[event_id];
  1785. ModelEquip newModelEquipSet;
  1786. newModelEquipSet.modelid = fields[2].GetUInt32();
  1787. newModelEquipSet.equipment_id = fields[3].GetUInt32();
  1788. @@ -308,12 +286,12 @@ void GameEventMgr::LoadFromDB()
  1789. {
  1790. if(!sObjectMgr.GetEquipmentInfo(newModelEquipSet.equipment_id))
  1791. {
  1792. - sLog.outErrorDb("Table `game_event_model_equip` have creature (Guid: %u) with equipment_id %u not found in table `creature_equip_template`, set to no equipment.", guid, newModelEquipSet.equipment_id);
  1793. + sLog.outErrorDb("Table `game_event_model_equip` have creature (Guid: %u) with equipment_id %u not found in table `creature_equip_template`, set to no equipment.", Guid, newModelEquipSet.equipment_id);
  1794. continue;
  1795. }
  1796. }
  1797.  
  1798. - equiplist.push_back(std::pair<uint32, ModelEquip>(guid, newModelEquipSet));
  1799. + mGameEventModelEquip[EventId].push_back(std::pair<uint32, ModelEquip>(Guid, newModelEquipSet));
  1800.  
  1801. } while( result->NextRow() );
  1802. delete result;
  1803. @@ -322,7 +300,6 @@ void GameEventMgr::LoadFromDB()
  1804. sLog.outString( ">> Loaded %u model/equipment changes in game events", count );
  1805. }
  1806.  
  1807. - mGameEventQuests.resize(mGameEvent.size());
  1808. // 0 1 2
  1809. result = WorldDatabase.Query("SELECT id, quest, event FROM game_event_creature_quest");
  1810.  
  1811. @@ -344,19 +321,18 @@ void GameEventMgr::LoadFromDB()
  1812. Field *fields = result->Fetch();
  1813.  
  1814. bar.step();
  1815. - uint32 id = fields[0].GetUInt32();
  1816. - uint32 quest = fields[1].GetUInt32();
  1817. - uint16 event_id = fields[2].GetUInt16();
  1818. + uint32 Id = fields[0].GetUInt32();
  1819. + uint32 Quest = fields[1].GetUInt32();
  1820. + uint16 EventId = fields[2].GetUInt16();
  1821.  
  1822. - if(event_id >= mGameEventQuests.size())
  1823. + if(mGameEvent.find(EventId)==mGameEvent.end())
  1824. {
  1825. - sLog.outErrorDb("`game_event_creature_quest` game event id (%u) is out of range compared to max event id in `game_event`",event_id);
  1826. + sLog.outErrorDb("`game_event_creature_quest` game event id (%u) not exist in `game_event`",EventId);
  1827. continue;
  1828. }
  1829.  
  1830. ++count;
  1831. - QuestRelList& questlist = mGameEventQuests[event_id];
  1832. - questlist.push_back(QuestRelation(id, quest));
  1833. + mGameEventQuests[EventId].push_back(QuestRelation(Id, Quest));
  1834.  
  1835. } while( result->NextRow() );
  1836. delete result;
  1837. @@ -365,7 +341,6 @@ void GameEventMgr::LoadFromDB()
  1838. sLog.outString( ">> Loaded %u quests additions in game events", count );
  1839. }
  1840.  
  1841. - mGameEventPoolIds.resize(mGameEvent.size()*2-1);
  1842. // 1 2
  1843. result = WorldDatabase.Query("SELECT pool_template.entry, game_event_pool.event "
  1844. "FROM pool_template JOIN game_event_pool ON pool_template.entry = game_event_pool.pool_entry");
  1845. @@ -389,26 +364,23 @@ void GameEventMgr::LoadFromDB()
  1846.  
  1847. bar2.step();
  1848.  
  1849. - uint32 entry = fields[0].GetUInt16();
  1850. - int16 event_id = fields[1].GetInt16();
  1851. -
  1852. - int32 internal_event_id = mGameEvent.size() + event_id - 1;
  1853. -
  1854. - if (internal_event_id < 0 || (size_t)internal_event_id >= mGameEventPoolIds.size())
  1855. + uint32 Entry = fields[0].GetUInt16();
  1856. + int16 EventId = fields[1].GetInt16();
  1857. + uint16 RealEventId = uint16(EventId < 0 ? EventId * -1 : EventId);
  1858. + if(mGameEvent.find(RealEventId)==mGameEvent.end())
  1859. {
  1860. - sLog.outErrorDb("`game_event_pool` game event id (%i) is out of range compared to max event id in `game_event`",event_id);
  1861. + sLog.outErrorDb("`game_event_pool` game event id (%u) not exist in `game_event`",RealEventId);
  1862. continue;
  1863. }
  1864.  
  1865. - if (!sPoolMgr.CheckPool(entry))
  1866. + if (!sPoolMgr.CheckPool(Entry))
  1867. {
  1868. - sLog.outErrorDb("Pool Id (%u) has all creatures or gameobjects with explicit chance sum <>100 and no equal chance defined. The pool system cannot pick one to spawn.", entry);
  1869. + sLog.outErrorDb("Pool Id (%u) has all creatures or gameobjects with explicit chance sum <>100 and no equal chance defined. The pool system cannot pick one to spawn.", Entry);
  1870. continue;
  1871. }
  1872.  
  1873. ++count;
  1874. - IdList& poollist = mGameEventPoolIds[internal_event_id];
  1875. - poollist.push_back(entry);
  1876. + mGameEventPoolIds[EventId].push_back(Entry);
  1877.  
  1878. } while( result->NextRow() );
  1879. sLog.outString();
  1880. @@ -419,7 +391,6 @@ void GameEventMgr::LoadFromDB()
  1881.  
  1882. uint32 GameEventMgr::Initialize() // return the next event delay in ms
  1883. {
  1884. - m_ActiveEvents.clear();
  1885. uint32 delay = Update();
  1886. sLog.outBasic("Game Event system initialized." );
  1887. m_IsGameEventsInit = true;
  1888. @@ -430,34 +401,34 @@ uint32 GameEventMgr::Update() // return the next e
  1889. {
  1890. uint32 nextEventDelay = max_ge_check_delay; // 1 day
  1891. uint32 calcDelay;
  1892. - for (uint16 itr = 1; itr < mGameEvent.size(); ++itr)
  1893. +
  1894. + for (GameEventDataMap::iterator iter = mGameEvent.begin(); iter != mGameEvent.end(); iter++)
  1895. {
  1896. //sLog.outErrorDb("Checking event %u",itr);
  1897. - if (CheckOneGameEvent(itr))
  1898. + if (CheckOneGameEvent(iter->second))
  1899. {
  1900. //sLog.outDebug("GameEvent %u is active",itr->first);
  1901. - if (!IsActiveEvent(itr))
  1902. - StartEvent(itr);
  1903. + if (!iter->second.active)
  1904. + StartEvent(iter->first);
  1905. }
  1906. else
  1907. {
  1908. //sLog.outDebug("GameEvent %u is not active",itr->first);
  1909. - if (IsActiveEvent(itr))
  1910. - StopEvent(itr);
  1911. + if (iter->second.active)
  1912. + StopEvent(iter->first);
  1913. else
  1914. {
  1915. if (!m_IsGameEventsInit)
  1916. {
  1917. - int16 event_nid = (-1) * (itr);
  1918. // spawn all negative ones for this event
  1919. - GameEventSpawn(event_nid);
  1920. + GameEventSpawn(int16(iter->first * -1));
  1921.  
  1922. // disable any event specific quest (for cases where creature is spawned, but event not active).
  1923. - UpdateEventQuests(itr, false);
  1924. + UpdateEventQuests(iter->first, false);
  1925. }
  1926. }
  1927. }
  1928. - calcDelay = NextCheck(itr);
  1929. + calcDelay = NextCheck(iter->second);
  1930. if (calcDelay < nextEventDelay)
  1931. nextEventDelay = calcDelay;
  1932. }
  1933. @@ -465,55 +436,58 @@ uint32 GameEventMgr::Update() // return the next e
  1934. return (nextEventDelay + 1) * IN_MILISECONDS; // Add 1 second to be sure event has started/stopped at next call
  1935. }
  1936.  
  1937. -void GameEventMgr::UnApplyEvent(uint16 event_id)
  1938. +void GameEventMgr::UnApplyEvent(uint16 EventId)
  1939. {
  1940. - sLog.outString("GameEvent %u \"%s\" removed.", event_id, mGameEvent[event_id].description.c_str());
  1941. + GameEventData gEvent = mGameEvent[EventId];
  1942. + sLog.outString("GameEvent %u \"%s\" removed.", EventId, gEvent.description.c_str());
  1943. // un-spawn positive event tagged objects
  1944. - GameEventUnspawn(event_id);
  1945. + GameEventUnspawn(EventId);
  1946. // spawn negative event tagget objects
  1947. - int16 event_nid = (-1) * event_id;
  1948. - GameEventSpawn(event_nid);
  1949. + GameEventSpawn(-1 * int16(EventId));
  1950. // restore equipment or model
  1951. - ChangeEquipOrModel(event_id, false);
  1952. + ChangeEquipOrModel(EventId, false);
  1953. // Remove quests that are events only to non event npc
  1954. - UpdateEventQuests(event_id, false);
  1955. -}
  1956. + UpdateEventQuests(EventId, false);
  1957.  
  1958. -void GameEventMgr::ApplyNewEvent(uint16 event_id)
  1959. -{
  1960. - switch(sWorld.getConfig(CONFIG_EVENT_ANNOUNCE))
  1961. + if(gEvent.node) // Update World Node Status
  1962. {
  1963. - case 0: // disable
  1964. - break;
  1965. - case 1: // announce events
  1966. - sWorld.SendWorldText(LANG_EVENTMESSAGE, mGameEvent[event_id].description.c_str());
  1967. - break;
  1968. + WorldPacket data(SMSG_UPDATE_WORLD_STATE, 8);
  1969. + data << uint32(gEvent.node) << uint32(false);
  1970. + sWorld.SendGlobalMessage(&data);
  1971. }
  1972. +}
  1973. +
  1974. +void GameEventMgr::ApplyNewEvent(uint16 EventId)
  1975. +{
  1976. + GameEventData gEvent = mGameEvent[EventId];
  1977. + if(sWorld.getConfig(CONFIG_EVENT_ANNOUNCE))
  1978. + sWorld.SendWorldText(LANG_EVENTMESSAGE, gEvent.description.c_str());
  1979.  
  1980. - sLog.outString("GameEvent %u \"%s\" started.", event_id, mGameEvent[event_id].description.c_str());
  1981. + sLog.outString("GameEvent %u \"%s\" started.", EventId, gEvent.description.c_str());
  1982. // spawn positive event tagget objects
  1983. - GameEventSpawn(event_id);
  1984. + GameEventSpawn(EventId);
  1985. // un-spawn negative event tagged objects
  1986. - int16 event_nid = (-1) * event_id;
  1987. - GameEventUnspawn(event_nid);
  1988. + GameEventUnspawn(-1 * int16(EventId));
  1989. // Change equipement or model
  1990. - ChangeEquipOrModel(event_id, true);
  1991. + ChangeEquipOrModel(EventId, true);
  1992. // Add quests that are events only to non event npc
  1993. - UpdateEventQuests(event_id, true);
  1994. + UpdateEventQuests(EventId, true);
  1995. +
  1996. + if(gEvent.node) // Update World Node Status
  1997. + {
  1998. + WorldPacket data(SMSG_UPDATE_WORLD_STATE, 8);
  1999. + data << uint32(gEvent.node) << uint32(true);
  2000. + sWorld.SendGlobalMessage(&data);
  2001. + }
  2002. }
  2003.  
  2004. -void GameEventMgr::GameEventSpawn(int16 event_id)
  2005. +void GameEventMgr::GameEventSpawn(int16 EventId)
  2006. {
  2007. - int32 internal_event_id = mGameEvent.size() + event_id - 1;
  2008. -
  2009. - if (internal_event_id < 0 || (size_t)internal_event_id >= mGameEventCreatureGuids.size())
  2010. - {
  2011. - sLog.outError("GameEventMgr::GameEventSpawn attempt access to out of range mGameEventCreatureGuids element %i (size: " SIZEFMTD ")",internal_event_id,mGameEventCreatureGuids.size());
  2012. - return;
  2013. - }
  2014. -
  2015. - for (GuidList::iterator itr = mGameEventCreatureGuids[internal_event_id].begin();itr != mGameEventCreatureGuids[internal_event_id].end();++itr)
  2016. + if(mGameEventCreatureGuids.find(EventId) != mGameEventCreatureGuids.end())
  2017. {
  2018. + GuidList CreatureList = mGameEventCreatureGuids[EventId];
  2019. + for (GuidList::iterator itr = CreatureList.begin();itr != CreatureList.end();++itr)
  2020. + {
  2021. // Add to correct cell
  2022. CreatureData const* data = sObjectMgr.GetCreatureData(*itr);
  2023. if (data)
  2024. @@ -536,69 +510,58 @@ void GameEventMgr::GameEventSpawn(int16 event_id)
  2025. map->Add(pCreature);
  2026. }
  2027. }
  2028. - }
  2029. - }
  2030. -
  2031. - if (internal_event_id < 0 || (size_t)internal_event_id >= mGameEventGameobjectGuids.size())
  2032. - {
  2033. - sLog.outError("GameEventMgr::GameEventSpawn attempt access to out of range mGameEventGameobjectGuids element %i (size: " SIZEFMTD ")",internal_event_id,mGameEventGameobjectGuids.size());
  2034. - return;
  2035. + }
  2036. + }
  2037. }
  2038.  
  2039. - for (GuidList::iterator itr = mGameEventGameobjectGuids[internal_event_id].begin();itr != mGameEventGameobjectGuids[internal_event_id].end();++itr)
  2040. + if(mGameEventGameobjectGuids.find(EventId) != mGameEventGameobjectGuids.end())
  2041. {
  2042. - // Add to correct cell
  2043. - GameObjectData const* data = sObjectMgr.GetGOData(*itr);
  2044. - if (data)
  2045. - {
  2046. - sObjectMgr.AddGameobjectToGrid(*itr, data);
  2047. - // Spawn if necessary (loaded grids only)
  2048. - // this base map checked as non-instanced and then only existed
  2049. - Map* map = const_cast<Map*>(sMapMgr.CreateBaseMap(data->mapid));
  2050. - // We use current coords to unspawn, not spawn coords since creature can have changed grid
  2051. - if(!map->Instanceable() && map->IsLoaded(data->posX, data->posY))
  2052. - {
  2053. - GameObject* pGameobject = new GameObject;
  2054. - //sLog.outDebug("Spawning gameobject %u", *itr);
  2055. - if (!pGameobject->LoadFromDB(*itr, map))
  2056. - {
  2057. - delete pGameobject;
  2058. - }
  2059. - else
  2060. - {
  2061. - if(pGameobject->isSpawnedByDefault())
  2062. - map->Add(pGameobject);
  2063. - }
  2064. - }
  2065. + GuidList GameObjectList = mGameEventGameobjectGuids[EventId];
  2066. + for (GuidList::iterator itr = GameObjectList.begin();itr != GameObjectList.end();++itr)
  2067. + {
  2068. +
  2069. + // Add to correct cell
  2070. + GameObjectData const* data = sObjectMgr.GetGOData(*itr);
  2071. + if (data)
  2072. + {
  2073. + sObjectMgr.AddGameobjectToGrid(*itr, data);
  2074. + // Spawn if necessary (loaded grids only)
  2075. + // this base map checked as non-instanced and then only existed
  2076. + Map* map = const_cast<Map*>(sMapMgr.CreateBaseMap(data->mapid));
  2077. + // We use current coords to unspawn, not spawn coords since creature can have changed grid
  2078. + if(!map->Instanceable() && map->IsLoaded(data->posX, data->posY))
  2079. + {
  2080. + GameObject* pGameobject = new GameObject;
  2081. + if (!pGameobject->LoadFromDB(*itr, map))
  2082. + delete pGameobject;
  2083. + else if(pGameobject->isSpawnedByDefault())
  2084. + map->Add(pGameobject);
  2085. + }
  2086. }
  2087. + }
  2088. }
  2089.  
  2090. - if (internal_event_id < 0 || (size_t)internal_event_id >= mGameEventPoolIds.size())
  2091. - {
  2092. - sLog.outError("GameEventMgr::GameEventSpawn attempt access to out of range mGameEventPoolIds element %i (size: " SIZEFMTD ")",internal_event_id,mGameEventPoolIds.size());
  2093. - return;
  2094. - }
  2095.  
  2096. - for (IdList::iterator itr = mGameEventPoolIds[internal_event_id].begin();itr != mGameEventPoolIds[internal_event_id].end();++itr)
  2097. + if(mGameEventPoolIds.find(EventId) != mGameEventPoolIds.end())
  2098. {
  2099. + IdList PoolList = mGameEventPoolIds[EventId];
  2100. + for (IdList::iterator itr = PoolList.begin();itr != PoolList.end();++itr)
  2101. + {
  2102. sPoolMgr.SpawnPool(*itr, 0, 0);
  2103. sPoolMgr.SpawnPool(*itr, 0, TYPEID_GAMEOBJECT);
  2104. sPoolMgr.SpawnPool(*itr, 0, TYPEID_UNIT);
  2105. + }
  2106. }
  2107. }
  2108.  
  2109. -void GameEventMgr::GameEventUnspawn(int16 event_id)
  2110. +void GameEventMgr::GameEventUnspawn(int16 EventId)
  2111. {
  2112. - int32 internal_event_id = mGameEvent.size() + event_id - 1;
  2113. -
  2114. - if (internal_event_id < 0 || (size_t)internal_event_id >= mGameEventCreatureGuids.size())
  2115. - {
  2116. - sLog.outError("GameEventMgr::GameEventUnspawn attempt access to out of range mGameEventCreatureGuids element %i (size: " SIZEFMTD ")",internal_event_id,mGameEventCreatureGuids.size());
  2117. - return;
  2118. - }
  2119.  
  2120. - for (GuidList::iterator itr = mGameEventCreatureGuids[internal_event_id].begin();itr != mGameEventCreatureGuids[internal_event_id].end();++itr)
  2121. + if(mGameEventCreatureGuids.find(EventId) != mGameEventCreatureGuids.end())
  2122. {
  2123. + GuidList CreatureList = mGameEventCreatureGuids[EventId];
  2124. + for (GuidList::iterator itr = CreatureList.begin();itr != CreatureList.end();++itr)
  2125. + {
  2126. // Remove the creature from grid
  2127. if( CreatureData const* data = sObjectMgr.GetCreatureData(*itr) )
  2128. {
  2129. @@ -607,16 +570,14 @@ void GameEventMgr::GameEventUnspawn(int16 event_id)
  2130. if( Creature* pCreature = ObjectAccessor::GetCreatureInWorld(MAKE_NEW_GUID(*itr, data->id, HIGHGUID_UNIT)) )
  2131. pCreature->AddObjectToRemoveList();
  2132. }
  2133. + }
  2134. }
  2135.  
  2136. - if (internal_event_id < 0 || (size_t)internal_event_id >= mGameEventGameobjectGuids.size())
  2137. - {
  2138. - sLog.outError("GameEventMgr::GameEventUnspawn attempt access to out of range mGameEventGameobjectGuids element %i (size: " SIZEFMTD ")",internal_event_id,mGameEventGameobjectGuids.size());
  2139. - return;
  2140. - }
  2141. -
  2142. - for (GuidList::iterator itr = mGameEventGameobjectGuids[internal_event_id].begin();itr != mGameEventGameobjectGuids[internal_event_id].end();++itr)
  2143. + if(mGameEventGameobjectGuids.find(EventId) != mGameEventGameobjectGuids.end())
  2144. {
  2145. + GuidList GameObjectList = mGameEventGameobjectGuids[EventId];
  2146. + for (GuidList::iterator itr = GameObjectList.begin();itr != GameObjectList.end();++itr)
  2147. + {
  2148. // Remove the gameobject from grid
  2149. if(GameObjectData const* data = sObjectMgr.GetGOData(*itr))
  2150. {
  2151. @@ -625,17 +586,15 @@ void GameEventMgr::GameEventUnspawn(int16 event_id)
  2152. if( GameObject* pGameobject = ObjectAccessor::GetGameObjectInWorld(MAKE_NEW_GUID(*itr, data->id, HIGHGUID_GAMEOBJECT)) )
  2153. pGameobject->AddObjectToRemoveList();
  2154. }
  2155. - }
  2156. - if (internal_event_id < 0 || (size_t)internal_event_id >= mGameEventPoolIds.size())
  2157. - {
  2158. - sLog.outError("GameEventMgr::GameEventUnspawn attempt access to out of range mGameEventPoolIds element %i (size: " SIZEFMTD ")",internal_event_id,mGameEventPoolIds.size());
  2159. - return;
  2160. + }
  2161. }
  2162.  
  2163. - for (IdList::iterator itr = mGameEventPoolIds[internal_event_id].begin();itr != mGameEventPoolIds[internal_event_id].end();++itr)
  2164. + if(mGameEventPoolIds.find(EventId) != mGameEventPoolIds.end())
  2165. {
  2166. - sPoolMgr.DespawnPool(*itr);
  2167. - }
  2168. + IdList PoolList = mGameEventPoolIds[EventId];
  2169. + for (IdList::iterator itr = PoolList.begin();itr != PoolList.end();++itr)
  2170. + sPoolMgr.DespawnPool(*itr);
  2171. + }
  2172. }
  2173.  
  2174. void GameEventMgr::ChangeEquipOrModel(int16 event_id, bool activate)
  2175. @@ -751,11 +710,9 @@ GameEventMgr::GameEventMgr()
  2176.  
  2177. MANGOS_DLL_SPEC bool IsHolidayActive( HolidayIds id )
  2178. {
  2179. - GameEventMgr::GameEventDataMap const& events = sGameEventMgr.GetEventMap();
  2180. - GameEventMgr::ActiveEvents const& ae = sGameEventMgr.GetActiveEventList();
  2181. -
  2182. - for(GameEventMgr::ActiveEvents::const_iterator itr = ae.begin(); itr != ae.end(); ++itr)
  2183. - if (events[*itr].holiday_id == id)
  2184. + GameEventMgr::GameEventDataMap const& Events = sGameEventMgr.GetEventMap();
  2185. + for(GameEventMgr::GameEventDataMap::const_iterator itr = Events.begin(); itr != Events.end(); ++itr)
  2186. + if(itr->second.holiday_id==id && itr->second.active)
  2187. return true;
  2188.  
  2189. return false;
  2190. diff --git a/src/game/GameEventMgr.h b/src/game/GameEventMgr.h
  2191. index cc61c4c..476d684 100644
  2192. --- a/src/game/GameEventMgr.h
  2193. +++ b/src/game/GameEventMgr.h
  2194. @@ -31,15 +31,15 @@ class GameObject;
  2195.  
  2196. struct GameEventData
  2197. {
  2198. - GameEventData() : start(1),end(0),occurence(0),length(0) {}
  2199. + GameEventData() : start(1),end(0),occurence(0),length(0),holiday_id(0),node(0),active(false) {}
  2200. time_t start;
  2201. time_t end;
  2202. + bool active;
  2203. uint32 occurence;
  2204. uint32 length;
  2205. + uint32 node;
  2206. uint32 holiday_id;
  2207. std::string description;
  2208. -
  2209. - bool isValid() const { return length > 0; }
  2210. };
  2211.  
  2212. struct ModelEquip
  2213. @@ -55,21 +55,19 @@ class GameEventMgr
  2214. public:
  2215. GameEventMgr();
  2216. ~GameEventMgr() {};
  2217. - typedef std::set<uint16> ActiveEvents;
  2218. - typedef std::vector<GameEventData> GameEventDataMap;
  2219. - ActiveEvents const& GetActiveEventList() const { return m_ActiveEvents; }
  2220. - GameEventDataMap const& GetEventMap() const { return mGameEvent; }
  2221. - bool CheckOneGameEvent(uint16 entry) const;
  2222. - uint32 NextCheck(uint16 entry) const;
  2223. - void LoadFromDB();
  2224. + typedef std::map<uint16,GameEventData> GameEventDataMap;
  2225. +
  2226. uint32 Update();
  2227. - bool IsActiveEvent(uint16 event_id) { return ( m_ActiveEvents.find(event_id)!=m_ActiveEvents.end()); }
  2228. +
  2229. + void LoadFromDB();
  2230. uint32 Initialize();
  2231. - void StartEvent(uint16 event_id, bool overwrite = false);
  2232. - void StopEvent(uint16 event_id, bool overwrite = false);
  2233. + uint32 NextCheck(GameEventData Event) const;
  2234. + bool CheckOneGameEvent(GameEventData Event) const;
  2235. + GameEventDataMap const& GetEventMap() const { return mGameEvent; }
  2236. +
  2237. + void StopEvent(uint16 EventId, bool OverWrite = false);
  2238. + void StartEvent(uint16 EventId, bool OverWrite = false);
  2239. private:
  2240. - void AddActiveEvent(uint16 event_id) { m_ActiveEvents.insert(event_id); }
  2241. - void RemoveActiveEvent(uint16 event_id) { m_ActiveEvents.erase(event_id); }
  2242. void ApplyNewEvent(uint16 event_id);
  2243. void UnApplyEvent(uint16 event_id);
  2244. void GameEventSpawn(int16 event_id);
  2245. @@ -79,21 +77,21 @@ class GameEventMgr
  2246. protected:
  2247. typedef std::list<uint32> GuidList;
  2248. typedef std::list<uint16> IdList;
  2249. - typedef std::vector<GuidList> GameEventGuidMap;
  2250. - typedef std::vector<IdList> GameEventIdMap;
  2251. + typedef std::map<int16,GuidList> GameEventGuidMap;
  2252. + typedef std::map<int16,IdList> GameEventIdMap;
  2253. typedef std::pair<uint32, ModelEquip> ModelEquipPair;
  2254. typedef std::list<ModelEquipPair> ModelEquipList;
  2255. - typedef std::vector<ModelEquipList> GameEventModelEquipMap;
  2256. + typedef std::map<uint16,ModelEquipList> GameEventModelEquipMap;
  2257. typedef std::pair<uint32, uint32> QuestRelation;
  2258. typedef std::list<QuestRelation> QuestRelList;
  2259. - typedef std::vector<QuestRelList> GameEventQuestMap;
  2260. - GameEventQuestMap mGameEventQuests;
  2261. + typedef std::map<uint16,QuestRelList> GameEventQuestMap;
  2262. +
  2263. GameEventModelEquipMap mGameEventModelEquip;
  2264. - GameEventGuidMap mGameEventCreatureGuids;
  2265. GameEventGuidMap mGameEventGameobjectGuids;
  2266. + GameEventGuidMap mGameEventCreatureGuids;
  2267. GameEventIdMap mGameEventPoolIds;
  2268. + GameEventQuestMap mGameEventQuests;
  2269. GameEventDataMap mGameEvent;
  2270. - ActiveEvents m_ActiveEvents;
  2271. bool m_IsGameEventsInit;
  2272. };
  2273.  
  2274. diff --git a/src/game/GridDefines.h b/src/game/GridDefines.h
  2275. index ebfbf20..864489c 100644
  2276. --- a/src/game/GridDefines.h
  2277. +++ b/src/game/GridDefines.h
  2278. @@ -40,7 +40,7 @@ class Player;
  2279. #define CENTER_GRID_OFFSET (SIZE_OF_GRIDS/2)
  2280.  
  2281. #define MIN_GRID_DELAY (MINUTE*IN_MILISECONDS)
  2282. -#define MIN_MAP_UPDATE_DELAY 50
  2283. +#define MIN_MAP_UPDATE_DELAY 35
  2284.  
  2285. #define MAX_NUMBER_OF_CELLS 8
  2286. #define SIZE_OF_GRID_CELL (SIZE_OF_GRIDS/MAX_NUMBER_OF_CELLS)
  2287. diff --git a/src/game/Group.cpp b/src/game/Group.cpp
  2288. index 18e77bf..2ca13a0 100644
  2289. --- a/src/game/Group.cpp
  2290. +++ b/src/game/Group.cpp
  2291. @@ -1444,7 +1444,7 @@ uint32 Group::CanJoinBattleGroundQueue(BattleGroundTypeId bgTypeId, BattleGround
  2292. if(!reference)
  2293. return BG_JOIN_ERR_OFFLINE_MEMBER;
  2294.  
  2295. - BGQueueIdBasedOnLevel queue_id = reference->GetBattleGroundQueueIdFromLevel();
  2296. + uint8 queue_id = reference->GetBGLevelQueueId();
  2297. uint32 arenaTeamId = reference->GetArenaTeamId(arenaSlot);
  2298. uint32 team = reference->GetTeam();
  2299.  
  2300. @@ -1459,7 +1459,7 @@ uint32 Group::CanJoinBattleGroundQueue(BattleGroundTypeId bgTypeId, BattleGround
  2301. if(member->GetTeam() != team)
  2302. return BG_JOIN_ERR_MIXED_FACTION;
  2303. // not in the same battleground level braket, don't let join
  2304. - if(member->GetBattleGroundQueueIdFromLevel() != queue_id)
  2305. + if(member->GetBGLevelQueueId() != queue_id)
  2306. return BG_JOIN_ERR_MIXED_LEVELS;
  2307. // don't let join rated matches if the arena team id doesn't match
  2308. if(isRated && member->GetArenaTeamId(arenaSlot) != arenaTeamId)
  2309. diff --git a/src/game/InstanceData.cpp b/src/game/InstanceData.cpp
  2310. index 394aa58..c1f236a 100644
  2311. --- a/src/game/InstanceData.cpp
  2312. +++ b/src/game/InstanceData.cpp
  2313. @@ -22,8 +22,10 @@
  2314.  
  2315. void InstanceData::SaveToDB()
  2316. {
  2317. - if(!Save()) return;
  2318. - std::string data = Save();
  2319. - CharacterDatabase.escape_string(data);
  2320. - CharacterDatabase.PExecute("UPDATE instance SET data = '%s' WHERE id = '%d'", data.c_str(), instance->GetInstanceId());
  2321. + if(const char *data_str = Save())
  2322. + {
  2323. + std::string data = data_str;
  2324. + CharacterDatabase.escape_string(data);
  2325. + CharacterDatabase.PExecute("UPDATE instance SET data = '%s' WHERE id = '%d'", data.c_str(), instance->GetInstanceId());
  2326. + }
  2327. }
  2328. diff --git a/src/game/Level2.cpp b/src/game/Level2.cpp
  2329. index ca2cc96..9bc41c5 100644
  2330. --- a/src/game/Level2.cpp
  2331. +++ b/src/game/Level2.cpp
  2332. @@ -398,9 +398,9 @@ bool ChatHandler::HandleGoObjectCommand(const char* args)
  2333.  
  2334. bool ChatHandler::HandleGameObjectTargetCommand(const char* args)
  2335. {
  2336. - Player* pl = m_session->GetPlayer();
  2337. QueryResult *result;
  2338. - GameEventMgr::ActiveEvents const& activeEventsList = sGameEventMgr.GetActiveEventList();
  2339. + Player* pl = m_session->GetPlayer();
  2340. + GameEventMgr::GameEventDataMap const& Events = sGameEventMgr.GetEventMap();
  2341. if(*args)
  2342. {
  2343. // number or [name] Shift-click form |color|Hgameobject_entry:go_id|h[name]|h|r
  2344. @@ -429,15 +429,18 @@ bool ChatHandler::HandleGameObjectTargetCommand(const char* args)
  2345. eventFilter << " AND (event IS NULL ";
  2346. bool initString = true;
  2347.  
  2348. - for (GameEventMgr::ActiveEvents::const_iterator itr = activeEventsList.begin(); itr != activeEventsList.end(); ++itr)
  2349. + for (GameEventMgr::GameEventDataMap::const_iterator itr = Events.begin(); itr != Events.end(); ++itr)
  2350. {
  2351. + if(itr->second.active)
  2352. + {
  2353. if (initString)
  2354. {
  2355. - eventFilter << "OR event IN (" <<*itr;
  2356. - initString =false;
  2357. + eventFilter << "OR event IN (" << itr->first;
  2358. + initString =false;
  2359. }
  2360. else
  2361. - eventFilter << "," << *itr;
  2362. + eventFilter << "," << itr->first;
  2363. + }
  2364. }
  2365.  
  2366. if (!initString)
  2367. @@ -3689,12 +3692,10 @@ bool ChatHandler::HandleLookupEventCommand(const char* args)
  2368.  
  2369. uint32 counter = 0;
  2370.  
  2371. - GameEventMgr::GameEventDataMap const& events = sGameEventMgr.GetEventMap();
  2372. - GameEventMgr::ActiveEvents const& activeEvents = sGameEventMgr.GetActiveEventList();
  2373. -
  2374. - for(uint32 id = 0; id < events.size(); ++id )
  2375. + GameEventMgr::GameEventDataMap const &gEvents = sGameEventMgr.GetEventMap();
  2376. + for (GameEventMgr::GameEventDataMap::const_iterator iter = gEvents.begin(); iter != gEvents.end(); iter++)
  2377. {
  2378. - GameEventData const& eventData = events[id];
  2379. + GameEventData eventData = iter->second;
  2380.  
  2381. std::string descr = eventData.description;
  2382. if(descr.empty())
  2383. @@ -3702,12 +3703,12 @@ bool ChatHandler::HandleLookupEventCommand(const char* args)
  2384.  
  2385. if (Utf8FitTo(descr, wnamepart))
  2386. {
  2387. - char const* active = activeEvents.find(id) != activeEvents.end() ? GetMangosString(LANG_ACTIVE) : "";
  2388. + char const* active = eventData.active ? GetMangosString(LANG_ACTIVE) : "";
  2389.  
  2390. if(m_session)
  2391. - PSendSysMessage(LANG_EVENT_ENTRY_LIST_CHAT,id,id,eventData.description.c_str(),active );
  2392. + PSendSysMessage(LANG_EVENT_ENTRY_LIST_CHAT,iter->first,iter->first,eventData.description.c_str(),active );
  2393. else
  2394. - PSendSysMessage(LANG_EVENT_ENTRY_LIST_CONSOLE,id,eventData.description.c_str(),active );
  2395. + PSendSysMessage(LANG_EVENT_ENTRY_LIST_CONSOLE,iter->first,eventData.description.c_str(),active );
  2396.  
  2397. ++counter;
  2398. }
  2399. @@ -3727,16 +3728,15 @@ bool ChatHandler::HandleEventListCommand(const char* args)
  2400. if (arg == "all")
  2401. all = true;
  2402.  
  2403. - GameEventMgr::GameEventDataMap const& events = sGameEventMgr.GetEventMap();
  2404. - GameEventMgr::ActiveEvents const& activeEvents = sGameEventMgr.GetActiveEventList();
  2405. + GameEventMgr::GameEventDataMap const& gEvents = sGameEventMgr.GetEventMap();
  2406.  
  2407. char const* active = GetMangosString(LANG_ACTIVE);
  2408. char const* inactive = GetMangosString(LANG_FACTION_INACTIVE);
  2409. char const* state = "";
  2410.  
  2411. - for (uint32 event_id = 0; event_id < events.size(); ++event_id)
  2412. + for (GameEventMgr::GameEventDataMap::const_iterator iter = gEvents.begin(); iter != gEvents.end(); iter++)
  2413. {
  2414. - if (activeEvents.find(event_id) == activeEvents.end())
  2415. + if (!iter->second.active)
  2416. {
  2417. if (!all)
  2418. continue;
  2419. @@ -3745,12 +3745,12 @@ bool ChatHandler::HandleEventListCommand(const char* args)
  2420. else
  2421. state = active;
  2422.  
  2423. - GameEventData const& eventData = events[event_id];
  2424. + GameEventData eventData = iter->second;
  2425.  
  2426. if(m_session)
  2427. - PSendSysMessage(LANG_EVENT_ENTRY_LIST_CHAT, event_id, event_id, eventData.description.c_str(), state);
  2428. + PSendSysMessage(LANG_EVENT_ENTRY_LIST_CHAT, iter->first, iter->first, eventData.description.c_str(), state);
  2429. else
  2430. - PSendSysMessage(LANG_EVENT_ENTRY_LIST_CONSOLE, event_id, eventData.description.c_str(), state);
  2431. + PSendSysMessage(LANG_EVENT_ENTRY_LIST_CONSOLE, iter->first, eventData.description.c_str(), state);
  2432.  
  2433. ++counter;
  2434. }
  2435. @@ -3771,33 +3771,23 @@ bool ChatHandler::HandleEventInfoCommand(const char* args)
  2436. if(!cId)
  2437. return false;
  2438.  
  2439. - uint32 event_id = atoi(cId);
  2440. + uint32 event_id = uint32(atoi(cId));
  2441.  
  2442. - GameEventMgr::GameEventDataMap const& events = sGameEventMgr.GetEventMap();
  2443. -
  2444. - if(event_id >=events.size())
  2445. - {
  2446. - SendSysMessage(LANG_EVENT_NOT_EXIST);
  2447. - SetSentErrorMessage(true);
  2448. - return false;
  2449. - }
  2450. + GameEventMgr::GameEventDataMap gEvents = ((GameEventMgr::GameEventDataMap)sGameEventMgr.GetEventMap());
  2451.  
  2452. - GameEventData const& eventData = events[event_id];
  2453. - if(!eventData.isValid())
  2454. + if(gEvents.find(event_id) == gEvents.end())
  2455. {
  2456. SendSysMessage(LANG_EVENT_NOT_EXIST);
  2457. SetSentErrorMessage(true);
  2458. return false;
  2459. }
  2460.  
  2461. - GameEventMgr::ActiveEvents const& activeEvents = sGameEventMgr.GetActiveEventList();
  2462. - bool active = activeEvents.find(event_id) != activeEvents.end();
  2463. - char const* activeStr = active ? GetMangosString(LANG_ACTIVE) : "";
  2464. -
  2465. + GameEventData eventData = gEvents[event_id];
  2466. + char const* activeStr = eventData.active ? GetMangosString(LANG_ACTIVE) : "";
  2467. std::string startTimeStr = TimeToTimestampStr(eventData.start);
  2468. std::string endTimeStr = TimeToTimestampStr(eventData.end);
  2469.  
  2470. - uint32 delay = sGameEventMgr.NextCheck(event_id);
  2471. + uint32 delay = sGameEventMgr.NextCheck(eventData);
  2472. time_t nextTime = time(NULL)+delay;
  2473. std::string nextStr = nextTime >= eventData.start && nextTime < eventData.end ? TimeToTimestampStr(time(NULL)+delay) : "-";
  2474.  
  2475. @@ -3820,27 +3810,18 @@ bool ChatHandler::HandleEventStartCommand(const char* args)
  2476. if(!cId)
  2477. return false;
  2478.  
  2479. - int32 event_id = atoi(cId);
  2480. -
  2481. - GameEventMgr::GameEventDataMap const& events = sGameEventMgr.GetEventMap();
  2482. -
  2483. - if(event_id < 1 || event_id >=events.size())
  2484. - {
  2485. - SendSysMessage(LANG_EVENT_NOT_EXIST);
  2486. - SetSentErrorMessage(true);
  2487. - return false;
  2488. - }
  2489. + uint32 event_id = uint32(atoi(cId));
  2490. + GameEventMgr::GameEventDataMap events = ((GameEventMgr::GameEventDataMap)sGameEventMgr.GetEventMap());
  2491.  
  2492. - GameEventData const& eventData = events[event_id];
  2493. - if(!eventData.isValid())
  2494. + if(events.find(event_id)==events.end())
  2495. {
  2496. SendSysMessage(LANG_EVENT_NOT_EXIST);
  2497. SetSentErrorMessage(true);
  2498. return false;
  2499. }
  2500. + GameEventData eventData = events[event_id];
  2501.  
  2502. - GameEventMgr::ActiveEvents const& activeEvents = sGameEventMgr.GetActiveEventList();
  2503. - if(activeEvents.find(event_id) != activeEvents.end())
  2504. + if(eventData.active)
  2505. {
  2506. PSendSysMessage(LANG_EVENT_ALREADY_ACTIVE,event_id);
  2507. SetSentErrorMessage(true);
  2508. @@ -3862,28 +3843,19 @@ bool ChatHandler::HandleEventStopCommand(const char* args)
  2509. if(!cId)
  2510. return false;
  2511.  
  2512. - int32 event_id = atoi(cId);
  2513. -
  2514. - GameEventMgr::GameEventDataMap const& events = sGameEventMgr.GetEventMap();
  2515. -
  2516. - if(event_id < 1 || event_id >=events.size())
  2517. - {
  2518. - SendSysMessage(LANG_EVENT_NOT_EXIST);
  2519. - SetSentErrorMessage(true);
  2520. - return false;
  2521. - }
  2522. + uint32 event_id = uint32(atoi(cId));
  2523. + GameEventMgr::GameEventDataMap gEvents = ((GameEventMgr::GameEventDataMap)sGameEventMgr.GetEventMap());
  2524.  
  2525. - GameEventData const& eventData = events[event_id];
  2526. - if(!eventData.isValid())
  2527. + if(gEvents.find(event_id) == gEvents.end())
  2528. {
  2529. SendSysMessage(LANG_EVENT_NOT_EXIST);
  2530. SetSentErrorMessage(true);
  2531. return false;
  2532. }
  2533.  
  2534. - GameEventMgr::ActiveEvents const& activeEvents = sGameEventMgr.GetActiveEventList();
  2535. + GameEventData eventData = gEvents[event_id];
  2536.  
  2537. - if(activeEvents.find(event_id) == activeEvents.end())
  2538. + if(!eventData.active)
  2539. {
  2540. PSendSysMessage(LANG_EVENT_NOT_ACTIVE,event_id);
  2541. SetSentErrorMessage(true);
  2542. diff --git a/src/game/Map.cpp b/src/game/Map.cpp
  2543. index 2347b00..9807287 100644
  2544. --- a/src/game/Map.cpp
  2545. +++ b/src/game/Map.cpp
  2546. @@ -25,7 +25,9 @@
  2547. #include "CellImpl.h"
  2548. #include "InstanceData.h"
  2549. #include "Map.h"
  2550. +#include "BattleGroundMgr.h"
  2551. #include "GridNotifiersImpl.h"
  2552. +#include "Database/DatabaseImpl.h"
  2553. #include "Config/ConfigEnv.h"
  2554. #include "Transports.h"
  2555. #include "ObjectAccessor.h"
  2556. @@ -54,6 +56,44 @@ struct ScriptAction
  2557. ScriptInfo const* script; // pointer to static script data
  2558. };
  2559.  
  2560. +class MapRunnable : public ACE_Based::Runnable //Map Updater Class
  2561. +{
  2562. + public:
  2563. + MapRunnable(Map *map) : m_Map(map),m_resultQueue(NULL){}
  2564. + ~MapRunnable(){ CharacterDatabase.UnSetResultQueue(m_resultQueue); }
  2565. +
  2566. + void run()
  2567. + {
  2568. + IntervalTimer i_timer;
  2569. + uint32 realCurrTime = 0,realPrevTime = getMSTime();
  2570. + i_timer.SetInterval(sWorld.getConfig(CONFIG_MAPUPDATER_INTERVAL));
  2571. + while(!sWorld.m_WorldStarted) // Sleep while server isnt completly online
  2572. + ACE_Based::Thread::Sleep(MIN_UNLOAD_DELAY);
  2573. +
  2574. + m_resultQueue = new SqlResultQueue;
  2575. + CharacterDatabase.SetResultQueue(m_resultQueue);
  2576. +
  2577. + while(!World::IsStopped())
  2578. + {
  2579. + realCurrTime = getMSTime();
  2580. + i_timer.Update(realCurrTime - realPrevTime);
  2581. +
  2582. + if(i_timer.Passed())
  2583. + {
  2584. + m_Map->Update(i_timer.GetCurrent());
  2585. + m_resultQueue->Update();
  2586. + i_timer.SetCurrent(0);
  2587. + }else ACE_Based::Thread::Sleep(MIN_UNLOAD_DELAY); //Avoid High CPU Usage
  2588. +
  2589. + realPrevTime = realCurrTime;
  2590. + }
  2591. + }
  2592. +
  2593. + protected:
  2594. + Map *m_Map;
  2595. + SqlResultQueue *m_resultQueue;
  2596. +};
  2597. +
  2598. Map::~Map()
  2599. {
  2600. ObjectAccessor::DelinkMap(this);
  2601. @@ -198,12 +238,11 @@ void Map::DeleteStateMachine()
  2602. }
  2603.  
  2604. Map::Map(uint32 id, time_t expiry, uint32 InstanceId, uint8 SpawnMode, Map* _parent)
  2605. - : i_mapEntry (sMapStore.LookupEntry(id)), i_spawnMode(SpawnMode),
  2606. - i_id(id), i_InstanceId(InstanceId), m_unloadTimer(0),
  2607. - m_VisibleDistance(DEFAULT_VISIBILITY_DISTANCE),
  2608. - m_activeNonPlayersIter(m_activeNonPlayers.end()),
  2609. - i_gridExpiry(expiry), m_parentMap(_parent ? _parent : this),
  2610. - m_hiDynObjectGuid(1), m_hiPetGuid(1), m_hiVehicleGuid(1)
  2611. +: i_mapEntry (sMapStore.LookupEntry(id)), i_spawnMode(SpawnMode), m_hiVehicleGuid(1),
  2612. +m_hiPetGuid(1), i_InstanceId(InstanceId), stUpdater(UPDATER_ACTIVE), m_unloadTimer(0),
  2613. +m_activeNonPlayersIter(m_activeNonPlayers.end()), i_id(id),m_hiDynObjectGuid(1),
  2614. +i_gridExpiry(expiry), m_parentMap(_parent ? _parent : this),
  2615. +m_VisibleDistance(DEFAULT_VISIBILITY_DISTANCE)
  2616. {
  2617. for(unsigned int idx=0; idx < MAX_NUMBER_OF_GRIDS; ++idx)
  2618. {
  2619. @@ -585,15 +624,32 @@ bool Map::loaded(const GridPair &p) const
  2620. return ( getNGrid(p.x_coord, p.y_coord) && isGridObjectDataLoaded(p.x_coord, p.y_coord) );
  2621. }
  2622.  
  2623. +bool Map::HaveParentPlayers()
  2624. +{
  2625. + if(!i_InstanceId && Instanceable())
  2626. + {
  2627. + MapInstanced::InstancedMaps InstanceList = ((MapInstanced*)this)->GetInstancedMaps();
  2628. + for(MapInstanced::InstancedMaps::iterator m_Iter = InstanceList.begin(); m_Iter != InstanceList.end(); m_Iter++)
  2629. + if(!m_Iter->second->GetPlayers().isEmpty())
  2630. + return true;
  2631. + }
  2632. + else if(!GetPlayers().isEmpty())
  2633. + return true;
  2634. + return false;
  2635. +}
  2636. +
  2637. void Map::Update(const uint32 &t_diff)
  2638. {
  2639. - /// update players at tick
  2640. - for(m_mapRefIter = m_mapRefManager.begin(); m_mapRefIter != m_mapRefManager.end(); ++m_mapRefIter)
  2641. - {
  2642. - Player* plr = m_mapRefIter->getSource();
  2643. - if(plr && plr->IsInWorld())
  2644. - plr->Update(t_diff);
  2645. - }
  2646. + //Unload unused map only if there isnt transports, if isnt a continent and isnt a BG or arena
  2647. + if(m_parentMap == this && sMapMgr.m_TransportsByMap.end() == sMapMgr.m_TransportsByMap.find(i_id) &&
  2648. + Instanceable() && !IsBattleGroundOrArena())
  2649. + {
  2650. + bool bHavePlayers = HaveParentPlayers();
  2651. + if(bHavePlayers && m_unloadTimer)
  2652. + m_unloadTimer = 0;
  2653. + else if(!bHavePlayers && !m_unloadTimer)
  2654. + m_unloadTimer = sWorld.getConfig(CONFIG_MAPUPDATER_UNLOAD_DELAY);
  2655. + }
  2656.  
  2657. /// update active cells around players and active objects
  2658. resetMarkedCells();
  2659. @@ -606,11 +662,32 @@ void Map::Update(const uint32 &t_diff)
  2660.  
  2661. // the player iterator is stored in the map object
  2662. // to make sure calls to Map::Remove don't invalidate it
  2663. - for(m_mapRefIter = m_mapRefManager.begin(); m_mapRefIter != m_mapRefManager.end(); ++m_mapRefIter)
  2664. + MapRefManager::iterator m_mapNextRefIter = m_mapRefIter;
  2665. + for(m_mapRefIter = m_mapRefManager.begin(); m_mapRefIter != m_mapRefManager.end(); m_mapRefIter = m_mapNextRefIter)
  2666. {
  2667. - Player* plr = m_mapRefIter->getSource();
  2668. + //Avoid crash at erase somewhere
  2669. + m_mapNextRefIter = m_mapRefIter; ++m_mapNextRefIter;
  2670. +
  2671. + if(Player* plr = m_mapRefIter->getSource())
  2672. + {
  2673. + if(WorldSession *m_sess = plr->GetSession())
  2674. + {
  2675. + if(!m_sess->IsUpdating())
  2676. + {
  2677. + m_sess->SetUpdating(true);
  2678.  
  2679. - if(!plr->IsInWorld())
  2680. + if(plr->IsInWorld())
  2681. + plr->Update(t_diff);
  2682. +
  2683. + if(m_sess->GetUpdateStatus() == SESSION_UPDATE_MAP)
  2684. + if(!m_sess->Update(0)) // If session update fails move it to remove queue
  2685. + m_sess->SetUpdateStatus(SESSION_REMOVE_QUEUE);
  2686. +
  2687. + m_sess->SetUpdating(false);
  2688. + }
  2689. + }
  2690. +
  2691. + if(!plr->IsInWorld())
  2692. continue;
  2693.  
  2694. CellPair standing_cell(MaNGOS::ComputeCellPair(plr->GetPositionX(), plr->GetPositionY()));
  2695. @@ -646,6 +723,7 @@ void Map::Update(const uint32 &t_diff)
  2696. }
  2697. }
  2698. }
  2699. + }
  2700. }
  2701.  
  2702. // non-player active objects
  2703. @@ -718,6 +796,15 @@ void Map::Update(const uint32 &t_diff)
  2704. ///- Process necessary scripts
  2705. if (!m_scriptSchedule.empty())
  2706. ScriptsProcess();
  2707. +
  2708. + DoDelayedMovesAndRemoves();
  2709. +}
  2710. +
  2711. +void Map::DelayedNotifyPosition(Player *player)
  2712. +{
  2713. + CellPair p = MaNGOS::ComputeCellPair(player->GetPositionX(), player->GetPositionY());
  2714. + Cell cell(p);
  2715. + AddNotifier(player,cell,p);
  2716. }
  2717.  
  2718. void Map::Remove(Player *player, bool remove)
  2719. @@ -1116,8 +1203,9 @@ bool Map::UnloadGrid(const uint32 &x, const uint32 &y, bool pForce)
  2720.  
  2721. void Map::UnloadAll(bool pForce)
  2722. {
  2723. - // clear all delayed moves, useless anyway do this moves before map unload.
  2724. - i_creaturesToMove.clear();
  2725. +
  2726. + i_creaturesToMove.clear(); // clear all delayed moves
  2727. + i_objectsToClientUpdate.clear(); //Clear update object set
  2728.  
  2729. for (GridRefManager<NGridType>::iterator i = GridRefManager<NGridType>::begin(); i != GridRefManager<NGridType>::end(); )
  2730. {
  2731. @@ -2198,6 +2286,77 @@ uint32 Map::GetPlayersCountExceptGMs() const
  2732. return count;
  2733. }
  2734.  
  2735. +void Map::Restart()
  2736. +{
  2737. + stUpdater = UPDATER_RESTARTING;
  2738. +
  2739. + if(Instanceable())
  2740. + {
  2741. + // Process Players in instances on this map
  2742. + MapInstanced::InstancedMaps InstanceList = ((MapInstanced*)this)->GetInstancedMaps();
  2743. + for(MapInstanced::InstancedMaps::iterator m_Iter = InstanceList.begin(); m_Iter != InstanceList.end(); m_Iter++)
  2744. + {
  2745. + PlayerList const& pList = m_Iter->second->GetPlayers();
  2746. +
  2747. + for(PlayerList::const_iterator itr = pList.begin(), next; itr != pList.end(); itr = next)
  2748. + {
  2749. + next = itr; ++next;
  2750. + if(Player *_player = itr->getSource())
  2751. + {
  2752. + if(WorldSession *m_sess = _player->GetSession())
  2753. + {
  2754. + uint32 B_Time = getMSTime(); // Try to prevent full crash for 2 seconds if it's login
  2755. + while(m_sess->PlayerLoading() && m_sess->IsUpdating() && (getMSTime()-B_Time) < 2000);
  2756. + _player->CombatStop(true); //Stop Attacking
  2757. + _player->getHostileRefManager().deleteReferences();
  2758. + m_sess->LogoutPlayer(true); // Send logout to players
  2759. + m_sess->SetUpdating(false); //
  2760. + m_sess->SetUpdateStatus(SESSION_UPDATE_WORLD); // Change Session processor to World Thread
  2761. + }
  2762. + }
  2763. + }
  2764. +
  2765. + if(InstanceData *i_data = ((InstanceMap *)m_Iter->second)->GetInstanceData())
  2766. + i_data->SaveToDB(); // Save all InstanceData on this map
  2767. + }
  2768. + }
  2769. + else
  2770. + { //Process players in Continent map
  2771. + MapRefManager::iterator next;
  2772. + for(m_mapRefIter = m_mapRefManager.begin(); m_mapRefIter != m_mapRefManager.end(); m_mapRefIter = next)
  2773. + {
  2774. + next = m_mapRefIter; ++next;
  2775. + if(Player *_player = m_mapRefIter->getSource())
  2776. + {
  2777. + if(WorldSession *m_sess = _player ? _player->GetSession() : NULL)
  2778. + {
  2779. + uint32 B_Time = getMSTime(); // Try to prevent full crash for 2 seconds if it's login
  2780. + while(m_sess->PlayerLoading() && m_sess->IsUpdating() && (getMSTime()-B_Time) < 2000);
  2781. + _player->CombatStop(true); //Stop Attacking
  2782. + _player->getHostileRefManager().deleteReferences();
  2783. + m_sess->LogoutPlayer(true); // Send logout to players
  2784. + m_sess->SetUpdating(false); //
  2785. + m_sess->SetUpdateStatus(SESSION_UPDATE_WORLD); //Change Session processor to World Thread
  2786. + }
  2787. + }
  2788. + }
  2789. + }
  2790. +
  2791. + UnloadAll(true); //Map Unload
  2792. + stUpdater = UPDATER_PAUSED;
  2793. +}
  2794. +
  2795. +bool Map::StartUpdater()
  2796. +{
  2797. + sLog.outDebug("MapUpdater: Initializated for map %u.\r\n",GetId());
  2798. + uThread = new ACE_Based::Thread(new MapRunnable(this));
  2799. + stUpdater = UPDATER_ACTIVE;
  2800. + return bool(uThread->ThreadId());
  2801. +}
  2802. +
  2803. +bool Map::StopUpdater()
  2804. +{ return ACE_Based::Thread::kill_self(); }
  2805. +
  2806. void Map::SendToPlayers(WorldPacket const* data) const
  2807. {
  2808. for(MapRefManager::const_iterator itr = m_mapRefManager.begin(); itr != m_mapRefManager.end(); ++itr)
  2809. @@ -2671,6 +2830,19 @@ bool BattleGroundMap::CanEnter(Player * player)
  2810. return Map::CanEnter(player);
  2811. }
  2812.  
  2813. +void BattleGroundMap::Update(const uint32& t_diff)
  2814. +{
  2815. + Map::Update(t_diff);
  2816. + if(m_bg)
  2817. + {
  2818. + m_bg->Update(t_diff);
  2819. +
  2820. + if (m_bg->CanUnload())
  2821. + sBattleGroundMgr.DestroyBattleGround(m_bg);
  2822. + }
  2823. +
  2824. +}
  2825. +
  2826. bool BattleGroundMap::Add(Player * player)
  2827. {
  2828. {
  2829. diff --git a/src/game/Map.h b/src/game/Map.h
  2830. index d63cb51..10d7148 100644
  2831. --- a/src/game/Map.h
  2832. +++ b/src/game/Map.h
  2833. @@ -68,6 +68,14 @@ typedef RGuard<GridRWLock, ACE_Thread_Mutex> GridReadGuard;
  2834. typedef WGuard<GridRWLock, ACE_Thread_Mutex> GridWriteGuard;
  2835. typedef MaNGOS::SingleThreaded<GridRWLock>::Lock NullGuard;
  2836.  
  2837. +enum UpdaterStatus
  2838. +{
  2839. + UPDATER_ACTIVE = 1,
  2840. + UPDATER_RESTARTING = 2,
  2841. + UPDATER_PAUSED = 3,
  2842. + UPDATER_STOP = 4
  2843. +};
  2844. +
  2845. //******************************************
  2846. // Map file format defines
  2847. //******************************************
  2848. @@ -397,6 +405,7 @@ class MANGOS_DLL_SPEC Map : public GridRefManager<NGridType>, public MaNGOS::Obj
  2849. }
  2850.  
  2851. void AddObjectToRemoveList(WorldObject *obj);
  2852. + void DelayedNotifyPosition( Player * player );
  2853. void DoDelayedMovesAndRemoves();
  2854.  
  2855. virtual bool RemoveBones(uint64 guid, float x, float y);
  2856. @@ -409,10 +418,16 @@ class MANGOS_DLL_SPEC Map : public GridRefManager<NGridType>, public MaNGOS::Obj
  2857. bool isCellMarked(uint32 pCellId) { return marked_cells.test(pCellId); }
  2858. void markCell(uint32 pCellId) { marked_cells.set(pCellId); }
  2859.  
  2860. + bool HaveParentPlayers();
  2861. bool HavePlayers() const { return !m_mapRefManager.isEmpty(); }
  2862. uint32 GetPlayersCountExceptGMs() const;
  2863. bool ActiveObjectsNearGrid(uint32 x,uint32 y) const;
  2864.  
  2865. + void Restart();
  2866. + bool StopUpdater();
  2867. + bool StartUpdater();
  2868. + ACE_Based::Thread *GetThread(){ return uThread; }
  2869. + UpdaterStatus GetUpdaterStatus() { return stUpdater; }
  2870. void SendToPlayers(WorldPacket const* data) const;
  2871.  
  2872. typedef MapRefManager PlayerList;
  2873. @@ -517,6 +532,8 @@ class MANGOS_DLL_SPEC Map : public GridRefManager<NGridType>, public MaNGOS::Obj
  2874.  
  2875. MapRefManager m_mapRefManager;
  2876. MapRefManager::iterator m_mapRefIter;
  2877. + ACE_Based::Thread *uThread;
  2878. + UpdaterStatus stUpdater;
  2879.  
  2880. typedef std::set<WorldObject*> ActiveNonPlayers;
  2881. ActiveNonPlayers m_activeNonPlayers;
  2882. @@ -621,12 +638,12 @@ class MANGOS_DLL_SPEC BattleGroundMap : public Map
  2883. BattleGroundMap(uint32 id, time_t, uint32 InstanceId, Map* _parent, uint8 spawnMode);
  2884. ~BattleGroundMap();
  2885.  
  2886. + void SetUnload();
  2887. bool Add(Player *);
  2888. + void Update(const uint32&);
  2889. void Remove(Player *, bool);
  2890. - bool CanEnter(Player* player);
  2891. - void SetUnload();
  2892. void UnloadAll(bool pForce);
  2893. -
  2894. + bool CanEnter(Player* player);
  2895. virtual void InitVisibilityDistance();
  2896. BattleGround* GetBG() { return m_bg; }
  2897. void SetBG(BattleGround* bg) { m_bg = bg; }
  2898. diff --git a/src/game/MapInstanced.cpp b/src/game/MapInstanced.cpp
  2899. index 1b76f73..25ef956 100644
  2900. --- a/src/game/MapInstanced.cpp
  2901. +++ b/src/game/MapInstanced.cpp
  2902. @@ -20,6 +20,7 @@
  2903. #include "ObjectMgr.h"
  2904. #include "MapManager.h"
  2905. #include "BattleGround.h"
  2906. +#include "BattleGroundMgr.h"
  2907. #include "VMapFactory.h"
  2908. #include "InstanceSaveMgr.h"
  2909. #include "World.h"
  2910. @@ -217,7 +218,8 @@ BattleGroundMap* MapInstanced::CreateBattleGroundMap(uint32 InstanceId, BattleGr
  2911. sLog.outDebug("MapInstanced::CreateBattleGroundMap: instance:%d for map:%d and bgType:%d created.", InstanceId, GetId(), bg->GetTypeID());
  2912.  
  2913. // 0-59 normal spawn 60-69 difficulty_1, 70-79 difficulty_2, 80 dufficulty_3
  2914. - uint8 spawnMode = (bg->GetQueueId() > QUEUE_ID_MAX_LEVEL_59) ? (bg->GetQueueId() - QUEUE_ID_MAX_LEVEL_59) : 0;
  2915. + uint8 SpawnQueue = uint8(float(sBattleGroundMgr.GetMaxQueueId()) * 0.75f);
  2916. + uint8 spawnMode = (bg->GetQueueId() > SpawnQueue) ? (bg->GetQueueId() - SpawnQueue) : 0;
  2917. // some bgs don't have different spawnmodes, with this we can stay close to dbc-data
  2918. while (!GetMapDifficultyData(GetId(), Difficulty(spawnMode)))
  2919. spawnMode--;
  2920. diff --git a/src/game/MapManager.cpp b/src/game/MapManager.cpp
  2921. index 94055bf..f615f3b 100644
  2922. --- a/src/game/MapManager.cpp
  2923. +++ b/src/game/MapManager.cpp
  2924. @@ -36,9 +36,9 @@ INSTANTIATE_CLASS_MUTEX(MapManager, ACE_Thread_Mutex);
  2925.  
  2926. extern GridState* si_GridStates[]; // debugging code, should be deleted some day
  2927.  
  2928. -MapManager::MapManager() : i_gridCleanUpDelay(sWorld.getConfig(CONFIG_INTERVAL_GRIDCLEAN))
  2929. +MapManager::MapManager() : i_gridCleanUpDelay(sWorld.getConfig(CONFIG_INTERVAL_GRIDCLEAN)), uCrashCount(0)
  2930. {
  2931. - i_timer.SetInterval(sWorld.getConfig(CONFIG_INTERVAL_MAPUPDATE));
  2932. + SetMapUpdateInterval(sWorld.getConfig(CONFIG_MAPUPDATER_INTERVAL));
  2933. }
  2934.  
  2935. MapManager::~MapManager()
  2936. @@ -120,6 +120,8 @@ MapManager::_createBaseMap(uint32 id)
  2937. {
  2938. m = new Map(id, i_gridCleanUpDelay, 0, REGULAR_DIFFICULTY);
  2939. }
  2940. +
  2941. + assert(m->StartUpdater());
  2942. i_maps[id] = m;
  2943. }
  2944.  
  2945. @@ -138,6 +140,15 @@ Map* MapManager::CreateMap(uint32 id, const WorldObject* obj)
  2946. return m;
  2947. }
  2948.  
  2949. +Map* MapManager::FindMapByThread(ACE_thread_t tId)
  2950. +{
  2951. + for(MapMapType::iterator iter=i_maps.begin(); iter != i_maps.end(); ++iter)
  2952. + if(ACE_Based::Thread *Updater = iter->second->GetThread())
  2953. + if(Updater->ThreadId() == tId)
  2954. + return iter->second;
  2955. + return NULL;
  2956. +}
  2957. +
  2958. Map* MapManager::FindMap(uint32 mapid, uint32 instanceId) const
  2959. {
  2960. Map *map = _findMap(mapid);
  2961. @@ -256,19 +267,38 @@ void
  2962. MapManager::Update(uint32 diff)
  2963. {
  2964. i_timer.Update(diff);
  2965. - if( !i_timer.Passed() )
  2966. - return;
  2967. -
  2968. - for(MapMapType::iterator iter=i_maps.begin(); iter != i_maps.end(); ++iter)
  2969. - {
  2970. - checkAndCorrectGridStatesArray(); // debugging code, should be deleted some day
  2971. - iter->second->Update(i_timer.GetCurrent());
  2972. - }
  2973. -
  2974. - for (TransportSet::iterator iter = m_Transports.begin(); iter != m_Transports.end(); ++iter)
  2975. - (*iter)->Update(i_timer.GetCurrent());
  2976. -
  2977. - i_timer.SetCurrent(0);
  2978. + if( i_timer.Passed() )
  2979. + {
  2980. +
  2981. + for (TransportSet::iterator iter = m_Transports.begin(); iter != m_Transports.end(); ++iter)
  2982. + (*iter)->Update(i_timer.GetCurrent());
  2983. +
  2984. + for(MapMapType::iterator iter=i_maps.begin(),next; iter != i_maps.end(); iter = next)
  2985. + {
  2986. + next = iter;++next;
  2987. + UpdaterStatus MapStatus = iter->second->GetUpdaterStatus();
  2988. + if(MapStatus == UPDATER_PAUSED)
  2989. + {
  2990. + delete iter->second->GetThread();
  2991. + iter->second->StartUpdater();
  2992. + }
  2993. + //If is possible and no player enter in the map by a time, delete it
  2994. + else if(MapStatus == UPDATER_ACTIVE && iter->second->CanUnload(diff))
  2995. + {
  2996. + sLog.outDebug("MapUpdater: Unloading Map %u",iter->second->GetId());
  2997. + ACE_Based::Thread *t_Thread = iter->second->GetThread();
  2998. + t_Thread->kill(SIGTERM);
  2999. + t_Thread->wait();
  3000. +
  3001. + delete iter->second;
  3002. + delete t_Thread;
  3003. + i_maps.erase(iter);
  3004. + }
  3005. +
  3006. + }
  3007. +
  3008. + i_timer.SetCurrent(0);
  3009. + }
  3010. }
  3011.  
  3012. void MapManager::DoDelayedMovesAndRemoves()
  3013. diff --git a/src/game/MapManager.h b/src/game/MapManager.h
  3014. index 3586845..0fbeced 100644
  3015. --- a/src/game/MapManager.h
  3016. +++ b/src/game/MapManager.h
  3017. @@ -75,7 +75,9 @@ class MANGOS_DLL_DECL MapManager : public MaNGOS::Singleton<MapManager, MaNGOS::
  3018.  
  3019. void SetMapUpdateInterval(uint32 t)
  3020. {
  3021. - if( t > MIN_MAP_UPDATE_DELAY )
  3022. + t >>= 2;
  3023. + // Manager updates 4 times more faster than maps
  3024. + if( t < MIN_MAP_UPDATE_DELAY )
  3025. t = MIN_MAP_UPDATE_DELAY;
  3026.  
  3027. i_timer.SetInterval(t);
  3028. @@ -111,6 +113,9 @@ class MANGOS_DLL_DECL MapManager : public MaNGOS::Singleton<MapManager, MaNGOS::
  3029. void DoDelayedMovesAndRemoves();
  3030.  
  3031. void LoadTransports();
  3032. + uint16 GetCrashCount(){ return uCrashCount; }
  3033. + void IncreaseCrashCount(){ uCrashCount++; }
  3034. + Map* FindMapByThread(ACE_thread_t tId);
  3035.  
  3036. typedef std::set<Transport *> TransportSet;
  3037. TransportSet m_Transports;
  3038. @@ -151,7 +156,7 @@ class MANGOS_DLL_DECL MapManager : public MaNGOS::Singleton<MapManager, MaNGOS::
  3039. uint32 i_gridCleanUpDelay;
  3040. MapMapType i_maps;
  3041. IntervalTimer i_timer;
  3042. -
  3043. + uint16 uCrashCount;
  3044. uint32 i_MaxInstanceId;
  3045. };
  3046.  
  3047. diff --git a/src/game/MovementHandler.cpp b/src/game/MovementHandler.cpp
  3048. index 5853824..6a36f7f 100644
  3049. --- a/src/game/MovementHandler.cpp
  3050. +++ b/src/game/MovementHandler.cpp
  3051. @@ -44,8 +44,10 @@ void WorldSession::HandleMoveWorldportAckOpcode()
  3052. if(!GetPlayer()->IsBeingTeleportedFar())
  3053. return;
  3054.  
  3055. - // get the teleport destination
  3056. - WorldLocation &loc = GetPlayer()->GetTeleportDest();
  3057. + // get the teleport destination and original localization
  3058. + WorldLocation org_loc, loc;
  3059. + GetPlayer()->GetPosition(org_loc);
  3060. + loc = GetPlayer()->GetTeleportDest();
  3061.  
  3062. // possible errors in the coordinate validity check
  3063. if(!MapManager::IsValidMapCoord(loc.mapid, loc.coord_x, loc.coord_y, loc.coord_z, loc.orientation))
  3064. @@ -74,6 +76,19 @@ void WorldSession::HandleMoveWorldportAckOpcode()
  3065. GetPlayer()->Relocate(loc.coord_x, loc.coord_y, loc.coord_z, loc.orientation);
  3066.  
  3067. GetPlayer()->SendInitialPacketsBeforeAddToMap();
  3068. + //Abort teleport to map not activated
  3069. +
  3070. + if(Map *m_Map_p = sMapMgr.FindMap(loc.mapid))
  3071. + {
  3072. + if(m_Map_p->GetUpdaterStatus() != UPDATER_ACTIVE)
  3073. + {
  3074. + GetPlayer()->ResetMap();
  3075. + GetPlayer()->SendTransferAborted(loc.mapid, TRANSFER_ABORT_MAP_NOT_ALLOWED,0);
  3076. + GetPlayer()->TeleportTo(org_loc.mapid, org_loc.coord_x, org_loc.coord_y, org_loc.coord_z, org_loc.orientation);
  3077. + return;
  3078. + }
  3079. + }
  3080. +
  3081. // the CanEnter checks are done in TeleporTo but conditions may change
  3082. // while the player is in transit, for example the map may get full
  3083. if(!GetPlayer()->GetMap()->Add(GetPlayer()))
  3084. @@ -164,6 +179,9 @@ void WorldSession::HandleMoveWorldportAckOpcode()
  3085.  
  3086. //lets process all delayed operations on successful teleport
  3087. GetPlayer()->ProcessDelayedOperations();
  3088. +
  3089. + // Set session updater to map again
  3090. + SetUpdateStatus(SESSION_UPDATE_MAP);
  3091. }
  3092.  
  3093. void WorldSession::HandleMoveTeleportAck(WorldPacket& recv_data)
  3094. diff --git a/src/game/Object.cpp b/src/game/Object.cpp
  3095. index c3aaa99..f8f5d91 100644
  3096. --- a/src/game/Object.cpp
  3097. +++ b/src/game/Object.cpp
  3098. @@ -1924,9 +1924,12 @@ struct WorldObjectChangeAccumulator
  3099. WorldObjectChangeAccumulator(WorldObject &obj, UpdateDataMapType &d) : i_updateDatas(d), i_object(obj) {}
  3100. void Visit(PlayerMapType &m)
  3101. {
  3102. - for(PlayerMapType::iterator iter = m.begin(); iter != m.end(); ++iter)
  3103. + for(PlayerMapType::iterator iter = m.begin(), next; iter != m.end(); iter = next)
  3104. + {
  3105. + next = iter; ++next;
  3106. if(iter->getSource()->HaveAtClient(&i_object))
  3107. i_object.BuildUpdateDataForPlayer(iter->getSource(), i_updateDatas);
  3108. + }
  3109. }
  3110.  
  3111. template<class SKIP> void Visit(GridRefManager<SKIP> &) {}
  3112. diff --git a/src/game/ObjectMgr.cpp b/src/game/ObjectMgr.cpp
  3113. index 3407fd9..eedd9d5 100644
  3114. --- a/src/game/ObjectMgr.cpp
  3115. +++ b/src/game/ObjectMgr.cpp
  3116. @@ -7233,7 +7233,12 @@ bool PlayerCondition::Meets(Player const * player) const
  3117. case CONDITION_NO_AURA:
  3118. return !player->HasAura(value1, value2);
  3119. case CONDITION_ACTIVE_EVENT:
  3120. - return sGameEventMgr.IsActiveEvent(value1);
  3121. + {
  3122. + GameEventMgr::GameEventDataMap gEvents = ((GameEventMgr::GameEventDataMap)sGameEventMgr.GetEventMap());
  3123. + if(gEvents.find(value1) != gEvents.end())
  3124. + return gEvents[value1].active;
  3125. + return false;
  3126. + }
  3127. default:
  3128. return false;
  3129. }
  3130. @@ -7371,7 +7376,7 @@ bool PlayerCondition::IsValid(ConditionType condition, uint32 value1, uint32 val
  3131. case CONDITION_ACTIVE_EVENT:
  3132. {
  3133. GameEventMgr::GameEventDataMap const& events = sGameEventMgr.GetEventMap();
  3134. - if(value1 >=events.size() || !events[value1].isValid())
  3135. + if(events.find(value1) == events.end())
  3136. {
  3137. sLog.outErrorDb("Active event condition requires existed event id (%u), skipped", value1);
  3138. return false;
  3139. diff --git a/src/game/Player.cpp b/src/game/Player.cpp
  3140. index bec9861..d721d3e 100644
  3141. --- a/src/game/Player.cpp
  3142. +++ b/src/game/Player.cpp
  3143. @@ -36,6 +36,7 @@
  3144. #include "ChannelMgr.h"
  3145. #include "MapManager.h"
  3146. #include "MapInstanced.h"
  3147. +#include "GameEventMgr.h"
  3148. #include "InstanceSaveMgr.h"
  3149. #include "GridNotifiers.h"
  3150. #include "GridNotifiersImpl.h"
  3151. @@ -318,6 +319,7 @@ Player::Player (WorldSession *session): Unit(), m_achievementMgr(this), m_reputa
  3152. m_zoneUpdateTimer = 0;
  3153.  
  3154. m_areaUpdateId = 0;
  3155. + bPosNotifyAfterAddToMap = false;
  3156.  
  3157. m_nextSave = sWorld.getConfig(CONFIG_INTERVAL_SAVE);
  3158.  
  3159. @@ -1068,6 +1070,12 @@ void Player::Update( uint32 p_time )
  3160. m_nextMailDelivereTime = 0;
  3161. }
  3162.  
  3163. + if(bPosNotifyAfterAddToMap)
  3164. + {
  3165. + GetMap()->DelayedNotifyPosition(this);
  3166. + bPosNotifyAfterAddToMap = false;
  3167. + }
  3168. +
  3169. //used to implement delayed far teleports
  3170. SetCanDelayTeleport(true);
  3171. Unit::Update( p_time );
  3172. @@ -1704,6 +1712,9 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati
  3173. return true;
  3174. }
  3175.  
  3176. + // Change session updater to world thread at teleport
  3177. + m_session->SetUpdateStatus(SESSION_UPDATE_WORLD);
  3178. +
  3179. SetSelection(0);
  3180.  
  3181. CombatStop();
  3182. @@ -1872,6 +1883,8 @@ void Player::AddToWorld()
  3183. if(m_items[i])
  3184. m_items[i]->AddToWorld();
  3185. }
  3186. +
  3187. + bPosNotifyAfterAddToMap = true;
  3188. }
  3189.  
  3190. void Player::RemoveFromWorld()
  3191. @@ -7764,7 +7777,8 @@ void Player::SendInitWorldStates(uint32 zoneid, uint32 areaid)
  3192. data << uint32(mapid); // mapid
  3193. data << uint32(zoneid); // zone id
  3194. data << uint32(areaid); // area id, new 2.1.0
  3195. - data << uint16(NumberOfFields); // count of uint64 blocks
  3196. + size_t count_pos = data.wpos();
  3197. + data << uint16(0); // count of uint64 blocks
  3198. data << uint32(0x8d8) << uint32(0x0); // 1
  3199. data << uint32(0x8d7) << uint32(0x0); // 2
  3200. data << uint32(0x8d6) << uint32(0x0); // 3
  3201. @@ -7775,6 +7789,18 @@ void Player::SendInitWorldStates(uint32 zoneid, uint32 areaid)
  3202. data << uint32(0xC77) << uint32(sWorld.getConfig(CONFIG_ARENA_SEASON_IN_PROGRESS));
  3203. // 8 Arena season id
  3204. data << uint32(0xF3D) << uint32(sWorld.getConfig(CONFIG_ARENA_SEASON_ID));
  3205. +
  3206. + // Events nodes
  3207. + GameEventMgr::GameEventDataMap const& Events = sGameEventMgr.GetEventMap();
  3208. + for(GameEventMgr::GameEventDataMap::const_iterator iter = Events.begin(); iter != Events.end(); iter++)
  3209. + {
  3210. + if(iter->second.node)
  3211. + {
  3212. + data << uint32(iter->second.node) << uint32(iter->second.active);
  3213. + NumberOfFields++;
  3214. + }
  3215. + }
  3216. +
  3217. if(mapid == 530) // Outland
  3218. {
  3219. data << uint32(0x9bf) << uint32(0x0); // 7
  3220. @@ -8080,6 +8106,8 @@ void Player::SendInitWorldStates(uint32 zoneid, uint32 areaid)
  3221. data << uint32(0x915) << uint32(0x0); // 10
  3222. break;
  3223. }
  3224. +
  3225. + data.put<uint16>(count_pos,NumberOfFields);
  3226. GetSession()->SendPacket(&data);
  3227. }
  3228.  
  3229. @@ -18691,16 +18719,16 @@ bool Player::GetBGAccessByLevel(BattleGroundTypeId bgTypeId) const
  3230. return true;
  3231. }
  3232.  
  3233. -BGQueueIdBasedOnLevel Player::GetBattleGroundQueueIdFromLevel() const
  3234. +uint8 Player::GetBGLevelQueueId() const
  3235. {
  3236. - // for ranges 0 - 19, 20 - 29, 30 - 39, 40 - 49, 50 - 59, 60 - 69, 70 - 79, 80
  3237. - uint32 queue_id = ( getLevel() / 10) - 1;
  3238. - if( queue_id >= MAX_BATTLEGROUND_QUEUES )
  3239. + uint8 QueueId = uint8(( getLevel() / 10) - 1), MaxQueueId = sBattleGroundMgr.GetMaxQueueId();
  3240. +
  3241. + if( QueueId >= MaxQueueId )
  3242. {
  3243. - sLog.outError("BattleGround: too high queue_id %u this shouldn't happen", queue_id);
  3244. - return QUEUE_ID_MAX_LEVEL_80;
  3245. + sLog.outError("BattleGround: too high queue_id %u this shouldn't happen", QueueId);
  3246. + return uint8(MaxQueueId - 1);
  3247. }
  3248. - return BGQueueIdBasedOnLevel(queue_id);
  3249. + return QueueId;
  3250. }
  3251.  
  3252. float Player::GetReputationPriceDiscount( Creature const* pCreature ) const
  3253. diff --git a/src/game/Player.h b/src/game/Player.h
  3254. index c3b6469..df0338e 100644
  3255. --- a/src/game/Player.h
  3256. +++ b/src/game/Player.h
  3257. @@ -1958,7 +1958,7 @@ class MANGOS_DLL_SPEC Player : public Unit
  3258. BattleGround* GetBattleGround() const;
  3259.  
  3260.  
  3261. - BGQueueIdBasedOnLevel GetBattleGroundQueueIdFromLevel() const;
  3262. + uint8 GetBGLevelQueueId() const;
  3263.  
  3264. bool InBattleGroundQueue() const
  3265. {
  3266. @@ -2507,7 +2507,7 @@ class MANGOS_DLL_SPEC Player : public Unit
  3267. uint32 m_teleport_options;
  3268. bool mSemaphoreTeleport_Near;
  3269. bool mSemaphoreTeleport_Far;
  3270. -
  3271. + bool bPosNotifyAfterAddToMap;
  3272. uint32 m_DelayedOperations;
  3273. bool m_bCanDelayTeleport;
  3274. bool m_bHasDelayedTeleport;
  3275. diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp
  3276. index a71d259..dc8ebf0 100644
  3277. --- a/src/game/Spell.cpp
  3278. +++ b/src/game/Spell.cpp
  3279. @@ -5826,6 +5826,16 @@ bool Spell::CheckTarget( Unit* target, uint32 eff )
  3280.  
  3281. return true;
  3282. }
  3283. +bool Spell::IsDeletable()
  3284. +{
  3285. + if(m_caster && m_caster->GetOwner() && m_caster->GetOwner()->GetTypeId() == TYPEID_PLAYER)
  3286. + {
  3287. + Player *mo_caster = ((Player *)m_caster->GetOwner());
  3288. + if(mo_caster->GetSession()->PlayerLoading() && mo_caster->GetSession()->IsUpdating())
  3289. + return false;
  3290. + }
  3291. + return !m_referencedFromCurrentSpell && !m_executedCurrently;
  3292. +}
  3293.  
  3294. bool Spell::IsNeedSendToClient() const
  3295. {
  3296. diff --git a/src/game/Spell.h b/src/game/Spell.h
  3297. index bda3a18..ed7fe95 100644
  3298. --- a/src/game/Spell.h
  3299. +++ b/src/game/Spell.h
  3300. @@ -425,7 +425,7 @@ class Spell
  3301. bool IsMeleeAttackResetSpell() const { return !m_IsTriggeredSpell && (m_spellInfo->InterruptFlags & SPELL_INTERRUPT_FLAG_AUTOATTACK); }
  3302. bool IsRangedAttackResetSpell() const { return !m_IsTriggeredSpell && IsRangedSpell() && (m_spellInfo->InterruptFlags & SPELL_INTERRUPT_FLAG_AUTOATTACK); }
  3303.  
  3304. - bool IsDeletable() const { return !m_referencedFromCurrentSpell && !m_executedCurrently; }
  3305. + bool IsDeletable();
  3306. void SetReferencedFromCurrent(bool yes) { m_referencedFromCurrentSpell = yes; }
  3307. void SetExecutedCurrently(bool yes) { m_executedCurrently = yes; }
  3308. uint64 GetDelayStart() const { return m_delayStart; }
  3309. diff --git a/src/game/World.cpp b/src/game/World.cpp
  3310. index ca23473..5f265b5 100644
  3311. --- a/src/game/World.cpp
  3312. +++ b/src/game/World.cpp
  3313. @@ -86,6 +86,7 @@ World::World()
  3314. m_ShutdownMask = 0;
  3315. m_ShutdownTimer = 0;
  3316. m_gameTime=time(NULL);
  3317. + m_WorldStarted = false;
  3318. m_startTime=m_gameTime;
  3319. m_maxActiveSessionCount = 0;
  3320. m_maxQueuedSessionCount = 0;
  3321. @@ -571,14 +572,13 @@ void World::LoadConfigSettings(bool reload)
  3322. if(reload)
  3323. sMapMgr.SetGridCleanUpDelay(m_configs[CONFIG_INTERVAL_GRIDCLEAN]);
  3324.  
  3325. - m_configs[CONFIG_INTERVAL_MAPUPDATE] = sConfig.GetIntDefault("MapUpdateInterval", 100);
  3326. - if(m_configs[CONFIG_INTERVAL_MAPUPDATE] < MIN_MAP_UPDATE_DELAY)
  3327. - {
  3328. - sLog.outError("MapUpdateInterval (%i) must be greater %u. Use this minimal value.",m_configs[CONFIG_INTERVAL_MAPUPDATE],MIN_MAP_UPDATE_DELAY);
  3329. - m_configs[CONFIG_INTERVAL_MAPUPDATE] = MIN_MAP_UPDATE_DELAY;
  3330. - }
  3331. + m_configs[CONFIG_MAPUPDATER_BACKTRACE] = sConfig.GetIntDefault("MapUpdater.BackTrace", 1);
  3332. + m_configs[CONFIG_MAPUPDATER_SHUT_ATCRASH] = sConfig.GetIntDefault("MapUpdater.ShutdownAtCrash", 20);
  3333. + m_configs[CONFIG_MAPUPDATER_INTERVAL] = sConfig.GetIntDefault("MapUpdater.Interval", 100);
  3334. + m_configs[CONFIG_MAPUPDATER_UNLOAD_DELAY] = sConfig.GetIntDefault("MapUpdater.UnloadDelay", 600000);
  3335. +
  3336. if(reload)
  3337. - sMapMgr.SetMapUpdateInterval(m_configs[CONFIG_INTERVAL_MAPUPDATE]);
  3338. + sMapMgr.SetMapUpdateInterval(m_configs[CONFIG_MAPUPDATER_INTERVAL]);
  3339.  
  3340. m_configs[CONFIG_INTERVAL_CHANGEWEATHER] = sConfig.GetIntDefault("ChangeWeatherInterval", 10 * MINUTE * IN_MILISECONDS);
  3341.  
  3342. @@ -1668,10 +1668,6 @@ void World::Update(uint32 diff)
  3343. m_timers[WUPDATE_EVENTS].Reset();
  3344. }
  3345.  
  3346. - /// </ul>
  3347. - ///- Move all creatures with "delayed move" and remove and delete all objects with "delayed remove"
  3348. - sMapMgr.DoDelayedMovesAndRemoves();
  3349. -
  3350. // update the instance reset times
  3351. sInstanceSaveMgr.Update();
  3352.  
  3353. @@ -2051,11 +2047,23 @@ void World::UpdateSessions( uint32 diff )
  3354. next = itr;
  3355. ++next;
  3356. ///- and remove not active sessions from the list
  3357. - if(!itr->second->Update(diff)) // As interval = 0
  3358. + if(!itr->second->IsUpdating())
  3359. {
  3360. - RemoveQueuedPlayer (itr->second);
  3361. - delete itr->second;
  3362. - m_sessions.erase(itr);
  3363. + itr->second->SetUpdating(true);
  3364. + if(SESSION_UPDATE_WORLD == itr->second->GetUpdateStatus())
  3365. + {
  3366. + ///- and remove not active sessions from the list
  3367. + if(!itr->second->Update(0)) // As interval = 0
  3368. + itr->second->SetUpdateStatus(SESSION_REMOVE_QUEUE);
  3369. + }
  3370. +
  3371. + if(SESSION_REMOVE_QUEUE == itr->second->GetUpdateStatus())
  3372. + {
  3373. + RemoveQueuedPlayer (itr->second);
  3374. + delete itr->second;
  3375. + m_sessions.erase(itr);
  3376. + }
  3377. + itr->second->SetUpdating(false);
  3378. }
  3379. }
  3380. }
  3381. diff --git a/src/game/World.h b/src/game/World.h
  3382. index 74c897a..5295d0e 100644
  3383. --- a/src/game/World.h
  3384. +++ b/src/game/World.h
  3385. @@ -87,7 +87,10 @@ enum WorldConfigs
  3386. CONFIG_GRID_UNLOAD,
  3387. CONFIG_INTERVAL_SAVE,
  3388. CONFIG_INTERVAL_GRIDCLEAN,
  3389. - CONFIG_INTERVAL_MAPUPDATE,
  3390. + CONFIG_MAPUPDATER_INTERVAL,
  3391. + CONFIG_MAPUPDATER_BACKTRACE,
  3392. + CONFIG_MAPUPDATER_SHUT_ATCRASH,
  3393. + CONFIG_MAPUPDATER_UNLOAD_DELAY,
  3394. CONFIG_INTERVAL_CHANGEWEATHER,
  3395. CONFIG_PORT_WORLD,
  3396. CONFIG_SOCKET_SELECTTIME,
  3397. @@ -381,6 +384,7 @@ class World
  3398. World();
  3399. ~World();
  3400.  
  3401. + bool m_WorldStarted;
  3402. WorldSession* FindSession(uint32 id) const;
  3403. void AddSession(WorldSession *s);
  3404. bool RemoveSession(uint32 id);
  3405. diff --git a/src/game/WorldSession.cpp b/src/game/WorldSession.cpp
  3406. index 3ee5a7f..9832e94 100644
  3407. --- a/src/game/WorldSession.cpp
  3408. +++ b/src/game/WorldSession.cpp
  3409. @@ -39,11 +39,11 @@
  3410.  
  3411. /// WorldSession constructor
  3412. WorldSession::WorldSession(uint32 id, WorldSocket *sock, AccountTypes sec, uint8 expansion, time_t mute_time, LocaleConstant locale) :
  3413. -LookingForGroup_auto_join(false), LookingForGroup_auto_add(false), m_muteTime(mute_time),
  3414. -_player(NULL), m_Socket(sock),_security(sec), _accountId(id), m_expansion(expansion),
  3415. +LookingForGroup_auto_join(false), LookingForGroup_auto_add(false), m_muteTime(mute_time), eUpdateStatus(SESSION_UPDATE_WORLD),
  3416. +_player(NULL), m_Socket(sock),_security(sec), _accountId(id), m_expansion(expansion), b_UpdatingSess(false), m_latency(0),
  3417. m_sessionDbcLocale(sWorld.GetAvailableDbcLocale(locale)), m_sessionDbLocaleIndex(sObjectMgr.GetIndexForLocale(locale)),
  3418. _logoutTime(0), m_inQueue(false), m_playerLoading(false), m_playerLogout(false), m_playerRecentlyLogout(false), m_playerSave(false),
  3419. -m_latency(0), m_TutorialsChanged(false)
  3420. +m_TutorialsChanged(false)
  3421. {
  3422. if (sock)
  3423. {
  3424. @@ -289,6 +289,8 @@ void WorldSession::LogoutPlayer(bool Save)
  3425.  
  3426. m_playerLogout = true;
  3427. m_playerSave = Save;
  3428. +
  3429. + eUpdateStatus = SESSION_UPDATE_WORLD;
  3430.  
  3431. if (_player)
  3432. {
  3433. diff --git a/src/game/WorldSession.h b/src/game/WorldSession.h
  3434. index d8e2eb0..279d02f 100644
  3435. --- a/src/game/WorldSession.h
  3436. +++ b/src/game/WorldSession.h
  3437. @@ -103,6 +103,13 @@ enum PartyResult
  3438. PARTY_RESULT_INVITE_RESTRICTED = 13
  3439. };
  3440.  
  3441. +enum SessionUpdateStatus
  3442. +{
  3443. + SESSION_UPDATE_MAP = 1,
  3444. + SESSION_UPDATE_WORLD = 2,
  3445. + SESSION_REMOVE_QUEUE = 3
  3446. +};
  3447. +
  3448. /// Player session in the World
  3449. class MANGOS_DLL_SPEC WorldSession
  3450. {
  3451. @@ -137,6 +144,11 @@ class MANGOS_DLL_SPEC WorldSession
  3452. AccountTypes GetSecurity() const { return _security; }
  3453. uint32 GetAccountId() const { return _accountId; }
  3454. Player* GetPlayer() const { return _player; }
  3455. +
  3456. + bool IsUpdating(){ return b_UpdatingSess; }
  3457. + void SetUpdating(bool bUpd){ b_UpdatingSess = bUpd; }
  3458. + SessionUpdateStatus GetUpdateStatus(){ return eUpdateStatus; }
  3459. + void SetUpdateStatus(SessionUpdateStatus Status) { eUpdateStatus = Status; }
  3460. char const* GetPlayerName() const;
  3461. void SetSecurity(AccountTypes security) { _security = security; }
  3462. std::string const& GetRemoteAddress() { return m_Address; }
  3463. @@ -741,7 +753,9 @@ class MANGOS_DLL_SPEC WorldSession
  3464. WorldSocket *m_Socket;
  3465. std::string m_Address;
  3466.  
  3467. + SessionUpdateStatus eUpdateStatus;
  3468. AccountTypes _security;
  3469. + bool b_UpdatingSess;
  3470. uint32 _accountId;
  3471. uint8 m_expansion;
  3472.  
  3473. diff --git a/src/mangosd/Master.cpp b/src/mangosd/Master.cpp
  3474. index 1117a17..6157178 100644
  3475. --- a/src/mangosd/Master.cpp
  3476. +++ b/src/mangosd/Master.cpp
  3477. @@ -27,6 +27,7 @@
  3478. #include "Master.h"
  3479. #include "WorldSocket.h"
  3480. #include "WorldRunnable.h"
  3481. +#include "MapManager.h"
  3482. #include "World.h"
  3483. #include "Log.h"
  3484. #include "Timer.h"
  3485. @@ -519,29 +520,68 @@ void Master::clearOnlineAccounts()
  3486. }
  3487.  
  3488. /// Handle termination signals
  3489. -void Master::_OnSignal(int s)
  3490. +void Master::_OnSignal(int Signal)
  3491. {
  3492. - switch (s)
  3493. - {
  3494. - case SIGINT:
  3495. - World::StopNow(RESTART_EXIT_CODE);
  3496. - break;
  3497. - case SIGTERM:
  3498. - #ifdef _WIN32
  3499. - case SIGBREAK:
  3500. - #endif
  3501. - World::StopNow(SHUTDOWN_EXIT_CODE);
  3502. - break;
  3503. - }
  3504. -
  3505. - signal(s, _OnSignal);
  3506. + ACE_thread_t ThreadId = ACE_Based::Thread::currentId();
  3507. + sLog.outDebug("Signal Handler: Signal %.2u received from thread "I64FMT".\r\n",Signal,ThreadId);
  3508. +
  3509. + if(Signal == SIGINT)
  3510. + World::StopNow(RESTART_EXIT_CODE);
  3511. + else if(Signal == SIGTERM
  3512. + #ifdef _WIN32
  3513. + || Signal == SIGBREAK
  3514. + #endif
  3515. + )
  3516. + {
  3517. + if(Map *map = MapManager::Instance().FindMapByThread(ThreadId))
  3518. + map->StopUpdater();
  3519. + else World::StopNow(SHUTDOWN_EXIT_CODE);
  3520. + }
  3521. + else
  3522. + {
  3523. + MapManager::Instance().IncreaseCrashCount();
  3524. + uint16 CrashCount = sWorld.getConfig(CONFIG_MAPUPDATER_SHUT_ATCRASH);
  3525. + if(CrashCount && CrashCount <= MapManager::Instance().GetCrashCount())
  3526. + {
  3527. + sLog.outError("Signal Handler: Too many crash detected. Shutting down server...\r\n");
  3528. + ObjectAccessor::Instance().SaveAllPlayers();
  3529. + exit(Signal);
  3530. + }
  3531. + else if(Map *map = MapManager::Instance().FindMapByThread(ThreadId))
  3532. + {
  3533. + sLog.outError("MapUpdater: Map %u has crashed. Saving data and restarting the map...",map->GetId());
  3534. +
  3535. + if(sWorld.getConfig(CONFIG_MAPUPDATER_BACKTRACE))
  3536. + {
  3537. + ACE_Stack_Trace StackTrace;
  3538. + sLog.outError("\r\n************ BackTrace ************\r\n************************"
  3539. + "***********\r\n%s\r\n***********************************\r\n",StackTrace.c_str());
  3540. + }
  3541. +
  3542. + map->Restart();
  3543. + map->StopUpdater();
  3544. +
  3545. + }
  3546. + else
  3547. + {
  3548. + ACE_Stack_Trace StackTrace;
  3549. + sLog.outError("\r\n************ BackTrace ************\r\n************************"
  3550. + "***********\r\n%s\r\n***********************************\r\n",StackTrace.c_str());
  3551. + sLog.outDebug("Signal Handler: Crash detected from unknown thread "I64FMT".\r\n",ThreadId);
  3552. + exit(Signal);
  3553. + }
  3554. + }
  3555. + signal(Signal, _OnSignal);
  3556. }
  3557.  
  3558. /// Define hook '_OnSignal' for all termination signals
  3559. void Master::_HookSignals()
  3560. {
  3561. - signal(SIGINT, _OnSignal);
  3562. - signal(SIGTERM, _OnSignal);
  3563. + signal(SIGINT, _OnSignal);
  3564. + signal(SIGTERM, _OnSignal);
  3565. + signal(SIGSEGV, _OnSignal);
  3566. + signal(SIGABRT, _OnSignal);
  3567. + signal(SIGFPE , _OnSignal);
  3568. #ifdef _WIN32
  3569. signal(SIGBREAK, _OnSignal);
  3570. #endif
  3571. @@ -550,8 +590,11 @@ void Master::_HookSignals()
  3572. /// Unhook the signals before leaving
  3573. void Master::_UnhookSignals()
  3574. {
  3575. - signal(SIGINT, 0);
  3576. - signal(SIGTERM, 0);
  3577. + signal(SIGINT, 0);
  3578. + signal(SIGTERM, 0);
  3579. + signal(SIGSEGV, 0);
  3580. + signal(SIGABRT, 0);
  3581. + signal(SIGFPE , 0);
  3582. #ifdef _WIN32
  3583. signal(SIGBREAK, 0);
  3584. #endif
  3585. diff --git a/src/mangosd/WorldRunnable.cpp b/src/mangosd/WorldRunnable.cpp
  3586. index 28c4bf8..5782bf3 100644
  3587. --- a/src/mangosd/WorldRunnable.cpp
  3588. +++ b/src/mangosd/WorldRunnable.cpp
  3589. @@ -49,6 +49,7 @@ void WorldRunnable::run()
  3590.  
  3591. uint32 prevSleepTime = 0; // used for balanced full tick time length near WORLD_SLEEP_CONST
  3592.  
  3593. + sWorld.m_WorldStarted = true;
  3594. ///- While we have not World::m_stopEvent, update the world
  3595. while (!World::IsStopped())
  3596. {
  3597. diff --git a/src/mangosd/mangosd.conf.dist.in b/src/mangosd/mangosd.conf.dist.in
  3598. index d925a15..73e7afb 100644
  3599. --- a/src/mangosd/mangosd.conf.dist.in
  3600. +++ b/src/mangosd/mangosd.conf.dist.in
  3601. @@ -1,4 +1,4 @@
  3602. -#####################################
  3603. +Ԫ�#####################################
  3604. # MaNGOS Configuration file #
  3605. #####################################
  3606. ConfVersion=2008080101
  3607. @@ -104,10 +104,6 @@ BindIP = "0.0.0.0"
  3608. # Grid clean up delay (in milliseconds)
  3609. # Default: 300000 (5 min)
  3610. #
  3611. -# MapUpdateInterval
  3612. -# Map update interval (in milliseconds)
  3613. -# Default: 100
  3614. -#
  3615. # ChangeWeatherInterval
  3616. # Weather update interval (in milliseconds)
  3617. # Default: 600000 (10 min)
  3618. @@ -170,7 +166,6 @@ MaxOverspeedPings = 2
  3619. GridUnload = 1
  3620. SocketSelectTime = 10000
  3621. GridCleanUpDelay = 300000
  3622. -MapUpdateInterval = 100
  3623. ChangeWeatherInterval = 600000
  3624. PlayerSaveInterval = 900000
  3625. vmap.enableLOS = 0
  3626. @@ -184,6 +179,32 @@ MaxCoreStuckTime = 0
  3627. AddonChannel = 1
  3628.  
  3629. ###################################################################################################################
  3630. +# MAP UPDATER
  3631. +#
  3632. +# Backtrace
  3633. +# Set to 1 to output a backtrace
  3634. +# Default: 1 ( ON )
  3635. +#
  3636. +# Interval
  3637. +# MapUpdater interval between map updating ( and manager )
  3638. +# Default: 100
  3639. +#
  3640. +# UnloadDelay
  3641. +# Unloading map delay if there's no players (in ms)
  3642. +# Default: 300000 ( 5 minutes )
  3643. +#
  3644. +# ShutdownAtCrash
  3645. +# Set this to 0 if you dont want to get shutdown at x map crashes and else the crash number
  3646. +# Default: 0 ( Don't shutdown )
  3647. +#
  3648. +###################################################################################################################
  3649. +
  3650. +MapUpdater.BackTrace = 1
  3651. +MapUpdater.Interval = 100
  3652. +MapUpdater.UnloadDelay = 600000
  3653. +MapUpdater.ShutdownAtCrash = 20
  3654. +
  3655. +###################################################################################################################
  3656. # SERVER LOGGING
  3657. #
  3658. # LogSQL
  3659. diff --git a/src/shared/Database/Database.cpp b/src/shared/Database/Database.cpp
  3660. index dff2ff1..60061c4 100644
  3661. --- a/src/shared/Database/Database.cpp
  3662. +++ b/src/shared/Database/Database.cpp
  3663. @@ -112,6 +112,16 @@ void Database::SetResultQueue(SqlResultQueue * queue)
  3664.  
  3665. }
  3666.  
  3667. +void Database::UnSetResultQueue(SqlResultQueue * queue)
  3668. +{
  3669. + QueryQueues::iterator itr = m_queryQueues.find(ACE_Based::Thread::current());
  3670. + if(itr != m_queryQueues.end())
  3671. + {
  3672. + delete itr->second;
  3673. + m_queryQueues.erase(itr);
  3674. + }
  3675. +}
  3676. +
  3677. QueryResult* Database::PQuery(const char *format,...)
  3678. {
  3679. if(!format) return NULL;
  3680. diff --git a/src/shared/Database/Database.h b/src/shared/Database/Database.h
  3681. index 5935692..9b31a39 100644
  3682. --- a/src/shared/Database/Database.h
  3683. +++ b/src/shared/Database/Database.h
  3684. @@ -59,36 +59,36 @@ class MANGOS_DLL_SPEC Database
  3685.  
  3686. // Query / member
  3687. template<class Class>
  3688. - bool AsyncQuery(Class *object, void (Class::*method)(QueryResult*), const char *sql);
  3689. + void AsyncQuery(Class *object, void (Class::*method)(QueryResult*), const char *sql);
  3690. template<class Class, typename ParamType1>
  3691. - bool AsyncQuery(Class *object, void (Class::*method)(QueryResult*, ParamType1), ParamType1 param1, const char *sql);
  3692. + void AsyncQuery(Class *object, void (Class::*method)(QueryResult*, ParamType1), ParamType1 param1, const char *sql);
  3693. template<class Class, typename ParamType1, typename ParamType2>
  3694. - bool AsyncQuery(Class *object, void (Class::*method)(QueryResult*, ParamType1, ParamType2), ParamType1 param1, ParamType2 param2, const char *sql);
  3695. + void AsyncQuery(Class *object, void (Class::*method)(QueryResult*, ParamType1, ParamType2), ParamType1 param1, ParamType2 param2, const char *sql);
  3696. template<class Class, typename ParamType1, typename ParamType2, typename ParamType3>
  3697. - bool AsyncQuery(Class *object, void (Class::*method)(QueryResult*, ParamType1, ParamType2, ParamType3), ParamType1 param1, ParamType2 param2, ParamType3 param3, const char *sql);
  3698. + void AsyncQuery(Class *object, void (Class::*method)(QueryResult*, ParamType1, ParamType2, ParamType3), ParamType1 param1, ParamType2 param2, ParamType3 param3, const char *sql);
  3699. // Query / static
  3700. template<typename ParamType1>
  3701. - bool AsyncQuery(void (*method)(QueryResult*, ParamType1), ParamType1 param1, const char *sql);
  3702. + void AsyncQuery(void (*method)(QueryResult*, ParamType1), ParamType1 param1, const char *sql);
  3703. template<typename ParamType1, typename ParamType2>
  3704. - bool AsyncQuery(void (*method)(QueryResult*, ParamType1, ParamType2), ParamType1 param1, ParamType2 param2, const char *sql);
  3705. + void AsyncQuery(void (*method)(QueryResult*, ParamType1, ParamType2), ParamType1 param1, ParamType2 param2, const char *sql);
  3706. template<typename ParamType1, typename ParamType2, typename ParamType3>
  3707. - bool AsyncQuery(void (*method)(QueryResult*, ParamType1, ParamType2, ParamType3), ParamType1 param1, ParamType2 param2, ParamType3 param3, const char *sql);
  3708. + void AsyncQuery(void (*method)(QueryResult*, ParamType1, ParamType2, ParamType3), ParamType1 param1, ParamType2 param2, ParamType3 param3, const char *sql);
  3709. // PQuery / member
  3710. template<class Class>
  3711. - bool AsyncPQuery(Class *object, void (Class::*method)(QueryResult*), const char *format,...) ATTR_PRINTF(4,5);
  3712. + void AsyncPQuery(Class *object, void (Class::*method)(QueryResult*), const char *format,...) ATTR_PRINTF(4,5);
  3713. template<class Class, typename ParamType1>
  3714. - bool AsyncPQuery(Class *object, void (Class::*method)(QueryResult*, ParamType1), ParamType1 param1, const char *format,...) ATTR_PRINTF(5,6);
  3715. + void AsyncPQuery(Class *object, void (Class::*method)(QueryResult*, ParamType1), ParamType1 param1, const char *format,...) ATTR_PRINTF(5,6);
  3716. template<class Class, typename ParamType1, typename ParamType2>
  3717. - bool AsyncPQuery(Class *object, void (Class::*method)(QueryResult*, ParamType1, ParamType2), ParamType1 param1, ParamType2 param2, const char *format,...) ATTR_PRINTF(6,7);
  3718. + void AsyncPQuery(Class *object, void (Class::*method)(QueryResult*, ParamType1, ParamType2), ParamType1 param1, ParamType2 param2, const char *format,...) ATTR_PRINTF(6,7);
  3719. template<class Class, typename ParamType1, typename ParamType2, typename ParamType3>
  3720. - bool AsyncPQuery(Class *object, void (Class::*method)(QueryResult*, ParamType1, ParamType2, ParamType3), ParamType1 param1, ParamType2 param2, ParamType3 param3, const char *format,...) ATTR_PRINTF(7,8);
  3721. + void AsyncPQuery(Class *object, void (Class::*method)(QueryResult*, ParamType1, ParamType2, ParamType3), ParamType1 param1, ParamType2 param2, ParamType3 param3, const char *format,...) ATTR_PRINTF(7,8);
  3722. // PQuery / static
  3723. template<typename ParamType1>
  3724. - bool AsyncPQuery(void (*method)(QueryResult*, ParamType1), ParamType1 param1, const char *format,...) ATTR_PRINTF(4,5);
  3725. + void AsyncPQuery(void (*method)(QueryResult*, ParamType1), ParamType1 param1, const char *format,...) ATTR_PRINTF(4,5);
  3726. template<typename ParamType1, typename ParamType2>
  3727. - bool AsyncPQuery(void (*method)(QueryResult*, ParamType1, ParamType2), ParamType1 param1, ParamType2 param2, const char *format,...) ATTR_PRINTF(5,6);
  3728. + void AsyncPQuery(void (*method)(QueryResult*, ParamType1, ParamType2), ParamType1 param1, ParamType2 param2, const char *format,...) ATTR_PRINTF(5,6);
  3729. template<typename ParamType1, typename ParamType2, typename ParamType3>
  3730. - bool AsyncPQuery(void (*method)(QueryResult*, ParamType1, ParamType2, ParamType3), ParamType1 param1, ParamType2 param2, ParamType3 param3, const char *format,...) ATTR_PRINTF(6,7);
  3731. + void AsyncPQuery(void (*method)(QueryResult*, ParamType1, ParamType2, ParamType3), ParamType1 param1, ParamType2 param2, ParamType3 param3, const char *format,...) ATTR_PRINTF(6,7);
  3732. template<class Class>
  3733. // QueryHolder
  3734. bool DelayQueryHolder(Class *object, void (Class::*method)(QueryResult*, SqlQueryHolder*), SqlQueryHolder *holder);
  3735. @@ -128,6 +128,7 @@ class MANGOS_DLL_SPEC Database
  3736.  
  3737. // sets the result queue of the current thread, be careful what thread you call this from
  3738. void SetResultQueue(SqlResultQueue * queue);
  3739. + void UnSetResultQueue(SqlResultQueue * queue);
  3740.  
  3741. bool CheckRequiredField(char const* table_name, char const* required_name);
  3742. private:
  3743. diff --git a/src/shared/Database/DatabaseImpl.h b/src/shared/Database/DatabaseImpl.h
  3744. index 3e0ea93..9c55eb3 100644
  3745. --- a/src/shared/Database/DatabaseImpl.h
  3746. +++ b/src/shared/Database/DatabaseImpl.h
  3747. @@ -22,18 +22,18 @@
  3748. /// Function body definitions for the template function members of the Database class
  3749.  
  3750. #define ASYNC_QUERY_BODY(sql, queue_itr) \
  3751. - if (!sql) return false; \
  3752. + if (!sql) return; \
  3753. \
  3754. QueryQueues::iterator queue_itr; \
  3755. \
  3756. { \
  3757. ACE_Based::Thread * queryThread = ACE_Based::Thread::current(); \
  3758. queue_itr = m_queryQueues.find(queryThread); \
  3759. - if (queue_itr == m_queryQueues.end()) return false; \
  3760. + if (queue_itr == m_queryQueues.end()) return; \
  3761. }
  3762.  
  3763. #define ASYNC_PQUERY_BODY(format, szQuery) \
  3764. - if(!format) return false; \
  3765. + if(!format) return; \
  3766. \
  3767. char szQuery [MAX_QUERY_LEN]; \
  3768. \
  3769. @@ -47,7 +47,7 @@
  3770. if(res==-1) \
  3771. { \
  3772. sLog.outError("SQL Query truncated (and not execute) for format: %s",format); \
  3773. - return false; \
  3774. + return; \
  3775. } \
  3776. }
  3777.  
  3778. @@ -65,121 +65,121 @@
  3779. // -- Query / member --
  3780.  
  3781. template<class Class>
  3782. -bool
  3783. +void
  3784. Database::AsyncQuery(Class *object, void (Class::*method)(QueryResult*), const char *sql)
  3785. {
  3786. ASYNC_QUERY_BODY(sql, itr)
  3787. - return m_threadBody->Delay(new SqlQuery(sql, new MaNGOS::QueryCallback<Class>(object, method), itr->second));
  3788. + m_threadBody->Delay(new SqlQuery(sql, new MaNGOS::QueryCallback<Class>(object, method), itr->second));
  3789. }
  3790.  
  3791. template<class Class, typename ParamType1>
  3792. -bool
  3793. +void
  3794. Database::AsyncQuery(Class *object, void (Class::*method)(QueryResult*, ParamType1), ParamType1 param1, const char *sql)
  3795. {
  3796. ASYNC_QUERY_BODY(sql, itr)
  3797. - return m_threadBody->Delay(new SqlQuery(sql, new MaNGOS::QueryCallback<Class, ParamType1>(object, method, (QueryResult*)NULL, param1), itr->second));
  3798. + m_threadBody->Delay(new SqlQuery(sql, new MaNGOS::QueryCallback<Class, ParamType1>(object, method, (QueryResult*)NULL, param1), itr->second));
  3799. }
  3800.  
  3801. template<class Class, typename ParamType1, typename ParamType2>
  3802. -bool
  3803. +void
  3804. Database::AsyncQuery(Class *object, void (Class::*method)(QueryResult*, ParamType1, ParamType2), ParamType1 param1, ParamType2 param2, const char *sql)
  3805. {
  3806. ASYNC_QUERY_BODY(sql, itr)
  3807. - return m_threadBody->Delay(new SqlQuery(sql, new MaNGOS::QueryCallback<Class, ParamType1, ParamType2>(object, method, (QueryResult*)NULL, param1, param2), itr->second));
  3808. + m_threadBody->Delay(new SqlQuery(sql, new MaNGOS::QueryCallback<Class, ParamType1, ParamType2>(object, method, (QueryResult*)NULL, param1, param2), itr->second));
  3809. }
  3810.  
  3811. template<class Class, typename ParamType1, typename ParamType2, typename ParamType3>
  3812. -bool
  3813. +void
  3814. Database::AsyncQuery(Class *object, void (Class::*method)(QueryResult*, ParamType1, ParamType2, ParamType3), ParamType1 param1, ParamType2 param2, ParamType3 param3, const char *sql)
  3815. {
  3816. ASYNC_QUERY_BODY(sql, itr)
  3817. - return m_threadBody->Delay(new SqlQuery(sql, new MaNGOS::QueryCallback<Class, ParamType1, ParamType2, ParamType3>(object, method, (QueryResult*)NULL, param1, param2, param3), itr->second));
  3818. + m_threadBody->Delay(new SqlQuery(sql, new MaNGOS::QueryCallback<Class, ParamType1, ParamType2, ParamType3>(object, method, (QueryResult*)NULL, param1, param2, param3), itr->second));
  3819. }
  3820.  
  3821. // -- Query / static --
  3822.  
  3823. template<typename ParamType1>
  3824. -bool
  3825. +void
  3826. Database::AsyncQuery(void (*method)(QueryResult*, ParamType1), ParamType1 param1, const char *sql)
  3827. {
  3828. ASYNC_QUERY_BODY(sql, itr)
  3829. - return m_threadBody->Delay(new SqlQuery(sql, new MaNGOS::SQueryCallback<ParamType1>(method, (QueryResult*)NULL, param1), itr->second));
  3830. + m_threadBody->Delay(new SqlQuery(sql, new MaNGOS::SQueryCallback<ParamType1>(method, (QueryResult*)NULL, param1), itr->second));
  3831. }
  3832.  
  3833. template<typename ParamType1, typename ParamType2>
  3834. -bool
  3835. +void
  3836. Database::AsyncQuery(void (*method)(QueryResult*, ParamType1, ParamType2), ParamType1 param1, ParamType2 param2, const char *sql)
  3837. {
  3838. ASYNC_QUERY_BODY(sql, itr)
  3839. - return m_threadBody->Delay(new SqlQuery(sql, new MaNGOS::SQueryCallback<ParamType1, ParamType2>(method, (QueryResult*)NULL, param1, param2), itr->second));
  3840. + m_threadBody->Delay(new SqlQuery(sql, new MaNGOS::SQueryCallback<ParamType1, ParamType2>(method, (QueryResult*)NULL, param1, param2), itr->second));
  3841. }
  3842.  
  3843. template<typename ParamType1, typename ParamType2, typename ParamType3>
  3844. -bool
  3845. +void
  3846. Database::AsyncQuery(void (*method)(QueryResult*, ParamType1, ParamType2, ParamType3), ParamType1 param1, ParamType2 param2, ParamType3 param3, const char *sql)
  3847. {
  3848. ASYNC_QUERY_BODY(sql, itr)
  3849. - return m_threadBody->Delay(new SqlQuery(sql, new MaNGOS::SQueryCallback<ParamType1, ParamType2, ParamType3>(method, (QueryResult*)NULL, param1, param2, param3), itr->second));
  3850. + m_threadBody->Delay(new SqlQuery(sql, new MaNGOS::SQueryCallback<ParamType1, ParamType2, ParamType3>(method, (QueryResult*)NULL, param1, param2, param3), itr->second));
  3851. }
  3852.  
  3853. // -- PQuery / member --
  3854.  
  3855. template<class Class>
  3856. -bool
  3857. +void
  3858. Database::AsyncPQuery(Class *object, void (Class::*method)(QueryResult*), const char *format,...)
  3859. {
  3860. ASYNC_PQUERY_BODY(format, szQuery)
  3861. - return AsyncQuery(object, method, szQuery);
  3862. + AsyncQuery(object, method, szQuery);
  3863. }
  3864.  
  3865. template<class Class, typename ParamType1>
  3866. -bool
  3867. +void
  3868. Database::AsyncPQuery(Class *object, void (Class::*method)(QueryResult*, ParamType1), ParamType1 param1, const char *format,...)
  3869. {
  3870. ASYNC_PQUERY_BODY(format, szQuery)
  3871. - return AsyncQuery(object, method, param1, szQuery);
  3872. + AsyncQuery(object, method, param1, szQuery);
  3873. }
  3874.  
  3875. template<class Class, typename ParamType1, typename ParamType2>
  3876. -bool
  3877. +void
  3878. Database::AsyncPQuery(Class *object, void (Class::*method)(QueryResult*, ParamType1, ParamType2), ParamType1 param1, ParamType2 param2, const char *format,...)
  3879. {
  3880. ASYNC_PQUERY_BODY(format, szQuery)
  3881. - return AsyncQuery(object, method, param1, param2, szQuery);
  3882. + AsyncQuery(object, method, param1, param2, szQuery);
  3883. }
  3884.  
  3885. template<class Class, typename ParamType1, typename ParamType2, typename ParamType3>
  3886. -bool
  3887. +void
  3888. Database::AsyncPQuery(Class *object, void (Class::*method)(QueryResult*, ParamType1, ParamType2, ParamType3), ParamType1 param1, ParamType2 param2, ParamType3 param3, const char *format,...)
  3889. {
  3890. ASYNC_PQUERY_BODY(format, szQuery)
  3891. - return AsyncQuery(object, method, param1, param2, param3, szQuery);
  3892. + AsyncQuery(object, method, param1, param2, param3, szQuery);
  3893. }
  3894.  
  3895. // -- PQuery / static --
  3896.  
  3897. template<typename ParamType1>
  3898. -bool
  3899. +void
  3900. Database::AsyncPQuery(void (*method)(QueryResult*, ParamType1), ParamType1 param1, const char *format,...)
  3901. {
  3902. ASYNC_PQUERY_BODY(format, szQuery)
  3903. - return AsyncQuery(method, param1, szQuery);
  3904. + AsyncQuery(method, param1, szQuery);
  3905. }
  3906.  
  3907. template<typename ParamType1, typename ParamType2>
  3908. -bool
  3909. +void
  3910. Database::AsyncPQuery(void (*method)(QueryResult*, ParamType1, ParamType2), ParamType1 param1, ParamType2 param2, const char *format,...)
  3911. {
  3912. ASYNC_PQUERY_BODY(format, szQuery)
  3913. - return AsyncQuery(method, param1, param2, szQuery);
  3914. + AsyncQuery(method, param1, param2, szQuery);
  3915. }
  3916.  
  3917. template<typename ParamType1, typename ParamType2, typename ParamType3>
  3918. -bool
  3919. +void
  3920. Database::AsyncPQuery(void (*method)(QueryResult*, ParamType1, ParamType2, ParamType3), ParamType1 param1, ParamType2 param2, ParamType3 param3, const char *format,...)
  3921. {
  3922. ASYNC_PQUERY_BODY(format, szQuery)
  3923. - return AsyncQuery(method, param1, param2, param3, szQuery);
  3924. + AsyncQuery(method, param1, param2, param3, szQuery);
  3925. }
  3926.  
  3927. // -- QueryHolder --
  3928. diff --git a/src/shared/Database/SqlDelayThread.cpp b/src/shared/Database/SqlDelayThread.cpp
  3929. index 9ad6756..544f050 100644
  3930. --- a/src/shared/Database/SqlDelayThread.cpp
  3931. +++ b/src/shared/Database/SqlDelayThread.cpp
  3932. @@ -36,8 +36,10 @@ void SqlDelayThread::run()
  3933. // empty the queue before exiting
  3934. ACE_Based::Thread::Sleep(10);
  3935. SqlOperation* s;
  3936. - while (m_sqlQueue.next(s))
  3937. + while (!m_sqlQueue.empty())
  3938. {
  3939. + SqlQueue::iterator i = m_sqlQueue.begin();
  3940. + SqlOperation* s = *i; m_sqlQueue.erase(i);
  3941. s->Execute(m_dbEngine);
  3942. delete s;
  3943. }
  3944. diff --git a/src/shared/Database/SqlDelayThread.h b/src/shared/Database/SqlDelayThread.h
  3945. index 4e78e99..2cfd1f2 100644
  3946. --- a/src/shared/Database/SqlDelayThread.h
  3947. +++ b/src/shared/Database/SqlDelayThread.h
  3948. @@ -29,7 +29,7 @@ class SqlOperation;
  3949.  
  3950. class SqlDelayThread : public ACE_Based::Runnable
  3951. {
  3952. - typedef ACE_Based::LockedQueue<SqlOperation*, ACE_Thread_Mutex> SqlQueue;
  3953. + typedef std::deque<SqlOperation*> SqlQueue;
  3954.  
  3955. private:
  3956. SqlQueue m_sqlQueue; ///< Queue of SQL statements
  3957. @@ -41,7 +41,7 @@ class SqlDelayThread : public ACE_Based::Runnable
  3958. SqlDelayThread(Database* db);
  3959.  
  3960. ///< Put sql statement to delay queue
  3961. - bool Delay(SqlOperation* sql) { m_sqlQueue.add(sql); return true; }
  3962. + void Delay(SqlOperation* sql) { m_sqlQueue.push_back(sql); }
  3963.  
  3964. virtual void Stop(); ///< Stop event
  3965. virtual void run(); ///< Main Thread loop
  3966. diff --git a/src/shared/Threading.cpp b/src/shared/Threading.cpp
  3967. index 3938286..a5e1b5e 100644
  3968. --- a/src/shared/Threading.cpp
  3969. +++ b/src/shared/Threading.cpp
  3970. @@ -152,6 +152,28 @@ bool Thread::wait()
  3971. return (_res == 0);
  3972. }
  3973.  
  3974. +bool Thread::kill_self( )
  3975. +{
  3976. + #if defined (ACE_HAS_WTHREADS)
  3977. + return TerminateThread(currentHandle(),SIGTERM);
  3978. + #elif(ACE_HAS_PTHREADS)
  3979. + pthread_exit( (void *) SIGTERM );
  3980. + #else
  3981. + return !ACE_Thread::kill(currentId(), SIGTERM);
  3982. + #endif
  3983. +}
  3984. +
  3985. +bool Thread::kill( int Signal )
  3986. +{
  3987. + #if defined (ACE_HAS_WTHREADS)
  3988. + return TerminateThread(m_hThreadHandle,Signal);
  3989. + #elif(ACE_HAS_PTHREADS)
  3990. + pthread_kill(m_iThreadId, Signal);
  3991. + #else
  3992. + return !ACE_Thread::kill(m_iThreadId, Signal);
  3993. + #endif
  3994. +}
  3995. +
  3996. void Thread::destroy()
  3997. {
  3998. if (!m_iThreadId || !m_task)
  3999. diff --git a/src/shared/Threading.h b/src/shared/Threading.h
  4000. index 574b964..71df9be 100644
  4001. --- a/src/shared/Threading.h
  4002. +++ b/src/shared/Threading.h
  4003. @@ -73,8 +73,9 @@ namespace ACE_Based
  4004. explicit Thread(Runnable* instance);
  4005. ~Thread();
  4006.  
  4007. - bool start();
  4008. bool wait();
  4009. + bool start();
  4010. + bool kill(int);
  4011. void destroy();
  4012.  
  4013. void suspend();
  4014. @@ -82,9 +83,12 @@ namespace ACE_Based
  4015.  
  4016. void setPriority(Priority type);
  4017.  
  4018. + static bool kill_self();
  4019. static void Sleep(unsigned long msecs);
  4020. static ACE_thread_t currentId();
  4021. static ACE_hthread_t currentHandle();
  4022. + inline ACE_thread_t ThreadId(){ return m_iThreadId; }
  4023. + inline ACE_hthread_t Handle( ){ return m_hThreadHandle; }
  4024. static Thread * current();
  4025.  
  4026. private:
  4027. --
  4028. 1.6.2.msysgit.0.186.gf7512
  4029. [/quote]
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement