Skip to content

Commit

Permalink
Rework asynchronous sending on bg creation and manage client instance…
Browse files Browse the repository at this point in the history
… ids in queue
  • Loading branch information
killerwife committed Oct 8, 2024
1 parent e1b079f commit 0486e5b
Show file tree
Hide file tree
Showing 8 changed files with 156 additions and 121 deletions.
8 changes: 7 additions & 1 deletion src/game/BattleGround/BattleGround.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,12 @@ BattleGround::~BattleGround()
// skip template bgs as they were never added to visible bg list
BattleGroundBracketId bracketId = GetBracketId();
if (bracketId != BG_BRACKET_ID_TEMPLATE)
sBattleGroundMgr.DeleteClientVisibleInstanceId(GetTypeId(), bracketId, GetClientInstanceId());
{
sWorld.GetBGQueue().GetMessager().AddMessage([bgTypeId = GetTypeId(), bracketId, clientInstanceId = GetClientInstanceId()](BattleGroundQueue* queue)
{
queue->DeleteClientVisibleInstanceId(bgTypeId, bracketId, clientInstanceId);
});
}

// unload map
// map can be null at bg destruction
Expand Down Expand Up @@ -1280,6 +1285,7 @@ void BattleGround::RemovePlayerAtLeave(ObjectGuid playerGuid, bool isOnTransport
// we should update battleground queue, but only if bg isn't ending
if (IsBattleGround() && GetStatus() < STATUS_WAIT_LEAVE)
{
SetInvitedCount(team, GetInvitedCount(team) - 1); // change ahead of free slot queue - will be synched again after
// a player has left the battleground, so there are free slots -> add to queue
if (!AddToBgFreeSlotQueue()) // avoid setting two messages - if was already in queue, just update count
{
Expand Down
28 changes: 21 additions & 7 deletions src/game/BattleGround/BattleGroundHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,9 +77,16 @@ Send battleground list
*/
void WorldSession::SendBattleGroundList(ObjectGuid guid, BattleGroundTypeId bgTypeId) const
{
WorldPacket data;
sBattleGroundMgr.BuildBattleGroundListPacket(data, guid, _player, bgTypeId);
SendPacket(data);
sWorld.GetBGQueue().GetMessager().AddMessage([playerGuid = _player->GetObjectGuid(), masterGuid = guid, playerLevel = _player->GetLevel(), bgTypeId](BattleGroundQueue* queue)
{
WorldPacket data;
queue->BuildBattleGroundListPacket(data, masterGuid, playerLevel, BattleGroundTypeId(bgTypeId));
sWorld.GetMessager().AddMessage([playerGuid, data](World* world)
{
if (Player* player = sObjectMgr.GetPlayer(playerGuid))
player->GetSession()->SendPacket(data);
});
});
}

// Sent by client when player wants to join a battleground
Expand Down Expand Up @@ -376,10 +383,17 @@ void WorldSession::HandleBattlefieldListOpcode(WorldPacket& recv_data)
sLog.outError("Battleground: invalid bgtype received.");
return;
}

WorldPacket data;
sBattleGroundMgr.BuildBattleGroundListPacket(data, _player->GetObjectGuid(), _player, BattleGroundTypeId(bgTypeId));
SendPacket(data);

sWorld.GetBGQueue().GetMessager().AddMessage([playerGuid = _player->GetObjectGuid(), masterGuid = _player->GetObjectGuid(), playerLevel = _player->GetLevel(), bgTypeId](BattleGroundQueue* queue)
{
WorldPacket data;
queue->BuildBattleGroundListPacket(data, masterGuid, playerLevel, BattleGroundTypeId(bgTypeId));
sWorld.GetMessager().AddMessage([playerGuid, data](World* world)
{
if (Player* player = sObjectMgr.GetPlayer(playerGuid))
player->GetSession()->SendPacket(data);
});
});
}

// Sent by client when requesting teleport to the battleground location
Expand Down
75 changes: 3 additions & 72 deletions src/game/BattleGround/BattleGroundMgr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -381,36 +381,7 @@ BattleGround* BattleGroundMgr::GetBattleGroundTemplate(BattleGroundTypeId bgType
return m_battleGrounds[bgTypeId].empty() ? nullptr : m_battleGrounds[bgTypeId].begin()->second;
}

/**
Function that returns client instance id from battleground type id and bracket id
@param battleground type id
@param bracket id
*/
uint32 BattleGroundMgr::CreateClientVisibleInstanceId(BattleGroundTypeId bgTypeId, BattleGroundBracketId bracketId)
{
if (IsArenaType(bgTypeId))
return 0; // arenas don't have client-instanceids

// we create here an instanceid, which is just for
// displaying this to the client and without any other use..
// the client-instanceIds are unique for each battleground-type
// the instance-id just needs to be as low as possible, beginning with 1
// the following works, because std::set is default ordered with "<"
// the optimalization would be to use as bitmask std::vector<uint32> - but that would only make code unreadable

uint32 lastId = 0;
ClientBattleGroundIdSet& ids = m_clientBattleGroundIds[bgTypeId][bracketId];
for (ClientBattleGroundIdSet::const_iterator itr = ids.begin(); itr != ids.end();)
{
if ((++lastId) != *itr) // if there is a gap between the ids, we will break..
break;
lastId = *itr;
}
ids.insert(lastId + 1);

return lastId + 1;
}

/**
Function that creates a new battleground that is actually used
Expand All @@ -420,7 +391,7 @@ uint32 BattleGroundMgr::CreateClientVisibleInstanceId(BattleGroundTypeId bgTypeI
@param arena type
@param isRated
*/
BattleGround* BattleGroundMgr::CreateNewBattleGround(BattleGroundTypeId bgTypeId, BattleGroundBracketId bracketId, ArenaType arenaType, bool isRated)
BattleGround* BattleGroundMgr::CreateNewBattleGround(BattleGroundTypeId bgTypeId, BattleGroundBracketId bracketId, ArenaType arenaType, bool isRated, uint32 instanceId, uint32 clientInstanceId)
{
// get the template BG
BattleGround* bgTemplate = GetBattleGroundTemplate(bgTypeId);
Expand Down Expand Up @@ -480,9 +451,9 @@ BattleGround* BattleGroundMgr::CreateNewBattleGround(BattleGroundTypeId bgTypeId
bg->SetBracketId(bracketId);

// will also set m_bgMap, instanceid
sMapMgr.CreateBgMap(bg->GetMapId(), bg);
sMapMgr.CreateBgMap(bg->GetMapId(), instanceId, bg);

bg->SetClientInstanceId(CreateClientVisibleInstanceId(bgTypeId, bracketId));
bg->SetClientInstanceId(clientInstanceId);

// reset the new bg (set status to status_wait_queue from status_none)
bg->Reset();
Expand Down Expand Up @@ -957,46 +928,6 @@ void BattleGroundMgr::ResetAllArenaData()
}
}

/**
Method that builds battleground list data
@param packet
@param battlemaster guid
@param player
@param battleground type id
*/
void BattleGroundMgr::BuildBattleGroundListPacket(WorldPacket& data, ObjectGuid guid, Player* player, BattleGroundTypeId bgTypeId) const
{
if (!player)
return;

data.Initialize(SMSG_BATTLEFIELD_LIST);
data << guid; // battlemaster guid
data << uint32(bgTypeId); // battleground id
if (bgTypeId == BATTLEGROUND_AA) // arena
{
data << uint8(5); // unk
data << uint32(0); // unk
}
else // battleground
{
data << uint8(0x00); // unk

size_t count_pos = data.wpos();
uint32 count = 0;
data << uint32(0); // number of bg instances

uint32 bracket_id = GetBattleGroundBracketIdFromLevel(bgTypeId, player->GetLevel());
ClientBattleGroundIdSet const& ids = m_clientBattleGroundIds[bgTypeId][bracket_id];
for (std::set<uint32>::const_iterator itr = ids.begin(); itr != ids.end(); ++itr)
{
data << uint32(*itr);
++count;
}
data.put<uint32>(count_pos, count);
}
}

/**
Method that sends player to battleground
Expand Down
11 changes: 1 addition & 10 deletions src/game/BattleGround/BattleGroundMgr.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,26 +52,19 @@ class BattleGroundMgr
static void BuildPvpLogDataPacket(WorldPacket& /*data*/, BattleGround* /*bg*/);
static void BuildBattleGroundStatusPacket(WorldPacket& data, bool bgExists, uint32 bgTypeId, uint32 bgClientInstanceId, bool isRated, uint32 mapId, uint8 queueSlot, uint8 statusId, uint32 time1, uint32 time2, ArenaType arenaType, Team arenaTeam);
static void BuildPlaySoundPacket(WorldPacket& /*data*/, uint32 /*soundId*/);
void BuildBattleGroundListPacket(WorldPacket& /*data*/, ObjectGuid /*guid*/, Player* /*player*/, BattleGroundTypeId /*bgTypeId*/) const;

