[8815] Reimplemented bgQueues announces, fixed possible problems with multithreaded queues Mutexes have to be still commented because of ACE bug. When player enters new bg from battleground, do not rewrite his m_BgData with zeros. patch is tested.

Signed-off-by: Triply <triply@getmangos.com>
This commit is contained in:
Triply 2009-11-14 18:34:27 +01:00
parent d5ee544367
commit ef26908948
8 changed files with 101 additions and 100 deletions

View file

@ -24,7 +24,7 @@ CREATE TABLE `db_version` (
`version` varchar(120) default NULL,
`creature_ai_version` varchar(120) default NULL,
`cache_id` int(10) default '0',
`required_8803_02_mangos_playercreateinfo_action` bit(1) default NULL
`required_8815_01_mangos_mangos_string` bit(1) default NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Used DB version notes';
--

View file

@ -0,0 +1,8 @@
ALTER TABLE db_version CHANGE COLUMN required_8803_02_mangos_playercreateinfo_action required_8815_01_mangos_mangos_string bit;
-- this sql might delete some of your translated strings, if you translate them
DELETE FROM mangos_string WHERE entry in (718, 719);
INSERT INTO mangos_string VALUES (718,'|cffff0000[Arena Queue Announcer]:|r All Arenas -- Joined : %ux%u : %u|r',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL);
INSERT INTO mangos_string VALUES (719,'|cffff0000[Arena Queue Announcer]:|r All Arenas -- Left : %ux%u : %u|r',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL);

View file

@ -156,6 +156,7 @@ pkgdata_DATA = \
8800_01_mangos_spell_elixir.sql \
8803_01_mangos_playercreateinfo_spell.sql \
8803_02_mangos_playercreateinfo_action.sql \
8815_01_mangos_mangos_string.sql \
README
## Additional files to include when running 'make dist'
@ -292,4 +293,5 @@ EXTRA_DIST = \
8800_01_mangos_spell_elixir.sql \
8803_01_mangos_playercreateinfo_spell.sql \
8803_02_mangos_playercreateinfo_action.sql \
8815_01_mangos_mangos_string.sql \
README

View file

@ -149,11 +149,11 @@ void WorldSession::HandleBattlemasterJoinOpcode( WorldPacket & recv_data )
// _player->GetGroup() was already checked, grp is already initialized
BattleGroundQueue& bgQueue = sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId];
GroupQueueInfo * ginfo = bgQueue.AddGroup(_player, bgTypeId, 0, false, isPremade, 0);
uint32 avgTime = bgQueue.GetAverageQueueWaitTime(ginfo, _player->GetBattleGroundQueueIdFromLevel());
if (joinAsGroup /* && _player->GetGroup()*/)
{
sLog.outDebug("Battleground: the following players are joining as group:");
GroupQueueInfo * ginfo = bgQueue.AddGroup(_player, grp, bgTypeId, 0, false, isPremade, 0);
uint32 avgTime = bgQueue.GetAverageQueueWaitTime(ginfo, _player->GetBattleGroundQueueIdFromLevel());
for(GroupReference *itr = grp->GetFirstMember(); itr != NULL; itr = itr->next())
{
Player *member = itr->getSource();
@ -167,13 +167,14 @@ void WorldSession::HandleBattlemasterJoinOpcode( WorldPacket & recv_data )
member->GetSession()->SendPacket(&data);
sBattleGroundMgr.BuildGroupJoinedBattlegroundPacket(&data, bgTypeId);
member->GetSession()->SendPacket(&data);
bgQueue.AddPlayer(member, ginfo);
sLog.outDebug("Battleground: player joined queue for bg queue type %u bg type %u: GUID %u, NAME %s",bgQueueTypeId,bgTypeId,member->GetGUIDLow(), member->GetName());
}
sLog.outDebug("Battleground: group end");
}
else
{
GroupQueueInfo * ginfo = bgQueue.AddGroup(_player, NULL, bgTypeId, 0, false, isPremade, 0);
uint32 avgTime = bgQueue.GetAverageQueueWaitTime(ginfo, _player->GetBattleGroundQueueIdFromLevel());
// already checked if queueSlot is valid, now just get it
uint32 queueSlot = _player->AddBattleGroundQueueId(bgQueueTypeId);
@ -181,12 +182,9 @@ void WorldSession::HandleBattlemasterJoinOpcode( WorldPacket & recv_data )
// send status packet (in queue)
sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, queueSlot, STATUS_WAIT_QUEUE, avgTime, 0, ginfo->ArenaType);
SendPacket(&data);
bgQueue.AddPlayer(_player, ginfo);
sLog.outDebug("Battleground: player joined queue for bg queue type %u bg type %u: GUID %u, NAME %s",bgQueueTypeId,bgTypeId,_player->GetGUIDLow(), _player->GetName());
}
sBattleGroundMgr.ScheduleQueueUpdate(0, 0, bgQueueTypeId, bgTypeId, _player->GetBattleGroundQueueIdFromLevel());
//we should announce queue status here, if we want
}
void WorldSession::HandleBattleGroundPlayerPositionsOpcode( WorldPacket & /*recv_data*/ )
@ -377,6 +375,7 @@ void WorldSession::HandleBattleFieldPortOpcode( WorldPacket &recv_data )
if (!_player->IsInvitedForBattleGroundQueueType(bgQueueTypeId))
return; // cheating?
if (!_player->InBattleGround())
_player->SetBattleGroundEntryPoint();
// resurrect the player
@ -673,13 +672,14 @@ void WorldSession::HandleBattlemasterJoinArena( WorldPacket & recv_data )
}
BattleGroundQueue &bgQueue = sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId];
GroupQueueInfo * ginfo = bgQueue.AddGroup(_player, bgTypeId, arenatype, isRated, false, arenaRating, ateamId);
uint32 avgTime = bgQueue.GetAverageQueueWaitTime(ginfo, _player->GetBattleGroundQueueIdFromLevel());
if (asGroup)
{
sLog.outDebug("Battleground: arena join as group start");
if (isRated)
sLog.outDebug("Battleground: arena team id %u, leader %s queued with rating %u for type %u",_player->GetArenaTeamId(arenaslot),_player->GetName(),arenaRating,arenatype);
GroupQueueInfo * ginfo = bgQueue.AddGroup(_player, grp, bgTypeId, arenatype, isRated, false, arenaRating, ateamId);
uint32 avgTime = bgQueue.GetAverageQueueWaitTime(ginfo, _player->GetBattleGroundQueueIdFromLevel());
for(GroupReference *itr = grp->GetFirstMember(); itr != NULL; itr = itr->next())
{
Player *member = itr->getSource();
@ -693,7 +693,6 @@ void WorldSession::HandleBattlemasterJoinArena( WorldPacket & recv_data )
member->GetSession()->SendPacket(&data);
sBattleGroundMgr.BuildGroupJoinedBattlegroundPacket(&data, bgTypeId);
member->GetSession()->SendPacket(&data);
bgQueue.AddPlayer(member, ginfo);
sLog.outDebug("Battleground: player joined queue for arena as group bg queue type %u bg type %u: GUID %u, NAME %s",bgQueueTypeId,bgTypeId,member->GetGUIDLow(), member->GetName());
}
sLog.outDebug("Battleground: arena join as group end");
@ -701,13 +700,14 @@ void WorldSession::HandleBattlemasterJoinArena( WorldPacket & recv_data )
}
else
{
GroupQueueInfo * ginfo = bgQueue.AddGroup(_player, NULL, bgTypeId, arenatype, isRated, false, arenaRating, ateamId);
uint32 avgTime = bgQueue.GetAverageQueueWaitTime(ginfo, _player->GetBattleGroundQueueIdFromLevel());
uint32 queueSlot = _player->AddBattleGroundQueueId(bgQueueTypeId);
WorldPacket data;
// send status packet (in queue)
sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, queueSlot, STATUS_WAIT_QUEUE, avgTime, 0, arenatype);
SendPacket(&data);
bgQueue.AddPlayer(_player, ginfo);
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());
}
sBattleGroundMgr.ScheduleQueueUpdate(arenaRating, arenatype, bgQueueTypeId, bgTypeId, _player->GetBattleGroundQueueIdFromLevel());

