aboutsummaryrefslogtreecommitdiff
path: root/src/server/game/Handlers/SocialHandler.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/server/game/Handlers/SocialHandler.cpp')
-rw-r--r--src/server/game/Handlers/SocialHandler.cpp97
1 files changed, 65 insertions, 32 deletions
diff --git a/src/server/game/Handlers/SocialHandler.cpp b/src/server/game/Handlers/SocialHandler.cpp
index c3fd69433bd..4271570e945 100644
--- a/src/server/game/Handlers/SocialHandler.cpp
+++ b/src/server/game/Handlers/SocialHandler.cpp
@@ -45,43 +45,76 @@ void WorldSession::HandleAddFriendOpcode(WorldPacket& recvData)
TC_LOG_DEBUG("network", "WorldSession::HandleAddFriendOpcode: %s asked to add friend: %s",
GetPlayer()->GetName().c_str(), friendName.c_str());
- FriendsResult friendResult = FRIEND_NOT_FOUND;
- ObjectGuid friendGuid = sCharacterCache->GetCharacterGuidByName(friendName);
- if (!friendGuid.IsEmpty())
+ CharacterCacheEntry const* friendCharacterInfo = sCharacterCache->GetCharacterCacheByName(friendName);
+ if (!friendCharacterInfo)
{
- if (CharacterCacheEntry const* characterInfo = sCharacterCache->GetCharacterCacheByGuid(friendGuid))
+ sSocialMgr->SendFriendStatus(GetPlayer(), FRIEND_NOT_FOUND, ObjectGuid::Empty);
+ return;
+ }
+
+ auto processFriendRequest = [this,
+ playerGuid = _player->GetGUID(),
+ friendGuid = friendCharacterInfo->Guid,
+ team = Player::TeamForRace(friendCharacterInfo->Race),
+ friendNote = std::move(friendNote)]()
+ {
+ if (playerGuid.GetCounter() != GetGUIDLow())
+ return; // not the player initiating request, do nothing
+
+ FriendsResult friendResult = FRIEND_NOT_FOUND;
+ 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);
+ };
+
+ if (HasPermission(rbac::RBAC_PERM_ALLOW_GM_FRIEND))
+ {
+ processFriendRequest();
+ return;
+ }
+
+ // First try looking up friend candidate security from online object
+ if (Player* friendPlayer = ObjectAccessor::FindPlayer(friendCharacterInfo->Guid))
+ {
+ if (!AccountMgr::IsPlayerAccount(friendPlayer->GetSession()->GetSecurity()))
{
- 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)))
- {
- 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(), FRIEND_NOT_FOUND, ObjectGuid::Empty);
+ return;
}
+
+ processFriendRequest();
+ return;
}
- sSocialMgr->SendFriendStatus(GetPlayer(), friendResult, friendGuid);
+ // When not found, consult database
+ GetQueryProcessor().AddCallback(AccountMgr::GetSecurityAsync(friendCharacterInfo->AccountId, realm.Id.Realm,
+ [this, continuation = std::move(processFriendRequest)](uint32 friendSecurity)
+ {
+ if (!AccountMgr::IsPlayerAccount(friendSecurity))
+ {
+ sSocialMgr->SendFriendStatus(GetPlayer(), FRIEND_NOT_FOUND, ObjectGuid::Empty);
+ return;
+ }
+
+ continuation();
+ }));
}
void WorldSession::HandleDelFriendOpcode(WorldPacket& recvData)