/* Battlegrounds */
BattleGround* GetBattleGroundThroughClientInstance(uint32 /*instanceId*/, BattleGroundTypeId /*bgTypeId*/);
BattleGround* GetBattleGround(uint32 /*instanceId*/, BattleGroundTypeId /*bgTypeId*/); // there must be uint32 because MAX_BATTLEGROUND_TYPE_ID means unknown

BattleGround* GetBattleGroundTemplate(BattleGroundTypeId /*bgTypeId*/) const;
BattleGround* CreateNewBattleGround(BattleGroundTypeId /*bgTypeId*/, BattleGroundBracketId /*bracketEntry*/, ArenaType /*arenaType*/, bool /*isRated*/);
BattleGround* CreateNewBattleGround(BattleGroundTypeId bgTypeId, BattleGroundBracketId bracketEntry, ArenaType arenaType, bool isRated, uint32 instanceId, uint32 clientInstanceId);

uint32 CreateBattleGround(BattleGroundTypeId /*bgTypeId*/, bool /*isArena*/, uint32 /*minPlayersPerTeam*/, uint32 /*maxPlayersPerTeam*/, uint32 /*levelMin*/, uint32 /*levelMax*/, char const* /*battleGroundName*/, uint32 /*mapId*/, float /*team1StartLocX*/, float /*team1StartLocY*/, float /*team1StartLocZ*/, float /*team1StartLocO*/, float /*team2StartLocX*/, float /*team2StartLocY*/, float /*team2StartLocZ*/, float /*team2StartLocO*/, float /*startMaxDist*/, uint32 /*playerSkinReflootId*/);

