Skip to content

Commit

Permalink
Fix battlegrounds remaining open if player logs out after being invited.
Browse files Browse the repository at this point in the history
  • Loading branch information
ratkosrb committed May 13, 2024
1 parent 91a4f32 commit a11a619
Show file tree
Hide file tree
Showing 8 changed files with 74 additions and 6 deletions.
7 changes: 7 additions & 0 deletions src/game/Battlegrounds/BattleGround.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,9 @@ void BattleGround::Update(uint32 diff)
// BattleGround Template instance cannot be updated, because it would be deleted
if (!GetInvitedCount(HORDE) && !GetInvitedCount(ALLIANCE))
delete this;
// update queue to avoid bg remaining indefinitely until player logs back in if he logs out after it pops
else if (GetStatus() <= STATUS_WAIT_JOIN && (GetBgMap()->GetCreateTime() + 2 * MINUTE) < time(nullptr))
sBattleGroundMgr.ScheduleQueueUpdate(BattleGroundMgr::BgQueueTypeId(GetTypeID()), GetTypeID(), GetBracketId());

return;
}
Expand Down Expand Up @@ -741,6 +744,10 @@ void BattleGround::EndBattleGround(Team winner)
#else
DoOrSimulateScriptTextForMap(winTextId, GetHeraldEntry(), GetBgMap());
#endif

// remove any invited players from the queue when bg ends
if (GetInvitedCount(HORDE) || GetInvitedCount(ALLIANCE))
sBattleGroundMgr.ScheduleQueueUpdate(BattleGroundMgr::BgQueueTypeId(GetTypeID()), GetTypeID(), GetBracketId());
}

uint32 BattleGround::GetBonusHonorFromKill(uint32 kills) const
Expand Down
44 changes: 39 additions & 5 deletions src/game/Battlegrounds/BattleGroundMgr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -639,19 +639,53 @@ should be called from BattleGround::RemovePlayer function in some cases
void BattleGroundQueue::Update(BattleGroundTypeId bgTypeId, BattleGroundBracketId bracketId)
{
//ACE_Guard<ACE_Recursive_Thread_Mutex> guard(m_lock);
// First, remove old offline players

// First, remove players who shouldn't be in queue anymore
QueuedPlayersMap::iterator itrOffline = m_queuedPlayers.begin();
while (itrOffline != m_queuedPlayers.end())
{
// remove offline players
if (!itrOffline->second.online && WorldTimer::getMSTimeDiffToNow(itrOffline->second.lastOnlineTime) > OFFLINE_BG_QUEUE_TIME)
{
RemovePlayer(itrOffline->first, true);
itrOffline = m_queuedPlayers.begin();
continue;
}
else
++itrOffline;

// remove players who are in queue for bg that has ended
GroupQueueInfo* group = itrOffline->second.groupInfo;
if (group->isInvitedToBgInstanceGuid)
{
BattleGround* bg;
if ((bg = sBattleGroundMgr.GetBattleGround(group->isInvitedToBgInstanceGuid, group->bgTypeId)) && bg->GetStatus() == STATUS_WAIT_LEAVE)
{
if (itrOffline->second.online)
{
if (Player* player = ObjectAccessor::FindPlayerNotInWorld(itrOffline->first))
{
BattleGroundQueueTypeId queueTypeId = BattleGroundMgr::BgQueueTypeId(group->bgTypeId);
uint32 queueSlot = player->GetBattleGroundQueueIndex(queueTypeId);
if (queueSlot < PLAYER_MAX_BATTLEGROUND_QUEUES)
{
player->RemoveBattleGroundQueueId(queueTypeId);

WorldPacket data;
sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, queueSlot, STATUS_NONE, 0, 0);
player->GetSession()->SendPacket(&data);
}
}
}

RemovePlayer(itrOffline->first, true);
itrOffline = m_queuedPlayers.begin();
continue;
}
}

++itrOffline;
}
//if no players in queue - do nothing

