diff options
Diffstat (limited to 'src')
-rwxr-xr-x | src/server/game/Achievements/AchievementMgr.cpp | 2 | ||||
-rwxr-xr-x | src/server/game/Battlegrounds/ArenaTeam.cpp | 882 | ||||
-rwxr-xr-x | src/server/game/Battlegrounds/ArenaTeam.h | 149 | ||||
-rwxr-xr-x | src/server/game/Battlegrounds/Battleground.cpp | 2 | ||||
-rwxr-xr-x | src/server/game/Entities/Player/Player.cpp | 82 | ||||
-rwxr-xr-x | src/server/game/Globals/ObjectMgr.cpp | 38 | ||||
-rwxr-xr-x | src/server/game/Server/Protocol/Handlers/ArenaTeamHandler.cpp | 211 | ||||
-rwxr-xr-x | src/server/game/Server/Protocol/Handlers/PetitionsHandler.cpp | 190 | ||||
-rwxr-xr-x | src/server/shared/Database/Implementation/CharacterDatabase.cpp | 22 | ||||
-rwxr-xr-x | src/server/shared/Database/Implementation/CharacterDatabase.h | 17 |
10 files changed, 812 insertions, 783 deletions
diff --git a/src/server/game/Achievements/AchievementMgr.cpp b/src/server/game/Achievements/AchievementMgr.cpp index d435744bba3..f3de2374e59 100755 --- a/src/server/game/Achievements/AchievementMgr.cpp +++ b/src/server/game/Achievements/AchievementMgr.cpp @@ -1492,7 +1492,7 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui if (ArenaTeam * at = sObjectMgr->GetArenaTeamById(arena_team_id)) if (at->GetType() == reqTeamType) { - SetCriteriaProgress(achievementCriteria, at->GetStats().rating, PROGRESS_HIGHEST); + SetCriteriaProgress(achievementCriteria, at->GetStats().Rating, PROGRESS_HIGHEST); break; } } diff --git a/src/server/game/Battlegrounds/ArenaTeam.cpp b/src/server/game/Battlegrounds/ArenaTeam.cpp index f0d354384ba..d05fa7b9544 100755 --- a/src/server/game/Battlegrounds/ArenaTeam.cpp +++ b/src/server/game/Battlegrounds/ArenaTeam.cpp @@ -18,270 +18,257 @@ #include "ObjectMgr.h" #include "WorldPacket.h" - #include "ArenaTeam.h" #include "World.h" #include "Group.h" -void ArenaTeamMember::ModifyPersonalRating(Player* plr, int32 mod, uint32 slot) -{ - if (int32(personal_rating) + mod < 0) - personal_rating = 0; - else - personal_rating += mod; - if (plr) - plr->SetArenaTeamInfoField(slot, ARENA_TEAM_PERSONAL_RATING, personal_rating); -} - -void ArenaTeamMember::ModifyMatchmakerRating(int32 mod, uint32 /*slot*/) -{ - if (int32(matchmaker_rating) + mod < 0) - matchmaker_rating = 0; - else - matchmaker_rating += mod; -} - ArenaTeam::ArenaTeam() { - m_TeamId = 0; - m_Type = 0; - m_Name = ""; - m_CaptainGuid = 0; - m_BackgroundColor = 0; // background - m_EmblemStyle = 0; // icon - m_EmblemColor = 0; // icon color - m_BorderStyle = 0; // border - m_BorderColor = 0; // border color - m_stats.games_week = 0; - m_stats.games_season = 0; - m_stats.rank = 0; - m_stats.rating = sWorld->getIntConfig(CONFIG_ARENA_START_RATING); - m_stats.wins_week = 0; - m_stats.wins_season = 0; + TeamId = 0; + Type = 0; + TeamName = ""; + CaptainGuid = 0; + BackgroundColor = 0; + EmblemStyle = 0; + EmblemColor = 0; + BorderStyle = 0; + BorderColor = 0; + Stats.WeekGames = 0; + Stats.SeasonGames = 0; + Stats.Rank = 0; + Stats.Rating = sWorld->getIntConfig(CONFIG_ARENA_START_RATING); + Stats.WeekWins = 0; + Stats.SeasonWins = 0; } ArenaTeam::~ArenaTeam() { } -bool ArenaTeam::Create(uint64 captainGuid, uint32 type, std::string ArenaTeamName) +bool ArenaTeam::Create(uint32 captainGuid, uint8 type, std::string teamName, uint32 backgroundColor, uint8 emblemStyle, uint32 emblemColor, uint8 borderStyle, uint32 borderColor) { - if (!sObjectMgr->GetPlayer(captainGuid)) // player not exist + // Check if captain is present + if (!sObjectMgr->GetPlayer(captainGuid)) return false; - if (sObjectMgr->GetArenaTeamByName(ArenaTeamName)) // arena team with this name already exist + + // Check if arena team name is already taken + if (sObjectMgr->GetArenaTeamByName(TeamName)) return false; - uint32 captainLowGuid = GUID_LOPART(captainGuid); - sLog->outDebug(LOG_FILTER_BATTLEGROUND, "Creating arena team %s to leader: %u", ArenaTeamName.c_str(), captainLowGuid); - m_CaptainGuid = captainGuid; - m_Name = ArenaTeamName; - m_Type = type; + // Generate new arena team id + TeamId = sObjectMgr->GenerateArenaTeamId(); - m_TeamId = sObjectMgr->GenerateArenaTeamId(); + // Assign member variables + CaptainGuid = captainGuid; + Type = type; + TeamName = teamName; + BackgroundColor = backgroundColor; + EmblemStyle = emblemStyle; + EmblemColor = emblemColor; + BorderStyle = borderStyle; + BorderColor = borderColor; - // ArenaTeamName already assigned to ArenaTeam::name, use it to encode string for DB - CharacterDatabase.escape_string(ArenaTeamName); - SQLTransaction trans = CharacterDatabase.BeginTransaction(); - // CharacterDatabase.PExecute("DELETE FROM arena_team WHERE arenateamid='%u'", m_TeamId); - MAX(arenateam)+1 not exist - trans->PAppend("DELETE FROM arena_team_member WHERE arenateamid='%u'", m_TeamId); - trans->PAppend("INSERT INTO arena_team (arenateamid,name,captainguid,type,BackgroundColor,EmblemStyle,EmblemColor,BorderStyle,BorderColor) " - "VALUES('%u','%s','%u','%u','%u','%u','%u','%u','%u')", - m_TeamId, ArenaTeamName.c_str(), captainLowGuid, m_Type, m_BackgroundColor, m_EmblemStyle, m_EmblemColor, m_BorderStyle, m_BorderColor); - trans->PAppend("INSERT INTO arena_team_stats (arenateamid, rating, games, wins, played, wins2, rank) VALUES " - "('%u', '%u', '%u', '%u', '%u', '%u', '%u')", m_TeamId, m_stats.rating, m_stats.games_week, m_stats.wins_week, m_stats.games_season, m_stats.wins_season, m_stats.rank); - CharacterDatabase.CommitTransaction(trans); + // Save arena team to db + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_ADD_ARENA_TEAM); + stmt->setUInt32(0, TeamId); + stmt->setString(1, TeamName); + stmt->setUInt32(2, GUID_LOPART(CaptainGuid)); + stmt->setUInt8(3, Type); + stmt->setUInt16(4, Stats.Rating); + stmt->setUInt32(5, BackgroundColor); + stmt->setUInt8(6, EmblemStyle); + stmt->setUInt32(7, EmblemColor); + stmt->setUInt8(8, BorderStyle); + stmt->setUInt32(9, BorderColor); + CharacterDatabase.Execute(stmt); + + // Add captain as member + AddMember(CaptainGuid); - AddMember(m_CaptainGuid); - sLog->outArena("New ArenaTeam created [Id: %u] [Type: %u] [Captain low GUID: %u]", GetId(), GetType(), captainLowGuid); + sLog->outArena("New ArenaTeam created [Id: %u] [Type: %u] [Captain low GUID: %u]", GetId(), GetType(), GUID_LOPART(CaptainGuid)); return true; } -bool ArenaTeam::AddMember(const uint64& PlayerGuid) +bool ArenaTeam::AddMember(const uint64& playerGuid) { - std::string plName; - uint8 plClass; - uint32 plPRating; - uint32 plMMRating; + std::string playerName; + uint8 playerClass; - // arena team is full (can't have more than type * 2 players!) + // Check if arena team is full (Can't have more than type * 2 players) if (GetMembersSize() >= GetType() * 2) return false; - Player *pl = sObjectMgr->GetPlayer(PlayerGuid); - if (pl) + // Get player name and class either from db or ObjectMgr + Player *player = sObjectMgr->GetPlayer(playerGuid); + if (player) { - if (pl->GetArenaTeamId(GetSlot())) - { - sLog->outError("Arena::AddMember() : player already in this sized team"); - return false; - } - - plClass = pl->getClass(); - plName = pl->GetName(); + playerClass = player->getClass(); + playerName = player->GetName(); } else { - // 0 1 - QueryResult result = CharacterDatabase.PQuery("SELECT name, class FROM characters WHERE guid='%u'", GUID_LOPART(PlayerGuid)); + // 0 1 + // SELECT name, class FROM characters WHERE guid = ? + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_LOAD_PLAYER_NAME_CLASS); + stmt->setUInt32(0, GUID_LOPART(playerGuid)); + PreparedQueryResult result = CharacterDatabase.Query(stmt); + if (!result) return false; - plName = (*result)[0].GetString(); - plClass = (*result)[1].GetUInt8(); + playerName = (*result)[0].GetString(); + playerClass = (*result)[1].GetUInt8(); + } - // check if player already in arenateam of that size - if (Player::GetArenaTeamIdFromDB(PlayerGuid, GetType()) != 0) - { - sLog->outError("Arena::AddMember() : player already in this sized team"); - return false; - } + // Check if player is already in a similar arena team + if (player && player->GetArenaTeamId(GetSlot()) || Player::GetArenaTeamIdFromDB(playerGuid, GetType()) != 0) + { + sLog->outError("Arena: Player %s (guid: %u) already has an arena team of type %u", playerName.c_str(), playerGuid, GetType()); + return false; } - plMMRating = sWorld->getIntConfig(CONFIG_ARENA_START_MATCHMAKER_RATING); - plPRating = 0; + // Set player's personal rating + uint32 personalRating = 0; if (sWorld->getIntConfig(CONFIG_ARENA_START_PERSONAL_RATING) > 0) - plPRating = sWorld->getIntConfig(CONFIG_ARENA_START_PERSONAL_RATING); + personalRating = sWorld->getIntConfig(CONFIG_ARENA_START_PERSONAL_RATING); else if (GetRating() >= 1000) - plPRating = 1000; + personalRating = 1000; - sWorld->getIntConfig(CONFIG_ARENA_START_PERSONAL_RATING); + // Try to get player's match maker rating from db and fall back to config setting if not found + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_LOAD_MATCH_MAKER_RATING); + stmt->setUInt32(0, GUID_LOPART(playerGuid)); + stmt->setUInt8(1, GetSlot()); + PreparedQueryResult result = CharacterDatabase.Query(stmt); - QueryResult result = CharacterDatabase.PQuery("SELECT matchmaker_rating FROM character_arena_stats WHERE guid='%u' AND slot='%u'", GUID_LOPART(PlayerGuid), GetSlot()); + uint32 matchMakerRating; if (result) - plMMRating = (*result)[0].GetUInt32(); + matchMakerRating = (*result)[0].GetUInt32(); + else + matchMakerRating = sWorld->getIntConfig(CONFIG_ARENA_START_MATCHMAKER_RATING); - // remove all player signs from another petitions - // this will be prevent attempt joining player to many arenateams and corrupt arena team data integrity - Player::RemovePetitionsAndSigns(PlayerGuid, GetType()); + // Remove all player signatures from other petitions + // This will prevent player from joining too many arena teams and corrupt arena team data integrity + Player::RemovePetitionsAndSigns(playerGuid, GetType()); + // Feed data to the struct ArenaTeamMember newmember; - newmember.name = plName; - newmember.guid = PlayerGuid; - newmember.Class = plClass; - newmember.games_season = 0; - newmember.games_week = 0; - newmember.wins_season = 0; - newmember.wins_week = 0; - newmember.personal_rating = plPRating; - newmember.matchmaker_rating = plMMRating; - - m_members.push_back(newmember); - - CharacterDatabase.PExecute("INSERT INTO arena_team_member (arenateamid, guid) VALUES ('%u', '%u')", m_TeamId, GUID_LOPART(newmember.guid)); - - if (pl) + newmember.Name = playerName; + newmember.Guid = playerGuid; + newmember.Class = playerClass; + newmember.SeasonGames = 0; + newmember.WeekGames = 0; + newmember.SeasonWins = 0; + newmember.WeekWins = 0; + newmember.PersonalRating = personalRating; + newmember.MatchMakerRating = matchMakerRating; + + Members.push_back(newmember); + + // Save player's arena team membership to db + stmt = CharacterDatabase.GetPreparedStatement(CHAR_SET_ARENA_TEAM_MEMBER); + stmt->setUInt32(0, TeamId); + stmt->setUInt32(1, playerGuid); + CharacterDatabase.Execute(stmt); + + // Inform player if online + if (player) { - pl->SetInArenaTeam(m_TeamId, GetSlot(), GetType()); - pl->SetArenaTeamIdInvited(0); + player->SetInArenaTeam(TeamId, GetSlot(), GetType()); + player->SetArenaTeamIdInvited(0); - // hide promote/remove buttons - if (m_CaptainGuid != PlayerGuid) - pl->SetArenaTeamInfoField(GetSlot(), ARENA_TEAM_MEMBER, 1); - sLog->outArena("Player: %s [GUID: %u] joined arena team type: %u [Id: %u].", pl->GetName(), pl->GetGUIDLow(), GetType(), GetId()); + // Hide promote/remove buttons + if (CaptainGuid != playerGuid) + player->SetArenaTeamInfoField(GetSlot(), ARENA_TEAM_MEMBER, 1); } + + sLog->outArena("Player: %s [GUID: %u] joined arena team type: %u [Id: %u].", playerName, playerGuid, GetType(), GetId()); + return true; } -bool ArenaTeam::LoadArenaTeamFromDB(QueryResult arenaTeamDataResult) +bool ArenaTeam::LoadArenaTeamFromDB(QueryResult result) { - if (!arenaTeamDataResult) + if (!result) return false; - Field *fields = arenaTeamDataResult->Fetch(); - - m_TeamId = fields[0].GetUInt32(); - m_Name = fields[1].GetString(); - m_CaptainGuid = MAKE_NEW_GUID(fields[2].GetUInt32(), 0, HIGHGUID_PLAYER); - m_Type = fields[3].GetUInt32(); - m_BackgroundColor = fields[4].GetUInt32(); - m_EmblemStyle = fields[5].GetUInt8(); - m_EmblemColor = fields[6].GetUInt32(); - m_BorderStyle = fields[7].GetUInt8(); - m_BorderColor = fields[8].GetUInt32(); - //load team stats - m_stats.rating = fields[9].GetUInt32(); - m_stats.games_week = fields[10].GetUInt32(); - m_stats.wins_week = fields[11].GetUInt32(); - m_stats.games_season = fields[12].GetUInt32(); - m_stats.wins_season = fields[13].GetUInt32(); - m_stats.rank = fields[14].GetUInt32(); + Field *fields = result->Fetch(); + + TeamId = fields[0].GetUInt32(); + TeamName = fields[1].GetString(); + CaptainGuid = MAKE_NEW_GUID(fields[2].GetUInt32(), 0, HIGHGUID_PLAYER); + Type = fields[3].GetUInt8(); + BackgroundColor = fields[4].GetUInt32(); + EmblemStyle = fields[5].GetUInt8(); + EmblemColor = fields[6].GetUInt32(); + BorderStyle = fields[7].GetUInt8(); + BorderColor = fields[8].GetUInt32(); + Stats.Rating = fields[9].GetUInt16(); + Stats.WeekGames = fields[10].GetUInt16(); + Stats.WeekWins = fields[11].GetUInt16(); + Stats.SeasonGames = fields[12].GetUInt16(); + Stats.SeasonWins = fields[13].GetUInt16(); + Stats.Rank = fields[14].GetUInt32(); return true; } -bool ArenaTeam::LoadMembersFromDB(QueryResult arenaTeamMembersResult) +bool ArenaTeam::LoadMembersFromDB(QueryResult result) { - if (!arenaTeamMembersResult) + if (!result) return false; bool captainPresentInTeam = false; do { - Field *fields = arenaTeamMembersResult->Fetch(); - //prevent crash if db records are broken, when all members in result are already processed and current team hasn't got any members - if (!fields) - break; - uint32 arenaTeamId = fields[0].GetUInt32(); - if (arenaTeamId < m_TeamId) - { - //there is in table arena_team_member record which doesn't have arenateamid in arena_team table, report error - sLog->outErrorDb("ArenaTeam %u does not exist but it has record in arena_team_member table, deleting it!", arenaTeamId); - CharacterDatabase.PExecute("DELETE FROM arena_team_member WHERE arenateamid = '%u'", arenaTeamId); - continue; - } + Field *fields = result->Fetch(); - if (arenaTeamId > m_TeamId) - //we loaded all members for this arena_team already, break cycle + // Prevent crash if db records are broken when all members in result are already processed and current team doesn't have any members + if (!fields) break; - uint32 player_guid = fields[1].GetUInt32(); - - QueryResult result = CharacterDatabase.PQuery( - "SELECT personal_rating, matchmaker_rating FROM character_arena_stats WHERE guid = '%u' AND slot = '%u'", player_guid, GetSlot()); - - uint32 personalrating = 0; - uint32 matchmakerrating = 1500; + uint32 arenaTeamId = fields[0].GetUInt32(); - if (result) - { - personalrating = (*result)[0].GetUInt32(); - matchmakerrating = (*result)[1].GetUInt32(); - } + // We loaded all members for this arena_team already, break cycle + if (arenaTeamId > TeamId) + break; - ArenaTeamMember newmember; - newmember.guid = MAKE_NEW_GUID(player_guid, 0, HIGHGUID_PLAYER); - newmember.games_week = fields[2].GetUInt32(); - newmember.wins_week = fields[3].GetUInt32(); - newmember.games_season = fields[4].GetUInt32(); - newmember.wins_season = fields[5].GetUInt32(); - newmember.name = fields[6].GetString(); - newmember.Class = fields[7].GetUInt8(); - newmember.personal_rating = personalrating; - newmember.matchmaker_rating = matchmakerrating; - - //check if member exists in characters table - if (newmember.name.empty()) + ArenaTeamMember newMember; + newMember.Guid = MAKE_NEW_GUID(fields[1].GetUInt32(), 0, HIGHGUID_PLAYER); + newMember.WeekGames = fields[2].GetUInt16(); + newMember.WeekWins = fields[3].GetUInt16(); + newMember.SeasonGames = fields[4].GetUInt16(); + newMember.SeasonWins = fields[5].GetUInt16(); + newMember.Name = fields[6].GetString(); + newMember.Class = fields[7].GetUInt8(); + newMember.PersonalRating = fields[8].GetUInt16(); + newMember.MatchMakerRating = fields[9].GetUInt16() > 0 ? fields[9].GetUInt16() : 1500; + + // Delete member if character information is missing + if (newMember.Name.empty()) { - sLog->outErrorDb("ArenaTeam %u has member with empty name - probably player %u doesn't exist, deleting him from memberlist!", arenaTeamId, GUID_LOPART(newmember.guid)); - this->DelMember(newmember.guid); + sLog->outErrorDb("ArenaTeam %u has member with empty name - probably player %u doesn't exist, deleting him from memberlist!", arenaTeamId, GUID_LOPART(newMember.Guid)); + this->DelMember(newMember.Guid, true); continue; } - if (newmember.guid == GetCaptain()) + // Check if team team has a valid captain + if (newMember.Guid == GetCaptain()) captainPresentInTeam = true; - m_members.push_back(newmember); - }while (arenaTeamMembersResult->NextRow()); + // Put the player in the team + Members.push_back(newMember); + } + while (result->NextRow()); if (Empty() || !captainPresentInTeam) { - // arena team is empty or captain is not in team, delete from db - sLog->outErrorDb("ArenaTeam %u does not have any members or its captain is not in team, disbanding it...", m_TeamId); + // Arena team is empty or captain is not in team, delete from db + sLog->outErrorDb("ArenaTeam %u does not have any members or its captain is not in team, disbanding it...", TeamId); return false; } @@ -290,35 +277,41 @@ bool ArenaTeam::LoadMembersFromDB(QueryResult arenaTeamMembersResult) void ArenaTeam::SetCaptain(const uint64& guid) { - // disable remove/promote buttons - Player *oldcaptain = sObjectMgr->GetPlayer(GetCaptain()); - if (oldcaptain) - oldcaptain->SetArenaTeamInfoField(GetSlot(), ARENA_TEAM_MEMBER, 1); + // Disable remove/promote buttons + Player* oldCaptain = sObjectMgr->GetPlayer(GetCaptain()); + if (oldCaptain) + oldCaptain->SetArenaTeamInfoField(GetSlot(), ARENA_TEAM_MEMBER, 1); - // set new captain - m_CaptainGuid = guid; + // Set new captain + CaptainGuid = guid; - // update database - CharacterDatabase.PExecute("UPDATE arena_team SET captainguid = '%u' WHERE arenateamid = '%u'", GUID_LOPART(guid), GetId()); + // Update database + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPDATE_ARENA_TEAM_CAPTAIN); + stmt->setUInt32(0, GUID_LOPART(guid)); + stmt->setUInt32(1, GetId()); + CharacterDatabase.Execute(stmt); - // enable remove/promote buttons - Player *newcaptain = sObjectMgr->GetPlayer(guid); - if (newcaptain) + // Enable remove/promote buttons + Player *newCaptain = sObjectMgr->GetPlayer(guid); + if (newCaptain) { - newcaptain->SetArenaTeamInfoField(GetSlot(), ARENA_TEAM_MEMBER, 0); - sLog->outArena("Player: %s [GUID: %u] promoted player: %s [GUID: %u] to leader of arena team [Id: %u] [Type: %u].", oldcaptain->GetName(), oldcaptain->GetGUIDLow(), newcaptain->GetName(), newcaptain->GetGUIDLow(), GetId(), GetType()); + newCaptain->SetArenaTeamInfoField(GetSlot(), ARENA_TEAM_MEMBER, 0); + sLog->outArena("Player: %s [GUID: %u] promoted player: %s [GUID: %u] to leader of arena team [Id: %u] [Type: %u].", + oldCaptain->GetName(), oldCaptain->GetGUIDLow(), newCaptain->GetName(), newCaptain->GetGUIDLow(), GetId(), GetType()); } } -void ArenaTeam::DelMember(uint64 guid) +void ArenaTeam::DelMember(uint64 guid, bool cleanDb) { - for (MemberList::iterator itr = m_members.begin(); itr != m_members.end(); ++itr) - if (itr->guid == guid) + // Remove member from team + for (MemberList::iterator itr = Members.begin(); itr != Members.end(); ++itr) + if (itr->Guid == guid) { - m_members.erase(itr); + Members.erase(itr); break; } + // Inform player and remove arena team info from player data if (Player *player = sObjectMgr->GetPlayer(guid)) { player->GetSession()->SendArenaTeamCommandResult(ERR_ARENA_TEAM_QUIT_S, GetName(), "", 0); @@ -327,35 +320,52 @@ void ArenaTeam::DelMember(uint64 guid) player->SetArenaTeamInfoField(GetSlot(), ArenaTeamInfoType(i), 0); sLog->outArena("Player: %s [GUID: %u] left arena team type: %u [Id: %u].", player->GetName(), player->GetGUIDLow(), GetType(), GetId()); } - CharacterDatabase.PExecute("DELETE FROM arena_team_member WHERE arenateamid = '%u' AND guid = '%u'", GetId(), GUID_LOPART(guid)); + + // Only used for single member deletion, for arena team disband we use a single query for more efficiency + if (cleanDb) + { + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_ARENA_TEAM_MEMBER); + stmt->setUInt32(0, GetId()); + stmt->setUInt32(1, GUID_LOPART(guid)); + CharacterDatabase.Execute(stmt); + } } -void ArenaTeam::Disband(WorldSession *session) +void ArenaTeam::Disband(WorldSession* session) { - // event + // Remove all members from arena team + while (!Members.empty()) + DelMember(Members.front().Guid, false); + + // Broadcast update if (session) - // probably only 1 string required... + { BroadcastEvent(ERR_ARENA_TEAM_DISBANDED_S, 0, 2, session->GetPlayerName(), GetName(), ""); - while (!m_members.empty()) - // Removing from members is done in DelMember. - DelMember(m_members.front().guid); - - if (session) if (Player *player = session->GetPlayer()) sLog->outArena("Player: %s [GUID: %u] disbanded arena team type: %u [Id: %u].", player->GetName(), player->GetGUIDLow(), GetType(), GetId()); + } + // Update database SQLTransaction trans = CharacterDatabase.BeginTransaction(); - trans->PAppend("DELETE FROM arena_team WHERE arenateamid = '%u'", m_TeamId); - trans->PAppend("DELETE FROM arena_team_member WHERE arenateamid = '%u'", m_TeamId); //< this should be alredy done by calling DelMember(memberGuids[j]); for each member - trans->PAppend("DELETE FROM arena_team_stats WHERE arenateamid = '%u'", m_TeamId); + + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_ARENA_TEAM); + stmt->setUInt32(0, TeamId); + trans->Append(stmt); + + stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_ARENA_TEAM_MEMBERS); + stmt->setUInt32(0, TeamId); + trans->Append(stmt); + CharacterDatabase.CommitTransaction(trans); - sObjectMgr->RemoveArenaTeam(m_TeamId); + + // Remove arena team from ObjectMgr + sObjectMgr->RemoveArenaTeam(TeamId); } -void ArenaTeam::Roster(WorldSession *session) +void ArenaTeam::Roster(WorldSession* session) { - Player *pl = NULL; + Player* pl = NULL; uint8 unk308 = 0; @@ -365,21 +375,21 @@ void ArenaTeam::Roster(WorldSession *session) data << uint32(GetMembersSize()); // members count data << uint32(GetType()); // arena team type? - for (MemberList::const_iterator itr = m_members.begin(); itr != m_members.end(); ++itr) + for (MemberList::const_iterator itr = Members.begin(); itr != Members.end(); ++itr) { - pl = sObjectMgr->GetPlayer(itr->guid); + pl = sObjectMgr->GetPlayer(itr->Guid); - data << uint64(itr->guid); // guid + data << uint64(itr->Guid); // guid data << uint8((pl ? 1 : 0)); // online flag - data << itr->name; // member name - data << uint32((itr->guid == GetCaptain() ? 0 : 1));// captain flag 0 captain 1 member + data << itr->Name; // member name + data << uint32((itr->Guid == GetCaptain() ? 0 : 1));// captain flag 0 captain 1 member data << uint8((pl ? pl->getLevel() : 0)); // unknown, level? data << uint8(itr->Class); // class - data << uint32(itr->games_week); // played this week - data << uint32(itr->wins_week); // wins this week - data << uint32(itr->games_season); // played this season - data << uint32(itr->wins_season); // wins this season - data << uint32(itr->personal_rating); // personal rating + data << uint32(itr->WeekGames); // played this week + data << uint32(itr->WeekWins); // wins this week + data << uint32(itr->SeasonGames); // played this season + data << uint32(itr->SeasonWins); // wins this season + data << uint32(itr->PersonalRating); // personal rating if (unk308) { data << float(0.0); // 308 unk @@ -391,47 +401,47 @@ void ArenaTeam::Roster(WorldSession *session) sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Sent SMSG_ARENA_TEAM_ROSTER"); } -void ArenaTeam::Query(WorldSession *session) +void ArenaTeam::Query(WorldSession* session) { WorldPacket data(SMSG_ARENA_TEAM_QUERY_RESPONSE, 4*7+GetName().size()+1); data << uint32(GetId()); // team id data << GetName(); // team name data << uint32(GetType()); // arena team type (2=2x2, 3=3x3 or 5=5x5) - data << uint32(m_BackgroundColor); // background color - data << uint32(m_EmblemStyle); // emblem style - data << uint32(m_EmblemColor); // emblem color - data << uint32(m_BorderStyle); // border style - data << uint32(m_BorderColor); // border color + data << uint32(BackgroundColor); // background color + data << uint32(EmblemStyle); // emblem style + data << uint32(EmblemColor); // emblem color + data << uint32(BorderStyle); // border style + data << uint32(BorderColor); // border color session->SendPacket(&data); sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Sent SMSG_ARENA_TEAM_QUERY_RESPONSE"); } -void ArenaTeam::Stats(WorldSession *session) +void ArenaTeam::SendStats(WorldSession* session) { WorldPacket data(SMSG_ARENA_TEAM_STATS, 4*7); data << uint32(GetId()); // team id - data << uint32(m_stats.rating); // rating - data << uint32(m_stats.games_week); // games this week - data << uint32(m_stats.wins_week); // wins this week - data << uint32(m_stats.games_season); // played this season - data << uint32(m_stats.wins_season); // wins this season - data << uint32(m_stats.rank); // rank + data << uint32(Stats.Rating); // rating + data << uint32(Stats.WeekGames); // games this week + data << uint32(Stats.WeekWins); // wins this week + data << uint32(Stats.SeasonGames); // played this season + data << uint32(Stats.SeasonWins); // wins this season + data << uint32(Stats.Rank); // rank session->SendPacket(&data); } void ArenaTeam::NotifyStatsChanged() { - // this is called after a rated match ended - // updates arena team stats for every member of the team (not only the ones who participated!) - for (MemberList::const_iterator itr = m_members.begin(); itr != m_members.end(); ++itr) + // This is called after a rated match ended + // Updates arena team stats for every member of the team (not only the ones who participated!) + for (MemberList::const_iterator itr = Members.begin(); itr != Members.end(); ++itr) { - Player * plr = sObjectMgr->GetPlayer(itr->guid); + Player* plr = sObjectMgr->GetPlayer(itr->Guid); if (plr) - Stats(plr->GetSession()); + SendStats(plr->GetSession()); } } -void ArenaTeam::InspectStats(WorldSession *session, uint64 guid) +void ArenaTeam::Inspect(WorldSession* session, uint64 guid) { ArenaTeamMember* member = GetMember(guid); if (!member) @@ -441,64 +451,37 @@ void ArenaTeam::InspectStats(WorldSession *session, uint64 guid) data << uint64(guid); // player guid data << uint8(GetSlot()); // slot (0...2) data << uint32(GetId()); // arena team id - data << uint32(m_stats.rating); // rating - data << uint32(m_stats.games_season); // season played - data << uint32(m_stats.wins_season); // season wins - data << uint32(member->games_season); // played (count of all games, that the inspected member participated...) - data << uint32(member->personal_rating); // personal rating + data << uint32(Stats.Rating); // rating + data << uint32(Stats.SeasonGames); // season played + data << uint32(Stats.SeasonWins); // season wins + data << uint32(member->SeasonGames); // played (count of all games, that the inspected member participated...) + data << uint32(member->PersonalRating); // personal rating session->SendPacket(&data); } -void ArenaTeam::SetEmblem(uint32 backgroundColor, uint32 emblemStyle, uint32 emblemColor, uint32 borderStyle, uint32 borderColor) +void ArenaTeamMember::ModifyPersonalRating(Player* plr, int32 mod, uint32 slot) { - m_BackgroundColor = backgroundColor; - m_EmblemStyle = emblemStyle; - m_EmblemColor = emblemColor; - m_BorderStyle = borderStyle; - m_BorderColor = borderColor; - - CharacterDatabase.PExecute("UPDATE arena_team SET BackgroundColor='%u', EmblemStyle='%u', EmblemColor='%u', BorderStyle='%u', BorderColor='%u' WHERE arenateamid='%u'", m_BackgroundColor, m_EmblemStyle, m_EmblemColor, m_BorderStyle, m_BorderColor, m_TeamId); + if (int32(PersonalRating) + mod < 0) + PersonalRating = 0; + else + PersonalRating += mod; + if (plr) + plr->SetArenaTeamInfoField(slot, ARENA_TEAM_PERSONAL_RATING, PersonalRating); } -void ArenaTeam::SetStats(uint32 stat_type, uint32 value) +void ArenaTeamMember::ModifyMatchmakerRating(int32 mod, uint32 /*slot*/) { - switch(stat_type) - { - case STAT_TYPE_RATING: - m_stats.rating = value; - CharacterDatabase.PExecute("UPDATE arena_team_stats SET rating = '%u' WHERE arenateamid = '%u'", value, GetId()); - break; - case STAT_TYPE_GAMES_WEEK: - m_stats.games_week = value; - CharacterDatabase.PExecute("UPDATE arena_team_stats SET games = '%u' WHERE arenateamid = '%u'", value, GetId()); - break; - case STAT_TYPE_WINS_WEEK: - m_stats.wins_week = value; - CharacterDatabase.PExecute("UPDATE arena_team_stats SET wins = '%u' WHERE arenateamid = '%u'", value, GetId()); - break; - case STAT_TYPE_GAMES_SEASON: - m_stats.games_season = value; - CharacterDatabase.PExecute("UPDATE arena_team_stats SET played = '%u' WHERE arenateamid = '%u'", value, GetId()); - break; - case STAT_TYPE_WINS_SEASON: - m_stats.wins_season = value; - CharacterDatabase.PExecute("UPDATE arena_team_stats SET wins2 = '%u' WHERE arenateamid = '%u'", value, GetId()); - break; - case STAT_TYPE_RANK: - m_stats.rank = value; - CharacterDatabase.PExecute("UPDATE arena_team_stats SET rank = '%u' WHERE arenateamid = '%u'", value, GetId()); - break; - default: - sLog->outError("unknown stat type in ArenaTeam::SetStats() %u", stat_type); - break; - } + if (int32(MatchMakerRating) + mod < 0) + MatchMakerRating = 0; + else + MatchMakerRating += mod; } -void ArenaTeam::BroadcastPacket(WorldPacket *packet) +void ArenaTeam::BroadcastPacket(WorldPacket* packet) { - for (MemberList::const_iterator itr = m_members.begin(); itr != m_members.end(); ++itr) + for (MemberList::const_iterator itr = Members.begin(); itr != Members.end(); ++itr) { - Player *player = sObjectMgr->GetPlayer(itr->guid); + Player* player = sObjectMgr->GetPlayer(itr->Guid); if (player) player->GetSession()->SendPacket(packet); } @@ -549,21 +532,21 @@ uint8 ArenaTeam::GetSlotByType(uint32 type) return 0xFF; } -bool ArenaTeam::HaveMember(const uint64& guid) const +bool ArenaTeam::IsMember(const uint64& guid) const { - for (MemberList::const_iterator itr = m_members.begin(); itr != m_members.end(); ++itr) - if (itr->guid == guid) + for (MemberList::const_iterator itr = Members.begin(); itr != Members.end(); ++itr) + if (itr->Guid == guid) return true; return false; } -uint32 ArenaTeam::GetPoints(uint32 MemberRating) +uint32 ArenaTeam::GetPoints(uint32 memberRating) { - // returns how many points would be awarded with this team type with this rating + // Returns how many points would be awarded with this team type with this rating float points; - uint32 rating = MemberRating + 150 < m_stats.rating ? MemberRating : m_stats.rating; + uint32 rating = memberRating + 150 < Stats.Rating ? memberRating : Stats.Rating; if (rating <= 1500) { @@ -575,72 +558,68 @@ uint32 ArenaTeam::GetPoints(uint32 MemberRating) else points = 1511.26f / (1.0f + 1639.28f * exp(-0.00412f * (float)rating)); - // type penalties for <5v5 teams - if (m_Type == ARENA_TEAM_2v2) + // Type penalties for teams < 5v5 + if (Type == ARENA_TEAM_2v2) points *= 0.76f; - else if (m_Type == ARENA_TEAM_3v3) + else if (Type == ARENA_TEAM_3v3) points *= 0.88f; return (uint32) points; } -uint32 ArenaTeam::GetAverageMMR(Group *group) const +uint32 ArenaTeam::GetAverageMMR(Group* group) const { - if (!group) //should never happen + if (!group) return 0; - uint32 matchmakerrating = 0; - uint32 player_divider = 0; - for (MemberList::const_iterator itr = m_members.begin(); itr != m_members.end(); ++itr) + uint32 matchMakerRating = 0; + uint32 playerDivider = 0; + for (MemberList::const_iterator itr = Members.begin(); itr != Members.end(); ++itr) { - // If player not online - if (!ObjectAccessor::FindPlayer(itr->guid)) + // Skip if player is not online + if (!ObjectAccessor::FindPlayer(itr->Guid)) continue; - // If not in group - if (!group->IsMember(itr->guid)) + // Skip if player is not member of group + if (!group->IsMember(itr->Guid)) continue; - matchmakerrating += itr->matchmaker_rating; - ++player_divider; + matchMakerRating += itr->MatchMakerRating; + ++playerDivider; } - //- x/0 = crash - if (player_divider == 0) - player_divider = 1; + // x/0 = crash + if (playerDivider == 0) + playerDivider = 1; - matchmakerrating /= player_divider; + matchMakerRating /= playerDivider; - return matchmakerrating; + return matchMakerRating; } -float ArenaTeam::GetChanceAgainst(uint32 own_rating, uint32 enemy_rating) +float ArenaTeam::GetChanceAgainst(uint32 ownRating, uint32 opponentRating) { - // returns the chance to win against a team with the given rating, used in the rating adjustment calculation + // Returns the chance to win against a team with the given rating, used in the rating adjustment calculation // ELO system - -/* if (sWorld->getIntConfig(CONFIG_ARENA_SEASON_ID) >= 6) - if (enemy_rating < 1000) - enemy_rating = 1000;*/ - return 1.0f/(1.0f+exp(log(10.0f)*(float)((float)enemy_rating - (float)own_rating)/400.0f)); + return 1.0f / (1.0f + exp(log(10.0f) * (float)((float)opponentRating - (float)ownRating) / 400.0f)); } -int32 ArenaTeam::GetRatingMod(uint32 own_rating, uint32 enemy_rating, bool won, bool calculating_mmr) +int32 ArenaTeam::GetRatingMod(uint32 ownRating, uint32 opponentRating, bool won, bool calculateMatchMakerRating) { - // 'chance' calculation - to beat the opponent - float chance = GetChanceAgainst(own_rating, enemy_rating); + // 'Chance' calculation - to beat the opponent + float chance = GetChanceAgainst(ownRating, opponentRating); float won_mod = (won) ? 1.0f : 0.0f; - // calculate the rating modification - // simulation on how it works. Not much info on how it really works + // Calculate the rating modification + // Simulation on how it works. Not much info on how it really works float mod; - if (won && !calculating_mmr) + if (won && !calculateMatchMakerRating) { - if (own_rating < 1000) + if (ownRating < 1000) mod = 48.0f * (won_mod - chance); - else if (own_rating < 1300) - mod = (24.0f + (24.0f * (1300.0f - int32(own_rating)) / 300.0f)) * (won_mod - chance); + else if (ownRating < 1300) + mod = (24.0f + (24.0f * (1300.0f - int32(ownRating)) / 300.0f)) * (won_mod - chance); else mod = 24.0f * (won_mod - chance); } @@ -650,205 +629,262 @@ int32 ArenaTeam::GetRatingMod(uint32 own_rating, uint32 enemy_rating, bool won, return (int32)ceil(mod); } -int32 ArenaTeam::GetPersonalRatingMod(int32 base_rating, uint32 own_rating, uint32 enemy_rating) +int32 ArenaTeam::GetPersonalRatingMod(int32 baseRating, uint32 ownRating, uint32 opponentRating) { - // max (2 * team rating gain/loss), min 0 gain/loss - float chance = GetChanceAgainst(own_rating, enemy_rating); + // Max (2 * team rating gain/loss), min 0 gain/loss + float chance = GetChanceAgainst(ownRating, opponentRating); chance *= 2.0f; - return (int32)ceil(float(base_rating) * chance); + + return (int32)ceil(float(baseRating) * chance); } void ArenaTeam::FinishGame(int32 mod) { - if (int32(m_stats.rating) + mod < 0) - m_stats.rating = 0; + // Rating can only drop to 0 + if (int32(Stats.Rating) + mod < 0) + Stats.Rating = 0; else { - m_stats.rating += mod; - for (MemberList::iterator itr = m_members.begin(); itr != m_members.end(); ++itr) - if (Player* member = ObjectAccessor::FindPlayer(itr->guid)) + Stats.Rating += mod; + + // Check if rating related achivements are met + for (MemberList::iterator itr = Members.begin(); itr != Members.end(); ++itr) + if (Player* member = ObjectAccessor::FindPlayer(itr->Guid)) { - member->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_TEAM_RATING, m_stats.rating, m_Type); - member->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_REACH_TEAM_RATING, m_stats.rating, m_Type); + member->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_TEAM_RATING, Stats.Rating, Type); + member->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_REACH_TEAM_RATING, Stats.Rating, Type); } } - m_stats.games_week += 1; - m_stats.games_season += 1; - // update team's rank - m_stats.rank = 1; + // Update number of games played per season or week + Stats.WeekGames += 1; + Stats.SeasonGames += 1; + + // Update team's rank, start with rank 1 and increase until no team with more rating was found + Stats.Rank = 1; ObjectMgr::ArenaTeamMap::const_iterator i = sObjectMgr->GetArenaTeamMapBegin(); for (; i != sObjectMgr->GetArenaTeamMapEnd(); ++i) { - if (i->second->GetType() == m_Type && i->second->GetStats().rating > m_stats.rating) - ++m_stats.rank; + if (i->second->GetType() == Type && i->second->GetStats().Rating > Stats.Rating) + ++Stats.Rank; } } int32 ArenaTeam::WonAgainst(uint32 againstRating) { - // called when the team has won - // own team rating versus opponents matchmaker rating - int32 mod = GetRatingMod(m_stats.rating, againstRating, true); + // Called when the team has won + // Own team rating versus opponents matchmaker rating + int32 mod = GetRatingMod(Stats.Rating, againstRating, true); - // modify the team stats accordingly + // Modify the team stats accordingly FinishGame(mod); - m_stats.wins_week += 1; - m_stats.wins_season += 1; - // return the rating change, used to display it on the results screen + // Update number of wins per season and week + Stats.WeekWins += 1; + Stats.SeasonWins += 1; + + // Return the rating change, used to display it on the results screen return mod; } int32 ArenaTeam::LostAgainst(uint32 againstRating) { - // called when the team has lost - // own team rating versus opponents matchmaker rating - int32 mod = GetRatingMod(m_stats.rating, againstRating, false); + // Called when the team has lost + // Own team rating versus opponents matchmaker rating + int32 mod = GetRatingMod(Stats.Rating, againstRating, false); - // modify the team stats accordingly + // Modify the team stats accordingly FinishGame(mod); // return the rating change, used to display it on the results screen return mod; } -void ArenaTeam::MemberLost(Player * plr, uint32 againstMatchmakerRating, int32 teamratingchange) +void ArenaTeam::MemberLost(Player* plr, uint32 againstMatchmakerRating, int32 teamratingchange) { - // called for each participant of a match after losing - for (MemberList::iterator itr = m_members.begin(); itr != m_members.end(); ++itr) + // Called for each participant of a match after losing + for (MemberList::iterator itr = Members.begin(); itr != Members.end(); ++itr) { - if (itr->guid == plr->GetGUID()) + if (itr->Guid == plr->GetGUID()) { - // update personal rating - int32 mod = GetPersonalRatingMod(teamratingchange, itr->personal_rating, (m_stats.rating - teamratingchange)); + // Update personal rating + int32 mod = GetPersonalRatingMod(teamratingchange, itr->PersonalRating, (Stats.Rating - teamratingchange)); itr->ModifyPersonalRating(plr, mod, GetSlot()); - // update matchmaker rating - mod = GetRatingMod(itr->matchmaker_rating, againstMatchmakerRating, false, true); + // Update matchmaker rating + mod = GetRatingMod(itr->MatchMakerRating, againstMatchmakerRating, false, true); itr->ModifyMatchmakerRating(mod, GetSlot()); - // update personal played stats - itr->games_week +=1; - itr->games_season +=1; + // Update personal played stats + itr->WeekGames +=1; + itr->SeasonGames +=1; + // update the unit fields - plr->SetArenaTeamInfoField(GetSlot(), ARENA_TEAM_GAMES_WEEK, itr->games_week); - plr->SetArenaTeamInfoField(GetSlot(), ARENA_TEAM_GAMES_SEASON, itr->games_season); + plr->SetArenaTeamInfoField(GetSlot(), ARENA_TEAM_GAMES_WEEK, itr->WeekGames); + plr->SetArenaTeamInfoField(GetSlot(), ARENA_TEAM_GAMES_SEASON, itr->SeasonGames); return; } } } -void ArenaTeam::OfflineMemberLost(uint64 guid, uint32 againstMatchmakerRating, int32 teamratingchange) +void ArenaTeam::OfflineMemberLost(uint64 guid, uint32 againstMatchMakerRating, int32 ratingChange) { - // called for offline player after ending rated arena match! - for (MemberList::iterator itr = m_members.begin(); itr != m_members.end(); ++itr) + // Called for offline player after ending rated arena match! + for (MemberList::iterator itr = Members.begin(); itr != Members.end(); ++itr) { - if (itr->guid == guid) + if (itr->Guid == guid) { // update personal rating - int32 mod = GetPersonalRatingMod(teamratingchange, itr->personal_rating, (m_stats.rating - teamratingchange)); + int32 mod = GetPersonalRatingMod(ratingChange, itr->PersonalRating, (Stats.Rating - ratingChange)); itr->ModifyPersonalRating(NULL, mod, GetSlot()); // update matchmaker rating - mod = GetRatingMod(itr->matchmaker_rating, againstMatchmakerRating, false, true); + mod = GetRatingMod(itr->MatchMakerRating, againstMatchMakerRating, false, true); itr->ModifyMatchmakerRating(mod, GetSlot()); // update personal played stats - itr->games_week +=1; - itr->games_season +=1; + itr->WeekGames +=1; + itr->SeasonGames +=1; return; } } } -void ArenaTeam::MemberWon(Player * plr, uint32 againstMatchmakerRating, int32 teamratingchange) +void ArenaTeam::MemberWon(Player* plr, uint32 againstMatchMakerRating, int32 ratingChange) { // called for each participant after winning a match - for (MemberList::iterator itr = m_members.begin(); itr != m_members.end(); ++itr) + for (MemberList::iterator itr = Members.begin(); itr != Members.end(); ++itr) { - if (itr->guid == plr->GetGUID()) + if (itr->Guid == plr->GetGUID()) { // update personal rating - int32 mod = GetPersonalRatingMod(teamratingchange, (m_stats.rating - teamratingchange), itr->personal_rating); + int32 mod = GetPersonalRatingMod(ratingChange, (Stats.Rating - ratingChange), itr->PersonalRating); itr->ModifyPersonalRating(plr, mod, GetSlot()); // update matchmaker rating - mod = GetRatingMod(itr->matchmaker_rating, againstMatchmakerRating, true, true); + mod = GetRatingMod(itr->MatchMakerRating, againstMatchMakerRating, true, true); itr->ModifyMatchmakerRating(mod, GetSlot()); // update personal stats - itr->games_week +=1; - itr->games_season +=1; - itr->wins_season += 1; - itr->wins_week += 1; + itr->WeekGames +=1; + itr->SeasonGames +=1; + itr->SeasonWins += 1; + itr->WeekWins += 1; // update unit fields - plr->SetArenaTeamInfoField(GetSlot(), ARENA_TEAM_GAMES_WEEK, itr->games_week); - plr->SetArenaTeamInfoField(GetSlot(), ARENA_TEAM_GAMES_SEASON, itr->games_season); + plr->SetArenaTeamInfoField(GetSlot(), ARENA_TEAM_GAMES_WEEK, itr->WeekGames); + plr->SetArenaTeamInfoField(GetSlot(), ARENA_TEAM_GAMES_SEASON, itr->SeasonGames); return; } } } -void ArenaTeam::UpdateArenaPointsHelper(std::map<uint32, uint32>& PlayerPoints) +void ArenaTeam::UpdateArenaPointsHelper(std::map<uint32, uint32>& playerPoints) { - // called after a match has ended and the stats are already modified - // helper function for arena point distribution (this way, when distributing, no actual calculation is required, just a few comparisons) + // Called after a match has ended and the stats are already modified + // Helper function for arena point distribution (this way, when distributing, no actual calculation is required, just a few comparisons) // 10 played games per week is a minimum - if (m_stats.games_week < 10) + if (Stats.WeekGames < 10) return; - // to get points, a player has to participate in at least 30% of the matches - uint32 min_plays = (uint32) ceil(m_stats.games_week * 0.3); - for (MemberList::const_iterator itr = m_members.begin(); itr != m_members.end(); ++itr) + + // To get points, a player has to participate in at least 30% of the matches + uint32 requiredGames = (uint32) ceil(Stats.WeekGames * 0.3); + + for (MemberList::const_iterator itr = Members.begin(); itr != Members.end(); ++itr) { - // the player participated in enough games, update his points - uint32 points_to_add = 0; - if (itr->games_week >= min_plays) - points_to_add = GetPoints(itr->personal_rating); - // OBSOLETE : CharacterDatabase.PExecute("UPDATE arena_team_member SET points_to_add = '%u' WHERE arenateamid = '%u' AND guid = '%u'", points_to_add, m_TeamId, itr->guid); - - std::map<uint32, uint32>::iterator plr_itr = PlayerPoints.find(GUID_LOPART(itr->guid)); - if (plr_itr != PlayerPoints.end()) + // The player participated in enough games, update his points + uint32 pointsToAdd = 0; + if (itr->WeekGames >= requiredGames) + pointsToAdd = GetPoints(itr->PersonalRating); + + std::map<uint32, uint32>::iterator plr_itr = playerPoints.find(GUID_LOPART(itr->Guid)); + if (plr_itr != playerPoints.end()) { - //check if there is already more points - if (plr_itr->second < points_to_add) - PlayerPoints[GUID_LOPART(itr->guid)] = points_to_add; + // Check if there is already more points + if (plr_itr->second < pointsToAdd) + playerPoints[GUID_LOPART(itr->Guid)] = pointsToAdd; } else - PlayerPoints[GUID_LOPART(itr->guid)] = points_to_add; + playerPoints[GUID_LOPART(itr->Guid)] = pointsToAdd; } } void ArenaTeam::SaveToDB() { - // save team and member stats to db - // called after a match has ended, or when calculating arena_points + // Save team and member stats to db + // Called after a match has ended or when calculating arena_points + SQLTransaction trans = CharacterDatabase.BeginTransaction(); - trans->PAppend("UPDATE arena_team_stats SET rating = '%u',games = '%u',played = '%u',rank = '%u',wins = '%u',wins2 = '%u' WHERE arenateamid = '%u'", m_stats.rating, m_stats.games_week, m_stats.games_season, m_stats.rank, m_stats.wins_week, m_stats.wins_season, GetId()); - for (MemberList::const_iterator itr = m_members.begin(); itr != m_members.end(); ++itr) + + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPDATE_ARENA_TEAM_STATS); + stmt->setUInt16(0, Stats.Rating); + stmt->setUInt16(1, Stats.WeekGames); + stmt->setUInt16(2, Stats.WeekWins); + stmt->setUInt16(3, Stats.SeasonGames); + stmt->setUInt16(4, Stats.SeasonWins); + stmt->setUInt32(5, Stats.Rank); + stmt->setUInt32(6, GetId()); + trans->Append(stmt); + + for (MemberList::const_iterator itr = Members.begin(); itr != Members.end(); ++itr) { - trans->PAppend("UPDATE arena_team_member SET played_week = '%u', wons_week = '%u', played_season = '%u', wons_season = '%u' WHERE arenateamid = '%u' AND guid = '%u'", itr->games_week, itr->wins_week, itr->games_season, itr->wins_season, m_TeamId, GUID_LOPART(itr->guid)); - trans->PAppend("REPLACE INTO character_arena_stats (guid,slot,personal_rating,matchmaker_rating) VALUES ('%u', '%u', '%u', '%u')", GUID_LOPART(itr->guid), GetSlot(), itr->personal_rating, itr->matchmaker_rating); + stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPDATE_ARENA_TEAM_MEMBER); + stmt->setUInt16(0, itr->WeekGames); + stmt->setUInt16(1, itr->WeekWins); + stmt->setUInt16(2, itr->SeasonGames); + stmt->setUInt16(3, itr->SeasonWins); + stmt->setUInt32(4, GetId()); + stmt->setUInt16(5, GUID_LOPART(itr->Guid)); + trans->Append(stmt); + + stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPDATE_ARENA_TEAM_MEMBER_STATS); + stmt->setUInt32(0, GUID_LOPART(itr->Guid)); + stmt->setUInt8(1, GetSlot()); + stmt->setUInt16(2, itr->PersonalRating); + stmt->setUInt16(3, itr->MatchMakerRating); + trans->Append(stmt); } + CharacterDatabase.CommitTransaction(trans); } void ArenaTeam::FinishWeek() { - m_stats.games_week = 0; // played this week - m_stats.wins_week = 0; // wins this week - for (MemberList::iterator itr = m_members.begin(); itr != m_members.end(); ++itr) + // Reset team stats + Stats.WeekGames = 0; + Stats.WeekWins = 0; + + // Reset member stats + for (MemberList::iterator itr = Members.begin(); itr != Members.end(); ++itr) { - itr->games_week = 0; - itr->wins_week = 0; + itr->WeekGames = 0; + itr->WeekWins = 0; } } bool ArenaTeam::IsFighting() const { - for (MemberList::const_iterator itr = m_members.begin(); itr != m_members.end(); ++itr) - if (Player *p = sObjectMgr->GetPlayer(itr->guid)) - if (p->GetMap()->IsBattleArena()) + for (MemberList::const_iterator itr = Members.begin(); itr != Members.end(); ++itr) + if (Player* player = sObjectMgr->GetPlayer(itr->Guid)) + if (player->GetMap()->IsBattleArena()) return true; + return false; } + +ArenaTeamMember* ArenaTeam::GetMember(const std::string& name) +{ + for (MemberList::iterator itr = Members.begin(); itr != Members.end(); ++itr) + if (itr->Name == name) + return &(*itr); + + return NULL; +} + +ArenaTeamMember* ArenaTeam::GetMember(const uint64& guid) +{ + for (MemberList::iterator itr = Members.begin(); itr != Members.end(); ++itr) + if (itr->Guid == guid) + return &(*itr); + + return NULL; +} diff --git a/src/server/game/Battlegrounds/ArenaTeam.h b/src/server/game/Battlegrounds/ArenaTeam.h index ff141d8ec3f..537afa7b66d 100755 --- a/src/server/game/Battlegrounds/ArenaTeam.h +++ b/src/server/game/Battlegrounds/ArenaTeam.h @@ -72,16 +72,6 @@ ERR_ARENA_TEAM_TOO_MANY_MEMBERS_S ERR_ARENA_TEAM_LEVEL_TOO_LOW_I */ -enum ArenaTeamStatTypes -{ - STAT_TYPE_RATING = 0, - STAT_TYPE_GAMES_WEEK = 1, - STAT_TYPE_WINS_WEEK = 2, - STAT_TYPE_GAMES_SEASON = 3, - STAT_TYPE_WINS_SEASON = 4, - STAT_TYPE_RANK = 5 -}; - enum ArenaTeamTypes { ARENA_TEAM_2v2 = 2, @@ -91,15 +81,15 @@ enum ArenaTeamTypes struct ArenaTeamMember { - uint64 guid; - std::string name; + uint64 Guid; + std::string Name; uint8 Class; - uint32 games_week; - uint32 wins_week; - uint32 games_season; - uint32 wins_season; - uint32 personal_rating; - uint32 matchmaker_rating; + uint16 WeekGames; + uint16 WeekWins; + uint16 SeasonGames; + uint16 SeasonWins; + uint16 PersonalRating; + uint16 MatchMakerRating; void ModifyPersonalRating(Player* plr, int32 mod, uint32 slot); void ModifyMatchmakerRating(int32 mod, uint32 slot); @@ -107,12 +97,12 @@ struct ArenaTeamMember struct ArenaTeamStats { - uint32 rating; - uint32 games_week; - uint32 wins_week; - uint32 games_season; - uint32 wins_season; - uint32 rank; + uint16 Rating; + uint16 WeekGames; + uint16 WeekWins; + uint16 SeasonGames; + uint16 SeasonWins; + uint32 Rank; }; #define MAX_ARENA_SLOT 3 // 0..2 slots @@ -123,109 +113,84 @@ class ArenaTeam ArenaTeam(); ~ArenaTeam(); - bool Create(uint64 captainGuid, uint32 type, std::string ArenaTeamName); - void Disband(WorldSession *session); + bool Create(uint32 captainGuid, uint8 type, std::string teamName, uint32 backgroundColor, uint8 emblemStyle, uint32 emblemColor, uint8 borderStyle, uint32 borderColor); + void Disband(WorldSession* session); typedef std::list<ArenaTeamMember> MemberList; - uint32 GetId() const { return m_TeamId; } - uint32 GetType() const { return m_Type; } + uint32 GetId() const { return TeamId; } + uint32 GetType() const { return Type; } uint8 GetSlot() const { return GetSlotByType(GetType()); } static uint8 GetSlotByType(uint32 type); - const uint64& GetCaptain() const { return m_CaptainGuid; } - std::string GetName() const { return m_Name; } - const ArenaTeamStats& GetStats() const { return m_stats; } - void SetStats(uint32 stat_type, uint32 value); - uint32 GetRating() const { return m_stats.rating; } - uint32 GetAverageMMR(Group *group) const; - - uint32 GetEmblemStyle() const { return m_EmblemStyle; } - uint32 GetEmblemColor() const { return m_EmblemColor; } - uint32 GetBorderStyle() const { return m_BorderStyle; } - uint32 GetBorderColor() const { return m_BorderColor; } - uint32 GetBackgroundColor() const { return m_BackgroundColor; } + const uint64& GetCaptain() const { return CaptainGuid; } + std::string GetName() const { return TeamName; } + const ArenaTeamStats& GetStats() const { return Stats; } + + uint32 GetRating() const { return Stats.Rating; } + uint32 GetAverageMMR(Group* group) const; void SetCaptain(const uint64& guid); bool AddMember(const uint64& PlayerGuid); // Shouldn't be const uint64& ed, because than can reference guid from members on Disband // and this method removes given record from list. So invalid reference can happen. - void DelMember(uint64 guid); - - void SetEmblem(uint32 backgroundColor, uint32 emblemStyle, uint32 emblemColor, uint32 borderStyle, uint32 borderColor); - - size_t GetMembersSize() const { return m_members.size(); } - bool Empty() const { return m_members.empty(); } - MemberList::iterator m_membersBegin() { return m_members.begin(); } - MemberList::iterator m_membersEnd() { return m_members.end(); } - bool HaveMember(const uint64& guid) const; + void DelMember(uint64 guid, bool cleanDb); - ArenaTeamMember* GetMember(const uint64& guid) - { - for (MemberList::iterator itr = m_members.begin(); itr != m_members.end(); ++itr) - if (itr->guid == guid) - return &(*itr); + size_t GetMembersSize() const { return Members.size(); } + bool Empty() const { return Members.empty(); } + MemberList::iterator m_membersBegin() { return Members.begin(); } + MemberList::iterator m_membersEnd() { return Members.end(); } + bool IsMember(const uint64& guid) const; - return NULL; - } - - ArenaTeamMember* GetMember(const std::string& name) - { - for (MemberList::iterator itr = m_members.begin(); itr != m_members.end(); ++itr) - if (itr->name == name) - return &(*itr); - - return NULL; - } + ArenaTeamMember* GetMember(const uint64& guid); + ArenaTeamMember* GetMember(const std::string& name); bool IsFighting() const; bool LoadArenaTeamFromDB(QueryResult arenaTeamDataResult); bool LoadMembersFromDB(QueryResult arenaTeamMembersResult); void LoadStatsFromDB(uint32 ArenaTeamId); - void SaveToDB(); - void BroadcastPacket(WorldPacket *packet); + void BroadcastPacket(WorldPacket* packet); void BroadcastEvent(ArenaTeamEvents event, uint64 guid, uint8 strCount, std::string str1, std::string str2, std::string str3); + void NotifyStatsChanged(); - void Roster(WorldSession *session); - void Query(WorldSession *session); - void Stats(WorldSession *session); - void InspectStats(WorldSession *session, uint64 guid); + void Roster(WorldSession* session); + void Query(WorldSession* session); + void SendStats(WorldSession* session); + void Inspect(WorldSession* session, uint64 guid); uint32 GetPoints(uint32 MemberRating); - int32 GetRatingMod(uint32 own_rating, uint32 enemy_rating, bool won, bool calculating_mmr = false); - int32 GetPersonalRatingMod(int32 base_rating, uint32 own_rating, uint32 enemy_rating); - float GetChanceAgainst(uint32 own_rating, uint32 enemy_rating); - int32 WonAgainst(uint32 againstRating); - void MemberWon(Player * plr, uint32 againstMatchmakerRating, int32 teamratingchange = 12); - int32 LostAgainst(uint32 againstRating); - void MemberLost(Player * plr, uint32 againstMatchmakerRating, int32 teamratingchange = -12); - void OfflineMemberLost(uint64 guid, uint32 againstMatchmakerRating, int32 teamratingchange = -12); + int32 GetRatingMod(uint32 ownRating, uint32 opponentRating, bool won, bool calculating_mmr = false); + int32 GetPersonalRatingMod(int32 base_rating, uint32 ownRating, uint32 opponentRating); + float GetChanceAgainst(uint32 ownRating, uint32 opponentRating); + int32 WonAgainst(uint32 againstRating); + void MemberWon(Player* plr, uint32 againstMatchmakerRating, int32 teamratingchange = 12); + int32 LostAgainst(uint32 againstRating); + void MemberLost(Player* plr, uint32 againstMatchmakerRating, int32 teamratingchange = -12); + void OfflineMemberLost(uint64 guid, uint32 againstMatchmakerRating, int32 teamratingchange = -12); void UpdateArenaPointsHelper(std::map<uint32, uint32> & PlayerPoints); - void NotifyStatsChanged(); - void FinishWeek(); void FinishGame(int32 mod); protected: - uint32 m_TeamId; - uint32 m_Type; - std::string m_Name; - uint64 m_CaptainGuid; + uint32 TeamId; + uint8 Type; + std::string TeamName; + uint64 CaptainGuid; - uint32 m_BackgroundColor; // ARGB format - uint32 m_EmblemStyle; // icon id - uint32 m_EmblemColor; // ARGB format - uint32 m_BorderStyle; // border image id - uint32 m_BorderColor; // ARGB format + uint32 BackgroundColor; // ARGB format + uint8 EmblemStyle; // icon id + uint32 EmblemColor; // ARGB format + uint8 BorderStyle; // border image id + uint32 BorderColor; // ARGB format - MemberList m_members; - ArenaTeamStats m_stats; + MemberList Members; + ArenaTeamStats Stats; }; #endif diff --git a/src/server/game/Battlegrounds/Battleground.cpp b/src/server/game/Battlegrounds/Battleground.cpp index fb4b957fd92..b78928e4fe0 100755 --- a/src/server/game/Battlegrounds/Battleground.cpp +++ b/src/server/game/Battlegrounds/Battleground.cpp @@ -775,7 +775,7 @@ void Battleground::EndBattleground(uint32 winner) // update achievement BEFORE personal rating update ArenaTeamMember* member = winner_arena_team->GetMember(plr->GetGUID()); if (member) - plr->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_WIN_RATED_ARENA, member->personal_rating); + plr->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_WIN_RATED_ARENA, member->PersonalRating); winner_arena_team->MemberWon(plr,loser_matchmaker_rating, winner_change); } diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 1b341697a69..d27f54efca5 100755 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -16225,6 +16225,7 @@ void Player::_LoadArenaTeamInfo(PreparedQueryResult result) { // arenateamid, played_week, played_season, personal_rating memset((void*)&m_uint32Values[PLAYER_FIELD_ARENA_TEAM_INFO_1_1], 0, sizeof(uint32) * MAX_ARENA_SLOT * ARENA_TEAM_END); + if (!result) return; @@ -16232,63 +16233,46 @@ void Player::_LoadArenaTeamInfo(PreparedQueryResult result) { Field* fields = result->Fetch(); - uint32 arenateamid = fields[0].GetUInt32(); - uint32 played_week = fields[1].GetUInt32(); - uint32 played_season = fields[2].GetUInt32(); - uint32 wons_season = fields[3].GetUInt32(); + uint32 arenaTeamId = fields[0].GetUInt32(); - ArenaTeam* aTeam = sObjectMgr->GetArenaTeamById(arenateamid); - if (!aTeam) + ArenaTeam* arenaTeam = sObjectMgr->GetArenaTeamById(arenaTeamId); + if (!arenaTeam) { - sLog->outError("Player::_LoadArenaTeamInfo: couldn't load arenateam %u", arenateamid); + sLog->outError("Player::_LoadArenaTeamInfo: couldn't load arenateam %u", arenaTeamId); continue; } - uint8 arenaSlot = aTeam->GetSlot(); + uint8 arenaSlot = arenaTeam->GetSlot(); - SetArenaTeamInfoField(arenaSlot, ARENA_TEAM_ID, arenateamid); - SetArenaTeamInfoField(arenaSlot, ARENA_TEAM_TYPE, aTeam->GetType()); - SetArenaTeamInfoField(arenaSlot, ARENA_TEAM_MEMBER, (aTeam->GetCaptain() == GetGUID()) ? 0 : 1); - SetArenaTeamInfoField(arenaSlot, ARENA_TEAM_GAMES_WEEK, played_week); - SetArenaTeamInfoField(arenaSlot, ARENA_TEAM_GAMES_SEASON, played_season); - SetArenaTeamInfoField(arenaSlot, ARENA_TEAM_WINS_SEASON, wons_season); + SetArenaTeamInfoField(arenaSlot, ARENA_TEAM_ID, arenaTeamId); + SetArenaTeamInfoField(arenaSlot, ARENA_TEAM_TYPE, arenaTeam->GetType()); + SetArenaTeamInfoField(arenaSlot, ARENA_TEAM_MEMBER, (arenaTeam->GetCaptain() == GetGUID()) ? 0 : 1); + SetArenaTeamInfoField(arenaSlot, ARENA_TEAM_GAMES_WEEK, uint32(fields[1].GetUInt16())); + SetArenaTeamInfoField(arenaSlot, ARENA_TEAM_GAMES_SEASON, uint32(fields[2].GetUInt16())); + SetArenaTeamInfoField(arenaSlot, ARENA_TEAM_WINS_SEASON, uint32(fields[3].GetUInt16())); } while (result->NextRow()); } void Player::_LoadArenaStatsInfo(PreparedQueryResult result) { - uint8 slot = 0; - if (!result) + uint16 personalRatingCache[] = {0, 0, 0}; + + if (result) { - for (; slot <= 2; ++slot) + do { - CharacterDatabase.PExecute("INSERT INTO character_arena_stats (guid, slot, personal_rating, matchmaker_rating) VALUES (%u, %u, 0, 1500)", GetGUIDLow(), slot); - SetArenaTeamInfoField(slot, ARENA_TEAM_PERSONAL_RATING, 0); + Field* fields = result->Fetch(); + + personalRatingCache[fields[0].GetUInt8()] = fields[1].GetUInt16(); } - return; + while (result->NextRow()); } - do + for (uint8 slot = 0; slot <= 2; ++slot) { - Field* fields = result->Fetch(); - - uint32 personalrating = 0; - uint32 matchmakerrating = 1500; - if (fields[0].GetUInt8() > slot) - { - CharacterDatabase.PExecute("INSERT INTO character_arena_stats (guid, slot, personal_rating, matchmaker_rating) VALUES (%u, %u, %u, %u)", GetGUIDLow(), slot, personalrating, matchmakerrating); - SetArenaTeamInfoField(slot, ARENA_TEAM_PERSONAL_RATING, personalrating); - slot++; - continue; - } - - personalrating = fields[1].GetUInt32(); - matchmakerrating = fields[2].GetUInt32(); - SetArenaTeamInfoField(slot, ARENA_TEAM_PERSONAL_RATING, personalrating); - slot++; + SetArenaTeamInfoField(slot, ARENA_TEAM_PERSONAL_RATING, uint32(personalRatingCache[slot])); } - while (result->NextRow()); } void Player::_LoadEquipmentSets(PreparedQueryResult result) @@ -16549,7 +16533,7 @@ bool Player::LoadFromDB(uint32 guid, SQLQueryHolder *holder) continue; if (ArenaTeam * at = sObjectMgr->GetArenaTeamById(arena_team_id)) - if (at->HaveMember(GetGUID())) + if (at->IsMember(GetGUID())) continue; // arena team not exist or not member, cleanup fields @@ -19732,21 +19716,25 @@ void Player::RemovePetitionsAndSigns(uint64 guid, uint32 type) void Player::LeaveAllArenaTeams(uint64 guid) { - QueryResult result = CharacterDatabase.PQuery("SELECT arena_team_member.arenateamid FROM arena_team_member JOIN arena_team ON arena_team_member.arenateamid = arena_team.arenateamid WHERE guid='%u'", GUID_LOPART(guid)); + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_LOAD_PLAYER_ARENA_TEAMS); + stmt->setUInt32(0, GUID_LOPART(guid)); + PreparedQueryResult result = CharacterDatabase.Query(stmt); + if (!result) return; do { - Field *fields = result->Fetch(); - uint32 at_id = fields[0].GetUInt32(); - if (at_id != 0) + Field* fields = result->Fetch(); + uint32 arenaTeamId = fields[0].GetUInt32(); + if (arenaTeamId != 0) { - ArenaTeam * at = sObjectMgr->GetArenaTeamById(at_id); - if (at) - at->DelMember(guid); + ArenaTeam* arenaTeam = sObjectMgr->GetArenaTeamById(arenaTeamId); + if (arenaTeam) + arenaTeam->DelMember(guid, true); } - } while (result->NextRow()); + } + while (result->NextRow()); } void Player::SetRestBonus (float rest_bonus_new) diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp index bae25b56fc5..7276f579560 100755 --- a/src/server/game/Globals/ObjectMgr.cpp +++ b/src/server/game/Globals/ObjectMgr.cpp @@ -3961,11 +3961,14 @@ void ObjectMgr::LoadArenaTeams() { uint32 oldMSTime = getMSTime(); - // 0 1 2 3 4 5 - QueryResult result = CharacterDatabase.Query("SELECT arena_team.arenateamid,name,captainguid,type,BackgroundColor,EmblemStyle," - // 6 7 8 9 10 11 12 13 14 - "EmblemColor,BorderStyle,BorderColor, rating,games,wins,played,wins2,rank " - "FROM arena_team LEFT JOIN arena_team_stats ON arena_team.arenateamid = arena_team_stats.arenateamid ORDER BY arena_team.arenateamid ASC"); + // Clean out the trash before loading anything + CharacterDatabase.Execute("DELETE FROM arena_team_member WHERE arenaTeamId NOT IN (SELECT arenaTeamId FROM arena_team)"); + + + // 0 1 2 3 4 5 6 7 8 + QueryResult result = CharacterDatabase.Query("SELECT arena_team.arenaTeamId, name, captainGuid, type, backgroundColor, emblemStyle, emblemColor, borderStyle, borderColor," + // 9 10 11 12 13 14 + "rating, seasonGames, seasonWins, weekGames, weekWins, rank FROM arena_team ORDER BY arena_team.arenaTeamId ASC"); if (!result) { @@ -3974,30 +3977,29 @@ void ObjectMgr::LoadArenaTeams() return; } - // load arena_team members - QueryResult arenaTeamMembersResult = CharacterDatabase.Query( - // 0 1 2 3 4 5 6 7 8 - "SELECT arenateamid,member.guid,played_week,wons_week,played_season,wons_season,name,class " - "FROM arena_team_member member LEFT JOIN characters chars on member.guid = chars.guid ORDER BY member.arenateamid ASC"); + QueryResult result2 = CharacterDatabase.Query( + // 0 1 2 3 4 5 6 7 8 9 + "SELECT arenaTeamId, atm.guid, atm.weekGames, atm.weekWins, atm.seasonGames, atm.seasonWins, c.name, class, personalRating, matchMakerRating FROM arena_team_member atm" + " INNER JOIN arena_team ate USING (arenaTeamId)" + " LEFT JOIN characters AS c ON atm.guid = c.guid" + " LEFT JOIN character_arena_stats AS cas ON c.guid = cas.guid AND (cas.slot = 0 AND ate.type = 2 OR cas.slot = 1 AND ate.type = 3 OR cas.slot = 2 AND ate.type = 5)" + " ORDER BY atm.arenateamid ASC"); uint32 count = 0; - do { - //Field *fields = result->Fetch(); - - ++count; + ArenaTeam* newArenaTeam = new ArenaTeam; - ArenaTeam *newArenaTeam = new ArenaTeam; - if (!newArenaTeam->LoadArenaTeamFromDB(result) || - !newArenaTeam->LoadMembersFromDB(arenaTeamMembersResult)) + if (!newArenaTeam->LoadArenaTeamFromDB(result) || !newArenaTeam->LoadMembersFromDB(result2)) { newArenaTeam->Disband(NULL); delete newArenaTeam; continue; } AddArenaTeam(newArenaTeam); - }while (result->NextRow()); + + ++count; + } while (result->NextRow()); sLog->outString(); sLog->outString(">> Loaded %u arena team definitions in %u ms", count, GetMSTimeDiffToNow(oldMSTime)); diff --git a/src/server/game/Server/Protocol/Handlers/ArenaTeamHandler.cpp b/src/server/game/Server/Protocol/Handlers/ArenaTeamHandler.cpp index c0e83dd2228..7886b9e45cc 100755 --- a/src/server/game/Server/Protocol/Handlers/ArenaTeamHandler.cpp +++ b/src/server/game/Server/Protocol/Handlers/ArenaTeamHandler.cpp @@ -27,74 +27,74 @@ #include "ObjectMgr.h" #include "SocialMgr.h" -void WorldSession::HandleInspectArenaTeamsOpcode(WorldPacket & recv_data) +void WorldSession::HandleInspectArenaTeamsOpcode(WorldPacket & recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "MSG_INSPECT_ARENA_TEAMS"); uint64 guid; - recv_data >> guid; + recvData >> guid; sLog->outDebug(LOG_FILTER_NETWORKIO, "Inspect Arena stats (GUID: %u TypeId: %u)", GUID_LOPART(guid),GuidHigh2TypeId(GUID_HIPART(guid))); - if (Player *plr = sObjectMgr->GetPlayer(guid)) + if (Player* player = sObjectMgr->GetPlayer(guid)) { for (uint8 i = 0; i < MAX_ARENA_SLOT; ++i) { - if (uint32 a_id = plr->GetArenaTeamId(i)) + if (uint32 a_id = player->GetArenaTeamId(i)) { - if (ArenaTeam *at = sObjectMgr->GetArenaTeamById(a_id)) - at->InspectStats(this, plr->GetGUID()); + if (ArenaTeam* arenaTeam = sObjectMgr->GetArenaTeamById(a_id)) + arenaTeam->Inspect(this, player->GetGUID()); } } } } -void WorldSession::HandleArenaTeamQueryOpcode(WorldPacket & recv_data) +void WorldSession::HandleArenaTeamQueryOpcode(WorldPacket & recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_ARENA_TEAM_QUERY"); - uint32 ArenaTeamId; - recv_data >> ArenaTeamId; + uint32 arenaTeamId; + recvData >> arenaTeamId; - if (ArenaTeam *arenateam = sObjectMgr->GetArenaTeamById(ArenaTeamId)) + if (ArenaTeam* arenaTeam = sObjectMgr->GetArenaTeamById(arenaTeamId)) { - arenateam->Query(this); - arenateam->Stats(this); + arenaTeam->Query(this); + arenaTeam->SendStats(this); } } -void WorldSession::HandleArenaTeamRosterOpcode(WorldPacket & recv_data) +void WorldSession::HandleArenaTeamRosterOpcode(WorldPacket & recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_ARENA_TEAM_ROSTER"); - uint32 ArenaTeamId; // arena team id - recv_data >> ArenaTeamId; + uint32 arenaTeamId; // arena team id + recvData >> arenaTeamId; - if (ArenaTeam *arenateam = sObjectMgr->GetArenaTeamById(ArenaTeamId)) - arenateam->Roster(this); + if (ArenaTeam* arenaTeam = sObjectMgr->GetArenaTeamById(arenaTeamId)) + arenaTeam->Roster(this); } -void WorldSession::HandleArenaTeamInviteOpcode(WorldPacket & recv_data) +void WorldSession::HandleArenaTeamInviteOpcode(WorldPacket & recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_ARENA_TEAM_INVITE"); - uint32 ArenaTeamId; // arena team id - std::string Invitedname; + uint32 arenaTeamId; // arena team id + std::string invitedName; - Player * player = NULL; + Player* player = NULL; - recv_data >> ArenaTeamId >> Invitedname; + recvData >> arenaTeamId >> invitedName; - if (!Invitedname.empty()) + if (!invitedName.empty()) { - if (!normalizePlayerName(Invitedname)) + if (!normalizePlayerName(invitedName)) return; - player = sObjectAccessor->FindPlayerByName(Invitedname.c_str()); + player = sObjectAccessor->FindPlayerByName(invitedName.c_str()); } if (!player) { - SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, "", Invitedname, ERR_ARENA_TEAM_PLAYER_NOT_FOUND_S); + SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, "", invitedName, ERR_ARENA_TEAM_PLAYER_NOT_FOUND_S); return; } @@ -104,14 +104,14 @@ void WorldSession::HandleArenaTeamInviteOpcode(WorldPacket & recv_data) return; } - ArenaTeam *arenateam = sObjectMgr->GetArenaTeamById(ArenaTeamId); - if (!arenateam) + ArenaTeam* arenaTeam = sObjectMgr->GetArenaTeamById(arenaTeamId); + if (!arenaTeam) { SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, "", "", ERR_ARENA_TEAM_PLAYER_NOT_IN_TEAM); return; } - // OK result but not send invite + // OK result but don't send invite if (player->GetSocial()->HasIgnore(GetPlayer()->GetGUIDLow())) return; @@ -121,7 +121,7 @@ void WorldSession::HandleArenaTeamInviteOpcode(WorldPacket & recv_data) return; } - if (player->GetArenaTeamId(arenateam->GetSlot())) + if (player->GetArenaTeamId(arenaTeam->GetSlot())) { SendArenaTeamCommandResult(ERR_ARENA_TEAM_INVITE_SS, "", player->GetName(), ERR_ALREADY_IN_ARENA_TEAM_S); return; @@ -133,19 +133,19 @@ void WorldSession::HandleArenaTeamInviteOpcode(WorldPacket & recv_data) return; } - if (arenateam->GetMembersSize() >= arenateam->GetType() * 2) + if (arenaTeam->GetMembersSize() >= arenaTeam->GetType() * 2) { - SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, arenateam->GetName(), "", ERR_ARENA_TEAM_TOO_MANY_MEMBERS_S); + SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, arenaTeam->GetName(), "", ERR_ARENA_TEAM_TOO_MANY_MEMBERS_S); return; } - sLog->outDebug(LOG_FILTER_BATTLEGROUND, "Player %s Invited %s to Join his ArenaTeam", GetPlayer()->GetName(), Invitedname.c_str()); + sLog->outDebug(LOG_FILTER_BATTLEGROUND, "Player %s Invited %s to Join his ArenaTeam", GetPlayer()->GetName(), invitedName.c_str()); - player->SetArenaTeamIdInvited(arenateam->GetId()); + player->SetArenaTeamIdInvited(arenaTeam->GetId()); WorldPacket data(SMSG_ARENA_TEAM_INVITE, (8+10)); data << GetPlayer()->GetName(); - data << arenateam->GetName(); + data << arenaTeam->GetName(); player->GetSession()->SendPacket(&data); sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Sent SMSG_ARENA_TEAM_INVITE"); @@ -155,112 +155,117 @@ void WorldSession::HandleArenaTeamAcceptOpcode(WorldPacket & /*recv_data*/) { sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_ARENA_TEAM_ACCEPT"); // empty opcode - ArenaTeam *at = sObjectMgr->GetArenaTeamById(_player->GetArenaTeamIdInvited()); - if (!at) + ArenaTeam* arenaTeam = sObjectMgr->GetArenaTeamById(_player->GetArenaTeamIdInvited()); + if (!arenaTeam) return; - if (_player->GetArenaTeamId(at->GetSlot())) + // Check if player is already in another team of the same size + if (_player->GetArenaTeamId(arenaTeam->GetSlot())) { - // already in arena team that size SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, "", "", ERR_ALREADY_IN_ARENA_TEAM); return; } - if (!sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD) && _player->GetTeam() != sObjectMgr->GetPlayerTeamByGUID(at->GetCaptain())) + // Only allow members of the other faction to join the team if cross faction interaction is enabled + if (!sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD) && _player->GetTeam() != sObjectMgr->GetPlayerTeamByGUID(arenaTeam->GetCaptain())) { - // not let enemies sign petition SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, "", "", ERR_ARENA_TEAM_NOT_ALLIED); return; } - if (!at->AddMember(_player->GetGUID())) + // Add player to team + if (!arenaTeam->AddMember(_player->GetGUID())) { - // arena team not found SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S,"","",ERR_ARENA_TEAM_INTERNAL); return; } - // event - at->BroadcastEvent(ERR_ARENA_TEAM_JOIN_SS, _player->GetGUID(), 2, _player->GetName(), at->GetName(), ""); + // Broadcast event + arenaTeam->BroadcastEvent(ERR_ARENA_TEAM_JOIN_SS, _player->GetGUID(), 2, _player->GetName(), arenaTeam->GetName(), ""); } void WorldSession::HandleArenaTeamDeclineOpcode(WorldPacket & /*recv_data*/) { sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_ARENA_TEAM_DECLINE"); // empty opcode - _player->SetArenaTeamIdInvited(0); // no more invited + // Remove invite from player + _player->SetArenaTeamIdInvited(0); } -void WorldSession::HandleArenaTeamLeaveOpcode(WorldPacket & recv_data) +void WorldSession::HandleArenaTeamLeaveOpcode(WorldPacket & recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_ARENA_TEAM_LEAVE"); - uint32 ArenaTeamId; // arena team id - recv_data >> ArenaTeamId; + uint32 arenaTeamId; + recvData >> arenaTeamId; - ArenaTeam *at = sObjectMgr->GetArenaTeamById(ArenaTeamId); - if (!at) + ArenaTeam* arenaTeam = sObjectMgr->GetArenaTeamById(arenaTeamId); + if (!arenaTeam) return; - if (_player->GetGUID() == at->GetCaptain() && at->GetMembersSize() > 1) + // Team captain can't leave the team if other members are still present + if (_player->GetGUID() == arenaTeam->GetCaptain() && arenaTeam->GetMembersSize() > 1) { - // check for correctness SendArenaTeamCommandResult(ERR_ARENA_TEAM_QUIT_S, "", "", ERR_ARENA_TEAM_LEADER_LEAVE_S); return; } - // arena team has only one member (=captain) - if (_player->GetGUID() == at->GetCaptain()) + // If team consists only of the captain, disband the team + if (_player->GetGUID() == arenaTeam->GetCaptain()) { - at->Disband(this); - delete at; + arenaTeam->Disband(this); + delete arenaTeam; return; } + else + arenaTeam->DelMember(_player->GetGUID(), true); - at->DelMember(_player->GetGUID()); + // Broadcast event + arenaTeam->BroadcastEvent(ERR_ARENA_TEAM_LEAVE_SS, _player->GetGUID(), 2, _player->GetName(), arenaTeam->GetName(), ""); - // event - at->BroadcastEvent(ERR_ARENA_TEAM_LEAVE_SS, _player->GetGUID(), 2, _player->GetName(), at->GetName(), ""); - - // send you are no longer member of team - SendArenaTeamCommandResult(ERR_ARENA_TEAM_QUIT_S, at->GetName(), "", 0); + // Inform player who left + SendArenaTeamCommandResult(ERR_ARENA_TEAM_QUIT_S, arenaTeam->GetName(), "", 0); } -void WorldSession::HandleArenaTeamDisbandOpcode(WorldPacket & recv_data) +void WorldSession::HandleArenaTeamDisbandOpcode(WorldPacket & recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_ARENA_TEAM_DISBAND"); - uint32 ArenaTeamId; // arena team id - recv_data >> ArenaTeamId; + uint32 arenaTeamId; + recvData >> arenaTeamId; - if (ArenaTeam *at = sObjectMgr->GetArenaTeamById(ArenaTeamId)) + if (ArenaTeam* arenaTeam = sObjectMgr->GetArenaTeamById(arenaTeamId)) { - if (at->GetCaptain() != _player->GetGUID()) + // Only captain can disband the team + if (arenaTeam->GetCaptain() != _player->GetGUID()) return; - if (at->IsFighting()) + // Teams cannot be disbanded during fights + if (arenaTeam->IsFighting()) return; - at->Disband(this); - delete at; + arenaTeam->Disband(this); + delete arenaTeam; } } -void WorldSession::HandleArenaTeamRemoveOpcode(WorldPacket & recv_data) +void WorldSession::HandleArenaTeamRemoveOpcode(WorldPacket & recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_ARENA_TEAM_REMOVE"); - uint32 ArenaTeamId; + uint32 arenaTeamId; std::string name; - recv_data >> ArenaTeamId; - recv_data >> name; + recvData >> arenaTeamId; + recvData >> name; - ArenaTeam *at = sObjectMgr->GetArenaTeamById(ArenaTeamId); - if (!at) // arena team not found + // Check for valid arena team + ArenaTeam* arenaTeam = sObjectMgr->GetArenaTeamById(arenaTeamId); + if (!arenaTeam) return; - if (at->GetCaptain() != _player->GetGUID()) + // Only captain can remove members + if (arenaTeam->GetCaptain() != _player->GetGUID()) { SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, "", "", ERR_ARENA_TEAM_PERMISSIONS); return; @@ -269,40 +274,44 @@ void WorldSession::HandleArenaTeamRemoveOpcode(WorldPacket & recv_data) if (!normalizePlayerName(name)) return; - ArenaTeamMember* member = at->GetMember(name); - if (!member) // member not found + // Check if team member exists + ArenaTeamMember* member = arenaTeam->GetMember(name); + if (!member) { SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, "", name, ERR_ARENA_TEAM_PLAYER_NOT_FOUND_S); return; } - if (at->GetCaptain() == member->guid) + // Captain cannot be removed + if (arenaTeam->GetCaptain() == member->Guid) { SendArenaTeamCommandResult(ERR_ARENA_TEAM_QUIT_S, "", "", ERR_ARENA_TEAM_LEADER_LEAVE_S); return; } - at->DelMember(member->guid); + arenaTeam->DelMember(member->Guid, true); - // event - at->BroadcastEvent(ERR_ARENA_TEAM_REMOVE_SSS, 0, 3, name, at->GetName(), _player->GetName()); + // Broadcast event + arenaTeam->BroadcastEvent(ERR_ARENA_TEAM_REMOVE_SSS, 0, 3, name, arenaTeam->GetName(), _player->GetName()); } -void WorldSession::HandleArenaTeamLeaderOpcode(WorldPacket & recv_data) +void WorldSession::HandleArenaTeamLeaderOpcode(WorldPacket & recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_ARENA_TEAM_LEADER"); - uint32 ArenaTeamId; + uint32 arenaTeamId; std::string name; - recv_data >> ArenaTeamId; - recv_data >> name; + recvData >> arenaTeamId; + recvData >> name; - ArenaTeam *at = sObjectMgr->GetArenaTeamById(ArenaTeamId); - if (!at) // arena team not found + // Check for valid arena team + ArenaTeam* arenaTeam = sObjectMgr->GetArenaTeamById(arenaTeamId); + if (!arenaTeam) return; - if (at->GetCaptain() != _player->GetGUID()) + // Only captain can pass leadership + if (arenaTeam->GetCaptain() != _player->GetGUID()) { SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, "", "", ERR_ARENA_TEAM_PERMISSIONS); return; @@ -311,29 +320,31 @@ void WorldSession::HandleArenaTeamLeaderOpcode(WorldPacket & recv_data) if (!normalizePlayerName(name)) return; - ArenaTeamMember* member = at->GetMember(name); - if (!member) // member not found + // Check if team member exists + ArenaTeamMember* member = arenaTeam->GetMember(name); + if (!member) { SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, "", name, ERR_ARENA_TEAM_PLAYER_NOT_FOUND_S); return; } - if (at->GetCaptain() == member->guid) // target player already captain + // Check if the target is already team captain + if (arenaTeam->GetCaptain() == member->Guid) return; - at->SetCaptain(member->guid); + arenaTeam->SetCaptain(member->Guid); - // event - at->BroadcastEvent(ERR_ARENA_TEAM_LEADER_CHANGED_SSS, 0, 3, _player->GetName(), name, at->GetName()); + // Broadcast event + arenaTeam->BroadcastEvent(ERR_ARENA_TEAM_LEADER_CHANGED_SSS, 0, 3, _player->GetName(), name, arenaTeam->GetName()); } -void WorldSession::SendArenaTeamCommandResult(uint32 team_action, const std::string& team, const std::string& player, uint32 error_id) +void WorldSession::SendArenaTeamCommandResult(uint32 teamAction, const std::string& team, const std::string& player, uint32 errorId) { WorldPacket data(SMSG_ARENA_TEAM_COMMAND_RESULT, 4+team.length()+1+player.length()+1+4); - data << uint32(team_action); + data << uint32(teamAction); data << team; data << player; - data << uint32(error_id); + data << uint32(errorId); SendPacket(&data); } diff --git a/src/server/game/Server/Protocol/Handlers/PetitionsHandler.cpp b/src/server/game/Server/Protocol/Handlers/PetitionsHandler.cpp index 1417661fba8..3e716bea6e9 100755 --- a/src/server/game/Server/Protocol/Handlers/PetitionsHandler.cpp +++ b/src/server/game/Server/Protocol/Handlers/PetitionsHandler.cpp @@ -695,22 +695,30 @@ void WorldSession::HandleOfferPetitionOpcode(WorldPacket & recv_data) void WorldSession::HandleTurnInPetitionOpcode(WorldPacket & recv_data) { - sLog->outDebug(LOG_FILTER_NETWORKIO, "Received opcode CMSG_TURN_IN_PETITION"); // ok - //recv_data.hexlike(); + sLog->outDebug(LOG_FILTER_NETWORKIO, "Received opcode CMSG_TURN_IN_PETITION"); + // Get petition guid from packet WorldPacket data; - uint64 petitionguid; + uint64 petitionGuid; + + recv_data >> petitionGuid; + // Check if player really has the required petition charter + Item* item = _player->GetItemByGuid(petitionGuid); + if (!item) + return; + + sLog->outDebug(LOG_FILTER_NETWORKIO, "Petition %u turned in by %u", GUID_LOPART(petitionGuid), _player->GetGUIDLow()); + + // Get petition data from db uint32 ownerguidlo; uint32 type; std::string name; - recv_data >> petitionguid; + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_LOAD_PETITION); + stmt->setUInt32(0, GUID_LOPART(petitionGuid)); + PreparedQueryResult result = CharacterDatabase.Query(stmt); - sLog->outDebug(LOG_FILTER_NETWORKIO, "Petition %u turned in by %u", GUID_LOPART(petitionguid), _player->GetGUIDLow()); - - // data - QueryResult result = CharacterDatabase.PQuery("SELECT ownerguid, name, type FROM petition WHERE petitionguid = '%u'", GUID_LOPART(petitionguid)); if (result) { Field *fields = result->Fetch(); @@ -720,145 +728,146 @@ void WorldSession::HandleTurnInPetitionOpcode(WorldPacket & recv_data) } else { - sLog->outError("petition table has broken data!"); + sLog->outError("Player %s (guid: %u) tried to turn in petition (guid: %u) that is not present in the database", _player->GetName(), _player->GetGUIDLow(), GUID_LOPART(petitionGuid)); return; } + // Only the petition owner can turn in the petition + if (_player->GetGUIDLow() != ownerguidlo) + return; + + // Petition type (guild/arena) specific checks if (type == GUILD_CHARTER_TYPE) { + // Check if player is already in a guild if (_player->GetGuildId()) { data.Initialize(SMSG_TURN_IN_PETITION_RESULTS, 4); - data << (uint32)PETITION_TURN_ALREADY_IN_GUILD; // already in guild + data << (uint32)PETITION_TURN_ALREADY_IN_GUILD; _player->GetSession()->SendPacket(&data); return; } + + // Check if guild name is already taken + if (sObjectMgr->GetGuildByName(name)) + { + Guild::SendCommandResult(this, GUILD_CREATE_S, ERR_GUILD_NAME_EXISTS_S, name); + return; + } } else { + // Check for valid arena bracket (2v2, 3v3, 5v5) uint8 slot = ArenaTeam::GetSlotByType(type); if (slot >= MAX_ARENA_SLOT) return; + // Check if player is already in an arena team if (_player->GetArenaTeamId(slot)) { - //data.Initialize(SMSG_TURN_IN_PETITION_RESULTS, 4); - //data << (uint32)PETITION_TURN_ALREADY_IN_GUILD; // already in guild - //_player->GetSession()->SendPacket(&data); SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, name, "", ERR_ALREADY_IN_ARENA_TEAM); return; } + + // Check if arena team name is already taken + if (sObjectMgr->GetArenaTeamByName(name)) + { + SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, name, "", ERR_ARENA_TEAM_NAME_EXISTS_S); + return; + } } - if (_player->GetGUIDLow() != ownerguidlo) - return; + // Get petition signatures from db + uint8 signatures; + + stmt = CharacterDatabase.GetPreparedStatement(CHAR_LOAD_PETITION_SIGNATURE); + stmt->setUInt32(0, GUID_LOPART(petitionGuid)); + result = CharacterDatabase.Query(stmt); - // signs - uint8 signs; - result = CharacterDatabase.PQuery("SELECT playerguid FROM petition_sign WHERE petitionguid = '%u'", GUID_LOPART(petitionguid)); if (result) - signs = uint8(result->GetRowCount()); + signatures = uint8(result->GetRowCount()); else - signs = 0; + signatures = 0; - uint32 count; - //if (signs < sWorld->getIntConfig(CONFIG_MIN_PETITION_SIGNS)) + uint32 requiredSignatures; if (type == GUILD_CHARTER_TYPE) - count = sWorld->getIntConfig(CONFIG_MIN_PETITION_SIGNS); + requiredSignatures = sWorld->getIntConfig(CONFIG_MIN_PETITION_SIGNS); else - count = type-1; - if (signs < count) + requiredSignatures = type-1; + + // Notify player if signatures are missing + if (signatures < requiredSignatures) { data.Initialize(SMSG_TURN_IN_PETITION_RESULTS, 4); - data << (uint32)PETITION_TURN_NEED_MORE_SIGNATURES; // need more signatures... + data << (uint32)PETITION_TURN_NEED_MORE_SIGNATURES; SendPacket(&data); return; } - if (type == GUILD_CHARTER_TYPE) - { - if (sObjectMgr->GetGuildByName(name)) - { - Guild::SendCommandResult(this, GUILD_CREATE_S, ERR_GUILD_NAME_EXISTS_S, name); - return; - } - } - else - { - if (sObjectMgr->GetArenaTeamByName(name)) - { - SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, name, "", ERR_ARENA_TEAM_NAME_EXISTS_S); - return; - } - } - - // and at last charter item check - Item *item = _player->GetItemByGuid(petitionguid); - if (!item) - return; - - // OK! + // Proceed with guild/arena team creation - // delete charter item + // Delete charter item _player->DestroyItem(item->GetBagSlot(),item->GetSlot(), true); - if (type == GUILD_CHARTER_TYPE) // create guild + if (type == GUILD_CHARTER_TYPE) { + // Create guild Guild* guild = new Guild; + if (!guild->Create(_player, name)) { delete guild; return; } - // register guild and add guildmaster + // Register guild and add guild master sObjectMgr->AddGuild(guild); - // add members - for (uint8 i = 0; i < signs; ++i) + // Add members from signatures + for (uint8 i = 0; i < signatures; ++i) { Field* fields = result->Fetch(); - guild->AddMember(fields[0].GetUInt64()); + guild->AddMember(MAKE_NEW_GUID(fields[0].GetUInt32(), 0, HIGHGUID_PLAYER)); result->NextRow(); } } - else // or arena team + else { - ArenaTeam* at = new ArenaTeam; - if (!at->Create(_player->GetGUID(), type, name)) + // Receive the rest of the packet in arena team creation case + uint32 background, icon, iconcolor, border, bordercolor; + recv_data >> background >> icon >> iconcolor >> border >> bordercolor; + + // Create arena team + ArenaTeam* arenaTeam = new ArenaTeam(); + + if (!arenaTeam->Create(_player->GetGUID(), type, name, background, icon, iconcolor, border, bordercolor)) { - sLog->outError("PetitionsHandler: arena team create failed."); - delete at; + delete arenaTeam; return; } - uint32 icon, iconcolor, border, bordercolor, backgroud; - recv_data >> backgroud >> icon >> iconcolor >> border >> bordercolor; - - at->SetEmblem(backgroud, icon, iconcolor, border, bordercolor); + // Register arena team + sObjectMgr->AddArenaTeam(arenaTeam); + sLog->outDebug(LOG_FILTER_NETWORKIO, "PetitonsHandler: Arena team (guid: %u) added to ObjectMgr", arenaTeam->GetId()); - // register team and add captain - sObjectMgr->AddArenaTeam(at); - sLog->outDebug(LOG_FILTER_NETWORKIO, "PetitonsHandler: arena team added to objmrg"); - - // add members - for (uint8 i = 0; i < signs; ++i) + // Add members + for (uint8 i = 0; i < signatures; ++i) { Field* fields = result->Fetch(); - uint64 memberGUID = fields[0].GetUInt64(); - sLog->outDebug(LOG_FILTER_NETWORKIO, "PetitionsHandler: adding arena member %u", GUID_LOPART(memberGUID)); - at->AddMember(memberGUID); + uint32 memberGUID = fields[0].GetUInt32(); + sLog->outDebug(LOG_FILTER_NETWORKIO, "PetitionsHandler: Adding arena team (guid: %u) member %u", arenaTeam->GetId(), memberGUID); + arenaTeam->AddMember(MAKE_NEW_GUID(memberGUID, 0, HIGHGUID_PLAYER)); result->NextRow(); } } SQLTransaction trans = CharacterDatabase.BeginTransaction(); - trans->PAppend("DELETE FROM petition WHERE petitionguid = '%u'", GUID_LOPART(petitionguid)); - trans->PAppend("DELETE FROM petition_sign WHERE petitionguid = '%u'", GUID_LOPART(petitionguid)); + trans->PAppend("DELETE FROM petition WHERE petitionguid = '%u'", GUID_LOPART(petitionGuid)); + trans->PAppend("DELETE FROM petition_sign WHERE petitionguid = '%u'", GUID_LOPART(petitionGuid)); CharacterDatabase.CommitTransaction(trans); // created - sLog->outDebug(LOG_FILTER_NETWORKIO, "TURN IN PETITION GUID %u", GUID_LOPART(petitionguid)); + sLog->outDebug(LOG_FILTER_NETWORKIO, "TURN IN PETITION GUID %u", GUID_LOPART(petitionGuid)); data.Initialize(SMSG_TURN_IN_PETITION_RESULTS, 4); data << (uint32)PETITION_TURN_OK; @@ -867,8 +876,7 @@ void WorldSession::HandleTurnInPetitionOpcode(WorldPacket & recv_data) void WorldSession::HandlePetitionShowListOpcode(WorldPacket & recv_data) { - sLog->outDebug(LOG_FILTER_NETWORKIO, "Received CMSG_PETITION_SHOWLIST"); // ok - //recv_data.hexlike(); + sLog->outDebug(LOG_FILTER_NETWORKIO, "Received CMSG_PETITION_SHOWLIST"); uint64 guid; recv_data >> guid; @@ -885,21 +893,12 @@ void WorldSession::SendPetitionShowList(uint64 guid) return; } - // remove fake death - if (GetPlayer()->HasUnitState(UNIT_STAT_DIED)) - GetPlayer()->RemoveAurasByType(SPELL_AURA_FEIGN_DEATH); - - uint8 count = 0; - if (pCreature->isTabardDesigner()) - count = 1; - else - count = 3; - WorldPacket data(SMSG_PETITION_SHOWLIST, 8+1+4*6); data << guid; // npc guid - data << count; // count - if (count == 1) + + if (pCreature->isTabardDesigner()) { + data << uint8(1); // count data << uint32(1); // index data << uint32(GUILD_CHARTER); // charter entry data << uint32(CHARTER_DISPLAY_ID); // charter display id @@ -909,6 +908,7 @@ void WorldSession::SendPetitionShowList(uint64 guid) } else { + data << uint8(3); // count // 2v2 data << uint32(1); // index data << uint32(ARENA_TEAM_CHARTER_2v2); // charter entry @@ -931,15 +931,7 @@ void WorldSession::SendPetitionShowList(uint64 guid) data << uint32(5); // unknown data << uint32(5); // required signs? } - //for (uint8 i = 0; i < count; ++i) - //{ - // data << uint32(i); // index - // data << uint32(GUILD_CHARTER); // charter entry - // data << uint32(CHARTER_DISPLAY_ID); // charter display id - // data << uint32(GUILD_CHARTER_COST+i); // charter cost - // data << uint32(0); // unknown - // data << uint32(9); // required signs? - //} + SendPacket(&data); sLog->outDebug(LOG_FILTER_NETWORKIO, "Sent SMSG_PETITION_SHOWLIST"); } diff --git a/src/server/shared/Database/Implementation/CharacterDatabase.cpp b/src/server/shared/Database/Implementation/CharacterDatabase.cpp index f42d5b3062e..37f7dea2167 100755 --- a/src/server/shared/Database/Implementation/CharacterDatabase.cpp +++ b/src/server/shared/Database/Implementation/CharacterDatabase.cpp @@ -66,7 +66,6 @@ bool CharacterDatabaseConnection::Open() PREPARE_STATEMENT(CHAR_LOAD_PLAYER_SPELLCOOLDOWNS, "SELECT spell, item, time FROM character_spell_cooldown WHERE guid = ?", CONNECTION_ASYNC) PREPARE_STATEMENT(CHAR_LOAD_PLAYER_DECLINEDNAMES, "SELECT genitive, dative, accusative, instrumental, prepositional FROM character_declinedname WHERE guid = ?", CONNECTION_ASYNC) PREPARE_STATEMENT(CHAR_LOAD_PLAYER_GUILD, "SELECT guildid,rank FROM guild_member WHERE guid = ?", CONNECTION_ASYNC) - PREPARE_STATEMENT(CHAR_LOAD_PLAYER_ARENAINFO, "SELECT arenateamid, played_week, played_season, wons_season FROM arena_team_member WHERE guid = ?", CONNECTION_ASYNC) PREPARE_STATEMENT(CHAR_LOAD_PLAYER_ACHIEVEMENTS, "SELECT achievement, date FROM character_achievement WHERE guid = ?", CONNECTION_ASYNC) PREPARE_STATEMENT(CHAR_LOAD_PLAYER_CRITERIAPROGRESS, "SELECT criteria, counter, date FROM character_achievement_progress WHERE guid = ?", CONNECTION_ASYNC) PREPARE_STATEMENT(CHAR_LOAD_PLAYER_EQUIPMENTSETS, "SELECT setguid, setindex, name, iconname, item0, item1, item2, item3, item4, item5, item6, item7, item8, " @@ -76,7 +75,7 @@ bool CharacterDatabaseConnection::Open() PREPARE_STATEMENT(CHAR_LOAD_PLAYER_TALENTS, "SELECT spell, spec FROM character_talent WHERE guid = ?", CONNECTION_ASYNC) PREPARE_STATEMENT(CHAR_LOAD_PLAYER_SKILLS, "SELECT skill, value, max FROM character_skills WHERE guid = ?", CONNECTION_ASYNC) PREPARE_STATEMENT(CHAR_LOAD_PLAYER_RANDOMBG, "SELECT guid FROM character_battleground_random WHERE guid = ?", CONNECTION_ASYNC) - PREPARE_STATEMENT(CHAR_LOAD_PLAYER_ARENASTATS, "SELECT slot, personal_rating, matchmaker_rating FROM character_arena_stats WHERE guid = ? ORDER BY slot ASC", CONNECTION_ASYNC) + PREPARE_STATEMENT(CHAR_LOAD_PLAYER_ARENASTATS, "SELECT slot, personalRating FROM character_arena_stats WHERE guid = ? ORDER BY slot ASC", CONNECTION_ASYNC) PREPARE_STATEMENT(CHAR_LOAD_PLAYER_BANNED, "SELECT guid FROM character_banned WHERE guid = ? AND active = 1", CONNECTION_ASYNC) PREPARE_STATEMENT(CHAR_LOAD_PLAYER_QUESTSTATUSREW, "SELECT quest FROM character_queststatus_rewarded WHERE guid = ?", CONNECTION_ASYNC) PREPARE_STATEMENT(CHAR_LOAD_ACCOUNT_INSTANCELOCKTIMES, "SELECT instanceId, releaseTime FROM account_instance_times WHERE accountId = ?", CONNECTION_ASYNC) @@ -113,6 +112,8 @@ bool CharacterDatabaseConnection::Open() PREPARE_STATEMENT(CHAR_GET_ACCOUNT_BY_NAME, "SELECT account FROM characters WHERE name = ?", CONNECTION_SYNCH) PREPARE_STATEMENT(CHAR_DEL_ACCOUNT_INSTANCE_LOCK_TIMES, "DELETE FROM account_instance_times WHERE accountId = ?", CONNECTION_ASYNC) PREPARE_STATEMENT(CHAR_ADD_ACCOUNT_INSTANCE_LOCK_TIMES, "INSERT INTO account_instance_times (accountId, instanceId, releaseTime) VALUES (?, ?, ?)", CONNECTION_ASYNC) + PREPARE_STATEMENT(CHAR_LOAD_PLAYER_NAME_CLASS, "SELECT name, class FROM characters WHERE guid = ?", CONNECTION_SYNCH); + PREPARE_STATEMENT(CHAR_LOAD_MATCH_MAKER_RATING, "SELECT matchMakerRating FROM character_arena_stats WHERE guid = ? AND slot = ?", CONNECTION_SYNCH); // Guild handling // 0: uint32, 1: string, 2: uint32, 3: string, 4: string, 5: uint64, 6-10: uint32, 11: uint64 @@ -282,6 +283,23 @@ bool CharacterDatabaseConnection::Open() PREPARE_STATEMENT(CHAR_DEL_GAME_EVENT_CONDITION_SAVE, "DELETE FROM game_event_condition_save WHERE eventEntry = ? AND condition_id = ?", CONNECTION_ASYNC) PREPARE_STATEMENT(CHAR_ADD_GAME_EVENT_CONDITION_SAVE, "INSERT INTO game_event_condition_save (eventEntry, condition_id, done) VALUES (?, ?, ?)", CONNECTION_ASYNC) + // Petitions + PREPARE_STATEMENT(CHAR_LOAD_PETITION, "SELECT ownerguid, name, type FROM petition WHERE petitionguid = ?", CONNECTION_SYNCH); + PREPARE_STATEMENT(CHAR_LOAD_PETITION_SIGNATURE, "SELECT playerguid FROM petition_sign WHERE petitionguid = ?", CONNECTION_SYNCH); + + // Arena teams + PREPARE_STATEMENT(CHAR_LOAD_PLAYER_ARENAINFO, "SELECT arenaTeamId, weekGames, seasonGames, seasonWins FROM arena_team_member WHERE guid = ?", CONNECTION_ASYNC) + PREPARE_STATEMENT(CHAR_ADD_ARENA_TEAM, "INSERT INTO arena_team (arenaTeamId, name, captainGuid, type, rating, backgroundColor, emblemStyle, emblemColor, borderStyle, borderColor) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_SET_ARENA_TEAM_MEMBER, "INSERT INTO arena_team_member (arenaTeamId, guid) VALUES (?, ?)", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_DEL_ARENA_TEAM, "DELETE FROM arena_team where arenaTeamId = ?", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_DEL_ARENA_TEAM_MEMBERS, "DELETE FROM arena_team_member WHERE arenaTeamId = ?", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_UPDATE_ARENA_TEAM_CAPTAIN, "UPDATE arena_team SET captainGuid = ? WHERE arenaTeamId = ?", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_DEL_ARENA_TEAM_MEMBER, "DELETE FROM arena_team_member WHERE arenaTeamId = ? AND guid = ?", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_UPDATE_ARENA_TEAM_STATS, "UPDATE arena_team SET rating = ?, weekGames = ?, weekWins = ?, seasonGames = ?, seasonWins = ?, rank = ? WHERE arenaTeamId = ?", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_UPDATE_ARENA_TEAM_MEMBER, "UPDATE arena_team_member SET weekGames = ?, weekWins = ?, seasonGames = ?, seasonWins = ? WHERE arenaTeamId = ? AND guid = ?", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_UPDATE_ARENA_TEAM_MEMBER_STATS, "REPLACE INTO character_arena_stats (guid, slot, personalRating, matchMakerRating) VALUES (?, ?, ?, ?)", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_LOAD_PLAYER_ARENA_TEAMS, "SELECT arena_team_member.arenaTeamId FROM arena_team_member JOIN arena_team ON arena_team_member.arenaTeamId = arena_team.arenaTeamId WHERE guid = ?", CONNECTION_SYNCH); + for (PreparedStatementMap::const_iterator itr = m_queries.begin(); itr != m_queries.end(); ++itr) PrepareStatement(itr->first, itr->second.first, itr->second.second); diff --git a/src/server/shared/Database/Implementation/CharacterDatabase.h b/src/server/shared/Database/Implementation/CharacterDatabase.h index 9abc7a65b68..93c87b1a407 100755 --- a/src/server/shared/Database/Implementation/CharacterDatabase.h +++ b/src/server/shared/Database/Implementation/CharacterDatabase.h @@ -117,6 +117,8 @@ enum CharacterDatabaseStatements CHAR_GET_ACCOUNT_BY_NAME, CHAR_DEL_ACCOUNT_INSTANCE_LOCK_TIMES, CHAR_ADD_ACCOUNT_INSTANCE_LOCK_TIMES, + CHAR_LOAD_PLAYER_NAME_CLASS, + CHAR_LOAD_MATCH_MAKER_RATING, CHAR_ADD_GUILD, CHAR_DEL_GUILD, @@ -235,6 +237,21 @@ enum CharacterDatabaseStatements CHAR_DEL_GAME_EVENT_CONDITION_SAVE, CHAR_ADD_GAME_EVENT_CONDITION_SAVE, + CHAR_ADD_ARENA_TEAM, + CHAR_SET_ARENA_TEAM_MEMBER, + CHAR_DEL_ARENA_TEAM, + CHAR_DEL_ARENA_TEAM_MEMBERS, + CHAR_UPDATE_ARENA_TEAM_CAPTAIN, + CHAR_DEL_ARENA_TEAM_MEMBER, + CHAR_UPDATE_ARENA_TEAM_STATS, + CHAR_UPDATE_ARENA_TEAM_MEMBER, + CHAR_UPDATE_ARENA_TEAM_MEMBER_STATS, + CHAR_LOAD_PLAYER_ARENA_TEAMS, + + + CHAR_LOAD_PETITION, + CHAR_LOAD_PETITION_SIGNATURE, + MAX_CHARACTERDATABASE_STATEMENTS, }; |