void AddBattleGround(uint32 instanceId, BattleGroundTypeId bgTypeId, BattleGround* bg) { m_battleGrounds[bgTypeId][instanceId] = bg; };
void RemoveBattleGround(uint32 instanceId, BattleGroundTypeId bgTypeId) { m_battleGrounds[bgTypeId].erase(instanceId); }

uint32 CreateClientVisibleInstanceId(BattleGroundTypeId /*bgTypeId*/, BattleGroundBracketId /*bracketId*/);
void DeleteClientVisibleInstanceId(BattleGroundTypeId bgTypeId, BattleGroundBracketId bracketId, uint32 clientInstanceId)
{
m_clientBattleGroundIds[bgTypeId][bracketId].erase(clientInstanceId);
}

void CreateInitialBattleGrounds();
void DeleteAllBattleGrounds();

Expand Down Expand Up @@ -143,8 +136,6 @@ class BattleGroundMgr

/* Battlegrounds */
BattleGroundSet m_battleGrounds[MAX_BATTLEGROUND_TYPE_ID];
typedef std::set<uint32> ClientBattleGroundIdSet;
ClientBattleGroundIdSet m_clientBattleGroundIds[MAX_BATTLEGROUND_TYPE_ID][MAX_BATTLEGROUND_BRACKETS]; // the instanceids just visible for the client
bool m_arenaTesting;
bool m_testing;
std::set<uint32> m_usedRefloot;
Expand Down
Loading

0 comments on commit 0486e5b

Please sign in to comment.