// if no players in queue - do nothing
if (m_queuedGroups[bracketId][BG_QUEUE_PREMADE_ALLIANCE].empty() &&
m_queuedGroups[bracketId][BG_QUEUE_PREMADE_HORDE].empty() &&
m_queuedGroups[bracketId][BG_QUEUE_NORMAL_ALLIANCE].empty() &&
Expand All @@ -669,7 +703,7 @@ void BattleGroundQueue::Update(BattleGroundTypeId bgTypeId, BattleGroundBracketI
std::default_random_engine(seed));
}

//battleground with free slot for player should be always in the beginning of the queue
// battleground with free slot for player should be always in the beginning of the queue
// maybe it would be better to create bgfreeslotqueue for each bracketId
BgFreeSlotQueueType::iterator itr, next;
for (itr = sBattleGroundMgr.m_bgFreeSlotQueue[bgTypeId].begin(); itr != sBattleGroundMgr.m_bgFreeSlotQueue[bgTypeId].end(); itr = next)
Expand Down
1 change: 1 addition & 0 deletions src/game/Chat/Chat.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -519,6 +519,7 @@ ChatCommand * ChatHandler::getCommandTable()
{ "item", SEC_TICKETMASTER, true, &ChatHandler::HandleListItemCommand, "", nullptr },
{ "object", SEC_TICKETMASTER, true, &ChatHandler::HandleListObjectCommand, "", nullptr },
{ "talents", SEC_TICKETMASTER, false, &ChatHandler::HandleListTalentsCommand, "", nullptr },
{ "maps", SEC_TICKETMASTER, true, &ChatHandler::HandleListMapsCommand, "", nullptr },
{ "movegens", SEC_TICKETMASTER, false, &ChatHandler::HandleListMoveGensCommand, "", nullptr },
{ "hostilerefs", SEC_TICKETMASTER, false, &ChatHandler::HandleListHostileRefsCommand, "", nullptr },
{ "threat", SEC_TICKETMASTER, false, &ChatHandler::HandleListThreatCommand, "", nullptr },
Expand Down
1 change: 1 addition & 0 deletions src/game/Chat/Chat.h
Original file line number Diff line number Diff line change
Expand Up @@ -607,6 +607,7 @@ class ChatHandler
bool HandleListItemCommand(char* args);
bool HandleListObjectCommand(char* args);
bool HandleListTalentsCommand(char* args);
bool HandleListMapsCommand(char* args);
bool HandleListMoveGensCommand(char* args);
bool HandleListHostileRefsCommand(char* args);
bool HandleListThreatCommand(char* args);
Expand Down
9 changes: 9 additions & 0 deletions src/game/Commands/ServerCommands.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2027,3 +2027,12 @@ bool ChatHandler::HandleWarEffortSetStageCommand(char* args)

return true;
}

bool ChatHandler::HandleListMapsCommand(char* /*args*/)
{
SendSysMessage("Listing all currently created maps:");
for (auto const& itr : sMapMgr.Maps())
PSendSysMessage("%u-%u - %s - Players %u - Created %s ago", itr.first.nMapId, itr.first.nInstanceId, playerLink(itr.second->GetMapName()).c_str(), itr.second->GetPlayersCountExceptGMs(), secsToTimeString(time(nullptr) - itr.second->GetCreateTime(), true).c_str());

return true;
}
11 changes: 11 additions & 0 deletions src/game/Handlers/BattleGroundHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -428,6 +428,7 @@ void WorldSession::HandleBattleFieldPortOpcode(WorldPacket& recv_data)
// bg template might and must be used in case of leaving queue, when instance is not created yet
if (!bg && action == 0)
bg = sBattleGroundMgr.GetBattleGroundTemplate(bgTypeId);

