diff options
Diffstat (limited to 'src')
19 files changed, 363 insertions, 381 deletions
diff --git a/src/server/database/Database/Implementation/CharacterDatabase.cpp b/src/server/database/Database/Implementation/CharacterDatabase.cpp index 7d6bdb02c94..301f3cf7d67 100644 --- a/src/server/database/Database/Implementation/CharacterDatabase.cpp +++ b/src/server/database/Database/Implementation/CharacterDatabase.cpp @@ -407,8 +407,7 @@ void CharacterDatabaseConnection::DoPrepareStatements()      PrepareStatement(CHAR_INS_CHAR_INSTANCE, "INSERT INTO character_instance (guid, instance, permanent, extendState) VALUES (?, ?, ?, ?)", CONNECTION_ASYNC);      PrepareStatement(CHAR_UPD_GENDER_AND_APPEARANCE, "UPDATE characters SET gender = ?, skin = ?, face = ?, hairStyle = ?, hairColor = ?, facialStyle = ? WHERE guid = ?", CONNECTION_ASYNC);      PrepareStatement(CHAR_DEL_CHARACTER_SKILL, "DELETE FROM character_skills WHERE guid = ? AND skill = ?", CONNECTION_ASYNC); -    PrepareStatement(CHAR_UPD_ADD_CHARACTER_SOCIAL_FLAGS, "UPDATE character_social SET flags = flags | ? WHERE guid = ? AND friend = ?", CONNECTION_ASYNC); -    PrepareStatement(CHAR_UPD_REM_CHARACTER_SOCIAL_FLAGS, "UPDATE character_social SET flags = flags & ~ ? WHERE guid = ? AND friend = ?", CONNECTION_ASYNC); +    PrepareStatement(CHAR_UPD_CHARACTER_SOCIAL_FLAGS, "UPDATE character_social SET flags = ? WHERE guid = ? AND friend = ?", CONNECTION_ASYNC);      PrepareStatement(CHAR_INS_CHARACTER_SOCIAL, "INSERT INTO character_social (guid, friend, flags) VALUES (?, ?, ?)", CONNECTION_ASYNC);      PrepareStatement(CHAR_DEL_CHARACTER_SOCIAL, "DELETE FROM character_social WHERE guid = ? AND friend = ?", CONNECTION_ASYNC);      PrepareStatement(CHAR_UPD_CHARACTER_SOCIAL_NOTE, "UPDATE character_social SET note = ? WHERE guid = ? AND friend = ?", CONNECTION_ASYNC); @@ -451,7 +450,7 @@ void CharacterDatabaseConnection::DoPrepareStatements()      PrepareStatement(CHAR_SEL_MAIL_ITEMS_BY_ENTRY, "SELECT mi.item_guid, m.sender, m.receiver, cs.account, cs.name, cr.account, cr.name "                       "FROM mail m INNER JOIN mail_items mi ON mi.mail_id = m.id INNER JOIN item_instance ii ON ii.guid = mi.item_guid "                       "INNER JOIN characters cs ON cs.guid = m.sender INNER JOIN characters cr ON cr.guid = m.receiver WHERE ii.itemEntry = ? LIMIT ?", CONNECTION_SYNCH); -    PrepareStatement(CHAR_SEL_AUCTIONHOUSE_ITEM_BY_ENTRY, "SELECT  ah.itemguid, ah.itemowner, c.account, c.name FROM auctionhouse ah INNER JOIN characters c ON c.guid = ah.itemowner INNER JOIN item_instance ii ON ii.guid = ah.itemguid WHERE ii.itemEntry = ? LIMIT ?", CONNECTION_SYNCH); +    PrepareStatement(CHAR_SEL_AUCTIONHOUSE_ITEM_BY_ENTRY, "SELECT ah.itemguid, ah.itemowner, c.account, c.name FROM auctionhouse ah INNER JOIN characters c ON c.guid = ah.itemowner INNER JOIN item_instance ii ON ii.guid = ah.itemguid WHERE ii.itemEntry = ? LIMIT ?", CONNECTION_SYNCH);      PrepareStatement(CHAR_SEL_GUILD_BANK_ITEM_BY_ENTRY, "SELECT gi.item_guid, gi.guildid, g.name FROM guild_bank_item gi INNER JOIN guild g ON g.guildid = gi.guildid INNER JOIN item_instance ii ON ii.guid = gi.item_guid WHERE ii.itemEntry = ? LIMIT ?", CONNECTION_SYNCH);      PrepareStatement(CHAR_DEL_CHAR_ACHIEVEMENT, "DELETE FROM character_achievement WHERE guid = ?", CONNECTION_ASYNC);      PrepareStatement(CHAR_DEL_CHAR_ACHIEVEMENT_PROGRESS, "DELETE FROM character_achievement_progress WHERE guid = ?", CONNECTION_ASYNC); diff --git a/src/server/database/Database/Implementation/CharacterDatabase.h b/src/server/database/Database/Implementation/CharacterDatabase.h index 4fde1008261..3373daea2f0 100644 --- a/src/server/database/Database/Implementation/CharacterDatabase.h +++ b/src/server/database/Database/Implementation/CharacterDatabase.h @@ -334,8 +334,7 @@ enum CharacterDatabaseStatements      CHAR_INS_CHAR_INSTANCE,      CHAR_UPD_GENDER_AND_APPEARANCE,      CHAR_DEL_CHARACTER_SKILL, -    CHAR_UPD_ADD_CHARACTER_SOCIAL_FLAGS, -    CHAR_UPD_REM_CHARACTER_SOCIAL_FLAGS, +    CHAR_UPD_CHARACTER_SOCIAL_FLAGS,      CHAR_INS_CHARACTER_SOCIAL,      CHAR_DEL_CHARACTER_SOCIAL,      CHAR_UPD_CHARACTER_SOCIAL_NOTE, diff --git a/src/server/game/Chat/Channels/Channel.cpp b/src/server/game/Chat/Channels/Channel.cpp index 684b19c87b5..83f25ddf0b2 100644 --- a/src/server/game/Chat/Channels/Channel.cpp +++ b/src/server/game/Chat/Channels/Channel.cpp @@ -797,7 +797,7 @@ void Channel::Invite(Player const* player, std::string const& newname)          return;      } -    if (!newp->GetSocial()->HasIgnore(guid.GetCounter())) +    if (!newp->GetSocial()->HasIgnore(guid))      {          InviteAppend appender(guid);          ChannelNameBuilder<InviteAppend> builder(this, appender); @@ -900,7 +900,7 @@ void Channel::SendToAll(Builder& builder, ObjectGuid guid /*= ObjectGuid::Empty*      for (PlayerContainer::const_iterator i = _playersStore.begin(); i != _playersStore.end(); ++i)          if (Player* player = ObjectAccessor::FindConnectedPlayer(i->first)) -            if (!guid || !player->GetSocial()->HasIgnore(guid.GetCounter())) +            if (!guid || !player->GetSocial()->HasIgnore(guid))                  localizer(player);  } diff --git a/src/server/game/DungeonFinding/LFGMgr.cpp b/src/server/game/DungeonFinding/LFGMgr.cpp index 0c9c654c394..fa8a17234fd 100644 --- a/src/server/game/DungeonFinding/LFGMgr.cpp +++ b/src/server/game/DungeonFinding/LFGMgr.cpp @@ -1829,7 +1829,7 @@ bool LFGMgr::HasIgnore(ObjectGuid guid1, ObjectGuid guid2)  {      Player* plr1 = ObjectAccessor::FindConnectedPlayer(guid1);      Player* plr2 = ObjectAccessor::FindConnectedPlayer(guid2); -    return plr1 && plr2 && (plr1->GetSocial()->HasIgnore(guid2.GetCounter()) || plr2->GetSocial()->HasIgnore(guid1.GetCounter())); +    return plr1 && plr2 && (plr1->GetSocial()->HasIgnore(guid2) || plr2->GetSocial()->HasIgnore(guid1));  }  void LFGMgr::SendLfgRoleChosen(ObjectGuid guid, ObjectGuid pguid, uint8 roles) diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 44864eaa9a1..798328be431 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -4378,16 +4378,15 @@ void Player::DeleteFromDB(ObjectGuid playerguid, uint32 accountId, bool updateRe              // Delete char from social list of online chars              stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_SOCIAL);              stmt->setUInt32(0, guid); -            PreparedQueryResult resultFriends = CharacterDatabase.Query(stmt); -            if (resultFriends) +            if (PreparedQueryResult resultFriends = CharacterDatabase.Query(stmt))              {                  do                  { -                    if (Player* pFriend = ObjectAccessor::FindPlayer(ObjectGuid(HighGuid::Player, 0, (*resultFriends)[0].GetUInt32()))) +                    if (Player* playerFriend = ObjectAccessor::FindPlayer(ObjectGuid(HighGuid::Player, 0, (*resultFriends)[0].GetUInt32())))                      { -                        pFriend->GetSocial()->RemoveFromSocialList(guid, false); -                        sSocialMgr->SendFriendStatus(pFriend, FRIEND_REMOVED, guid, false); +                        playerFriend->GetSocial()->RemoveFromSocialList(playerguid, SOCIAL_FLAG_ALL); +                        sSocialMgr->SendFriendStatus(playerFriend, FRIEND_REMOVED, playerguid);                      }                  } while (resultFriends->NextRow());              } @@ -17624,7 +17623,7 @@ bool Player::LoadFromDB(ObjectGuid guid, SQLQueryHolder *holder)      // unread mails and next delivery time, actual mails not loaded      _LoadMailInit(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_MAIL_COUNT), holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_MAIL_DATE)); -    m_social = sSocialMgr->LoadFromDB(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_SOCIAL_LIST), GetGUID().GetCounter()); +    m_social = sSocialMgr->LoadFromDB(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_SOCIAL_LIST), GetGUID());      // check PLAYER_CHOSEN_TITLE compatibility with PLAYER__FIELD_KNOWN_TITLES      // note: PLAYER__FIELD_KNOWN_TITLES updated at quest status loaded @@ -22480,7 +22479,7 @@ void Player::SetGroup(Group* group, int8 subgroup)  void Player::SendInitialPacketsBeforeAddToMap()  {      /// Pass 'this' as argument because we're not stored in ObjectAccessor yet -    GetSocial()->SendSocialList(this); +    GetSocial()->SendSocialList(this, SOCIAL_FLAG_ALL);      // guild bank list wtf? @@ -26629,3 +26628,9 @@ uint32 Player::DoRandomRoll(uint32 minimum, uint32 maximum)      return roll;  } + +void Player::RemoveSocial() +{ +    sSocialMgr->RemovePlayerSocial(GetGUID()); +    m_social = nullptr; +} diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index 146bf3afa80..9fcf2bb89d8 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -1094,7 +1094,8 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>          uint32 GetBarberShopCost(uint8 newhairstyle, uint8 newhaircolor, uint8 newfacialhair, BarberShopStyleEntry const* newSkin = nullptr) const; -        PlayerSocial *GetSocial() const { return m_social; } +        PlayerSocial* GetSocial() { return m_social; } +        void RemoveSocial();          PlayerTaxi m_taxi;          void InitTaxiNodesForLevel() { m_taxi.InitTaxiNodesForLevel(getRace(), getClass(), getLevel()); } @@ -2500,7 +2501,7 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>          uint32 m_questRewardTalentCount;          // Social -        PlayerSocial *m_social; +        PlayerSocial* m_social;          // Groups          GroupReference m_group; diff --git a/src/server/game/Entities/Player/SocialMgr.cpp b/src/server/game/Entities/Player/SocialMgr.cpp index 0527378bb4e..0390dc4b025 100644 --- a/src/server/game/Entities/Player/SocialMgr.cpp +++ b/src/server/game/Entities/Player/SocialMgr.cpp @@ -17,104 +17,85 @@   */  #include "SocialMgr.h" - -#include "DatabaseEnv.h"  #include "WorldSession.h"  #include "WorldPacket.h" +#include "DatabaseEnv.h" +#include "ObjectAccessor.h"  #include "Player.h" -#include "ObjectMgr.h"  #include "World.h" -#include "Util.h" -#include "AccountMgr.h" -PlayerSocial::PlayerSocial(): m_playerGUID() +PlayerSocial::PlayerSocial(): _playerGUID()  { }  uint32 PlayerSocial::GetNumberOfSocialsWithFlag(SocialFlag flag)  {      uint32 counter = 0; -    for (PlayerSocialMap::const_iterator itr = m_playerSocialMap.begin(); itr != m_playerSocialMap.end(); ++itr) -        if (itr->second.Flags & flag) +    for (PlayerSocialMap::const_iterator itr = _playerSocialMap.begin(); itr != _playerSocialMap.end(); ++itr) +        if ((itr->second.Flags & flag) != 0)              ++counter;      return counter;  } -bool PlayerSocial::AddToSocialList(ObjectGuid::LowType friendGuid, bool ignore) +bool PlayerSocial::AddToSocialList(ObjectGuid const& friendGuid, SocialFlag flag)  {      // check client limits -    if (ignore) -    { -        if (GetNumberOfSocialsWithFlag(SOCIAL_FLAG_IGNORED) >= SOCIALMGR_IGNORE_LIMIT) -            return false; -    } -    else -    { -        if (GetNumberOfSocialsWithFlag(SOCIAL_FLAG_FRIEND) >= SOCIALMGR_FRIEND_LIMIT) -            return false; -    } - -    uint8 flag = SOCIAL_FLAG_FRIEND; -    if (ignore) -        flag = SOCIAL_FLAG_IGNORED; +    if (GetNumberOfSocialsWithFlag(flag) >= (((flag & SOCIAL_FLAG_FRIEND) != 0) ? SOCIALMGR_FRIEND_LIMIT : SOCIALMGR_IGNORE_LIMIT)) +        return false; -    PlayerSocialMap::const_iterator itr = m_playerSocialMap.find(friendGuid); -    if (itr != m_playerSocialMap.end()) +    PlayerSocialMap::iterator itr = _playerSocialMap.find(friendGuid); +    if (itr != _playerSocialMap.end())      { -        PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_ADD_CHARACTER_SOCIAL_FLAGS); +        itr->second.Flags |= flag; -        stmt->setUInt8(0, flag); -        stmt->setUInt32(1, GetPlayerGUID()); -        stmt->setUInt32(2, friendGuid); +        PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHARACTER_SOCIAL_FLAGS); -        CharacterDatabase.Execute(stmt); +        stmt->setUInt8(0, itr->second.Flags); +        stmt->setUInt32(1, GetPlayerGUID().GetCounter()); +        stmt->setUInt32(2, friendGuid.GetCounter()); -        m_playerSocialMap[friendGuid].Flags |= flag; +        CharacterDatabase.Execute(stmt);      }      else      { +        _playerSocialMap[friendGuid].Flags |= flag; +          PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_CHARACTER_SOCIAL); -        stmt->setUInt32(0, GetPlayerGUID()); -        stmt->setUInt32(1, friendGuid); +        stmt->setUInt32(0, GetPlayerGUID().GetCounter()); +        stmt->setUInt32(1, friendGuid.GetCounter());          stmt->setUInt8(2, flag);          CharacterDatabase.Execute(stmt); - -        FriendInfo fi; -        fi.Flags |= flag; -        m_playerSocialMap[friendGuid] = fi;      } +      return true;  } -void PlayerSocial::RemoveFromSocialList(ObjectGuid::LowType friendGuid, bool ignore) +void PlayerSocial::RemoveFromSocialList(ObjectGuid const& friendGuid, SocialFlag flag)  { -    PlayerSocialMap::iterator itr = m_playerSocialMap.find(friendGuid); -    if (itr == m_playerSocialMap.end())                     // not exist +    PlayerSocialMap::iterator itr = _playerSocialMap.find(friendGuid); +    if (itr == _playerSocialMap.end())          return; -    uint8 flag = SOCIAL_FLAG_FRIEND; -    if (ignore) -        flag = SOCIAL_FLAG_IGNORED; -      itr->second.Flags &= ~flag; -    if (itr->second.Flags == 0) + +    if (!itr->second.Flags)      {          PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHARACTER_SOCIAL); -        stmt->setUInt32(0, GetPlayerGUID()); -        stmt->setUInt32(1, friendGuid); +        stmt->setUInt32(0, GetPlayerGUID().GetCounter()); +        stmt->setUInt32(1, friendGuid.GetCounter());          CharacterDatabase.Execute(stmt); -        m_playerSocialMap.erase(itr); +        _playerSocialMap.erase(itr);      }      else      { -        PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_REM_CHARACTER_SOCIAL_FLAGS); +        PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHARACTER_SOCIAL_FLAGS); -        stmt->setUInt8(0, flag); +        stmt->setUInt8(0, itr->second.Flags);          stmt->setUInt32(1, GetPlayerGUID());          stmt->setUInt32(2, friendGuid); @@ -122,78 +103,83 @@ void PlayerSocial::RemoveFromSocialList(ObjectGuid::LowType friendGuid, bool ign      }  } -void PlayerSocial::SetFriendNote(ObjectGuid::LowType friendGuid, std::string note) +void PlayerSocial::SetFriendNote(ObjectGuid const& friendGuid, std::string const& note)  { -    PlayerSocialMap::const_iterator itr = m_playerSocialMap.find(friendGuid); -    if (itr == m_playerSocialMap.end())                     // not exist +    PlayerSocialMap::iterator itr = _playerSocialMap.find(friendGuid); +    if (itr == _playerSocialMap.end())                  // not exist          return; -    utf8truncate(note, 48);                                  // DB and client size limitation +    itr->second.Note = note; +    utf8truncate(itr->second.Note, 48);                 // DB and client size limitation      PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHARACTER_SOCIAL_NOTE); -    stmt->setString(0, note); -    stmt->setUInt32(1, GetPlayerGUID()); -    stmt->setUInt32(2, friendGuid); +    stmt->setString(0, itr->second.Note); +    stmt->setUInt32(1, GetPlayerGUID().GetCounter()); +    stmt->setUInt32(2, friendGuid.GetCounter());      CharacterDatabase.Execute(stmt); - -    m_playerSocialMap[friendGuid].Note = note;  } -void PlayerSocial::SendSocialList(Player* player) +void PlayerSocial::SendSocialList(Player* player, uint32 flags)  { -    if (!player) -        return; +    ASSERT(player); -    uint32 size = m_playerSocialMap.size(); +    uint32 size = _playerSocialMap.size(); -    WorldPacket data(SMSG_CONTACT_LIST, (4+4+size*25));     // just can guess size -    data << uint32(7);                                      // 0x1 = Friendlist update. 0x2 = Ignorelist update. 0x4 = Mutelist update. -    data << uint32(size);                                   // friends count +    uint32 count = 0; +    WorldPacket data(SMSG_CONTACT_LIST, (4 + 4 + size * 25)); // just can guess size +    data << uint32(flags);                                    // 0x1 = Friendlist update. 0x2 = Ignorelist update. 0x4 = Mutelist update. +    data << uint32(size);                                     // friends count -    for (PlayerSocialMap::iterator itr = m_playerSocialMap.begin(); itr != m_playerSocialMap.end(); ++itr) +    for (PlayerSocialMap::value_type& v : _playerSocialMap)      { -        sSocialMgr->GetFriendInfo(player, itr->first, itr->second); +        if (!(v.second.Flags & flags)) +            continue; + +        ++count; +        sSocialMgr->GetFriendInfo(player, v.first, v.second); -        data << uint64(itr->first);                         // player guid -        data << uint32(itr->second.Flags);                  // player flag (0x1 = Friend, 0x2 = Ignored, 0x4 = Muted) -        data << itr->second.Note;                           // string note -        if (itr->second.Flags & SOCIAL_FLAG_FRIEND)         // if IsFriend() +        data << uint64(v.first);                              // player guid +        data << uint32(v.second.Flags);                       // player flag (0x1 = Friend, 0x2 = Ignored, 0x4 = Muted) +        data << v.second.Note;                                // string note +        if (v.second.Flags & SOCIAL_FLAG_FRIEND)              // if IsFriend()          { -            data << uint8(itr->second.Status);              // online/offline/etc? -            if (itr->second.Status)                         // if online +            data << uint8(v.second.Status);                   // online/offline/etc? +            if (v.second.Status)                              // if online              { -                data << uint32(itr->second.Area);           // player area -                data << uint32(itr->second.Level);          // player level -                data << uint32(itr->second.Class);          // player class +                data << uint32(v.second.Area);                // player area +                data << uint32(v.second.Level);               // player level +                data << uint32(v.second.Class);               // player class              }          } + +        // client's friends list and ignore list limit +        if (count >= (((flags & SOCIAL_FLAG_FRIEND) != 0) ? SOCIALMGR_FRIEND_LIMIT : SOCIALMGR_IGNORE_LIMIT)) +            break;      } -    player->GetSession()->SendPacket(&data); -    TC_LOG_DEBUG("network", "WORLD: Sent SMSG_CONTACT_LIST"); +    player->SendDirectMessage(&data);  } -bool PlayerSocial::HasFriend(ObjectGuid::LowType friendGuid) +bool PlayerSocial::_HasContact(ObjectGuid const& guid, SocialFlag flags)  { -    PlayerSocialMap::const_iterator itr = m_playerSocialMap.find(friendGuid); -    if (itr != m_playerSocialMap.end()) -        return itr->second.Flags & SOCIAL_FLAG_FRIEND; +    PlayerSocialMap::const_iterator itr = _playerSocialMap.find(guid); +    if (itr != _playerSocialMap.end()) +        return (itr->second.Flags & flags) != 0; +      return false;  } -bool PlayerSocial::HasIgnore(ObjectGuid::LowType ignore_guid) +bool PlayerSocial::HasFriend(ObjectGuid const& friendGuid)  { -    PlayerSocialMap::const_iterator itr = m_playerSocialMap.find(ignore_guid); -    if (itr != m_playerSocialMap.end()) -        return (itr->second.Flags & SOCIAL_FLAG_IGNORED) != 0; -    return false; +    return _HasContact(friendGuid, SOCIAL_FLAG_FRIEND);  } -SocialMgr::SocialMgr() { } - -SocialMgr::~SocialMgr() { } +bool PlayerSocial::HasIgnore(ObjectGuid const& ignoreGuid) +{ +    return _HasContact(ignoreGuid, SOCIAL_FLAG_IGNORED); +}  SocialMgr* SocialMgr::instance()  { @@ -201,7 +187,7 @@ SocialMgr* SocialMgr::instance()      return &instance;  } -void SocialMgr::GetFriendInfo(Player* player, ObjectGuid::LowType friendGUID, FriendInfo &friendInfo) +void SocialMgr::GetFriendInfo(Player* player, ObjectGuid const& friendGUID, FriendInfo& friendInfo)  {      if (!player)          return; @@ -211,12 +197,12 @@ void SocialMgr::GetFriendInfo(Player* player, ObjectGuid::LowType friendGUID, Fr      friendInfo.Level = 0;      friendInfo.Class = 0; -    Player* target = ObjectAccessor::FindPlayer(ObjectGuid(HighGuid::Player, friendGUID)); +    Player* target = ObjectAccessor::FindPlayer(friendGUID);      if (!target)          return; -    PlayerSocialMap::iterator itr = player->GetSocial()->m_playerSocialMap.find(friendGUID); -    if (itr != player->GetSocial()->m_playerSocialMap.end()) +    PlayerSocial::PlayerSocialMap::iterator itr = player->GetSocial()->_playerSocialMap.find(friendGUID); +    if (itr != player->GetSocial()->_playerSocialMap.end())          friendInfo.Note = itr->second.Note;      // PLAYER see his team only and PLAYER can't see MODERATOR, GAME MASTER, ADMINISTRATOR characters @@ -245,20 +231,14 @@ void SocialMgr::GetFriendInfo(Player* player, ObjectGuid::LowType friendGUID, Fr      }  } -void SocialMgr::MakeFriendStatusPacket(FriendsResult result, ObjectGuid::LowType guid, WorldPacket* data) -{ -    data->Initialize(SMSG_FRIEND_STATUS, 9); -    *data << uint8(result); -    *data << uint64(guid); -} - -void SocialMgr::SendFriendStatus(Player* player, FriendsResult result, ObjectGuid::LowType friendGuid, bool broadcast) +void SocialMgr::SendFriendStatus(Player* player, FriendsResult result, ObjectGuid const& friendGuid, bool broadcast /*= false*/)  {      FriendInfo fi; - -    WorldPacket data; -    MakeFriendStatusPacket(result, friendGuid, &data);      GetFriendInfo(player, friendGuid, fi); + +    WorldPacket data(SMSG_FRIEND_STATUS, 9); +    data << uint8(result); +    data << friendGuid;      switch (result)      {          case FRIEND_ADDED_OFFLINE: @@ -285,21 +265,20 @@ void SocialMgr::SendFriendStatus(Player* player, FriendsResult result, ObjectGui      if (broadcast)          BroadcastToFriendListers(player, &data);      else -        player->GetSession()->SendPacket(&data); +        player->SendDirectMessage(&data);  } -void SocialMgr::BroadcastToFriendListers(Player* player, WorldPacket* packet) +void SocialMgr::BroadcastToFriendListers(Player* player, WorldPacket const* packet)  { -    if (!player) -        return; +    ASSERT(player);      AccountTypes gmSecLevel = AccountTypes(sWorld->getIntConfig(CONFIG_GM_LEVEL_IN_WHO_LIST)); -    for (SocialMap::const_iterator itr = m_socialMap.begin(); itr != m_socialMap.end(); ++itr) +    for (SocialMap::const_iterator itr = _socialMap.begin(); itr != _socialMap.end(); ++itr)      { -        PlayerSocialMap::const_iterator itr2 = itr->second.m_playerSocialMap.find(player->GetGUID().GetCounter()); -        if (itr2 != itr->second.m_playerSocialMap.end() && (itr2->second.Flags & SOCIAL_FLAG_FRIEND)) +        PlayerSocial::PlayerSocialMap::const_iterator itr2 = itr->second._playerSocialMap.find(player->GetGUID()); +        if (itr2 != itr->second._playerSocialMap.end() && (itr2->second.Flags & SOCIAL_FLAG_FRIEND) != 0)          { -            Player* target = ObjectAccessor::FindPlayer(ObjectGuid(HighGuid::Player, 0, itr->first)); +            Player* target = ObjectAccessor::FindPlayer(itr->first);              if (!target)                  continue; @@ -316,33 +295,24 @@ void SocialMgr::BroadcastToFriendListers(Player* player, WorldPacket* packet)      }  } -PlayerSocial* SocialMgr::LoadFromDB(PreparedQueryResult result, ObjectGuid::LowType guid) +PlayerSocial* SocialMgr::LoadFromDB(PreparedQueryResult result, ObjectGuid const& guid)  { -    PlayerSocial *social = &m_socialMap[guid]; +    PlayerSocial* social = &_socialMap[guid];      social->SetPlayerGUID(guid); -    if (!result) -        return social; - -    ObjectGuid::LowType friendGuid = 0; -    uint8 flags = 0; -    std::string note = ""; - -    do +    if (result)      { -        Field* fields = result->Fetch(); - -        friendGuid = fields[0].GetUInt32(); -        flags = fields[1].GetUInt8(); -        note = fields[2].GetString(); +        do +        { +            Field* fields = result->Fetch(); -        social->m_playerSocialMap[friendGuid] = FriendInfo(flags, note); +            ObjectGuid friendGuid = ObjectGuid::Create<HighGuid::Player>(fields[0].GetUInt32()); -        // client's friends list and ignore list limit -        if (social->m_playerSocialMap.size() >= (SOCIALMGR_FRIEND_LIMIT + SOCIALMGR_IGNORE_LIMIT)) -            break; +            uint8 flag = fields[1].GetUInt8(); +            social->_playerSocialMap[friendGuid] = FriendInfo(flag, fields[2].GetString()); +        } +        while (result->NextRow());      } -    while (result->NextRow());      return social;  } diff --git a/src/server/game/Entities/Player/SocialMgr.h b/src/server/game/Entities/Player/SocialMgr.h index de1f7664ac8..adb3abcfae6 100644 --- a/src/server/game/Entities/Player/SocialMgr.h +++ b/src/server/game/Entities/Player/SocialMgr.h @@ -23,10 +23,7 @@  #include "Common.h"  #include "ObjectGuid.h" -class SocialMgr; -class PlayerSocial;  class Player; -class WorldPacket;  enum FriendStatus  { @@ -42,7 +39,9 @@ enum SocialFlag      SOCIAL_FLAG_FRIEND      = 0x01,      SOCIAL_FLAG_IGNORED     = 0x02,      SOCIAL_FLAG_MUTED       = 0x04,                          // guessed -    SOCIAL_FLAG_UNK         = 0x08                           // Unknown - does not appear to be RaF +    SOCIAL_FLAG_UNK         = 0x08,                          // Unknown - does not appear to be RaF + +    SOCIAL_FLAG_ALL         = SOCIAL_FLAG_FRIEND | SOCIAL_FLAG_IGNORED | SOCIAL_FLAG_MUTED  };  struct FriendInfo @@ -61,11 +60,8 @@ struct FriendInfo      { }  }; -typedef std::map<ObjectGuid::LowType, FriendInfo> PlayerSocialMap; -typedef std::map<ObjectGuid::LowType, PlayerSocial> SocialMap; -  /// Results of friend related commands -enum FriendsResult +enum FriendsResult : uint8  {      FRIEND_DB_ERROR         = 0x00,      FRIEND_LIST_FULL        = 0x01, @@ -92,57 +88,73 @@ enum FriendsResult      FRIEND_MUTE_ADDED       = 0x16,      FRIEND_MUTE_REMOVED     = 0x17,      FRIEND_MUTE_AMBIGUOUS   = 0x18,                         // That name is ambiguous, type more of the player's server name -    FRIEND_UNK7             = 0x19,                         // no message at client -    FRIEND_UNKNOWN          = 0x1A                          // Unknown friend response from server +    FRIEND_UNK1             = 0x19,                         // no message at client +    FRIEND_UNK2             = 0x1A, +    FRIEND_UNK3             = 0x1B, +    FRIEND_UNKNOWN          = 0x1C                          // Unknown friend response from server  }; -#define SOCIALMGR_FRIEND_LIMIT  50 -#define SOCIALMGR_IGNORE_LIMIT  50 +#define SOCIALMGR_FRIEND_LIMIT  50u +#define SOCIALMGR_IGNORE_LIMIT  50u  class TC_GAME_API PlayerSocial  {      friend class SocialMgr; +      public:          PlayerSocial();          // adding/removing -        bool AddToSocialList(ObjectGuid::LowType friendGuid, bool ignore); -        void RemoveFromSocialList(ObjectGuid::LowType friend_guid, bool ignore); -        void SetFriendNote(ObjectGuid::LowType friendGuid, std::string note); +        bool AddToSocialList(ObjectGuid const& guid, SocialFlag flag); +        void RemoveFromSocialList(ObjectGuid const& guid, SocialFlag flag); +        void SetFriendNote(ObjectGuid const& guid, std::string const& note); +          // Packet send's -        void SendSocialList(Player* player); +        void SendSocialList(Player* player, uint32 flags); +          // Misc -        bool HasFriend(ObjectGuid::LowType friend_guid); -        bool HasIgnore(ObjectGuid::LowType ignore_guid); -        ObjectGuid::LowType GetPlayerGUID() const { return m_playerGUID; } -        void SetPlayerGUID(ObjectGuid::LowType guid) { m_playerGUID = guid; } +        bool HasFriend(ObjectGuid const& friendGuid); +        bool HasIgnore(ObjectGuid const& ignoreGuid); + +        ObjectGuid const& GetPlayerGUID() const { return _playerGUID; } +        void SetPlayerGUID(ObjectGuid const& guid) { _playerGUID = guid; } +          uint32 GetNumberOfSocialsWithFlag(SocialFlag flag); +      private: -        PlayerSocialMap m_playerSocialMap; -        ObjectGuid::LowType m_playerGUID; +        bool _HasContact(ObjectGuid const& guid, SocialFlag flags); + +        typedef std::map<ObjectGuid, FriendInfo> PlayerSocialMap; +        PlayerSocialMap _playerSocialMap; + +        ObjectGuid _playerGUID;  };  class SocialMgr  {      private: -        SocialMgr(); -        ~SocialMgr(); +        SocialMgr() { } +        ~SocialMgr() { }      public:          static SocialMgr* instance();          // Misc -        void RemovePlayerSocial(ObjectGuid::LowType guid) { m_socialMap.erase(guid); } +        void RemovePlayerSocial(ObjectGuid const& guid) { _socialMap.erase(guid); } + +        void GetFriendInfo(Player* player, ObjectGuid const& friendGUID, FriendInfo& friendInfo); + +        // Packet send's +        void SendFriendStatus(Player* player, FriendsResult result, ObjectGuid const& friendGuid, bool broadcast = false); +        void BroadcastToFriendListers(Player* player, WorldPacket const* packet); -        void GetFriendInfo(Player* player, ObjectGuid::LowType friendGUID, FriendInfo &friendInfo); -        // Packet management -        void MakeFriendStatusPacket(FriendsResult result, ObjectGuid::LowType friend_guid, WorldPacket* data); -        void SendFriendStatus(Player* player, FriendsResult result, ObjectGuid::LowType friend_guid, bool broadcast); -        void BroadcastToFriendListers(Player* player, WorldPacket* packet);          // Loading -        PlayerSocial *LoadFromDB(PreparedQueryResult result, ObjectGuid::LowType guid); +        PlayerSocial* LoadFromDB(PreparedQueryResult result, ObjectGuid const& guid); +      private: -        SocialMap m_socialMap; +        typedef std::map<ObjectGuid, PlayerSocial> SocialMap; +        SocialMap _socialMap;  };  #define sSocialMgr SocialMgr::instance() +  #endif diff --git a/src/server/game/Guilds/Guild.cpp b/src/server/game/Guilds/Guild.cpp index 73117473359..1812a4b059b 100644 --- a/src/server/game/Guilds/Guild.cpp +++ b/src/server/game/Guilds/Guild.cpp @@ -1523,7 +1523,7 @@ void Guild::HandleInviteMember(WorldSession* session, std::string const& name)      Player* player = session->GetPlayer();      // Do not show invitations from ignored players -    if (pInvitee->GetSocial()->HasIgnore(player->GetGUID().GetCounter())) +    if (pInvitee->GetSocial()->HasIgnore(player->GetGUID()))          return;      if (!sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD) && pInvitee->GetTeam() != player->GetTeam()) @@ -2159,7 +2159,7 @@ void Guild::BroadcastToGuild(WorldSession* session, bool officerOnly, std::strin          for (auto itr = m_members.begin(); itr != m_members.end(); ++itr)              if (Player* player = itr->second->FindConnectedPlayer())                  if (player->GetSession() && _HasRankRight(player, officerOnly ? GR_RIGHT_OFFCHATLISTEN : GR_RIGHT_GCHATLISTEN) && -                    !player->GetSocial()->HasIgnore(session->GetPlayer()->GetGUID().GetCounter())) +                    !player->GetSocial()->HasIgnore(session->GetPlayer()->GetGUID()))                      player->GetSession()->SendPacket(&data);      }  } diff --git a/src/server/game/Handlers/ArenaTeamHandler.cpp b/src/server/game/Handlers/ArenaTeamHandler.cpp index 1c39caa8087..831f73332d3 100644 --- a/src/server/game/Handlers/ArenaTeamHandler.cpp +++ b/src/server/game/Handlers/ArenaTeamHandler.cpp @@ -125,7 +125,7 @@ void WorldSession::HandleArenaTeamInviteOpcode(WorldPacket& recvData)      }      // OK result but don't send invite -    if (player->GetSocial()->HasIgnore(GetPlayer()->GetGUID().GetCounter())) +    if (player->GetSocial()->HasIgnore(GetPlayer()->GetGUID()))          return;      if (!sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD) && player->GetTeam() != GetPlayer()->GetTeam()) diff --git a/src/server/game/Handlers/CharacterHandler.cpp b/src/server/game/Handlers/CharacterHandler.cpp index d9950f2f6ca..cab80d23cba 100644 --- a/src/server/game/Handlers/CharacterHandler.cpp +++ b/src/server/game/Handlers/CharacterHandler.cpp @@ -917,7 +917,7 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder* holder)      }      // friend status -    sSocialMgr->SendFriendStatus(pCurrChar, FRIEND_ONLINE, pCurrChar->GetGUID().GetCounter(), true); +    sSocialMgr->SendFriendStatus(pCurrChar, FRIEND_ONLINE, pCurrChar->GetGUID(), true);      // Place character in world (and load zone) before some object loading      pCurrChar->LoadCorpse(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_CORPSE_LOCATION)); diff --git a/src/server/game/Handlers/GroupHandler.cpp b/src/server/game/Handlers/GroupHandler.cpp index 9ee0e387c1b..cf716855175 100644 --- a/src/server/game/Handlers/GroupHandler.cpp +++ b/src/server/game/Handlers/GroupHandler.cpp @@ -114,13 +114,13 @@ void WorldSession::HandleGroupInviteOpcode(WorldPacket& recvData)          return;      } -    if (player->GetSocial()->HasIgnore(GetPlayer()->GetGUID().GetCounter())) +    if (player->GetSocial()->HasIgnore(GetPlayer()->GetGUID()))      {          SendPartyResult(PARTY_OP_INVITE, membername, ERR_IGNORING_YOU_S);          return;      } -    if (!player->GetSocial()->HasFriend(GetPlayer()->GetGUID().GetCounter()) && GetPlayer()->getLevel() < sWorld->getIntConfig(CONFIG_PARTY_LEVEL_REQ)) +    if (!player->GetSocial()->HasFriend(GetPlayer()->GetGUID()) && GetPlayer()->getLevel() < sWorld->getIntConfig(CONFIG_PARTY_LEVEL_REQ))      {          SendPartyResult(PARTY_OP_INVITE, membername, ERR_INVITE_RESTRICTED);          return; diff --git a/src/server/game/Handlers/MiscHandler.cpp b/src/server/game/Handlers/MiscHandler.cpp index 9043eb7cc2c..4a80c2f07df 100644 --- a/src/server/game/Handlers/MiscHandler.cpp +++ b/src/server/game/Handlers/MiscHandler.cpp @@ -34,7 +34,6 @@  #include "Object.h"  #include "Battleground.h"  #include "OutdoorPvP.h" -#include "SocialMgr.h"  #include "AccountMgr.h"  #include "DBCEnums.h"  #include "ScriptMgr.h" @@ -514,188 +513,6 @@ void WorldSession::HandleStandStateChangeOpcode(WorldPacket& recvData)      _player->SetStandState(animstate);  } -void WorldSession::HandleContactListOpcode(WorldPacket& recvData) -{ -    uint32 unk; -    recvData >> unk; -    TC_LOG_DEBUG("network", "WORLD: Received CMSG_CONTACT_LIST - Unk: %d", unk); -    _player->GetSocial()->SendSocialList(_player); -} - -void WorldSession::HandleAddFriendOpcode(WorldPacket& recvData) -{ -    TC_LOG_DEBUG("network", "WORLD: Received CMSG_ADD_FRIEND"); - -    std::string friendName = GetTrinityString(LANG_FRIEND_IGNORE_UNKNOWN); -    std::string friendNote; - -    recvData >> friendName; - -    recvData >> friendNote; - -    if (!normalizePlayerName(friendName)) -        return; - -    TC_LOG_DEBUG("network", "WORLD: %s asked to add friend : '%s'", -        GetPlayer()->GetName().c_str(), friendName.c_str()); - -    PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_GUID_RACE_ACC_BY_NAME); - -    stmt->setString(0, friendName); - -    _addFriendCallback.SetParam(friendNote); -    _addFriendCallback.SetFutureResult(CharacterDatabase.AsyncQuery(stmt)); -} - -void WorldSession::HandleAddFriendOpcodeCallBack(PreparedQueryResult result, std::string const& friendNote) -{ -    if (!GetPlayer()) -        return; - -    ObjectGuid friendGuid; -    uint32 friendAccountId; -    uint32 team; -    FriendsResult friendResult; - -    friendResult = FRIEND_NOT_FOUND; - -    if (result) -    { -        Field* fields = result->Fetch(); - -        friendGuid = ObjectGuid(HighGuid::Player, 0, fields[0].GetUInt32()); -        team = Player::TeamForRace(fields[1].GetUInt8()); -        friendAccountId = fields[2].GetUInt32(); - -        if (HasPermission(rbac::RBAC_PERM_ALLOW_GM_FRIEND) || AccountMgr::IsPlayerAccount(AccountMgr::GetSecurity(friendAccountId, realm.Id.Realm))) -        { -            if (friendGuid) -            { -                if (friendGuid == GetPlayer()->GetGUID()) -                    friendResult = FRIEND_SELF; -                else if (GetPlayer()->GetTeam() != team && !HasPermission(rbac::RBAC_PERM_TWO_SIDE_ADD_FRIEND)) -                    friendResult = FRIEND_ENEMY; -                else if (GetPlayer()->GetSocial()->HasFriend(friendGuid.GetCounter())) -                    friendResult = FRIEND_ALREADY; -                else -                { -                    Player* pFriend = ObjectAccessor::FindPlayer(friendGuid); -                    if (pFriend && pFriend->IsVisibleGloballyFor(GetPlayer())) -                        friendResult = FRIEND_ADDED_ONLINE; -                    else -                        friendResult = FRIEND_ADDED_OFFLINE; -                    if (!GetPlayer()->GetSocial()->AddToSocialList(friendGuid.GetCounter(), false)) -                    { -                        friendResult = FRIEND_LIST_FULL; -                        TC_LOG_DEBUG("network", "WORLD: %s's friend list is full.", GetPlayer()->GetName().c_str()); -                    } -                } -                GetPlayer()->GetSocial()->SetFriendNote(friendGuid.GetCounter(), friendNote); -            } -        } -    } - -    sSocialMgr->SendFriendStatus(GetPlayer(), friendResult, friendGuid.GetCounter(), false); - -    TC_LOG_DEBUG("network", "WORLD: Sent (SMSG_FRIEND_STATUS)"); -} - -void WorldSession::HandleDelFriendOpcode(WorldPacket& recvData) -{ -    ObjectGuid FriendGUID; - -    TC_LOG_DEBUG("network", "WORLD: Received CMSG_DEL_FRIEND"); - -    recvData >> FriendGUID; - -    _player->GetSocial()->RemoveFromSocialList(FriendGUID.GetCounter(), false); - -    sSocialMgr->SendFriendStatus(GetPlayer(), FRIEND_REMOVED, FriendGUID.GetCounter(), false); - -    TC_LOG_DEBUG("network", "WORLD: Sent motd (SMSG_FRIEND_STATUS)"); -} - -void WorldSession::HandleAddIgnoreOpcode(WorldPacket& recvData) -{ -    TC_LOG_DEBUG("network", "WORLD: Received CMSG_ADD_IGNORE"); - -    std::string ignoreName = GetTrinityString(LANG_FRIEND_IGNORE_UNKNOWN); - -    recvData >> ignoreName; - -    if (!normalizePlayerName(ignoreName)) -        return; - -    TC_LOG_DEBUG("network", "WORLD: %s asked to Ignore: '%s'", -        GetPlayer()->GetName().c_str(), ignoreName.c_str()); - -    PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_GUID_BY_NAME); - -    stmt->setString(0, ignoreName); - -    _addIgnoreCallback = CharacterDatabase.AsyncQuery(stmt); -} - -void WorldSession::HandleAddIgnoreOpcodeCallBack(PreparedQueryResult result) -{ -    if (!GetPlayer()) -        return; - -    ObjectGuid IgnoreGuid; -    FriendsResult ignoreResult; - -    ignoreResult = FRIEND_IGNORE_NOT_FOUND; - -    if (result) -    { -        IgnoreGuid = ObjectGuid(HighGuid::Player, (*result)[0].GetUInt32()); - -        if (IgnoreGuid) -        { -            if (IgnoreGuid == GetPlayer()->GetGUID())              //not add yourself -                ignoreResult = FRIEND_IGNORE_SELF; -            else if (GetPlayer()->GetSocial()->HasIgnore(IgnoreGuid.GetCounter())) -                ignoreResult = FRIEND_IGNORE_ALREADY; -            else -            { -                ignoreResult = FRIEND_IGNORE_ADDED; - -                // ignore list full -                if (!GetPlayer()->GetSocial()->AddToSocialList(IgnoreGuid.GetCounter(), true)) -                    ignoreResult = FRIEND_IGNORE_FULL; -            } -        } -    } - -    sSocialMgr->SendFriendStatus(GetPlayer(), ignoreResult, IgnoreGuid.GetCounter(), false); - -    TC_LOG_DEBUG("network", "WORLD: Sent (SMSG_FRIEND_STATUS)"); -} - -void WorldSession::HandleDelIgnoreOpcode(WorldPacket& recvData) -{ -    ObjectGuid IgnoreGUID; - -    TC_LOG_DEBUG("network", "WORLD: Received CMSG_DEL_IGNORE"); - -    recvData >> IgnoreGUID; - -    _player->GetSocial()->RemoveFromSocialList(IgnoreGUID.GetCounter(), true); - -    sSocialMgr->SendFriendStatus(GetPlayer(), FRIEND_IGNORE_REMOVED, IgnoreGUID.GetCounter(), false); - -    TC_LOG_DEBUG("network", "WORLD: Sent motd (SMSG_FRIEND_STATUS)"); -} - -void WorldSession::HandleSetContactNotesOpcode(WorldPacket& recvData) -{ -    TC_LOG_DEBUG("network", "CMSG_SET_CONTACT_NOTES"); -    ObjectGuid guid; -    std::string note; -    recvData >> guid >> note; -    _player->GetSocial()->SetFriendNote(guid.GetCounter(), note); -} -  void WorldSession::HandleBugOpcode(WorldPacket& recvData)  {      uint32 suggestion, contentlen, typelen; diff --git a/src/server/game/Handlers/SocialHandler.cpp b/src/server/game/Handlers/SocialHandler.cpp new file mode 100644 index 00000000000..cd9968bf84e --- /dev/null +++ b/src/server/game/Handlers/SocialHandler.cpp @@ -0,0 +1,177 @@ +/* + * Copyright (C) 2008-2017 TrinityCore <http://www.trinitycore.org/> + * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "WorldSession.h" +#include "Player.h" +#include "SocialMgr.h" +#include "ObjectMgr.h" + +void WorldSession::HandleContactListOpcode(WorldPacket& recvData) +{ +    uint32 flags; +    recvData >> flags; +    _player->GetSocial()->SendSocialList(_player, flags); +} + +void WorldSession::HandleAddFriendOpcode(WorldPacket& recvData) +{ +    std::string friendName, friendNote; +    recvData >> friendName >> friendNote; + +    if (!normalizePlayerName(friendName)) +        return; + +    TC_LOG_DEBUG("network", "WorldSession::HandleAddFriendOpcode: %s asked to add friend: %s", +        GetPlayer()->GetName().c_str(), friendName.c_str()); + +    PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_GUID_RACE_ACC_BY_NAME); +    stmt->setString(0, friendName); + +    _addFriendCallback.SetParam(friendNote); +    _addFriendCallback.SetFutureResult(CharacterDatabase.AsyncQuery(stmt)); +} + +void WorldSession::HandleAddFriendOpcodeCallback(PreparedQueryResult result, std::string const& friendNote) +{ +    if (!GetPlayer()) +        return; + +    ObjectGuid friendGuid; +    FriendsResult friendResult = FRIEND_NOT_FOUND; + +    if (result) +    { +        Field* fields = result->Fetch(); + +        friendGuid = ObjectGuid(HighGuid::Player, 0, fields[0].GetUInt32()); +        uint32 team = Player::TeamForRace(fields[1].GetUInt8()); +        uint32 friendAccountId = fields[2].GetUInt32(); + +        if (HasPermission(rbac::RBAC_PERM_ALLOW_GM_FRIEND) || AccountMgr::IsPlayerAccount(AccountMgr::GetSecurity(friendAccountId, realm.Id.Realm))) +        { +            if (friendGuid) +            { +                if (friendGuid == GetPlayer()->GetGUID()) +                    friendResult = FRIEND_SELF; +                else if (GetPlayer()->GetTeam() != team && !HasPermission(rbac::RBAC_PERM_TWO_SIDE_ADD_FRIEND)) +                    friendResult = FRIEND_ENEMY; +                else if (GetPlayer()->GetSocial()->HasFriend(friendGuid)) +                    friendResult = FRIEND_ALREADY; +                else +                { +                    Player* pFriend = ObjectAccessor::FindPlayer(friendGuid); +                    if (pFriend && pFriend->IsVisibleGloballyFor(GetPlayer())) +                        friendResult = FRIEND_ADDED_ONLINE; +                    else +                        friendResult = FRIEND_ADDED_OFFLINE; +                    if (GetPlayer()->GetSocial()->AddToSocialList(friendGuid, SOCIAL_FLAG_FRIEND)) +                        GetPlayer()->GetSocial()->SetFriendNote(friendGuid, friendNote); +                    else +                        friendResult = FRIEND_LIST_FULL; +                } +            } +        } +    } + +    sSocialMgr->SendFriendStatus(GetPlayer(), friendResult, friendGuid); +} + +void WorldSession::HandleDelFriendOpcode(WorldPacket& recvData) +{ +    ObjectGuid friendGuid; +    recvData >> friendGuid; +    TC_LOG_DEBUG("network", "WorldSession::HandleDelFriendOpcode: %s", friendGuid.ToString().c_str()); + +    _player->GetSocial()->RemoveFromSocialList(friendGuid, SOCIAL_FLAG_FRIEND); + +    sSocialMgr->SendFriendStatus(GetPlayer(), FRIEND_REMOVED, friendGuid); +} + +void WorldSession::HandleAddIgnoreOpcode(WorldPacket& recvData) +{ +    std::string ignoreName; +    recvData >> ignoreName; + +    if (!normalizePlayerName(ignoreName)) +        return; + +    TC_LOG_DEBUG("network", "WorldSession::HandleAddIgnoreOpcode: %s asked to Ignore: %s", +        GetPlayer()->GetName().c_str(), ignoreName.c_str()); + +    PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_GUID_BY_NAME); +    stmt->setString(0, ignoreName); + +    _addIgnoreCallback = CharacterDatabase.AsyncQuery(stmt); +} + +void WorldSession::HandleAddIgnoreOpcodeCallback(PreparedQueryResult result) +{ +    if (!GetPlayer()) +        return; + +    ObjectGuid ignoreGuid; +    FriendsResult ignoreResult = FRIEND_IGNORE_NOT_FOUND; + +    if (result) +    { +        Field* fields = result->Fetch(); + +        if (ObjectGuid::LowType lowGuid = fields[0].GetUInt32()) +        { +            ignoreGuid = ObjectGuid::Create<HighGuid::Player>(lowGuid); + +            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; +            } +        } +    } + +    sSocialMgr->SendFriendStatus(GetPlayer(), ignoreResult, ignoreGuid); +} + +void WorldSession::HandleDelIgnoreOpcode(WorldPacket& recvData) +{ +    ObjectGuid ignoreGuid; +    recvData >> ignoreGuid; + +    TC_LOG_DEBUG("network", "WorldSession::HandleDelIgnoreOpcode: %s", ignoreGuid.ToString().c_str()); + +    _player->GetSocial()->RemoveFromSocialList(ignoreGuid, SOCIAL_FLAG_IGNORED); + +    sSocialMgr->SendFriendStatus(GetPlayer(), FRIEND_IGNORE_REMOVED, ignoreGuid); +} + +void WorldSession::HandleSetContactNotesOpcode(WorldPacket& recvData) +{ +    ObjectGuid guid; +    std::string note; +    recvData >> guid >> note; + +    TC_LOG_DEBUG("network", "WorldSession::HandleSetContactNotesOpcode: Contact: %s, Notes: %s", guid.ToString().c_str(), note.c_str()); + +    _player->GetSocial()->SetFriendNote(guid, note); +} diff --git a/src/server/game/Handlers/TradeHandler.cpp b/src/server/game/Handlers/TradeHandler.cpp index 5fba3c787df..dc992ebb537 100644 --- a/src/server/game/Handlers/TradeHandler.cpp +++ b/src/server/game/Handlers/TradeHandler.cpp @@ -673,7 +673,7 @@ void WorldSession::HandleInitiateTradeOpcode(WorldPacket& recvPacket)          return;      } -    if (pOther->GetSocial()->HasIgnore(GetPlayer()->GetGUID().GetCounter())) +    if (pOther->GetSocial()->HasIgnore(GetPlayer()->GetGUID()))      {          info.Status = TRADE_STATUS_IGNORE_YOU;          SendTradeStatus(info); diff --git a/src/server/game/Miscellaneous/Language.h b/src/server/game/Miscellaneous/Language.h index f4803d93851..308fa1dbfbb 100644 --- a/src/server/game/Miscellaneous/Language.h +++ b/src/server/game/Miscellaneous/Language.h @@ -78,7 +78,7 @@ enum TrinityStrings      LANG_UNKNOWN                        = 45,      LANG_ERROR                          = 46,      LANG_NON_EXIST_CHARACTER            = 47, -    LANG_FRIEND_IGNORE_UNKNOWN          = 48, +    // unused                           = 48,      LANG_LEVEL_MINREQUIRED              = 49,      LANG_LEVEL_MINREQUIRED_AND_ITEM     = 50,      LANG_NPC_TAINER_HELLO               = 51, diff --git a/src/server/game/Server/WorldSession.cpp b/src/server/game/Server/WorldSession.cpp index 7f3b5b1f449..a7dc3685171 100644 --- a/src/server/game/Server/WorldSession.cpp +++ b/src/server/game/Server/WorldSession.cpp @@ -542,8 +542,8 @@ void WorldSession::LogoutPlayer(bool save)          }          //! Broadcast a logout message to the player's friends -        sSocialMgr->SendFriendStatus(_player, FRIEND_OFFLINE, _player->GetGUID().GetCounter(), true); -        sSocialMgr->RemovePlayerSocial(_player->GetGUID().GetCounter()); +        sSocialMgr->SendFriendStatus(_player, FRIEND_OFFLINE, _player->GetGUID(), true); +        _player->RemoveSocial();          //! Call script hook before deletion          sScriptMgr->OnPlayerLogout(_player); @@ -1124,7 +1124,7 @@ void WorldSession::ProcessQueryCallbacks()      {          std::string param = _addFriendCallback.GetParam();          _addFriendCallback.GetResult(result); -        HandleAddFriendOpcodeCallBack(result, param); +        HandleAddFriendOpcodeCallback(result, param);          _addFriendCallback.FreeResult();      } @@ -1142,7 +1142,7 @@ void WorldSession::ProcessQueryCallbacks()      if (_addIgnoreCallback.valid() && _addIgnoreCallback.wait_for(std::chrono::seconds(0)) == std::future_status::ready)      {          result = _addIgnoreCallback.get(); -        HandleAddIgnoreOpcodeCallBack(result); +        HandleAddIgnoreOpcodeCallback(result);      }      //- SendStabledPet diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h index a591e45d699..d4320923a59 100644 --- a/src/server/game/Server/WorldSession.h +++ b/src/server/game/Server/WorldSession.h @@ -524,12 +524,14 @@ class TC_GAME_API WorldSession          void HandleSetSelectionOpcode(WorldPacket& recvPacket);          void HandleStandStateChangeOpcode(WorldPacket& recvPacket);          void HandleEmoteOpcode(WorldPacket& recvPacket); + +        // Social          void HandleContactListOpcode(WorldPacket& recvPacket);          void HandleAddFriendOpcode(WorldPacket& recvPacket); -        void HandleAddFriendOpcodeCallBack(PreparedQueryResult result, std::string const& friendNote); +        void HandleAddFriendOpcodeCallback(PreparedQueryResult result, std::string const& friendNote);          void HandleDelFriendOpcode(WorldPacket& recvPacket);          void HandleAddIgnoreOpcode(WorldPacket& recvPacket); -        void HandleAddIgnoreOpcodeCallBack(PreparedQueryResult result); +        void HandleAddIgnoreOpcodeCallback(PreparedQueryResult result);          void HandleDelIgnoreOpcode(WorldPacket& recvPacket);          void HandleSetContactNotesOpcode(WorldPacket& recvPacket);          void HandleBugOpcode(WorldPacket& recvPacket); diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp index 6de452c8b82..6a53b809368 100644 --- a/src/server/game/Spells/SpellEffects.cpp +++ b/src/server/game/Spells/SpellEffects.cpp @@ -4080,7 +4080,7 @@ void Spell::EffectDuel(SpellEffIndex effIndex)      Player* target = unitTarget->ToPlayer();      // caster or target already have requested duel -    if (caster->duel || target->duel || !target->GetSocial() || target->GetSocial()->HasIgnore(caster->GetGUID().GetCounter())) +    if (caster->duel || target->duel || !target->GetSocial() || target->GetSocial()->HasIgnore(caster->GetGUID()))          return;      // Players can only fight a duel in zones with this flag  | 
