TrinityCore
Loading...
Searching...
No Matches
SocialMgr.cpp
Go to the documentation of this file.
1/*
2 * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#include "SocialMgr.h"
19#include "DatabaseEnv.h"
20#include "ObjectAccessor.h"
21#include "Player.h"
22#include "RBAC.h"
23#include "SocialPackets.h"
24#include "World.h"
25#include "WorldSession.h"
26
28{ }
29
31{
32 uint32 counter = 0;
33 for (PlayerSocialMap::const_iterator itr = _playerSocialMap.begin(); itr != _playerSocialMap.end(); ++itr)
34 if ((itr->second.Flags & flag) != 0)
35 ++counter;
36
37 return counter;
38}
39
41{
42 // check client limits
44 return false;
45
46 PlayerSocialMap::iterator itr = _playerSocialMap.find(friendGuid);
47 if (itr != _playerSocialMap.end())
48 {
49 itr->second.Flags |= flag;
50
52
53 stmt->setUInt8(0, itr->second.Flags);
55 stmt->setUInt32(2, friendGuid.GetCounter());
56
57 CharacterDatabase.Execute(stmt);
58 }
59 else
60 {
61 _playerSocialMap[friendGuid].Flags |= flag;
62
64
66 stmt->setUInt32(1, friendGuid.GetCounter());
67 stmt->setUInt8(2, flag);
68
69 CharacterDatabase.Execute(stmt);
70 }
71
72 return true;
73}
74
76{
77 PlayerSocialMap::iterator itr = _playerSocialMap.find(friendGuid);
78 if (itr == _playerSocialMap.end())
79 return;
80
81 itr->second.Flags &= ~flag;
82
83 if (!itr->second.Flags)
84 {
86
87 stmt->setUInt32(0, GetPlayerGUID().GetCounter());
88 stmt->setUInt32(1, friendGuid.GetCounter());
89
90 CharacterDatabase.Execute(stmt);
91
92 _playerSocialMap.erase(itr);
93 }
94 else
95 {
97
98 stmt->setUInt8(0, itr->second.Flags);
99 stmt->setUInt32(1, GetPlayerGUID().GetCounter());
100 stmt->setUInt32(2, friendGuid.GetCounter());
101
102 CharacterDatabase.Execute(stmt);
103 }
104}
105
106void PlayerSocial::SetFriendNote(ObjectGuid const& friendGuid, std::string const& note)
107{
108 PlayerSocialMap::iterator itr = _playerSocialMap.find(friendGuid);
109 if (itr == _playerSocialMap.end()) // not exist
110 return;
111
112 itr->second.Note = note;
113 utf8truncate(itr->second.Note, 48); // DB and client size limitation
114
116
117 stmt->setString(0, itr->second.Note);
118 stmt->setUInt32(1, GetPlayerGUID().GetCounter());
119 stmt->setUInt32(2, friendGuid.GetCounter());
120
121 CharacterDatabase.Execute(stmt);
122}
123
125{
126 ASSERT(player);
127
128 uint32 friendsCount = 0;
129 uint32 ignoredCount = 0;
130
132 contactList.Flags = flags; // 0x1 = Friendlist update. 0x2 = Ignorelist update. 0x4 = Mutelist update.
133
134 for (PlayerSocialMap::value_type& v : _playerSocialMap)
135 {
136 uint8 contactFlags = v.second.Flags;
137 if (!(contactFlags & flags))
138 continue;
139
140 // Check client limit for friends list
141 if (contactFlags & SOCIAL_FLAG_FRIEND)
142 if (++friendsCount > SOCIALMGR_FRIEND_LIMIT)
143 continue;
144
145 // Check client limit for ignore list
146 if (contactFlags & SOCIAL_FLAG_IGNORED)
147 if (++ignoredCount > SOCIALMGR_IGNORE_LIMIT)
148 continue;
149
150 SocialMgr::GetFriendInfo(player, v.first, v.second);
151
152 WorldPackets::Social::ContactInfo& contact = contactList.Contacts.emplace_back();
153 contact.Guid = v.first;
154 contact.TypeFlags = v.second.Flags;
155 contact.Notes = v.second.Note;
156 contact.Status = v.second.Status;
157 contact.AreaID = v.second.Area;
158 contact.Level = v.second.Level;
159 contact.ClassID = v.second.Class;
160 }
161
162 player->SendDirectMessage(contactList.Write());
163}
164
166{
167 PlayerSocialMap::const_iterator itr = _playerSocialMap.find(guid);
168 if (itr != _playerSocialMap.end())
169 return (itr->second.Flags & flags) != 0;
170
171 return false;
172}
173
174bool PlayerSocial::HasFriend(ObjectGuid const& friendGuid)
175{
176 return _HasContact(friendGuid, SOCIAL_FLAG_FRIEND);
177}
178
179bool PlayerSocial::HasIgnore(ObjectGuid const& ignoreGuid)
180{
181 return _HasContact(ignoreGuid, SOCIAL_FLAG_IGNORED);
182}
183
185{
186 static SocialMgr instance;
187 return &instance;
188}
189
190void SocialMgr::GetFriendInfo(Player* player, ObjectGuid const& friendGUID, FriendInfo& friendInfo)
191{
192 if (!player)
193 return;
194
195 friendInfo.Status = FRIEND_STATUS_OFFLINE;
196 friendInfo.Area = 0;
197 friendInfo.Level = 0;
198 friendInfo.Class = 0;
199
200 Player* target = ObjectAccessor::FindPlayer(friendGUID);
201 if (!target)
202 return;
203
204 PlayerSocial::PlayerSocialMap::iterator itr = player->GetSocial()->_playerSocialMap.find(friendGUID);
205 if (itr != player->GetSocial()->_playerSocialMap.end())
206 friendInfo.Note = itr->second.Note;
207
208 // PLAYER see his team only and PLAYER can't see MODERATOR, GAME MASTER, ADMINISTRATOR characters
209 // MODERATOR, GAME MASTER, ADMINISTRATOR can see all
210
213 return;
214
215 // player can see member of other team only if CONFIG_ALLOW_TWO_SIDE_WHO_LIST
216 if (target->GetTeam() != player->GetTeam() && !player->GetSession()->HasPermission(rbac::RBAC_PERM_TWO_SIDE_WHO_LIST))
217 return;
218
219 if (target->IsVisibleGloballyFor(player))
220 {
221 if (target->isDND())
222 friendInfo.Status = FRIEND_STATUS_DND;
223 else if (target->isAFK())
224 friendInfo.Status = FRIEND_STATUS_AFK;
225 else
226 {
227 friendInfo.Status = FRIEND_STATUS_ONLINE;
228
229 if (target->GetSession()->GetRecruiterId() == player->GetSession()->GetAccountId() || target->GetSession()->GetAccountId() == player->GetSession()->GetRecruiterId())
230 friendInfo.Status = FriendStatus(uint32(friendInfo.Status) | FRIEND_STATUS_RAF);
231 }
232
233 friendInfo.Area = target->GetZoneId();
234 friendInfo.Level = target->GetLevel();
235 friendInfo.Class = target->GetClass();
236 }
237}
238
239void SocialMgr::SendFriendStatus(Player* player, FriendsResult result, ObjectGuid const& friendGuid, bool broadcast /*= false*/)
240{
241 FriendInfo fi;
242 GetFriendInfo(player, friendGuid, fi);
243
245 friendStatus.Notes = fi.Note;
246 friendStatus.ClassID = fi.Class;
247 friendStatus.Status = fi.Status;
248 friendStatus.Guid = friendGuid;
249 friendStatus.Level = fi.Level;
250 friendStatus.AreaID = fi.Area;
251 friendStatus.FriendResult = result;
252
253 if (broadcast)
254 BroadcastToFriendListers(player, friendStatus.Write());
255 else
256 player->SendDirectMessage(friendStatus.Write());
257}
258
260{
261 ASSERT(player);
262
263 AccountTypes gmSecLevel = AccountTypes(sWorld->getIntConfig(CONFIG_GM_LEVEL_IN_WHO_LIST));
264 for (SocialMap::const_iterator itr = _socialMap.begin(); itr != _socialMap.end(); ++itr)
265 {
266 PlayerSocial::PlayerSocialMap::const_iterator itr2 = itr->second._playerSocialMap.find(player->GetGUID());
267 if (itr2 != itr->second._playerSocialMap.end() && (itr2->second.Flags & SOCIAL_FLAG_FRIEND) != 0)
268 {
269 Player* target = ObjectAccessor::FindPlayer(itr->first);
270 if (!target)
271 continue;
272
273 WorldSession* session = target->GetSession();
274 if (!session->HasPermission(rbac::RBAC_PERM_WHO_SEE_ALL_SEC_LEVELS) && player->GetSession()->GetSecurity() > gmSecLevel)
275 continue;
276
277 if (target->GetTeam() != player->GetTeam() && !session->HasPermission(rbac::RBAC_PERM_TWO_SIDE_WHO_LIST))
278 continue;
279
280 if (player->IsVisibleGloballyFor(target))
281 session->SendPacket(packet);
282 }
283 }
284}
285
287{
288 PlayerSocial* social = &_socialMap[guid];
289 social->SetPlayerGUID(guid);
290
291 if (result)
292 {
293 do
294 {
295 Field* fields = result->Fetch();
296
297 ObjectGuid friendGuid = ObjectGuid::Create<HighGuid::Player>(fields[0].GetUInt32());
298
299 uint8 flag = fields[1].GetUInt8();
300 social->_playerSocialMap[friendGuid] = FriendInfo(flag, fields[2].GetString());
301 }
302 while (result->NextRow());
303 }
304
305 return social;
306}
@ CHAR_UPD_CHARACTER_SOCIAL_NOTE
@ CHAR_UPD_CHARACTER_SOCIAL_FLAGS
@ CHAR_DEL_CHARACTER_SOCIAL
@ CHAR_INS_CHARACTER_SOCIAL
AccountTypes
Definition Common.h:39
std::shared_ptr< PreparedResultSet > PreparedQueryResult
DatabaseWorkerPool< CharacterDatabaseConnection > CharacterDatabase
Accessor to the character database.
uint8_t uint8
Definition Define.h:135
uint32_t uint32
Definition Define.h:133
uint16 flags
#define ASSERT
Definition Errors.h:68
Role Based Access Control related classes definition.
FriendsResult
Results of friend related commands.
Definition SocialMgr.h:66
FriendStatus
Definition SocialMgr.h:30
@ FRIEND_STATUS_RAF
Definition SocialMgr.h:35
@ FRIEND_STATUS_AFK
Definition SocialMgr.h:33
@ FRIEND_STATUS_DND
Definition SocialMgr.h:34
@ FRIEND_STATUS_OFFLINE
Definition SocialMgr.h:31
@ FRIEND_STATUS_ONLINE
Definition SocialMgr.h:32
SocialFlag
Definition SocialMgr.h:39
@ SOCIAL_FLAG_FRIEND
Definition SocialMgr.h:40
@ SOCIAL_FLAG_IGNORED
Definition SocialMgr.h:41
#define SOCIALMGR_IGNORE_LIMIT
Definition SocialMgr.h:99
#define SOCIALMGR_FRIEND_LIMIT
Definition SocialMgr.h:98
void utf8truncate(std::string &utf8str, size_t len)
Definition Util.cpp:362
Class used to access individual fields of database query result.
Definition Field.h:92
uint8 GetUInt8() const
Definition Field.cpp:29
LowType GetCounter() const
Definition ObjectGuid.h:156
static ObjectGuid GetGUID(Object const *o)
Definition Object.h:78
void SetPlayerGUID(ObjectGuid const &guid)
Definition SocialMgr.h:120
ObjectGuid const & GetPlayerGUID() const
Definition SocialMgr.h:119
bool HasIgnore(ObjectGuid const &ignoreGuid)
PlayerSocialMap _playerSocialMap
Definition SocialMgr.h:128
uint32 GetNumberOfSocialsWithFlag(SocialFlag flag)
Definition SocialMgr.cpp:30
bool _HasContact(ObjectGuid const &guid, SocialFlag flags)
bool AddToSocialList(ObjectGuid const &guid, SocialFlag flag)
Definition SocialMgr.cpp:40
void SetFriendNote(ObjectGuid const &guid, std::string const &note)
bool HasFriend(ObjectGuid const &friendGuid)
void RemoveFromSocialList(ObjectGuid const &guid, SocialFlag flag)
Definition SocialMgr.cpp:75
void SendSocialList(Player *player, uint32 flags)
uint32 GetTeam() const
Definition Player.h:1818
void SendDirectMessage(WorldPacket const *data) const
Definition Player.cpp:6163
WorldSession * GetSession() const
Definition Player.h:1705
bool IsVisibleGloballyFor(Player const *player) const
Definition Player.cpp:22110
bool isDND() const
Definition Player.h:954
PlayerSocial * GetSocial()
Definition Player.h:960
bool isAFK() const
Definition Player.h:953
void setUInt32(uint8 index, uint32 value)
void setUInt8(uint8 index, uint8 value)
void setString(uint8 index, std::string const &value)
static SocialMgr * instance()
SocialMap _socialMap
Definition SocialMgr.h:156
static void GetFriendInfo(Player *player, ObjectGuid const &friendGUID, FriendInfo &friendInfo)
PlayerSocial * LoadFromDB(PreparedQueryResult result, ObjectGuid const &guid)
void SendFriendStatus(Player *player, FriendsResult result, ObjectGuid const &friendGuid, bool broadcast=false)
void BroadcastToFriendListers(Player *player, WorldPacket const *packet)
uint8 GetClass() const
Definition Unit.h:909
uint8 GetLevel() const
Definition Unit.h:903
uint32 GetZoneId() const
Definition Object.h:375
WorldPacket const * Write() override
std::vector< ContactInfo > Contacts
WorldPacket const * Write() override
Player session in the World.
void SendPacket(WorldPacket const *packet)
Send a packet to the client.
AccountTypes GetSecurity() const
uint32 GetRecruiterId() const
bool HasPermission(uint32 permissionId)
uint32 GetAccountId() const
#define sWorld
Definition World.h:901
@ CONFIG_GM_LEVEL_IN_WHO_LIST
Definition World.h:265
TC_GAME_API Player * FindPlayer(ObjectGuid const &)
@ RBAC_PERM_WHO_SEE_ALL_SEC_LEVELS
Definition RBAC.h:88
@ RBAC_PERM_TWO_SIDE_WHO_LIST
Definition RBAC.h:81
FriendStatus Status
Definition SocialMgr.h:50
uint8 Level
Definition SocialMgr.h:53
uint8 Class
Definition SocialMgr.h:54
std::string Note
Definition SocialMgr.h:55
uint32 Area
Definition SocialMgr.h:52