if (!bg)
{
sLog.Out(LOG_BASIC, LOG_LVL_DEBUG, "BattlegroundHandler: bgTemplate not found for type id %u.", bgTypeId);
Expand All @@ -447,14 +448,24 @@ void WorldSession::HandleBattleFieldPortOpcode(WorldPacket& recv_data)
action = 0;
sLog.Out(LOG_BASIC, LOG_LVL_DEBUG, "Battleground: player %s (%u) has a deserter debuff, do not port him to battleground!", _player->GetName(), _player->GetGUIDLow());
}

//if player don't match battleground max level, then do not allow him to enter! (this might happen when player leveled up during his waiting in queue
if (_player->GetLevel() > bg->GetMaxLevel())
{
sLog.Out(LOG_BASIC, LOG_LVL_ERROR, "Battleground: Player %s (%u) has level (%u) higher than maxlevel (%u) of battleground (%u)! Do not port him to battleground!",
_player->GetName(), _player->GetGUIDLow(), _player->GetLevel(), bg->GetMaxLevel(), bg->GetTypeID());
action = 0;
}

// do not allow entering bg which is already over
if (bg->GetStatus() == STATUS_WAIT_LEAVE)
{
sLog.Out(LOG_BASIC, LOG_LVL_ERROR, "Battleground: Player %s (%u) is attempting to enter battleground (%u) which has already ended!",
_player->GetName(), _player->GetGUIDLow(), bg->GetTypeID());
action = 0;
}
}

uint32 queueSlot = _player->GetBattleGroundQueueIndex(bgQueueTypeId);
WorldPacket data;
switch (action)
Expand Down
5 changes: 4 additions & 1 deletion src/game/Maps/Map.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ Map::Map(uint32 id, time_t expiry, uint32 InstanceId)
i_id(id), i_InstanceId(InstanceId), m_unloadTimer(0),
m_VisibleDistance(DEFAULT_VISIBILITY_DISTANCE), m_persistentState(nullptr),
m_activeNonPlayersIter(m_activeNonPlayers.end()), m_transportsUpdateIter(m_transports.end()),
i_gridExpiry(expiry), m_TerrainData(sTerrainMgr.LoadTerrain(id)),
m_createTime(time(nullptr)), i_gridExpiry(expiry), m_TerrainData(sTerrainMgr.LoadTerrain(id)),
i_data(nullptr), i_script_id(0), m_unloading(false), m_crashed(false),
_processingSendObjUpdates(false), _processingUnitsRelocation(false),
m_updateFinished(false), m_updateDiffMod(0), m_GridActivationDistance(DEFAULT_VISIBILITY_DISTANCE),
Expand Down Expand Up @@ -2411,6 +2411,8 @@ DungeonPersistentState* DungeonMap::GetPersistanceState() const

/* ******* Battleground Instance Maps ******* */

static uint32 s_bgCount = 0;

BattleGroundMap::BattleGroundMap(uint32 id, time_t expiry, uint32 InstanceId)
: Map(id, expiry, InstanceId), m_bg(nullptr)
{
Expand All @@ -2427,6 +2429,7 @@ void BattleGroundMap::Update(uint32 diff)
{
if (!GetBG())
return;

Map::Update(diff);

GetBG()->Update(diff);
Expand Down
2 changes: 2 additions & 0 deletions src/game/Maps/Map.h
Original file line number Diff line number Diff line change
Expand Up @@ -403,6 +403,7 @@ class Map : public GridRefManager<NGridType>
}

time_t GetGridExpiry(void) const { return i_gridExpiry; }
time_t GetCreateTime() const { return m_createTime; }
uint32 GetId(void) const { return i_id; }

// some calls like isInWater should not use vmaps due to processor power
Expand Down Expand Up @@ -701,6 +702,7 @@ class Map : public GridRefManager<NGridType>
TimePoint m_currentTime;
uint32 m_lastMvtSpellsUpdate = 0;
private:
time_t m_createTime; // time when map was created
time_t i_gridExpiry;

NGridType* i_grids[MAX_NUMBER_OF_GRIDS][MAX_NUMBER_OF_GRIDS];
Expand Down

0 comments on commit a11a619

Please sign in to comment.