aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/server/database/Database/Implementation/CharacterDatabase.cpp9
-rw-r--r--src/server/database/Database/Implementation/CharacterDatabase.h5
-rw-r--r--src/server/game/Battlegrounds/ArenaTeam.cpp7
-rw-r--r--src/server/game/Calendar/CalendarMgr.cpp8
-rw-r--r--src/server/game/Chat/Chat.cpp6
-rw-r--r--src/server/game/Entities/Creature/Creature.cpp2
-rw-r--r--src/server/game/Entities/GameObject/GameObject.cpp4
-rw-r--r--src/server/game/Entities/Player/Player.cpp125
-rw-r--r--src/server/game/Entities/Player/Player.h10
-rw-r--r--src/server/game/Events/GameEventMgr.cpp17
-rw-r--r--src/server/game/Events/GameEventMgr.h2
-rw-r--r--src/server/game/Globals/ObjectMgr.cpp20
-rw-r--r--src/server/game/Globals/ObjectMgr.h2
-rw-r--r--src/server/game/Guilds/Guild.cpp11
-rw-r--r--src/server/game/Handlers/CalendarHandler.cpp17
-rw-r--r--src/server/game/Handlers/CharacterHandler.cpp16
-rw-r--r--src/server/game/Handlers/MailHandler.cpp20
-rw-r--r--src/server/game/Handlers/NPCHandler.cpp6
-rw-r--r--src/server/game/Handlers/SocialHandler.cpp71
-rw-r--r--src/server/game/Handlers/SpellHandler.cpp83
-rw-r--r--src/server/game/Maps/Map.cpp12
-rw-r--r--src/server/game/Quests/QuestDef.cpp1
-rw-r--r--src/server/game/Quests/QuestDef.h4
-rw-r--r--src/server/game/Server/WorldSession.cpp18
-rw-r--r--src/server/game/Server/WorldSession.h18
-rw-r--r--src/server/game/World/World.cpp70
-rw-r--r--src/server/game/World/World.h10
-rw-r--r--src/server/scripts/Commands/cs_arena.cpp2
-rw-r--r--src/server/scripts/Commands/cs_ban.cpp2
-rw-r--r--src/server/scripts/Commands/cs_character.cpp11
-rw-r--r--src/server/scripts/Commands/cs_guild.cpp4
-rw-r--r--src/server/scripts/Commands/cs_misc.cpp2
-rw-r--r--src/server/scripts/Commands/cs_ticket.cpp2
33 files changed, 299 insertions, 298 deletions
diff --git a/src/server/database/Database/Implementation/CharacterDatabase.cpp b/src/server/database/Database/Implementation/CharacterDatabase.cpp
index 11604c63616..2b32f9f0a60 100644
--- a/src/server/database/Database/Implementation/CharacterDatabase.cpp
+++ b/src/server/database/Database/Implementation/CharacterDatabase.cpp
@@ -34,7 +34,6 @@ void CharacterDatabaseConnection::DoPrepareStatements()
PrepareStatement(CHAR_INS_QUEST_POOL_SAVE, "INSERT INTO pool_quest_save (pool_id, quest_id) VALUES (?, ?)", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_NONEXISTENT_GUILD_BANK_ITEM, "DELETE FROM guild_bank_item WHERE guildid = ? AND TabId = ? AND SlotId = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_EXPIRED_BANS, "UPDATE character_banned SET active = 0 WHERE unbandate <= UNIX_TIMESTAMP() AND unbandate <> bandate", CONNECTION_ASYNC);
- PrepareStatement(CHAR_SEL_GUID_BY_NAME, "SELECT guid FROM characters WHERE name = ?", CONNECTION_BOTH);
PrepareStatement(CHAR_SEL_CHECK_NAME, "SELECT 1 FROM characters WHERE name = ?", CONNECTION_BOTH);
PrepareStatement(CHAR_SEL_CHECK_GUID, "SELECT 1 FROM characters WHERE guid = ?", CONNECTION_SYNCH);
PrepareStatement(CHAR_SEL_SUM_CHARS, "SELECT COUNT(guid) FROM characters WHERE account = ?", CONNECTION_BOTH);
@@ -69,8 +68,6 @@ void CharacterDatabaseConnection::DoPrepareStatements()
"LEFT JOIN character_declinedname AS cd ON c.guid = cd.guid LEFT JOIN guild_member AS gm ON c.guid = gm.guid "
"LEFT JOIN character_banned AS cb ON c.guid = cb.guid AND cb.active = 1 WHERE c.deleteInfos_Account = ? AND c.deleteInfos_Name IS NOT NULL", CONNECTION_ASYNC);
PrepareStatement(CHAR_SEL_FREE_NAME, "SELECT name, at_login FROM characters WHERE guid = ? AND NOT EXISTS (SELECT NULL FROM characters WHERE name = ?)", CONNECTION_ASYNC);
- PrepareStatement(CHAR_SEL_GUID_RACE_ACC_BY_NAME, "SELECT guid, race, account FROM characters WHERE name = ?", CONNECTION_BOTH);
- PrepareStatement(CHAR_SEL_CHAR_LEVEL, "SELECT level FROM characters WHERE guid = ?", CONNECTION_SYNCH);
PrepareStatement(CHAR_SEL_CHAR_ZONE, "SELECT zone FROM characters WHERE guid = ?", CONNECTION_SYNCH);
PrepareStatement(CHAR_SEL_CHAR_POSITION_XYZ, "SELECT map, position_x, position_y, position_z FROM characters WHERE guid = ?", CONNECTION_SYNCH);
PrepareStatement(CHAR_SEL_CHAR_POSITION, "SELECT position_x, position_y, position_z, orientation, map, taxi_path FROM characters WHERE guid = ?", CONNECTION_SYNCH);
@@ -146,7 +143,7 @@ void CharacterDatabaseConnection::DoPrepareStatements()
PrepareStatement(CHAR_SEL_CHARACTER_QUESTSTATUSREW, "SELECT quest FROM character_queststatus_rewarded WHERE guid = ? AND active = 1", CONNECTION_ASYNC);
PrepareStatement(CHAR_SEL_ACCOUNT_INSTANCELOCKTIMES, "SELECT instanceId, releaseTime FROM account_instance_times WHERE accountId = ?", CONNECTION_ASYNC);
- PrepareStatement(CHAR_SEL_CHARACTER_ACTIONS_SPEC, "SELECT button, action, type FROM character_action WHERE guid = ? AND spec = ? ORDER BY button", CONNECTION_SYNCH);
+ PrepareStatement(CHAR_SEL_CHARACTER_ACTIONS_SPEC, "SELECT button, action, type FROM character_action WHERE guid = ? AND spec = ? ORDER BY button", CONNECTION_ASYNC);
PrepareStatement(CHAR_SEL_MAILITEMS, "SELECT " SelectItemInstanceContent ", ii.owner_guid FROM mail_items mi JOIN item_instance ii ON mi.item_guid = ii.guid LEFT JOIN item_instance_gems ig ON ii.guid = ig.itemGuid LEFT JOIN item_instance_transmog iit ON ii.guid = iit.itemGuid LEFT JOIN item_instance_modifiers im ON ii.guid = im.itemGuid WHERE mail_id = ?", CONNECTION_SYNCH);
PrepareStatement(CHAR_SEL_AUCTION_ITEMS, "SELECT " SelectItemInstanceContent " FROM auctionhouse ah JOIN item_instance ii ON ah.itemguid = ii.guid LEFT JOIN item_instance_gems ig ON ii.guid = ig.itemGuid LEFT JOIN item_instance_transmog iit ON ii.guid = iit.itemGuid LEFT JOIN item_instance_modifiers im ON ii.guid = im.itemGuid", CONNECTION_SYNCH);
PrepareStatement(CHAR_SEL_AUCTIONS, "SELECT id, auctioneerguid, itemguid, itemEntry, count, itemowner, buyoutprice, time, buyguid, lastbid, startbid, deposit FROM auctionhouse ah INNER JOIN item_instance ii ON ii.guid = ah.itemguid", CONNECTION_SYNCH);
@@ -194,7 +191,7 @@ void CharacterDatabaseConnection::DoPrepareStatements()
PrepareStatement(CHAR_DEL_ITEM_INSTANCE_MODIFIERS_BY_OWNER, "DELETE im FROM item_instance_modifiers im LEFT JOIN item_instance ii ON im.itemGuid = ii.guid WHERE ii.owner_guid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_UPD_GIFT_OWNER, "UPDATE character_gifts SET guid = ? WHERE item_guid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_GIFT, "DELETE FROM character_gifts WHERE item_guid = ?", CONNECTION_ASYNC);
- PrepareStatement(CHAR_SEL_CHARACTER_GIFT_BY_ITEM, "SELECT entry, flags FROM character_gifts WHERE item_guid = ?", CONNECTION_SYNCH);
+ PrepareStatement(CHAR_SEL_CHARACTER_GIFT_BY_ITEM, "SELECT entry, flags FROM character_gifts WHERE item_guid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_SEL_ACCOUNT_BY_NAME, "SELECT account FROM characters WHERE name = ?", CONNECTION_SYNCH);
PrepareStatement(CHAR_UPD_ACCOUNT_BY_GUID, "UPDATE characters SET account = ? WHERE guid = ?", CONNECTION_SYNCH);
PrepareStatement(CHAR_DEL_ACCOUNT_INSTANCE_LOCK_TIMES, "DELETE FROM account_instance_times WHERE accountId = ?", CONNECTION_ASYNC);
@@ -361,7 +358,6 @@ void CharacterDatabaseConnection::DoPrepareStatements()
PrepareStatement(CHAR_UPD_ARENA_TEAM_MEMBER, "UPDATE arena_team_member SET personalRating = ?, weekGames = ?, weekWins = ?, seasonGames = ?, seasonWins = ? WHERE arenaTeamId = ? AND guid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_CHARACTER_ARENA_STATS, "DELETE FROM character_arena_stats WHERE guid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_REP_CHARACTER_ARENA_STATS, "REPLACE INTO character_arena_stats (guid, slot, matchMakerRating) VALUES (?, ?, ?)", CONNECTION_ASYNC);
- PrepareStatement(CHAR_SEL_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);
PrepareStatement(CHAR_UPD_ARENA_TEAM_NAME, "UPDATE arena_team SET name = ? WHERE arenaTeamId = ?", CONNECTION_ASYNC);
// Character battleground data
@@ -507,7 +503,6 @@ void CharacterDatabaseConnection::DoPrepareStatements()
PrepareStatement(CHAR_SEL_CHAR_COD_ITEM_MAIL, "SELECT id, messageType, mailTemplateId, sender, subject, body, money, has_items FROM mail WHERE receiver = ? AND has_items <> 0 AND cod <> 0", CONNECTION_SYNCH);
PrepareStatement(CHAR_SEL_CHAR_SOCIAL, "SELECT DISTINCT guid FROM character_social WHERE friend = ?", CONNECTION_SYNCH);
PrepareStatement(CHAR_SEL_CHAR_OLD_CHARS, "SELECT guid, deleteInfos_Account FROM characters WHERE deleteDate IS NOT NULL AND deleteDate < ?", CONNECTION_SYNCH);
- PrepareStatement(CHAR_SEL_ARENA_TEAM_ID_BY_PLAYER_GUID, "SELECT arena_team_member.arenateamid FROM arena_team_member JOIN arena_team ON arena_team_member.arenateamid = arena_team.arenateamid WHERE guid = ? AND type = ? LIMIT 1", CONNECTION_SYNCH);
PrepareStatement(CHAR_SEL_MAIL, "SELECT id, messageType, sender, receiver, subject, body, has_items, expire_time, deliver_time, money, cod, checked, stationery, mailTemplateId FROM mail WHERE receiver = ? ORDER BY id DESC", CONNECTION_SYNCH);
PrepareStatement(CHAR_DEL_CHAR_AURA_FROZEN, "DELETE FROM character_aura WHERE spell = 9454 AND guid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_SEL_CHAR_INVENTORY_COUNT_ITEM, "SELECT COUNT(itemEntry) FROM character_inventory ci INNER JOIN item_instance ii ON ii.guid = ci.item WHERE itemEntry = ?", CONNECTION_SYNCH);
diff --git a/src/server/database/Database/Implementation/CharacterDatabase.h b/src/server/database/Database/Implementation/CharacterDatabase.h
index e98697227a5..306f545540a 100644
--- a/src/server/database/Database/Implementation/CharacterDatabase.h
+++ b/src/server/database/Database/Implementation/CharacterDatabase.h
@@ -32,7 +32,6 @@ enum CharacterDatabaseStatements : uint32
CHAR_INS_QUEST_POOL_SAVE,
CHAR_DEL_NONEXISTENT_GUILD_BANK_ITEM,
CHAR_DEL_EXPIRED_BANS,
- CHAR_SEL_GUID_BY_NAME,
CHAR_SEL_CHECK_NAME,
CHAR_SEL_CHECK_GUID,
CHAR_SEL_SUM_CHARS,
@@ -52,8 +51,6 @@ enum CharacterDatabaseStatements : uint32
CHAR_SEL_UNDELETE_ENUM,
CHAR_SEL_UNDELETE_ENUM_DECLINED_NAME,
CHAR_SEL_FREE_NAME,
- CHAR_SEL_GUID_RACE_ACC_BY_NAME,
- CHAR_SEL_CHAR_LEVEL,
CHAR_SEL_CHAR_ZONE,
CHAR_SEL_CHAR_POSITION_XYZ,
CHAR_SEL_CHAR_POSITION,
@@ -280,7 +277,6 @@ enum CharacterDatabaseStatements : uint32
CHAR_UPD_ARENA_TEAM_MEMBER,
CHAR_DEL_CHARACTER_ARENA_STATS,
CHAR_REP_CHARACTER_ARENA_STATS,
- CHAR_SEL_PLAYER_ARENA_TEAMS,
CHAR_UPD_ARENA_TEAM_NAME,
CHAR_SEL_PETITION,
@@ -413,7 +409,6 @@ enum CharacterDatabaseStatements : uint32
CHAR_SEL_CHAR_COD_ITEM_MAIL,
CHAR_SEL_CHAR_SOCIAL,
CHAR_SEL_CHAR_OLD_CHARS,
- CHAR_SEL_ARENA_TEAM_ID_BY_PLAYER_GUID,
CHAR_SEL_MAIL,
CHAR_DEL_CHAR_AURA_FROZEN,
CHAR_SEL_CHAR_INVENTORY_COUNT_ITEM,
diff --git a/src/server/game/Battlegrounds/ArenaTeam.cpp b/src/server/game/Battlegrounds/ArenaTeam.cpp
index e1e9f928f6e..61661093479 100644
--- a/src/server/game/Battlegrounds/ArenaTeam.cpp
+++ b/src/server/game/Battlegrounds/ArenaTeam.cpp
@@ -114,7 +114,7 @@ bool ArenaTeam::AddMember(ObjectGuid playerGuid)
return false;
// Check if player is already in a similar arena team
- if ((player && player->GetArenaTeamId(GetSlot())) || Player::GetArenaTeamIdFromDB(playerGuid, GetType()) != 0)
+ if ((player && player->GetArenaTeamId(GetSlot())) || Player::GetArenaTeamIdFromCharacterInfo(playerGuid, GetType()) != 0)
{
TC_LOG_DEBUG("bg.arena", "Arena: %s %s already has an arena team of type %u", playerGuid.ToString().c_str(), playerName.c_str(), GetType());
return false;
@@ -157,6 +157,7 @@ bool ArenaTeam::AddMember(ObjectGuid playerGuid)
newMember.MatchMakerRating = matchMakerRating;
Members.push_back(newMember);
+ sWorld->UpdateCharacterArenaTeamId(playerGuid, GetSlot(), GetId());
// Save player's arena team membership to db
stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_ARENA_TEAM_MEMBER);
@@ -252,6 +253,7 @@ bool ArenaTeam::LoadMembersFromDB(QueryResult result)
// Put the player in the team
Members.push_back(newMember);
+ sWorld->UpdateCharacterArenaTeamId(newMember.Guid, GetSlot(), GetId());
}
while (result->NextRow());
@@ -311,11 +313,14 @@ void ArenaTeam::DelMember(ObjectGuid guid, bool cleanDb)
{
// Remove member from team
for (MemberList::iterator itr = Members.begin(); itr != Members.end(); ++itr)
+ {
if (itr->Guid == guid)
{
Members.erase(itr);
+ sWorld->UpdateCharacterArenaTeamId(guid, GetSlot(), 0);
break;
}
+ }
// Remove arena team info from player data
if (Player* player = ObjectAccessor::FindPlayer(guid))
diff --git a/src/server/game/Calendar/CalendarMgr.cpp b/src/server/game/Calendar/CalendarMgr.cpp
index 2502ed30c3b..c699c2e075c 100644
--- a/src/server/game/Calendar/CalendarMgr.cpp
+++ b/src/server/game/Calendar/CalendarMgr.cpp
@@ -78,7 +78,7 @@ void CalendarMgr::LoadFromDB()
ObjectGuid::LowType guildID = UI64LIT(0);
if (flags & CALENDAR_FLAG_GUILD_EVENT || flags & CALENDAR_FLAG_WITHOUT_INVITES)
- guildID = Player::GetGuildIdFromDB(ownerGUID);
+ guildID = Player::GetGuildIdFromCharacterInfo(ownerGUID);
CalendarEvent* calendarEvent = new CalendarEvent(eventID, ownerGUID, guildID, type, textureID, time_t(date), flags, title, description, time_t(lockDate));
_events.insert(calendarEvent);
@@ -433,7 +433,7 @@ void CalendarMgr::SendCalendarEventInvite(CalendarInvite const& invite)
ObjectGuid invitee = invite.GetInviteeGUID();
Player* player = ObjectAccessor::FindConnectedPlayer(invitee);
- uint8 level = player ? player->getLevel() : Player::GetLevelFromDB(invitee);
+ uint8 level = player ? player->getLevel() : Player::GetLevelFromCharacterInfo(invitee);
WorldPackets::Calendar::SCalendarEventInvite packet;
packet.EventID = calendarEvent ? calendarEvent->GetEventId() : 0;
@@ -572,8 +572,8 @@ void CalendarMgr::SendCalendarEvent(ObjectGuid guid, CalendarEvent const& calend
ObjectGuid inviteeGuid = calendarInvite->GetInviteeGUID();
Player* invitee = ObjectAccessor::FindPlayer(inviteeGuid);
- uint8 inviteeLevel = invitee ? invitee->getLevel() : Player::GetLevelFromDB(inviteeGuid);
- ObjectGuid::LowType inviteeGuildId = invitee ? invitee->GetGuildId() : Player::GetGuildIdFromDB(inviteeGuid);
+ uint8 inviteeLevel = invitee ? invitee->getLevel() : Player::GetLevelFromCharacterInfo(inviteeGuid);
+ ObjectGuid::LowType inviteeGuildId = invitee ? invitee->GetGuildId() : Player::GetGuildIdFromCharacterInfo(inviteeGuid);
WorldPackets::Calendar::CalendarEventInviteInfo inviteInfo;
inviteInfo.Guid = inviteeGuid;
diff --git a/src/server/game/Chat/Chat.cpp b/src/server/game/Chat/Chat.cpp
index a48d1536766..ead2eb05498 100644
--- a/src/server/game/Chat/Chat.cpp
+++ b/src/server/game/Chat/Chat.cpp
@@ -937,7 +937,7 @@ ObjectGuid::LowType ChatHandler::extractLowGuidFromLink(char* text, HighGuid& gu
if (Player* player = ObjectAccessor::FindPlayerByName(name))
return player->GetGUID().GetCounter();
- ObjectGuid guid = ObjectMgr::GetPlayerGUIDByName(name);
+ ObjectGuid guid = sWorld->GetCharacterGuidByName(name);
if (guid.IsEmpty())
return 0;
@@ -994,7 +994,7 @@ bool ChatHandler::extractPlayerTarget(char* args, Player** player, ObjectGuid* p
*player = pl;
// if need guid value from DB (in name case for check player existence)
- ObjectGuid guid = !pl && (player_guid || player_name) ? ObjectMgr::GetPlayerGUIDByName(name) : ObjectGuid::Empty;
+ ObjectGuid guid = !pl && (player_guid || player_name) ? sWorld->GetCharacterGuidByName(name) : ObjectGuid::Empty;
// if allowed player guid (if no then only online players allowed)
if (player_guid)
@@ -1153,7 +1153,7 @@ bool ChatHandler::GetPlayerGroupAndGUIDByName(const char* cname, Player*& player
player = ObjectAccessor::FindPlayerByName(name);
if (offline)
- guid = ObjectMgr::GetPlayerGUIDByName(name.c_str());
+ guid = sWorld->GetCharacterGuidByName(name);
}
}
diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp
index 7c4361bf39a..e8a5eafe527 100644
--- a/src/server/game/Entities/Creature/Creature.cpp
+++ b/src/server/game/Entities/Creature/Creature.cpp
@@ -274,7 +274,7 @@ void Creature::RemoveCorpse(bool setSpawnTime)
m_corpseRemoveTime = time(NULL);
setDeathState(DEAD);
RemoveAllAuras();
- UpdateObjectVisibility();
+ DestroyForNearbyPlayers(); // old UpdateObjectVisibility()
loot.clear();
uint32 respawnDelay = m_respawnDelay;
if (IsAIEnabled)
diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp
index 4f0294aafe5..a2e58bccdd2 100644
--- a/src/server/game/Entities/GameObject/GameObject.cpp
+++ b/src/server/game/Entities/GameObject/GameObject.cpp
@@ -817,7 +817,7 @@ void GameObject::Update(uint32 diff)
if (!m_spawnedByDefault)
{
m_respawnTime = 0;
- UpdateObjectVisibility();
+ DestroyForNearbyPlayers(); // old UpdateObjectVisibility()
return;
}
@@ -827,7 +827,7 @@ void GameObject::Update(uint32 diff)
if (sWorld->getBoolConfig(CONFIG_SAVE_RESPAWN_TIME_IMMEDIATELY))
SaveRespawnTime();
- UpdateObjectVisibility();
+ DestroyForNearbyPlayers(); // old UpdateObjectVisibility()
break;
}
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index 476e2553966..ba5035e74ca 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -88,6 +88,7 @@
#include "Pet.h"
#include "PetPackets.h"
#include "PhasingHandler.h"
+#include "QueryCallback.h"
#include "QueryHolder.h"
#include "QuestDef.h"
#include "QuestObjectiveCriteriaMgr.h"
@@ -3704,7 +3705,7 @@ void Player::DestroyForPlayer(Player* target) const
{
Unit::DestroyForPlayer(target);
- for (uint8 i = 0; i < INVENTORY_SLOT_BAG_END; ++i)
+ for (uint8 i = 0; i < EQUIPMENT_SLOT_END; ++i)
{
if (m_items[i] == nullptr)
continue;
@@ -3788,10 +3789,14 @@ void Player::DeleteFromDB(ObjectGuid playerguid, uint32 accountId, bool updateRe
// Convert guid to low GUID for CharacterNameData, but also other methods on success
ObjectGuid::LowType guid = playerguid.GetCounter();
uint32 charDeleteMethod = sWorld->getIntConfig(CONFIG_CHARDELETE_METHOD);
+ CharacterInfo const* characterInfo = sWorld->GetCharacterInfo(playerguid);
+ std::string name;
+ if (characterInfo)
+ name = characterInfo->Name;
if (deleteFinally)
charDeleteMethod = CHAR_DELETE_REMOVE;
- else if (CharacterInfo const* characterInfo = sWorld->GetCharacterInfo(playerguid)) // To avoid a query, we select loaded data. If it doesn't exist, return.
+ else if (characterInfo) // To avoid a query, we select loaded data. If it doesn't exist, return.
{
// Define the required variables
uint32 charDeleteMinLvl;
@@ -3810,7 +3815,7 @@ void Player::DeleteFromDB(ObjectGuid playerguid, uint32 accountId, bool updateRe
}
SQLTransaction trans = CharacterDatabase.BeginTransaction();
- if (ObjectGuid::LowType guildId = GetGuildIdFromDB(playerguid))
+ if (ObjectGuid::LowType guildId = Player::GetGuildIdFromCharacterInfo(playerguid))
if (Guild* guild = sGuildMgr->GetGuildById(guildId))
guild->DeleteMember(trans, playerguid, false, false, true);
@@ -4159,7 +4164,7 @@ void Player::DeleteFromDB(ObjectGuid playerguid, uint32 accountId, bool updateRe
Garrison::DeleteFromDB(guid, trans);
- sWorld->DeleteCharacterInfo(playerguid);
+ sWorld->DeleteCharacterInfo(playerguid, name);
break;
}
// The character gets unlinked from the account, the name gets freed up and appears as deleted ingame
@@ -6934,26 +6939,17 @@ void Player::SetInGuild(ObjectGuid::LowType guildId)
SetUpdateFieldValue(m_values.ModifyValue(&Unit::m_unitData).ModifyValue(&UF::UnitData::GuildGUID), ObjectGuid::Empty);
RemovePlayerFlag(PLAYER_FLAGS_GUILD_LEVEL_ENABLED);
}
-}
-
-ObjectGuid::LowType Player::GetGuildIdFromDB(ObjectGuid guid)
-{
- PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_GUILD_MEMBER);
- stmt->setUInt64(0, guid.GetCounter());
- if (PreparedQueryResult result = CharacterDatabase.Query(stmt))
- return result->Fetch()[0].GetUInt64();
- return UI64LIT(0);
+ sWorld->UpdateCharacterGuildId(GetGUID(), guildId);
}
-uint8 Player::GetRankFromDB(ObjectGuid guid)
+ObjectGuid::LowType Player::GetGuildIdFromCharacterInfo(ObjectGuid guid)
{
- PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_GUILD_MEMBER);
- stmt->setUInt64(0, guid.GetCounter());
- if (PreparedQueryResult result = CharacterDatabase.Query(stmt))
- return result->Fetch()[1].GetUInt8();
+ CharacterInfo const* characterInfo = sWorld->GetCharacterInfo(guid);
+ if (!characterInfo)
+ return UI64LIT(0);
- return 0;
+ return characterInfo->GuildId;
}
void Player::SetArenaTeamInfoField(uint8 /*slot*/, ArenaTeamInfoType /*type*/, uint32 /*value*/)
@@ -6966,18 +6962,13 @@ void Player::SetInArenaTeam(uint32 ArenaTeamId, uint8 slot, uint8 type)
SetArenaTeamInfoField(slot, ARENA_TEAM_TYPE, type);
}
-uint32 Player::GetArenaTeamIdFromDB(ObjectGuid guid, uint8 type)
+uint32 Player::GetArenaTeamIdFromCharacterInfo(ObjectGuid guid, uint8 type)
{
- PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_ARENA_TEAM_ID_BY_PLAYER_GUID);
- stmt->setUInt64(0, guid.GetCounter());
- stmt->setUInt8(1, type);
- PreparedQueryResult result = CharacterDatabase.Query(stmt);
-
- if (!result)
+ CharacterInfo const* characterInfo = sWorld->GetCharacterInfo(guid);
+ if (!characterInfo)
return 0;
- uint32 id = (*result)[0].GetUInt32();
- return id;
+ return characterInfo->ArenaTeamId[type];
}
uint32 Player::GetZoneIdFromDB(ObjectGuid guid)
@@ -7026,19 +7017,13 @@ uint32 Player::GetZoneIdFromDB(ObjectGuid guid)
return zone;
}
-uint32 Player::GetLevelFromDB(ObjectGuid guid)
+uint32 Player::GetLevelFromCharacterInfo(ObjectGuid guid)
{
- PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_LEVEL);
- stmt->setUInt64(0, guid.GetCounter());
- PreparedQueryResult result = CharacterDatabase.Query(stmt);
-
- if (!result)
+ CharacterInfo const* characterInfo = sWorld->GetCharacterInfo(guid);
+ if (!characterInfo)
return 0;
- Field* fields = result->Fetch();
- uint8 level = fields[0].GetUInt8();
-
- return level;
+ return characterInfo->Level;
}
void Player::UpdateArea(uint32 newArea)
@@ -16028,17 +16013,17 @@ bool Player::SatisfyQuestWeek(Quest const* qInfo, bool /*msg*/)
return m_weeklyquests.find(qInfo->GetQuestId()) == m_weeklyquests.end();
}
-bool Player::SatisfyQuestSeasonal(Quest const* qInfo, bool /*msg*/)
+bool Player::SatisfyQuestSeasonal(Quest const* qInfo, bool /*msg*/) const
{
if (!qInfo->IsSeasonal() || m_seasonalquests.empty())
return true;
- uint16 eventId = sGameEventMgr->GetEventIdForQuest(qInfo);
- if (m_seasonalquests.find(eventId) == m_seasonalquests.end() || m_seasonalquests[eventId].empty())
+ auto itr = m_seasonalquests.find(qInfo->GetEventIdForQuest());
+ if (itr == m_seasonalquests.end() || itr->second.empty())
return true;
// if not found in cooldown list
- return m_seasonalquests[eventId].find(qInfo->GetQuestId()) == m_seasonalquests[eventId].end();
+ return itr->second.find(qInfo->GetQuestId()) == itr->second.end();
}
bool Player::SatisfyQuestMonth(Quest const* qInfo, bool /*msg*/)
@@ -16125,14 +16110,7 @@ bool Player::GetQuestRewardStatus(uint32 quest_id) const
if (qInfo)
{
if (qInfo->IsSeasonal() && !qInfo->IsRepeatable())
- {
- uint16 eventId = sGameEventMgr->GetEventIdForQuest(qInfo);
- auto seasonalQuestItr = m_seasonalquests.find(eventId);
- if (seasonalQuestItr != m_seasonalquests.end())
- return seasonalQuestItr->second.find(quest_id) != seasonalQuestItr->second.end();
-
- return false;
- }
+ return !SatisfyQuestSeasonal(qInfo, false);
// for repeatable quests: rewarded field is set after first reward only to prevent getting XP more than once
@@ -16155,14 +16133,9 @@ QuestStatus Player::GetQuestStatus(uint32 quest_id) const
if (Quest const* qInfo = sObjectMgr->GetQuestTemplate(quest_id))
{
if (qInfo->IsSeasonal() && !qInfo->IsRepeatable())
- {
- uint16 eventId = sGameEventMgr->GetEventIdForQuest(qInfo);
- auto seasonalQuestItr = m_seasonalquests.find(eventId);
- if (seasonalQuestItr == m_seasonalquests.end() || seasonalQuestItr->second.find(quest_id) == seasonalQuestItr->second.end())
- return QUEST_STATUS_NONE;
- }
+ return SatisfyQuestSeasonal(qInfo, false) ? QUEST_STATUS_NONE : QUEST_STATUS_REWARDED;
- if (!qInfo->IsRepeatable() && m_RewardedQuests.find(quest_id) != m_RewardedQuests.end())
+ if (!qInfo->IsRepeatable() && IsQuestRewarded(quest_id))
return QUEST_STATUS_REWARDED;
}
}
@@ -22025,17 +21998,13 @@ void Player::RemovePetitionsAndSigns(ObjectGuid guid)
void Player::LeaveAllArenaTeams(ObjectGuid guid)
{
- PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_PLAYER_ARENA_TEAMS);
- stmt->setUInt64(0, guid.GetCounter());
- PreparedQueryResult result = CharacterDatabase.Query(stmt);
-
- if (!result)
+ CharacterInfo const* characterInfo = sWorld->GetCharacterInfo(guid);
+ if (!characterInfo)
return;
- do
+ for (uint8 i = 0; i < MAX_ARENA_SLOT; ++i)
{
- Field* fields = result->Fetch();
- uint32 arenaTeamId = fields[0].GetUInt32();
+ uint32 arenaTeamId = characterInfo->ArenaTeamId[i];
if (arenaTeamId != 0)
{
ArenaTeam* arenaTeam = sArenaTeamMgr->GetArenaTeamById(arenaTeamId);
@@ -22043,7 +22012,6 @@ void Player::LeaveAllArenaTeams(ObjectGuid guid)
arenaTeam->DelMember(guid, true);
}
}
- while (result->NextRow());
}
bool Player::ActivateTaxiPathTo(std::vector<uint32> const& nodes, Creature* npc /*= nullptr*/, uint32 spellid /*= 0*/, uint32 preferredMountDisplay /*= 0*/)
@@ -24222,7 +24190,7 @@ void Player::SetSeasonalQuestStatus(uint32 quest_id)
if (!quest)
return;
- m_seasonalquests[sGameEventMgr->GetEventIdForQuest(quest)].insert(quest_id);
+ m_seasonalquests[quest->GetEventIdForQuest()].insert(quest_id);
m_SeasonalQuestChanged = true;
}
@@ -26997,15 +26965,22 @@ void Player::ActivateTalentGroup(ChrSpecializationEntry const* spec)
InitTalentForLevel();
+ // load them asynchronously
{
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHARACTER_ACTIONS_SPEC);
stmt->setUInt64(0, GetGUID().GetCounter());
stmt->setUInt8(1, GetActiveTalentGroup());
- if (PreparedQueryResult result = CharacterDatabase.Query(stmt))
- _LoadActions(result);
- }
- SendActionButtons(1);
+ WorldSession* mySess = GetSession();
+ mySess->GetQueryProcessor().AddQuery(CharacterDatabase.AsyncQuery(stmt)
+ .WithPreparedCallback([mySess](PreparedQueryResult result)
+ {
+ // safe callback, we can't pass this pointer directly
+ // in case player logs out before db response (player would be deleted in that case)
+ if (Player* thisPlayer = mySess->GetPlayer())
+ thisPlayer->LoadActions(result);
+ }));
+ }
UpdateDisplayPower();
Powers pw = GetPowerType();
@@ -27041,6 +27016,14 @@ void Player::ActivateTalentGroup(ChrSpecializationEntry const* spec)
}
}
+void Player::LoadActions(PreparedQueryResult result)
+{
+ if (result)
+ _LoadActions(result);
+
+ SendActionButtons(1);
+}
+
void Player::ResetTimeSync()
{
m_timeSyncTimer = 0;
diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h
index b23ed7f7fae..a482ad4c5c1 100644
--- a/src/server/game/Entities/Player/Player.h
+++ b/src/server/game/Entities/Player/Player.h
@@ -1336,7 +1336,7 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
bool SatisfyQuestDay(Quest const* qInfo, bool msg) const;
bool SatisfyQuestWeek(Quest const* qInfo, bool msg);
bool SatisfyQuestMonth(Quest const* qInfo, bool msg);
- bool SatisfyQuestSeasonal(Quest const* qInfo, bool msg);
+ bool SatisfyQuestSeasonal(Quest const* qInfo, bool msg) const;
bool GiveQuestSourceItem(Quest const* quest);
bool TakeQuestSourceItem(uint32 questId, bool msg);
bool GetQuestRewardStatus(uint32 quest_id) const;
@@ -1437,7 +1437,7 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
static uint32 GetUInt32ValueFromArray(Tokenizer const& data, uint16 index);
static float GetFloatValueFromArray(Tokenizer const& data, uint16 index);
static uint32 GetZoneIdFromDB(ObjectGuid guid);
- static uint32 GetLevelFromDB(ObjectGuid guid);
+ static uint32 GetLevelFromCharacterInfo(ObjectGuid guid);
static bool LoadPositionFromDB(uint32& mapid, float& x, float& y, float& z, float& o, bool& in_flight, ObjectGuid guid);
static bool IsValidGender(uint8 Gender) { return Gender <= GENDER_FEMALE; }
@@ -1610,6 +1610,7 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
std::vector<uint32> const& GetGlyphs(uint8 spec) const { return _specializationInfo.Glyphs[spec]; }
std::vector<uint32>& GetGlyphs(uint8 spec) { return _specializationInfo.Glyphs[spec]; }
ActionButtonList const& GetActionButtons() const { return m_actionButtons; }
+ void LoadActions(PreparedQueryResult result);
uint32 GetFreePrimaryProfessionPoints() const { return m_activePlayerData->CharacterPoints; }
void SetFreePrimaryProfessions(uint16 profs) { SetUpdateFieldValue(m_values.ModifyValue(&Player::m_activePlayerData).ModifyValue(&UF::ActivePlayerData::CharacterPoints), profs); }
@@ -1703,15 +1704,14 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
ObjectGuid::LowType GetGuildId() const { return m_unitData->GuildGUID->GetCounter(); /* return only lower part */ }
Guild* GetGuild();
Guild const* GetGuild() const;
- static ObjectGuid::LowType GetGuildIdFromDB(ObjectGuid guid);
- static uint8 GetRankFromDB(ObjectGuid guid);
+ static ObjectGuid::LowType GetGuildIdFromCharacterInfo(ObjectGuid guid);
ObjectGuid::LowType GetGuildIdInvited() const { return m_GuildIdInvited; }
static void RemovePetitionsAndSigns(ObjectGuid guid);
// Arena Team
void SetInArenaTeam(uint32 ArenaTeamId, uint8 slot, uint8 type);
void SetArenaTeamInfoField(uint8 slot, ArenaTeamInfoType type, uint32 value);
- static uint32 GetArenaTeamIdFromDB(ObjectGuid guid, uint8 slot);
+ static uint32 GetArenaTeamIdFromCharacterInfo(ObjectGuid guid, uint8 slot);
static void LeaveAllArenaTeams(ObjectGuid guid);
uint32 GetArenaTeamId(uint8 /*slot*/) const { return 0; }
uint32 GetArenaPersonalRating(uint8 slot) const { return m_activePlayerData->PvpInfo[slot].Rating; }
diff --git a/src/server/game/Events/GameEventMgr.cpp b/src/server/game/Events/GameEventMgr.cpp
index 2f3102f5e65..3969caedba3 100644
--- a/src/server/game/Events/GameEventMgr.cpp
+++ b/src/server/game/Events/GameEventMgr.cpp
@@ -767,7 +767,8 @@ void GameEventMgr::LoadFromDB()
uint32 questId = fields[0].GetUInt32();
uint32 eventEntry = fields[1].GetUInt32(); /// @todo Change to uint8
- if (!sObjectMgr->GetQuestTemplate(questId))
+ Quest* questTemplate = const_cast<Quest*>(sObjectMgr->GetQuestTemplate(questId));
+ if (!questTemplate)
{
TC_LOG_ERROR("sql.sql", "`game_event_seasonal_questrelation`: quest id (%u) does not exist in `quest_template`.", questId);
continue;
@@ -779,7 +780,7 @@ void GameEventMgr::LoadFromDB()
continue;
}
- _questToEventLinks[questId] = eventEntry;
+ questTemplate->SetEventIdForQuest(static_cast<uint16>(eventEntry));
++count;
}
while (result->NextRow());
@@ -1682,18 +1683,6 @@ void GameEventMgr::RunSmartAIScripts(uint16 event_id, bool activate)
});
}
-uint16 GameEventMgr::GetEventIdForQuest(Quest const* quest) const
-{
- if (!quest)
- return 0;
-
- std::unordered_map<uint32, uint16>::const_iterator itr = _questToEventLinks.find(quest->GetQuestId());
- if (itr == _questToEventLinks.end())
- return 0;
-
- return itr->second;
-}
-
bool IsHolidayActive(HolidayIds id)
{
if (id == HOLIDAY_NONE)
diff --git a/src/server/game/Events/GameEventMgr.h b/src/server/game/Events/GameEventMgr.h
index 2786485c1a1..d83f7edb5bd 100644
--- a/src/server/game/Events/GameEventMgr.h
+++ b/src/server/game/Events/GameEventMgr.h
@@ -118,7 +118,6 @@ class TC_GAME_API GameEventMgr
void HandleWorldEventGossip(Player* player, Creature* c);
uint64 GetNPCFlag(Creature* cr);
uint32 GetNpcTextId(uint32 guid);
- uint16 GetEventIdForQuest(Quest const* quest) const;
private:
void SendWorldStateUpdate(Player* player, uint16 event_id);
void AddActiveEvent(uint16 event_id) { m_ActiveEvents.insert(event_id); }
@@ -170,7 +169,6 @@ class TC_GAME_API GameEventMgr
QuestIdToEventConditionMap mQuestToEventConditions;
GameEventNPCFlagMap mGameEventNPCFlags;
ActiveEvents m_ActiveEvents;
- std::unordered_map<uint32, uint16> _questToEventLinks;
bool isSystemInit;
public:
GameEventGuidMap mGameEventCreatureGuids;
diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp
index fc12ac76f7f..3e8d5a1f02f 100644
--- a/src/server/game/Globals/ObjectMgr.cpp
+++ b/src/server/game/Globals/ObjectMgr.cpp
@@ -2541,18 +2541,6 @@ void ObjectMgr::RemoveGameobjectFromGrid(ObjectGuid::LowType guid, GameObjectDat
}
}
-// name must be checked to correctness (if received) before call this function
-ObjectGuid ObjectMgr::GetPlayerGUIDByName(std::string const& name)
-{
- PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_GUID_BY_NAME);
- stmt->setString(0, name);
-
- if (PreparedQueryResult result = CharacterDatabase.Query(stmt))
- return ObjectGuid::Create<HighGuid::Player>((*result)[0].GetUInt64());
-
- return ObjectGuid::Empty;
-}
-
bool ObjectMgr::GetPlayerNameByGUID(ObjectGuid const& guid, std::string& name)
{
CharacterInfo const* characterInfo = sWorld->GetCharacterInfo(guid);
@@ -2593,11 +2581,9 @@ uint32 ObjectMgr::GetPlayerAccountIdByGUID(ObjectGuid const& guid)
uint32 ObjectMgr::GetPlayerAccountIdByPlayerName(std::string const& name)
{
- PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_ACCOUNT_BY_NAME);
- stmt->setString(0, name);
-
- if (PreparedQueryResult result = CharacterDatabase.Query(stmt))
- return (*result)[0].GetUInt32();
+ ObjectGuid guid = sWorld->GetCharacterGuidByName(name);
+ if (!guid.IsEmpty())
+ return GetPlayerAccountIdByGUID(guid);
return 0;
}
diff --git a/src/server/game/Globals/ObjectMgr.h b/src/server/game/Globals/ObjectMgr.h
index 667b8ea1da4..67188e8028f 100644
--- a/src/server/game/Globals/ObjectMgr.h
+++ b/src/server/game/Globals/ObjectMgr.h
@@ -991,8 +991,6 @@ class TC_GAME_API ObjectMgr
void GetPlayerLevelInfo(uint32 race, uint32 class_, uint8 level, PlayerLevelInfo* info) const;
- static ObjectGuid GetPlayerGUIDByName(std::string const& name);
-
std::vector<uint32> const* GetGameObjectQuestItemList(uint32 id) const
{
GameObjectQuestItemMap::const_iterator itr = _gameObjectQuestItemStore.find(id);
diff --git a/src/server/game/Guilds/Guild.cpp b/src/server/game/Guilds/Guild.cpp
index 07e24e3c26e..96618d225d3 100644
--- a/src/server/game/Guilds/Guild.cpp
+++ b/src/server/game/Guilds/Guild.cpp
@@ -2364,7 +2364,8 @@ void Guild::LoadRankFromDB(Field* fields)
bool Guild::LoadMemberFromDB(Field* fields)
{
ObjectGuid::LowType lowguid = fields[1].GetUInt64();
- Member *member = new Member(m_id, ObjectGuid::Create<HighGuid::Player>(lowguid), fields[2].GetUInt8());
+ ObjectGuid playerGuid(ObjectGuid::Create<HighGuid::Player>(lowguid));
+ Member* member = new Member(m_id, playerGuid, fields[2].GetUInt8());
if (!member->LoadFromDB(fields))
{
SQLTransaction trans(nullptr);
@@ -2373,6 +2374,7 @@ bool Guild::LoadMemberFromDB(Field* fields)
return false;
}
+ sWorld->UpdateCharacterGuildId(playerGuid, GetId());
m_members[member->GetGUID()] = member;
return true;
}
@@ -2621,7 +2623,7 @@ void Guild::MassInviteToEvent(WorldSession* session, uint32 minLevel, uint32 max
}
Member* member = itr->second;
- uint32 level = Player::GetLevelFromDB(member->GetGUID());
+ uint32 level = Player::GetLevelFromCharacterInfo(member->GetGUID());
if (member->GetGUID() != session->GetPlayer()->GetGUID() && level >= minLevel && level <= maxLevel && member->IsRankNotLower(minRank))
packet.Invites.emplace_back(member->GetGUID(), level);
@@ -2640,7 +2642,7 @@ bool Guild::AddMember(SQLTransaction& trans, ObjectGuid guid, uint8 rankId)
if (player->GetGuildId())
return false;
}
- else if (Player::GetGuildIdFromDB(guid))
+ else if (Player::GetGuildIdFromCharacterInfo(guid))
return false;
// Remove all player signs from another petitions
@@ -2695,6 +2697,7 @@ bool Guild::AddMember(SQLTransaction& trans, ObjectGuid guid, uint8 rankId)
return false;
}
m_members[guid] = member;
+ sWorld->UpdateCharacterGuildId(guid, GetId());
}
member->SaveToDB(trans);
@@ -2767,6 +2770,8 @@ void Guild::DeleteMember(SQLTransaction& trans, ObjectGuid guid, bool isDisbandi
for (GuildPerkSpellsEntry const* entry : sGuildPerkSpellsStore)
player->RemoveSpell(entry->SpellID, false, false);
}
+ else
+ sWorld->UpdateCharacterGuildId(guid, 0);
Guild::_DeleteMemberFromDB(trans, guid.GetCounter());
if (!isDisbanding)
diff --git a/src/server/game/Handlers/CalendarHandler.cpp b/src/server/game/Handlers/CalendarHandler.cpp
index 46d61cab35a..82dedefb997 100644
--- a/src/server/game/Handlers/CalendarHandler.cpp
+++ b/src/server/game/Handlers/CalendarHandler.cpp
@@ -255,15 +255,16 @@ void WorldSession::HandleCalendarEventInvite(WorldPackets::Calendar::CalendarEve
}
else
{
- // Invitee offline, get data from database
- PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_GUID_RACE_ACC_BY_NAME);
- stmt->setString(0, calendarEventInvite.Name);
- if (PreparedQueryResult result = CharacterDatabase.Query(stmt))
+ // Invitee offline, get data from storage
+ ObjectGuid guid = sWorld->GetCharacterGuidByName(calendarEventInvite.Name);
+ if (!guid.IsEmpty())
{
- Field* fields = result->Fetch();
- inviteeGuid = ObjectGuid::Create<HighGuid::Player>(fields[0].GetUInt64());
- inviteeTeam = Player::TeamForRace(fields[1].GetUInt8());
- inviteeGuildId = Player::GetGuildIdFromDB(inviteeGuid);
+ if (CharacterInfo const* characterInfo = sWorld->GetCharacterInfo(guid))
+ {
+ inviteeGuid = guid;
+ inviteeTeam = Player::TeamForRace(characterInfo->Race);
+ inviteeGuildId = characterInfo->GuildId;
+ }
}
}
diff --git a/src/server/game/Handlers/CharacterHandler.cpp b/src/server/game/Handlers/CharacterHandler.cpp
index 6e9136a952f..b994e827e1a 100644
--- a/src/server/game/Handlers/CharacterHandler.cpp
+++ b/src/server/game/Handlers/CharacterHandler.cpp
@@ -1324,6 +1324,7 @@ void WorldSession::HandleCharRenameCallBack(std::shared_ptr<WorldPackets::Charac
SendCharRename(RESPONSE_SUCCESS, renameInfo.get());
sWorld->UpdateCharacterInfo(renameInfo->Guid, renameInfo->NewName);
+ sWorld->UpdateCharacterGuidByName(renameInfo->Guid, oldName, renameInfo->NewName);
}
void WorldSession::HandleSetPlayerDeclinedNames(WorldPackets::Character::SetPlayerDeclinedNames& packet)
@@ -1548,7 +1549,7 @@ void WorldSession::HandleCharCustomizeCallback(std::shared_ptr<WorldPackets::Cha
// character with this name already exist
/// @todo: make async
- ObjectGuid newGuid = ObjectMgr::GetPlayerGUIDByName(customizeInfo->CharName);
+ ObjectGuid newGuid = sWorld->GetCharacterGuidByName(customizeInfo->CharName);
if (!newGuid.IsEmpty())
{
if (newGuid != customizeInfo->CharGUID)
@@ -1599,6 +1600,7 @@ void WorldSession::HandleCharCustomizeCallback(std::shared_ptr<WorldPackets::Cha
CharacterDatabase.CommitTransaction(trans);
sWorld->UpdateCharacterInfo(customizeInfo->CharGUID, customizeInfo->CharName, customizeInfo->SexID);
+ sWorld->UpdateCharacterGuidByName(customizeInfo->CharGUID, oldName, customizeInfo->CharName);
SendCharCustomize(RESPONSE_SUCCESS, customizeInfo.get());
@@ -1862,7 +1864,7 @@ void WorldSession::HandleCharRaceOrFactionChangeCallback(std::shared_ptr<WorldPa
}
// character with this name already exist
- ObjectGuid newGuid = ObjectMgr::GetPlayerGUIDByName(factionChangeInfo->Name);
+ ObjectGuid newGuid = sWorld->GetCharacterGuidByName(factionChangeInfo->Name);
if (!newGuid.IsEmpty())
{
if (newGuid != factionChangeInfo->Guid)
@@ -1931,6 +1933,7 @@ void WorldSession::HandleCharRaceOrFactionChangeCallback(std::shared_ptr<WorldPa
}
sWorld->UpdateCharacterInfo(factionChangeInfo->Guid, factionChangeInfo->Name, factionChangeInfo->SexID, factionChangeInfo->RaceID);
+ sWorld->UpdateCharacterGuidByName(factionChangeInfo->Guid, oldName, factionChangeInfo->Name);
if (oldRace != factionChangeInfo->RaceID)
{
@@ -2034,16 +2037,11 @@ void WorldSession::HandleCharRaceOrFactionChangeCallback(std::shared_ptr<WorldPa
trans->Append(stmt);
}
- /// @todo: make this part async
if (!sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD))
{
// Reset guild
- stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_GUILD_MEMBER);
- stmt->setUInt64(0, lowGuid);
-
- if (PreparedQueryResult memberResult = CharacterDatabase.Query(stmt))
- if (Guild* guild = sGuildMgr->GetGuildById(memberResult->Fetch()[0].GetUInt64()))
- guild->DeleteMember(trans, factionChangeInfo->Guid, false, false, true);
+ if (Guild* guild = sGuildMgr->GetGuildById(characterInfo->GuildId))
+ guild->DeleteMember(trans, factionChangeInfo->Guid, false, false, true);
Player::LeaveAllArenaTeams(factionChangeInfo->Guid);
}
diff --git a/src/server/game/Handlers/MailHandler.cpp b/src/server/game/Handlers/MailHandler.cpp
index d15ea033240..bf4b8f790c4 100644
--- a/src/server/game/Handlers/MailHandler.cpp
+++ b/src/server/game/Handlers/MailHandler.cpp
@@ -85,7 +85,7 @@ void WorldSession::HandleSendMail(WorldPackets::Mail::SendMail& packet)
ObjectGuid receiverGuid;
if (normalizePlayerName(packet.Info.Target))
- receiverGuid = ObjectMgr::GetPlayerGUIDByName(packet.Info.Target);
+ receiverGuid = sWorld->GetCharacterGuidByName(packet.Info.Target);
if (!receiverGuid)
{
@@ -159,7 +159,12 @@ void WorldSession::HandleSendMail(WorldPackets::Mail::SendMail& packet)
}
else
{
- receiverTeam = ObjectMgr::GetPlayerTeamByGUID(receiverGuid);
+ if (CharacterInfo const* characterInfo = sWorld->GetCharacterInfo(receiverGuid))
+ {
+ receiverTeam = Player::TeamForRace(characterInfo->Race);
+ receiverLevel = characterInfo->Level;
+ receiverAccountId = characterInfo->AccountId;
+ }
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_MAIL_COUNT);
stmt->setUInt64(0, receiverGuid.GetCounter());
@@ -171,17 +176,6 @@ void WorldSession::HandleSendMail(WorldPackets::Mail::SendMail& packet)
mailsCount = fields[0].GetUInt64();
}
- stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_LEVEL);
- stmt->setUInt64(0, receiverGuid.GetCounter());
-
- result = CharacterDatabase.Query(stmt);
- if (result)
- {
- Field* fields = result->Fetch();
- receiverLevel = fields[0].GetUInt8();
- }
-
- receiverAccountId = ObjectMgr::GetPlayerAccountIdByGUID(receiverGuid);
receiverBnetAccountId = Battlenet::AccountMgr::GetIdByGameAccount(receiverAccountId);
}
diff --git a/src/server/game/Handlers/NPCHandler.cpp b/src/server/game/Handlers/NPCHandler.cpp
index ba17b382bb0..e756f48f7ac 100644
--- a/src/server/game/Handlers/NPCHandler.cpp
+++ b/src/server/game/Handlers/NPCHandler.cpp
@@ -315,13 +315,7 @@ void WorldSession::SendSpiritResurrect()
if (corpseGrave != ghostGrave)
_player->TeleportTo(corpseGrave->MapID, corpseGrave->Loc.X, corpseGrave->Loc.Y, corpseGrave->Loc.Z, (corpseGrave->Facing * M_PI) / 180); // Orientation is initially in degrees
- // or update at original position
- else
- _player->UpdateObjectVisibility();
}
- // or update at original position
- else
- _player->UpdateObjectVisibility();
}
void WorldSession::HandleBinderActivateOpcode(WorldPackets::NPC::Hello& packet)
diff --git a/src/server/game/Handlers/SocialHandler.cpp b/src/server/game/Handlers/SocialHandler.cpp
index a6cff8c2417..dcafebe93e1 100644
--- a/src/server/game/Handlers/SocialHandler.cpp
+++ b/src/server/game/Handlers/SocialHandler.cpp
@@ -43,30 +43,14 @@ void WorldSession::HandleAddFriendOpcode(WorldPackets::Social::AddFriend& packet
TC_LOG_DEBUG("network", "WorldSession::HandleAddFriendOpcode: %s asked to add friend: %s",
GetPlayerInfo().c_str(), packet.Name.c_str());
- PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_GUID_RACE_ACC_BY_NAME);
- stmt->setString(0, packet.Name);
-
- _queryProcessor.AddQuery(CharacterDatabase.AsyncQuery(stmt)
- .WithPreparedCallback(std::bind(&WorldSession::HandleAddFriendOpcodeCallBack, this, std::move(packet.Notes), std::placeholders::_1)));
-}
-
-void WorldSession::HandleAddFriendOpcodeCallBack(std::string const& friendNote, PreparedQueryResult result)
-{
- if (!GetPlayer())
- return;
-
- ObjectGuid friendGuid;
FriendsResult friendResult = FRIEND_NOT_FOUND;
-
- if (result)
+ ObjectGuid friendGuid = sWorld->GetCharacterGuidByName(packet.Name);
+ if (!friendGuid.IsEmpty())
{
- Field* fields = result->Fetch();
-
- if (ObjectGuid::LowType lowGuid = fields[0].GetUInt64())
+ if (CharacterInfo const* characterInfo = sWorld->GetCharacterInfo(friendGuid))
{
- friendGuid = ObjectGuid::Create<HighGuid::Player>(lowGuid);
- uint32 team = Player::TeamForRace(fields[1].GetUInt8());
- uint32 friendAccountId = fields[2].GetUInt32();
+ uint32 team = Player::TeamForRace(characterInfo->Race);
+ uint32 friendAccountId = characterInfo->AccountId;
if (HasPermission(rbac::RBAC_PERM_ALLOW_GM_FRIEND) || AccountMgr::IsPlayerAccount(AccountMgr::GetSecurity(friendAccountId, realm.Id.Realm)))
{
@@ -85,7 +69,7 @@ void WorldSession::HandleAddFriendOpcodeCallBack(std::string const& friendNote,
friendResult = FRIEND_ADDED_OFFLINE;
if (GetPlayer()->GetSocial()->AddToSocialList(friendGuid, SOCIAL_FLAG_FRIEND))
- GetPlayer()->GetSocial()->SetFriendNote(friendGuid, friendNote);
+ GetPlayer()->GetSocial()->SetFriendNote(friendGuid, packet.Notes);
else
friendResult = FRIEND_LIST_FULL;
}
@@ -112,42 +96,23 @@ void WorldSession::HandleAddIgnoreOpcode(WorldPackets::Social::AddIgnore& packet
return;
TC_LOG_DEBUG("network", "WorldSession::HandleAddIgnoreOpcode: %s asked to Ignore: %s",
- GetPlayerInfo().c_str(), packet.Name.c_str());
-
- PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_GUID_BY_NAME);
- stmt->setString(0, packet.Name);
+ GetPlayer()->GetName().c_str(), packet.Name.c_str());
- _queryProcessor.AddQuery(CharacterDatabase.AsyncQuery(stmt).WithPreparedCallback(std::bind(&WorldSession::HandleAddIgnoreOpcodeCallBack, this, std::placeholders::_1)));
-}
-
-void WorldSession::HandleAddIgnoreOpcodeCallBack(PreparedQueryResult result)
-{
- if (!GetPlayer())
- return;
-
- ObjectGuid ignoreGuid;
+ ObjectGuid ignoreGuid = sWorld->GetCharacterGuidByName(packet.Name);
FriendsResult ignoreResult = FRIEND_IGNORE_NOT_FOUND;
-
- if (result)
+ if (!ignoreGuid.IsEmpty())
{
- Field* fields = result->Fetch();
-
- if (ObjectGuid::LowType lowGuid = fields[0].GetUInt64())
+ if (ignoreGuid == GetPlayer()->GetGUID()) //not add yourself
+ ignoreResult = FRIEND_IGNORE_SELF;
+ else if (GetPlayer()->GetSocial()->HasIgnore(ignoreGuid))
+ ignoreResult = FRIEND_IGNORE_ALREADY;
+ else
{
- ignoreGuid = ObjectGuid::Create<HighGuid::Player>(lowGuid);
+ ignoreResult = FRIEND_IGNORE_ADDED;
- if (ignoreGuid == GetPlayer()->GetGUID()) //not add yourself
- ignoreResult = FRIEND_IGNORE_SELF;
- else if (GetPlayer()->GetSocial()->HasIgnore(ignoreGuid))
- ignoreResult = FRIEND_IGNORE_ALREADY;
- else
- {
- ignoreResult = FRIEND_IGNORE_ADDED;
-
- // ignore list full
- if (!GetPlayer()->GetSocial()->AddToSocialList(ignoreGuid, SOCIAL_FLAG_IGNORED))
- ignoreResult = FRIEND_IGNORE_FULL;
- }
+ // ignore list full
+ if (!GetPlayer()->GetSocial()->AddToSocialList(ignoreGuid, SOCIAL_FLAG_IGNORED))
+ ignoreResult = FRIEND_IGNORE_FULL;
}
}
diff --git a/src/server/game/Handlers/SpellHandler.cpp b/src/server/game/Handlers/SpellHandler.cpp
index c91231df279..a3ae9f579fd 100644
--- a/src/server/game/Handlers/SpellHandler.cpp
+++ b/src/server/game/Handlers/SpellHandler.cpp
@@ -132,31 +132,38 @@ void WorldSession::HandleUseItemOpcode(WorldPackets::Spells::UseItem& packet)
void WorldSession::HandleOpenItemOpcode(WorldPackets::Spells::OpenItem& packet)
{
- Player* player = _player;
+ Player* player = GetPlayer();
// ignore for remote control state
if (player->m_unitMovedByMe != player)
return;
TC_LOG_INFO("network", "bagIndex: %u, slot: %u", packet.Slot, packet.PackSlot);
+ // additional check, client outputs message on its own
+ if (!player->IsAlive())
+ {
+ player->SendEquipError(EQUIP_ERR_PLAYER_DEAD, nullptr, nullptr);
+ return;
+ }
+
Item* item = player->GetItemByPos(packet.Slot, packet.PackSlot);
if (!item)
{
- player->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, NULL, NULL);
+ player->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, nullptr, nullptr);
return;
}
ItemTemplate const* proto = item->GetTemplate();
if (!proto)
{
- player->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, item, NULL);
+ player->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, item, nullptr);
return;
}
// Verify that the bag is an actual bag or wrapped item that can be used "normally"
if (!(proto->GetFlags() & ITEM_FLAG_HAS_LOOT) && !item->HasItemFlag(ITEM_FIELD_FLAG_WRAPPED))
{
- player->SendEquipError(EQUIP_ERR_CLIENT_LOCKED_OUT, item, NULL);
+ player->SendEquipError(EQUIP_ERR_CLIENT_LOCKED_OUT, item, nullptr);
TC_LOG_ERROR("entities.player.cheat", "Possible hacking attempt: Player %s [%s] tried to open item [%s, entry: %u] which is not openable!",
player->GetName().c_str(), player->GetGUID().ToString().c_str(), item->GetGUID().ToString().c_str(), proto->GetId());
return;
@@ -170,7 +177,7 @@ void WorldSession::HandleOpenItemOpcode(WorldPackets::Spells::OpenItem& packet)
if (!lockInfo)
{
- player->SendEquipError(EQUIP_ERR_ITEM_LOCKED, item, NULL);
+ player->SendEquipError(EQUIP_ERR_ITEM_LOCKED, item, nullptr);
TC_LOG_ERROR("network", "WORLD::OpenItem: item [%s] has an unknown lockId: %u!", item->GetGUID().ToString().c_str(), lockId);
return;
}
@@ -178,7 +185,7 @@ void WorldSession::HandleOpenItemOpcode(WorldPackets::Spells::OpenItem& packet)
// was not unlocked yet
if (item->IsLocked())
{
- player->SendEquipError(EQUIP_ERR_ITEM_LOCKED, item, NULL);
+ player->SendEquipError(EQUIP_ERR_ITEM_LOCKED, item, nullptr);
return;
}
}
@@ -186,37 +193,51 @@ void WorldSession::HandleOpenItemOpcode(WorldPackets::Spells::OpenItem& packet)
if (item->HasItemFlag(ITEM_FIELD_FLAG_WRAPPED))// wrapped?
{
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHARACTER_GIFT_BY_ITEM);
-
stmt->setUInt64(0, item->GetGUID().GetCounter());
+ _queryProcessor.AddQuery(CharacterDatabase.AsyncQuery(stmt)
+ .WithPreparedCallback(std::bind(&WorldSession::HandleOpenWrappedItemCallback, this, item->GetPos(), item->GetGUID(), std::placeholders::_1)));
+ }
+ else
+ player->SendLoot(item->GetGUID(), LOOT_CORPSE);
+}
- PreparedQueryResult result = CharacterDatabase.Query(stmt);
-
- if (result)
- {
- Field* fields = result->Fetch();
- uint32 entry = fields[0].GetUInt32();
- uint32 flags = fields[1].GetUInt32();
-
- item->SetGiftCreator(ObjectGuid::Empty);
- item->SetEntry(entry);
- item->SetItemFlags(ItemFieldFlags(flags));
- item->SetState(ITEM_CHANGED, player);
- }
- else
- {
- TC_LOG_ERROR("network", "Wrapped item %s don't have record in character_gifts table and will deleted", item->GetGUID().ToString().c_str());
- player->DestroyItem(item->GetBagSlot(), item->GetSlot(), true);
- return;
- }
+void WorldSession::HandleOpenWrappedItemCallback(uint16 pos, ObjectGuid itemGuid, PreparedQueryResult result)
+{
+ if (!GetPlayer())
+ return;
- stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GIFT);
+ Item* item = GetPlayer()->GetItemByPos(pos);
+ if (!item)
+ return;
- stmt->setUInt64(0, item->GetGUID().GetCounter());
+ if (item->GetGUID() != itemGuid || !item->HasItemFlag(ITEM_FIELD_FLAG_WRAPPED)) // during getting result, gift was swapped with another item
+ return;
- CharacterDatabase.Execute(stmt);
+ if (!result)
+ {
+ TC_LOG_ERROR("network", "Wrapped item %s don't have record in character_gifts table and will deleted", item->GetGUID().ToString().c_str());
+ GetPlayer()->DestroyItem(item->GetBagSlot(), item->GetSlot(), true);
+ return;
}
- else
- player->SendLoot(item->GetGUID(), LOOT_CORPSE);
+
+ SQLTransaction trans = CharacterDatabase.BeginTransaction();
+
+ Field* fields = result->Fetch();
+ uint32 entry = fields[0].GetUInt32();
+ uint32 flags = fields[1].GetUInt32();
+
+ item->SetGiftCreator(ObjectGuid::Empty);
+ item->SetEntry(entry);
+ item->SetItemFlags(ItemFieldFlags(flags));
+ item->SetState(ITEM_CHANGED, GetPlayer());
+
+ GetPlayer()->SaveInventoryAndGoldToDB(trans);
+
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GIFT);
+ stmt->setUInt64(0, itemGuid.GetCounter());
+ trans->Append(stmt);
+
+ CharacterDatabase.CommitTransaction(trans);
}
void WorldSession::HandleGameObjectUseOpcode(WorldPackets::GameObject::GameObjUse& packet)
diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp
index 4004d7c03ed..a58f36b8e07 100644
--- a/src/server/game/Maps/Map.cpp
+++ b/src/server/game/Maps/Map.cpp
@@ -959,10 +959,15 @@ void Map::RemovePlayerFromMap(Player* player, bool remove)
{
sScriptMgr->OnPlayerLeaveMap(this, player);
+ player->getHostileRefManager().deleteReferences(); // multithreading crashfix
+
+ bool const inWorld = player->IsInWorld();
player->RemoveFromWorld();
SendRemoveTransports(player);
- player->UpdateObjectVisibility(true);
+ if (!inWorld) // if was in world, RemoveFromWorld() called DestroyForNearbyPlayers()
+ player->DestroyForNearbyPlayers(); // previous player->UpdateObjectVisibility(true)
+
if (player->IsInGrid())
player->RemoveFromGrid();
else
@@ -975,11 +980,14 @@ void Map::RemovePlayerFromMap(Player* player, bool remove)
template<class T>
void Map::RemoveFromMap(T *obj, bool remove)
{
+ bool const inWorld = obj->IsInWorld() && obj->GetTypeId() >= TYPEID_UNIT && obj->GetTypeId() <= TYPEID_GAMEOBJECT;
obj->RemoveFromWorld();
if (obj->isActiveObject())
RemoveFromActive(obj);
- obj->UpdateObjectVisibility(true);
+ if (!inWorld) // if was in world, RemoveFromWorld() called DestroyForNearbyPlayers()
+ obj->DestroyForNearbyPlayers(); // previous obj->UpdateObjectVisibility(true)
+
obj->RemoveFromGrid();
obj->ResetMap();
diff --git a/src/server/game/Quests/QuestDef.cpp b/src/server/game/Quests/QuestDef.cpp
index 247b2c37f30..91c6516e2e9 100644
--- a/src/server/game/Quests/QuestDef.cpp
+++ b/src/server/game/Quests/QuestDef.cpp
@@ -32,6 +32,7 @@ Quest::Quest(Field* questRecord)
EmoteOnComplete = 0;
_rewItemsCount = 0;
_rewChoiceItemsCount = 0;
+ _eventIdForQuest = 0;
_rewCurrencyCount = 0;
ID = questRecord[0].GetUInt32();
diff --git a/src/server/game/Quests/QuestDef.h b/src/server/game/Quests/QuestDef.h
index 6382134acab..6e6b90bdbd9 100644
--- a/src/server/game/Quests/QuestDef.h
+++ b/src/server/game/Quests/QuestDef.h
@@ -460,6 +460,9 @@ class TC_GAME_API Quest
uint32 GetRewItemsCount() const { return _rewItemsCount; }
uint32 GetRewCurrencyCount() const { return _rewCurrencyCount; }
+ void SetEventIdForQuest(uint16 eventId) { _eventIdForQuest = eventId; }
+ uint16 GetEventIdForQuest() const { return _eventIdForQuest; }
+
void BuildQuestRewards(WorldPackets::Quest::QuestRewards& rewards, Player* player) const;
typedef std::vector<int32> PrevQuests;
@@ -470,6 +473,7 @@ class TC_GAME_API Quest
private:
uint32 _rewChoiceItemsCount;
uint32 _rewItemsCount;
+ uint16 _eventIdForQuest;
uint32 _rewCurrencyCount;
public:
diff --git a/src/server/game/Server/WorldSession.cpp b/src/server/game/Server/WorldSession.cpp
index 1f5f2a829c7..f59c652b9a0 100644
--- a/src/server/game/Server/WorldSession.cpp
+++ b/src/server/game/Server/WorldSession.cpp
@@ -126,7 +126,7 @@ WorldSession::WorldSession(uint32 id, std::string&& name, uint32 battlenetAccoun
m_sessionDbLocaleIndex(locale),
m_latency(0),
m_clientTimeDelay(0),
- _tutorialsChanged(false),
+ _tutorialsChanged(TUTORIALS_FLAG_NONE),
_filterAddonMessages(false),
recruiterId(recruiter),
isRecruiter(isARecruiter),
@@ -802,10 +802,13 @@ void WorldSession::LoadTutorialsData(PreparedQueryResult result)
memset(_tutorials, 0, sizeof(uint32) * MAX_ACCOUNT_TUTORIAL_VALUES);
if (result)
+ {
for (uint8 i = 0; i < MAX_ACCOUNT_TUTORIAL_VALUES; ++i)
_tutorials[i] = (*result)[i].GetUInt32();
+ _tutorialsChanged |= TUTORIALS_FLAG_LOADED_FROM_DB;
+ }
- _tutorialsChanged = false;
+ _tutorialsChanged &= ~TUTORIALS_FLAG_CHANGED;
}
void WorldSession::SendTutorialsData()
@@ -817,20 +820,17 @@ void WorldSession::SendTutorialsData()
void WorldSession::SaveTutorialsData(SQLTransaction& trans)
{
- if (!_tutorialsChanged)
+ if (!(_tutorialsChanged & TUTORIALS_FLAG_CHANGED))
return;
- PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_HAS_TUTORIALS);
- stmt->setUInt32(0, GetAccountId());
- bool hasTutorials = bool(CharacterDatabase.Query(stmt));
- // Modify data in DB
- stmt = CharacterDatabase.GetPreparedStatement(hasTutorials ? CHAR_UPD_TUTORIALS : CHAR_INS_TUTORIALS);
+ bool const hasTutorialsInDB = (_tutorialsChanged & TUTORIALS_FLAG_LOADED_FROM_DB) != 0;
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(hasTutorialsInDB ? CHAR_UPD_TUTORIALS : CHAR_INS_TUTORIALS);
for (uint8 i = 0; i < MAX_ACCOUNT_TUTORIAL_VALUES; ++i)
stmt->setUInt32(i, _tutorials[i]);
stmt->setUInt32(MAX_ACCOUNT_TUTORIAL_VALUES, GetAccountId());
trans->Append(stmt);
- _tutorialsChanged = false;
+ _tutorialsChanged &= ~TUTORIALS_FLAG_CHANGED;
}
bool WorldSession::IsAddonRegistered(const std::string& prefix) const
diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h
index 9c492dbaace..320bf10dcfc 100644
--- a/src/server/game/Server/WorldSession.h
+++ b/src/server/game/Server/WorldSession.h
@@ -834,6 +834,13 @@ enum DeclinedNameResult
DECLINED_NAMES_RESULT_ERROR = 1
};
+enum TutorialsFlag : uint8
+{
+ TUTORIALS_FLAG_NONE = 0x00,
+ TUTORIALS_FLAG_CHANGED = 0x01,
+ TUTORIALS_FLAG_LOADED_FROM_DB = 0x02
+};
+
//class to deal with packet processing
//allows to determine if next packet is safe to be processed
class PacketFilter
@@ -1010,7 +1017,7 @@ class TC_GAME_API WorldSession
if (_tutorials[index] != value)
{
_tutorials[index] = value;
- _tutorialsChanged = true;
+ _tutorialsChanged |= TUTORIALS_FLAG_CHANGED;
}
}
// Auction
@@ -1187,10 +1194,8 @@ class TC_GAME_API WorldSession
// Social
void HandleContactListOpcode(WorldPackets::Social::SendContactList& packet);
void HandleAddFriendOpcode(WorldPackets::Social::AddFriend& packet);
- void HandleAddFriendOpcodeCallBack(std::string const& friendNote, PreparedQueryResult result);
void HandleDelFriendOpcode(WorldPackets::Social::DelFriend& packet);
void HandleAddIgnoreOpcode(WorldPackets::Social::AddIgnore& packet);
- void HandleAddIgnoreOpcodeCallBack(PreparedQueryResult result);
void HandleDelIgnoreOpcode(WorldPackets::Social::DelIgnore& packet);
void HandleSetContactNotesOpcode(WorldPackets::Social::SetContactNotes& packet);
@@ -1411,6 +1416,7 @@ class TC_GAME_API WorldSession
void HandleUseItemOpcode(WorldPackets::Spells::UseItem& packet);
void HandleOpenItemOpcode(WorldPackets::Spells::OpenItem& packet);
+ void HandleOpenWrappedItemCallback(uint16 pos, ObjectGuid itemGuid, PreparedQueryResult result);
void HandleCastSpellOpcode(WorldPackets::Spells::CastSpell& castRequest);
void HandleCancelCastOpcode(WorldPackets::Spells::CancelCast& packet);
void HandleCancelAuraOpcode(WorldPackets::Spells::CancelAura& cancelAura);
@@ -1722,6 +1728,10 @@ class TC_GAME_API WorldSession
};
uint64 GetConnectToInstanceKey() const { return _instanceConnectKey.Raw; }
+
+ public:
+ QueryCallbackProcessor& GetQueryProcessor() { return _queryProcessor; }
+
private:
void ProcessQueryCallbacks();
@@ -1814,7 +1824,7 @@ class TC_GAME_API WorldSession
std::atomic<uint32> m_clientTimeDelay;
AccountData _accountData[NUM_ACCOUNT_DATA_TYPES];
uint32 _tutorials[MAX_ACCOUNT_TUTORIAL_VALUES];
- bool _tutorialsChanged;
+ uint8 _tutorialsChanged;
std::vector<std::string> _registeredAddonPrefixes;
bool _filterAddonMessages;
uint32 recruiterId;
diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp
index 2d8caeaa696..7abaf15a857 100644
--- a/src/server/game/World/World.cpp
+++ b/src/server/game/World/World.cpp
@@ -1938,6 +1938,10 @@ void World::SetInitialWorldSettings()
sBlackMarketMgr->LoadAuctions();
}
+ // Load before guilds and arena teams
+ TC_LOG_INFO("server.loading", "Loading character info store...");
+ LoadCharacterInfoStore();
+
TC_LOG_INFO("server.loading", "Loading Guild rewards...");
sGuildMgr->LoadGuildRewards();
@@ -2181,8 +2185,6 @@ void World::SetInitialWorldSettings()
TC_LOG_INFO("server.loading", "Calculate next currency reset time...");
InitCurrencyResetTime();
- LoadCharacterInfoStore();
-
TC_LOG_INFO("server.loading", "Loading race and class expansion requirements...");
sObjectMgr->LoadRaceAndClassExpansionRequirements();
@@ -2843,20 +2845,20 @@ bool World::RemoveBanAccount(BanMode mode, std::string const& nameOrIP)
/// Ban an account or ban an IP address, duration will be parsed using TimeStringToSecs if it is positive, otherwise permban
BanReturn World::BanCharacter(std::string const& name, std::string const& duration, std::string const& reason, std::string const& author)
{
- Player* pBanned = ObjectAccessor::FindConnectedPlayerByName(name);
+ Player* banned = ObjectAccessor::FindConnectedPlayerByName(name);
ObjectGuid guid;
uint32 duration_secs = TimeStringToSecs(duration);
/// Pick a player to ban if not online
- if (!pBanned)
+ if (!banned)
{
- guid = ObjectMgr::GetPlayerGUIDByName(name);
+ guid = sWorld->GetCharacterGuidByName(name);
if (guid.IsEmpty())
return BAN_NOTFOUND; // Nobody to ban
}
else
- guid = pBanned->GetGUID();
+ guid = banned->GetGUID();
//Use transaction in order to ensure the order of the queries
SQLTransaction trans = CharacterDatabase.BeginTransaction();
@@ -2873,8 +2875,8 @@ BanReturn World::BanCharacter(std::string const& name, std::string const& durati
trans->Append(stmt);
CharacterDatabase.CommitTransaction(trans);
- if (pBanned)
- pBanned->GetSession()->KickPlayer();
+ if (banned)
+ banned->GetSession()->KickPlayer();
return BAN_SUCCESS;
}
@@ -2882,18 +2884,18 @@ BanReturn World::BanCharacter(std::string const& name, std::string const& durati
/// Remove a ban from a character
bool World::RemoveBanCharacter(std::string const& name)
{
- Player* pBanned = ObjectAccessor::FindConnectedPlayerByName(name);
+ Player* banned = ObjectAccessor::FindConnectedPlayerByName(name);
ObjectGuid guid;
/// Pick a player to ban if not online
- if (!pBanned)
+ if (!banned)
{
- guid = ObjectMgr::GetPlayerGUIDByName(name);
+ guid = sWorld->GetCharacterGuidByName(name);
if (guid.IsEmpty())
return false; // Nobody to ban
}
else
- guid = pBanned->GetGUID();
+ guid = banned->GetGUID();
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHARACTER_BAN);
stmt->setUInt64(0, guid.GetCounter());
@@ -3524,6 +3526,15 @@ void World::ProcessQueryCallbacks()
_queryProcessor.ProcessReadyQueries();
}
+ObjectGuid World::GetCharacterGuidByName(std::string const& name) const
+{
+ auto itr = _characterGuidByNameStore.find(name);
+ if (itr != _characterGuidByNameStore.end())
+ return itr->second;
+
+ return ObjectGuid::Empty;
+}
+
/**
* @brief Loads several pieces of information on server startup with the GUID
* There is no further database query necessary.
@@ -3556,8 +3567,6 @@ CharacterInfo const* World::GetCharacterInfo(ObjectGuid const& guid) const
void World::LoadCharacterInfoStore()
{
- TC_LOG_INFO("server.loading", "Loading character info store");
-
_characterInfoStore.clear();
QueryResult result = CharacterDatabase.Query("SELECT guid, name, account, race, gender, class, level, deleteDate FROM characters");
@@ -3587,9 +3596,18 @@ void World::AddCharacterInfo(ObjectGuid const& guid, uint32 accountId, std::stri
data.Sex = gender;
data.Class = playerClass;
data.Level = level;
+ data.GuildId = 0; // Will be set in guild loading or guild setting
+ for (uint8 i = 0; i < MAX_ARENA_SLOT; ++i)
+ data.ArenaTeamId[i] = 0; // Will be set in arena teams loading
data.IsDeleted = isDeleted;
}
+void World::DeleteCharacterInfo(ObjectGuid const& guid, std::string const& name)
+{
+ _characterInfoStore.erase(guid);
+ _characterGuidByNameStore.erase(name);
+}
+
void World::UpdateCharacterInfo(ObjectGuid const& guid, std::string const& name, uint8 gender /*= GENDER_NONE*/, uint8 race /*= RACE_NONE*/)
{
CharacterInfoContainer::iterator itr = _characterInfoStore.find(guid);
@@ -3627,6 +3645,30 @@ void World::UpdateCharacterInfoAccount(ObjectGuid const& guid, uint32 accountId)
itr->second.AccountId = accountId;
}
+void World::UpdateCharacterGuildId(ObjectGuid const& guid, ObjectGuid::LowType guildId)
+{
+ auto itr = _characterInfoStore.find(guid);
+ if (itr == _characterInfoStore.end())
+ return;
+
+ itr->second.GuildId = guildId;
+}
+
+void World::UpdateCharacterArenaTeamId(ObjectGuid const& guid, uint8 slot, uint32 arenaTeamId)
+{
+ auto itr = _characterInfoStore.find(guid);
+ if (itr == _characterInfoStore.end())
+ return;
+
+ itr->second.ArenaTeamId[slot] = arenaTeamId;
+}
+
+void World::UpdateCharacterGuidByName(ObjectGuid const& guid, std::string const& oldName, std::string const& newName)
+{
+ _characterGuidByNameStore.erase(oldName);
+ _characterGuidByNameStore[newName] = guid;
+}
+
void World::UpdateCharacterInfoDeleted(ObjectGuid const& guid, bool deleted, std::string const* name /*= nullptr*/)
{
CharacterInfoContainer::iterator itr = _characterInfoStore.find(guid);
diff --git a/src/server/game/World/World.h b/src/server/game/World/World.h
index 51036b31d06..18c0770fece 100644
--- a/src/server/game/World/World.h
+++ b/src/server/game/World/World.h
@@ -576,6 +576,8 @@ struct CharacterInfo
uint8 Race;
uint8 Sex;
uint8 Level;
+ ObjectGuid::LowType GuildId;
+ uint32 ArenaTeamId[3];
bool IsDeleted;
};
@@ -799,12 +801,16 @@ class TC_GAME_API World
void UpdateAreaDependentAuras();
CharacterInfo const* GetCharacterInfo(ObjectGuid const& guid) const;
+ ObjectGuid GetCharacterGuidByName(std::string const& name) const;
void AddCharacterInfo(ObjectGuid const& guid, uint32 accountId, std::string const& name, uint8 gender, uint8 race, uint8 playerClass, uint8 level, bool isDeleted);
- void DeleteCharacterInfo(ObjectGuid const& guid) { _characterInfoStore.erase(guid); }
+ void DeleteCharacterInfo(ObjectGuid const& guid, std::string const& name);
bool HasCharacterInfo(ObjectGuid const& guid) { return _characterInfoStore.find(guid) != _characterInfoStore.end(); }
void UpdateCharacterInfo(ObjectGuid const& guid, std::string const& name, uint8 gender = GENDER_NONE, uint8 race = RACE_NONE);
void UpdateCharacterInfoLevel(ObjectGuid const& guid, uint8 level);
void UpdateCharacterInfoAccount(ObjectGuid const& guid, uint32 accountId);
+ void UpdateCharacterGuildId(ObjectGuid const& guid, ObjectGuid::LowType guildId);
+ void UpdateCharacterArenaTeamId(ObjectGuid const& guid, uint8 slot, uint32 arenaTeamId);
+ void UpdateCharacterGuidByName(ObjectGuid const& guid, std::string const& oldName, std::string const& newName);
void UpdateCharacterInfoDeleted(ObjectGuid const& guid, bool deleted, std::string const* name = nullptr);
uint32 GetCleaningFlags() const { return m_CleaningFlags; }
@@ -921,8 +927,10 @@ class TC_GAME_API World
typedef std::unordered_map<uint8, Autobroadcast> AutobroadcastContainer;
AutobroadcastContainer m_Autobroadcasts;
+ typedef std::unordered_map<std::string, ObjectGuid> CharacterGuidByNameContainer;
typedef std::map<ObjectGuid, CharacterInfo> CharacterInfoContainer;
CharacterInfoContainer _characterInfoStore;
+ CharacterGuidByNameContainer _characterGuidByNameStore;
void LoadCharacterInfoStore();
void ProcessQueryCallbacks();
diff --git a/src/server/scripts/Commands/cs_arena.cpp b/src/server/scripts/Commands/cs_arena.cpp
index 48ff488216f..837bcc8462e 100644
--- a/src/server/scripts/Commands/cs_arena.cpp
+++ b/src/server/scripts/Commands/cs_arena.cpp
@@ -86,7 +86,7 @@ public:
if (type == 2 || type == 3 || type == 5 )
{
- if (Player::GetArenaTeamIdFromDB(target->GetGUID(), type) != 0)
+ if (Player::GetArenaTeamIdFromCharacterInfo(target->GetGUID(), type) != 0)
{
handler->PSendSysMessage(LANG_ARENA_ERROR_SIZE, target->GetName().c_str());
handler->SetSentErrorMessage(true);
diff --git a/src/server/scripts/Commands/cs_ban.cpp b/src/server/scripts/Commands/cs_ban.cpp
index 393058b0264..a2320449dcf 100644
--- a/src/server/scripts/Commands/cs_ban.cpp
+++ b/src/server/scripts/Commands/cs_ban.cpp
@@ -306,7 +306,7 @@ public:
if (!target)
{
- targetGuid = ObjectMgr::GetPlayerGUIDByName(name);
+ targetGuid = sWorld->GetCharacterGuidByName(name);
if (targetGuid.IsEmpty())
{
handler->PSendSysMessage(LANG_BANINFO_NOCHARACTER);
diff --git a/src/server/scripts/Commands/cs_character.cpp b/src/server/scripts/Commands/cs_character.cpp
index 9e3c199a638..d7305193ff5 100644
--- a/src/server/scripts/Commands/cs_character.cpp
+++ b/src/server/scripts/Commands/cs_character.cpp
@@ -214,7 +214,7 @@ public:
return;
}
- if (!ObjectMgr::GetPlayerGUIDByName(delInfo.name).IsEmpty())
+ if (!sWorld->GetCharacterGuidByName(delInfo.name).IsEmpty())
{
handler->PSendSysMessage(LANG_CHARACTER_DELETED_SKIP_NAME, delInfo.name.c_str(), delInfo.guid.ToString().c_str(), delInfo.accountId);
return;
@@ -386,6 +386,7 @@ public:
}
sWorld->UpdateCharacterInfo(targetGuid, newName);
+ sWorld->UpdateCharacterGuidByName(targetGuid, playerOldName, newName);
handler->PSendSysMessage(LANG_RENAME_PLAYER_WITH_NEW_NAME, playerOldName.c_str(), newName.c_str());
@@ -448,7 +449,7 @@ public:
if (!handler->extractPlayerTarget(nameStr, &target, &targetGuid, &targetName))
return false;
- int32 oldlevel = target ? target->getLevel() : Player::GetLevelFromDB(targetGuid);
+ int32 oldlevel = target ? target->getLevel() : Player::GetLevelFromCharacterInfo(targetGuid);
int32 newlevel = levelStr ? atoi(levelStr) : oldlevel;
if (newlevel < 1)
@@ -864,7 +865,7 @@ public:
}
else
{
- characterGuid = ObjectMgr::GetPlayerGUIDByName(characterName);
+ characterGuid = sWorld->GetCharacterGuidByName(characterName);
if (!characterGuid)
{
handler->PSendSysMessage(LANG_NO_PLAYER, characterName.c_str());
@@ -902,7 +903,7 @@ public:
if (!handler->extractPlayerTarget(nameStr, &target, &targetGuid, &targetName))
return false;
- int32 oldlevel = target ? target->getLevel() : Player::GetLevelFromDB(targetGuid);
+ int32 oldlevel = target ? target->getLevel() : Player::GetLevelFromCharacterInfo(targetGuid);
int32 addlevel = levelStr ? atoi(levelStr) : 1;
int32 newlevel = oldlevel + addlevel;
@@ -1059,7 +1060,7 @@ public:
return false;
}
- guid = ObjectMgr::GetPlayerGUIDByName(name);
+ guid = sWorld->GetCharacterGuidByName(name);
}
if (!ObjectMgr::GetPlayerAccountIdByGUID(guid))
diff --git a/src/server/scripts/Commands/cs_guild.cpp b/src/server/scripts/Commands/cs_guild.cpp
index a6da8f985ff..dccbbec60ac 100644
--- a/src/server/scripts/Commands/cs_guild.cpp
+++ b/src/server/scripts/Commands/cs_guild.cpp
@@ -162,7 +162,7 @@ public:
if (!handler->extractPlayerTarget((char*)args, &target, &targetGuid))
return false;
- ObjectGuid::LowType guildId = target ? target->GetGuildId() : Player::GetGuildIdFromDB(targetGuid);
+ ObjectGuid::LowType guildId = target ? target->GetGuildId() : Player::GetGuildIdFromCharacterInfo(targetGuid);
if (!guildId)
return false;
@@ -189,7 +189,7 @@ public:
if (!handler->extractPlayerTarget(nameStr, &target, &targetGuid, &target_name))
return false;
- ObjectGuid::LowType guildId = target ? target->GetGuildId() : Player::GetGuildIdFromDB(targetGuid);
+ ObjectGuid::LowType guildId = target ? target->GetGuildId() : Player::GetGuildIdFromCharacterInfo(targetGuid);
if (!guildId)
return false;
diff --git a/src/server/scripts/Commands/cs_misc.cpp b/src/server/scripts/Commands/cs_misc.cpp
index 4f8d7099fe3..10cf9398c00 100644
--- a/src/server/scripts/Commands/cs_misc.cpp
+++ b/src/server/scripts/Commands/cs_misc.cpp
@@ -2621,7 +2621,7 @@ public:
if (targetName)
{
// Check for offline players
- ObjectGuid guid = ObjectMgr::GetPlayerGUIDByName(name);
+ ObjectGuid guid = sWorld->GetCharacterGuidByName(name);
if (guid.IsEmpty())
{
handler->SendSysMessage(LANG_COMMAND_FREEZE_WRONG);
diff --git a/src/server/scripts/Commands/cs_ticket.cpp b/src/server/scripts/Commands/cs_ticket.cpp
index 4da93fad156..e517235dac7 100644
--- a/src/server/scripts/Commands/cs_ticket.cpp
+++ b/src/server/scripts/Commands/cs_ticket.cpp
@@ -125,7 +125,7 @@ bool ticket_commandscript::HandleTicketAssignToCommand(ChatHandler* handler, cha
return true;
}
- ObjectGuid targetGuid = ObjectMgr::GetPlayerGUIDByName(target);
+ ObjectGuid targetGuid = sWorld->GetCharacterGuidByName(target);
uint32 accountId = ObjectMgr::GetPlayerAccountIdByGUID(targetGuid);
// Target must exist and have administrative rights
if (!AccountMgr::HasPermission(accountId, rbac::RBAC_PERM_COMMANDS_BE_ASSIGNED_TICKET, realm.Id.Realm))