View file

@ -147,14 +147,12 @@ bool BattleGroundQueue::SelectionPool::AddGroup(GroupQueueInfo *ginfo, uint32 de
/*** BATTLEGROUND QUEUES ***/
/*********************************************************/
// add group to bg queue with the given leader and bg specifications
GroupQueueInfo * BattleGroundQueue::AddGroup(Player *leader, BattleGroundTypeId BgTypeId, uint8 ArenaType, bool isRated, bool isPremade, uint32 arenaRating, uint32 arenateamid)
// add group or player (grp == NULL) to bg queue with the given leader and bg specifications
GroupQueueInfo * BattleGroundQueue::AddGroup(Player *leader, Group* grp, BattleGroundTypeId BgTypeId, uint8 ArenaType, bool isRated, bool isPremade, uint32 arenaRating, uint32 arenateamid)
{
BGQueueIdBasedOnLevel queue_id = leader->GetBattleGroundQueueIdFromLevel();
// create new ginfo
// cannot use the method like in addplayer, because that could modify an in-queue group's stats
// (e.g. leader leaving queue then joining as individual again)
GroupQueueInfo* ginfo = new GroupQueueInfo;
ginfo->BgTypeId = BgTypeId;
ginfo->ArenaType = ArenaType;
@ -177,25 +175,79 @@ GroupQueueInfo * BattleGroundQueue::AddGroup(Player *leader, BattleGroundTypeId
index++;
sLog.outDebug("Adding Group to BattleGroundQueue bgTypeId : %u, queue_id : %u, index : %u", BgTypeId, queue_id, index);
//ACE_Guard<ACE_Recursive_Thread_Mutex> guard(m_Lock);
m_QueuedGroups[queue_id][index].push_back(ginfo);
uint32 lastOnlineTime = getMSTime();
// return ginfo, because it is needed to add players to this group info
return ginfo;
//announce world (this don't need mutex)
if (isRated && sWorld.getConfig(CONFIG_ARENA_QUEUE_ANNOUNCER_ENABLE))
{
sWorld.SendWorldText(LANG_ARENA_QUEUE_ANNOUNCE_WORLD_JOIN, ginfo->ArenaType, ginfo->ArenaType, ginfo->ArenaTeamRating);
}
//add player to playermap
void BattleGroundQueue::AddPlayer(Player *plr, GroupQueueInfo *ginfo)
//add players from group to ginfo
{
//ACE_Guard<ACE_Recursive_Thread_Mutex> guard(m_Lock);
//if player isn't in queue, he is added, if already is, then values are overwritten, no memory leak
PlayerQueueInfo& info = m_QueuedPlayers[plr->GetGUID()];
info.LastOnlineTime = getMSTime();
info.GroupInfo = ginfo;
if (grp)
{
for(GroupReference *itr = grp->GetFirstMember(); itr != NULL; itr = itr->next())
{
Player *member = itr->getSource();
if(!member)
continue; // this should never happen
PlayerQueueInfo& pl_info = m_QueuedPlayers[member->GetGUID()];
pl_info.LastOnlineTime = lastOnlineTime;
pl_info.GroupInfo = ginfo;
// add the pinfo to ginfo's list
ginfo->Players[plr->GetGUID()] = &info;
ginfo->Players[member->GetGUID()] = &pl_info;
}
}
else
{
PlayerQueueInfo& pl_info = m_QueuedPlayers[leader->GetGUID()];
pl_info.LastOnlineTime = lastOnlineTime;
pl_info.GroupInfo = ginfo;
ginfo->Players[leader->GetGUID()] = &pl_info;
}
//add GroupInfo to m_QueuedGroups
m_QueuedGroups[queue_id][index].push_back(ginfo);
//announce to world, this code needs mutex
if (!isRated && !isPremade && sWorld.getConfig(CONFIG_BATTLEGROUND_QUEUE_ANNOUNCER_ENABLE))
{
BattleGround* bg = sBattleGroundMgr.GetBattleGroundTemplate(ginfo->BgTypeId);
if (bg)
{
char const* bgName = bg->GetName();
uint32 MinPlayers = bg->GetMinPlayersPerTeam();
uint32 qHorde = 0;
uint32 qAlliance = 0;
uint32 q_min_level = (queue_id + 1) * 10;
GroupsQueueType::const_iterator itr;
for(itr = m_QueuedGroups[queue_id][BG_QUEUE_NORMAL_ALLIANCE].begin(); itr != m_QueuedGroups[queue_id][BG_QUEUE_NORMAL_ALLIANCE].end(); ++itr)
if (!(*itr)->IsInvitedToBGInstanceGUID)
qAlliance += (*itr)->Players.size();
for(itr = m_QueuedGroups[queue_id][BG_QUEUE_NORMAL_HORDE].begin(); itr != m_QueuedGroups[queue_id][BG_QUEUE_NORMAL_HORDE].end(); ++itr)
if (!(*itr)->IsInvitedToBGInstanceGUID)
qHorde += (*itr)->Players.size();
// Show queue status to player only (when joining queue)
if (sWorld.getConfig(CONFIG_BATTLEGROUND_QUEUE_ANNOUNCER_PLAYERONLY))
{
ChatHandler(leader).PSendSysMessage(LANG_BG_QUEUE_ANNOUNCE_SELF, bgName, q_min_level, q_min_level + 10,
qAlliance, (MinPlayers > qAlliance) ? MinPlayers - qAlliance : (uint32)0, qHorde, (MinPlayers > qHorde) ? MinPlayers - qHorde : (uint32)0);
}
// System message
else
{
sWorld.SendWorldText(LANG_BG_QUEUE_ANNOUNCE_WORLD, bgName, q_min_level, q_min_level + 10,
qAlliance, (MinPlayers > qAlliance) ? MinPlayers - qAlliance : (uint32)0, qHorde, (MinPlayers > qHorde) ? MinPlayers - qHorde : (uint32)0);
}
}
}
//release mutex
}
return ginfo;
}
void BattleGroundQueue::PlayerInvitedToBGUpdateAverageWaitTime(GroupQueueInfo* ginfo, BGQueueIdBasedOnLevel queue_id)
@ -319,9 +371,9 @@ void BattleGroundQueue::RemovePlayer(const uint64& guid, bool decreaseInvitedCou
// remove player queue info
m_QueuedPlayers.erase(itr);
//if we left BG queue(not porting) OR if arena team left queue for rated match
if ((decreaseInvitedCount && !group->ArenaType) || (group->ArenaType && group->IsRated && group->Players.empty()))
AnnounceWorld(group, guid, false);
// announce to world if arena team left queue for rated match, show only once
if (group->ArenaType && group->IsRated && group->Players.empty() && sWorld.getConfig(CONFIG_ARENA_QUEUE_ANNOUNCER_ENABLE))
sWorld.SendWorldText(LANG_ARENA_QUEUE_ANNOUNCE_WORLD_EXIT, group->ArenaType, group->ArenaType, group->ArenaTeamRating);
//if player leaves queue and he is invited to rated arena match, then he have to loose
if (group->IsInvitedToBGInstanceGUID && group->IsRated && decreaseInvitedCount)
@ -388,63 +440,6 @@ bool BattleGroundQueue::GetPlayerGroupInfoData(const uint64& guid, GroupQueueInf
return true;
}
//Announce world message
void BattleGroundQueue::AnnounceWorld(GroupQueueInfo *ginfo, const uint64& playerGUID, bool isAddedToQueue)
{
if(ginfo->ArenaType) //if Arena
{
if (sWorld.getConfig(CONFIG_ARENA_QUEUE_ANNOUNCER_ENABLE) && ginfo->IsRated)
{
BattleGround* bg = sBattleGroundMgr.GetBattleGroundTemplate(ginfo->BgTypeId);
if (!bg)
return;
char const* bgName = bg->GetName();
if (isAddedToQueue)
sWorld.SendWorldText(LANG_ARENA_QUEUE_ANNOUNCE_WORLD_JOIN, bgName, ginfo->ArenaType, ginfo->ArenaType, ginfo->ArenaTeamRating);
else
sWorld.SendWorldText(LANG_ARENA_QUEUE_ANNOUNCE_WORLD_EXIT, bgName, ginfo->ArenaType, ginfo->ArenaType, ginfo->ArenaTeamRating);
}
}
else //if BG
{
if (sWorld.getConfig(CONFIG_BATTLEGROUND_QUEUE_ANNOUNCER_ENABLE))
{
Player *plr = sObjectMgr.GetPlayer(playerGUID);
BattleGround* bg = sBattleGroundMgr.GetBattleGroundTemplate(ginfo->BgTypeId);
if (!bg || !plr)
return;
BGQueueIdBasedOnLevel queue_id = plr->GetBattleGroundQueueIdFromLevel();
char const* bgName = bg->GetName();
uint32 MinPlayers = bg->GetMinPlayersPerTeam();
uint32 qHorde = 0;
uint32 qAlliance = 0;
uint32 q_min_level = (queue_id + 1) * 10;
GroupsQueueType::const_iterator itr;
for(itr = m_QueuedGroups[queue_id][BG_QUEUE_NORMAL_ALLIANCE].begin(); itr != m_QueuedGroups[queue_id][BG_QUEUE_NORMAL_ALLIANCE].end(); ++itr)
if (!(*itr)->IsInvitedToBGInstanceGUID)
qAlliance += (*itr)->Players.size();
for(itr = m_QueuedGroups[queue_id][BG_QUEUE_NORMAL_HORDE].begin(); itr != m_QueuedGroups[queue_id][BG_QUEUE_NORMAL_HORDE].end(); ++itr)
if (!(*itr)->IsInvitedToBGInstanceGUID)
qHorde += (*itr)->Players.size();
// Show queue status to player only (when joining queue)
if (sWorld.getConfig(CONFIG_BATTLEGROUND_QUEUE_ANNOUNCER_PLAYERONLY))
{
ChatHandler(plr).PSendSysMessage(LANG_BG_QUEUE_ANNOUNCE_SELF,
bgName, q_min_level, q_min_level + 10, qAlliance, MinPlayers, qHorde, MinPlayers);
}
// System message
else
{
sWorld.SendWorldText(LANG_BG_QUEUE_ANNOUNCE_WORLD,
bgName, q_min_level, q_min_level + 10, qAlliance, MinPlayers, qHorde, MinPlayers);
}
}
}
}
bool BattleGroundQueue::InviteGroupToBG(GroupQueueInfo * ginfo, BattleGround * bg, uint32 side)
{
// set side if needed

View file

@ -81,17 +81,13 @@ class BattleGroundQueue
bool CheckPremadeMatch(BGQueueIdBasedOnLevel queue_id, uint32 MinPlayersPerTeam, uint32 MaxPlayersPerTeam);
bool CheckNormalMatch(BattleGround* bg_template, BGQueueIdBasedOnLevel queue_id, uint32 minPlayers, uint32 maxPlayers);
bool CheckSkirmishForSameFaction(BGQueueIdBasedOnLevel queue_id, uint32 minPlayersPerTeam);
GroupQueueInfo * AddGroup(Player * leader, BattleGroundTypeId bgTypeId, uint8 ArenaType, bool isRated, bool isPremade, uint32 ArenaRating, uint32 ArenaTeamId = 0);
void AddPlayer(Player *plr, GroupQueueInfo *ginfo);
GroupQueueInfo * AddGroup(Player* leader, Group* group, BattleGroundTypeId bgTypeId, uint8 ArenaType, bool isRated, bool isPremade, uint32 ArenaRating, uint32 ArenaTeamId = 0);
void RemovePlayer(const uint64& guid, bool decreaseInvitedCount);
bool IsPlayerInvited(const uint64& pl_guid, const uint32 bgInstanceGuid, const uint32 removeTime);
bool GetPlayerGroupInfoData(const uint64& guid, GroupQueueInfo* ginfo);
void PlayerInvitedToBGUpdateAverageWaitTime(GroupQueueInfo* ginfo, BGQueueIdBasedOnLevel queue_id);
uint32 GetAverageQueueWaitTime(GroupQueueInfo* ginfo, BGQueueIdBasedOnLevel queue_id);
void DecreaseGroupLength(uint32 queueId, uint32 AsGroup);
void AnnounceWorld(GroupQueueInfo *ginfo, const uint64& playerGUID, bool isAddedToQueue);
private:
//mutex that should not allow changing private data, nor allowing to update Queue during private data change.
ACE_Recursive_Thread_Mutex m_Lock;

View file

@ -1,4 +1,4 @@
#ifndef __REVISION_NR_H__
#define __REVISION_NR_H__
#define REVISION_NR "8814"
#define REVISION_NR "8815"
#endif // __REVISION_NR_H__

View file

@ -1,6 +1,6 @@
#ifndef __REVISION_SQL_H__
#define __REVISION_SQL_H__
#define REVISION_DB_CHARACTERS "required_8721_01_characters_guild"
#define REVISION_DB_MANGOS "required_8803_02_mangos_playercreateinfo_action"
#define REVISION_DB_MANGOS "required_8815_01_mangos_mangos_string"
#define REVISION_DB_REALMD "required_8728_01_realmd_account"
#endif // __REVISION_SQL_H__