Project SkyFire Core
SkyFire 5.4.8 server core API documentation
Loading...
Searching...
No Matches
SocialMgr.cpp
Go to the documentation of this file.
1/*
2* This file is part of Project SkyFire https://www.projectskyfire.org.
3* See LICENSE.md file for Copyright information
4*/
5
6#include "SocialMgr.h"
7
8#include "AccountMgr.h"
9#include "DatabaseEnv.h"
10#include "ObjectMgr.h"
11#include "Opcodes.h"
12#include "Player.h"
13#include "Util.h"
14#include "World.h"
15#include "WorldPacket.h"
16#include "WorldSession.h"
17
20
22{
23 uint32 counter = 0;
24 for (PlayerSocialMap::const_iterator itr = m_playerSocialMap.begin(); itr != m_playerSocialMap.end(); ++itr)
25 if (itr->second.Flags & flag)
26 ++counter;
27
28 return counter;
29}
30
31bool PlayerSocial::AddToSocialList(uint32 friendGuid, bool ignore)
32{
33 // check client limits
34 if (ignore)
35 {
37 return false;
38 }
39 else
40 {
42 return false;
43 }
44
46 if (ignore)
48
49 PlayerSocialMap::const_iterator itr = m_playerSocialMap.find(friendGuid);
50 if (itr != m_playerSocialMap.end())
51 {
53
54 stmt->setUInt8(0, flag);
55 stmt->setUInt32(1, GetPlayerGUID());
56 stmt->setUInt32(2, friendGuid);
57
58 CharacterDatabase.Execute(stmt);
59
60 m_playerSocialMap[friendGuid].Flags |= flag;
61 }
62 else
63 {
65
66 stmt->setUInt32(0, GetPlayerGUID());
67 stmt->setUInt32(1, friendGuid);
68 stmt->setUInt8(2, flag);
69
70 CharacterDatabase.Execute(stmt);
71
72 FriendInfo fi;
73 fi.Flags |= flag;
74 m_playerSocialMap[friendGuid] = fi;
75 }
76 return true;
77}
78
79void PlayerSocial::RemoveFromSocialList(uint32 friendGuid, bool ignore)
80{
81 PlayerSocialMap::iterator itr = m_playerSocialMap.find(friendGuid);
82 if (itr == m_playerSocialMap.end()) // not exist
83 return;
84
86 if (ignore)
88
89 itr->second.Flags &= ~flag;
90 if (itr->second.Flags == 0)
91 {
93
94 stmt->setUInt32(0, GetPlayerGUID());
95 stmt->setUInt32(1, friendGuid);
96
97 CharacterDatabase.Execute(stmt);
98
99 m_playerSocialMap.erase(itr);
100 }
101 else
102 {
104
105 stmt->setUInt8(0, flag);
106 stmt->setUInt32(1, GetPlayerGUID());
107 stmt->setUInt32(2, friendGuid);
108
109 CharacterDatabase.Execute(stmt);
110 }
111}
112
113void PlayerSocial::SetFriendNote(uint32 friendGuid, std::string note)
114{
115 PlayerSocialMap::const_iterator itr = m_playerSocialMap.find(friendGuid);
116 if (itr == m_playerSocialMap.end()) // not exist
117 return;
118
119 utf8truncate(note, 48); // DB and client size limitation
120
122
123 stmt->setString(0, note);
124 stmt->setUInt32(1, GetPlayerGUID());
125 stmt->setUInt32(2, friendGuid);
126
127 CharacterDatabase.Execute(stmt);
128
129 m_playerSocialMap[friendGuid].Note = note;
130}
131
133{
134 if (!player)
135 return;
136
137 uint32 size = m_playerSocialMap.size();
138
139 WorldPacket data(SMSG_CONTACT_LIST, 4 + 4 + (size * 33));
140 data << uint32(7); // 0x1 = Friendlist update. 0x2 = Ignorelist update. 0x4 = Mutelist update.
141 data << uint32(size); // friends count
142
143 for (PlayerSocialMap::iterator itr = m_playerSocialMap.begin(); itr != m_playerSocialMap.end(); ++itr)
144 {
145 sSocialMgr->GetFriendInfo(player, itr->first, itr->second);
146
147 data << uint64(itr->first); // player guid
148 data << uint32(0);
149 data << uint32(0);
150 data << uint32(itr->second.Flags); // player flag (0x1 = Friend, 0x2 = Ignored, 0x4 = Muted)
151 data << itr->second.Note; // string note
152
153 if (itr->second.Flags & SOCIAL_FLAG_FRIEND) // if IsFriend()
154 {
155 data << uint8(itr->second.Status); // online/offline/etc?
156 if (itr->second.Status) // if online
157 {
158 data << uint32(itr->second.Area); // player area
159 data << uint32(itr->second.Level); // player level
160 data << uint32(itr->second.Class); // player class
161 }
162 }
163 }
164
165 player->GetSession()->SendPacket(&data);
166 SF_LOG_DEBUG("network", "WORLD: Sent SMSG_CONTACT_LIST");
167}
168
170{
171 PlayerSocialMap::const_iterator itr = m_playerSocialMap.find(friendGuid);
172 if (itr != m_playerSocialMap.end())
173 return itr->second.Flags & SOCIAL_FLAG_FRIEND;
174 return false;
175}
176
178{
179 PlayerSocialMap::const_iterator itr = m_playerSocialMap.find(ignore_guid);
180 if (itr != m_playerSocialMap.end())
181 return itr->second.Flags & SOCIAL_FLAG_IGNORED;
182 return false;
183}
184
185void SocialMgr::GetFriendInfo(Player* player, uint32 friendGUID, FriendInfo& friendInfo)
186{
187 if (!player)
188 return;
189
190 friendInfo.Status = FRIEND_STATUS_OFFLINE;
191 friendInfo.Area = 0;
192 friendInfo.Level = 0;
193 friendInfo.Class = 0;
194
195 Player* target = ObjectAccessor::FindPlayer(friendGUID);
196 if (!target)
197 return;
198
199 PlayerSocialMap::iterator itr = player->GetSocial()->m_playerSocialMap.find(friendGUID);
200 if (itr != player->GetSocial()->m_playerSocialMap.end())
201 friendInfo.Note = itr->second.Note;
202
203 // PLAYER see his team only and PLAYER can't see MODERATOR, GAME MASTER, ADMINISTRATOR characters
204 // MODERATOR, GAME MASTER, ADMINISTRATOR can see all
205
208 return;
209
210 // player can see member of other team only if CONFIG_ALLOW_TWO_SIDE_WHO_LIST
211 if (target->GetTeam() != player->GetTeam() && !player->GetSession()->HasPermission(rbac::RBAC_PERM_TWO_SIDE_WHO_LIST))
212 return;
213
214 if (target->IsVisibleGloballyFor(player))
215 {
216 if (target->isDND())
217 friendInfo.Status = FRIEND_STATUS_DND;
218 else if (target->isAFK())
219 friendInfo.Status = FRIEND_STATUS_AFK;
220 else
221 friendInfo.Status = FRIEND_STATUS_ONLINE;
222
223 friendInfo.Area = target->GetZoneId();
224 friendInfo.Level = target->getLevel();
225 friendInfo.Class = target->getClass();
226 }
227}
228
230{
232 *data << uint8(result);
233 *data << uint64(guid);
234}
235
236void SocialMgr::SendFriendStatus(Player* player, FriendsResult result, uint32 friendGuid, bool broadcast)
237{
238 FriendInfo fi;
239
240 WorldPacket data;
241 MakeFriendStatusPacket(result, friendGuid, &data);
242 GetFriendInfo(player, friendGuid, fi);
243 switch (result)
244 {
247 data << fi.Note;
248 break;
249 default:
250 break;
251 }
252
253 switch (result)
254 {
256 case FRIEND_ONLINE:
257 data << uint8(fi.Status);
258 data << uint32(fi.Area);
259 data << uint32(fi.Level);
260 data << uint32(fi.Class);
261 break;
262 default:
263 break;
264 }
265
266 if (broadcast)
267 BroadcastToFriendListers(player, &data);
268 else
269 player->GetSession()->SendPacket(&data);
270}
271
273{
274 if (!player)
275 return;
276
278 for (SocialMap::const_iterator itr = m_socialMap.begin(); itr != m_socialMap.end(); ++itr)
279 {
280 PlayerSocialMap::const_iterator itr2 = itr->second.m_playerSocialMap.find(player->GetGUID());
281 if (itr2 != itr->second.m_playerSocialMap.end() && (itr2->second.Flags & SOCIAL_FLAG_FRIEND))
282 {
284 if (!target || !target->IsInWorld())
285 continue;
286
287 WorldSession* session = target->GetSession();
288 if (!session->HasPermission(rbac::RBAC_PERM_WHO_SEE_ALL_SEC_LEVELS) && player->GetSession()->GetSecurity() > gmSecLevel)
289 continue;
290
291 if (target->GetTeam() != player->GetTeam() && !session->HasPermission(rbac::RBAC_PERM_TWO_SIDE_WHO_LIST))
292 continue;
293
294 if (player->IsVisibleGloballyFor(target))
295 session->SendPacket(packet);
296 }
297 }
298}
299
301{
302 PlayerSocial* social = &m_socialMap[guid];
303 social->SetPlayerGUID(guid);
304
305 if (!result)
306 return social;
307
308 uint32 friendGuid = 0;
309 uint8 flags = 0;
310 std::string note;
311
312 do
313 {
314 Field* fields = result->Fetch();
315
316 friendGuid = fields[0].GetUInt32();
317 flags = fields[1].GetUInt8();
318 note = fields[2].GetString();
319
320 social->m_playerSocialMap[friendGuid] = FriendInfo(flags, note);
321
322 // client's friends list and ignore list limit
324 break;
325 } while (result->NextRow());
326
327 return social;
328}
@ CHAR_UPD_CHARACTER_SOCIAL_NOTE
@ CHAR_UPD_REM_CHARACTER_SOCIAL_FLAGS
@ CHAR_DEL_CHARACTER_SOCIAL
@ CHAR_INS_CHARACTER_SOCIAL
@ CHAR_UPD_ADD_CHARACTER_SOCIAL_FLAGS
AccountTypes
Definition Common.h:129
std::uint8_t uint8
Definition Define.h:79
std::uint32_t uint32
Definition Define.h:77
std::uint64_t uint64
Definition Define.h:76
#define SF_LOG_DEBUG(filterType__,...)
Definition Log.h:134
@ HIGHGUID_PLAYER
uint64 MAKE_NEW_GUID(uint32 l, uint32 e, uint32 h)
Skyfire::AutoPtr< PreparedResultSet, Skyfire::Mutex > PreparedQueryResult
Definition QueryResult.h:94
@ FRIEND_STATUS_AFK
Definition SocialMgr.h:22
@ FRIEND_STATUS_DND
Definition SocialMgr.h:23
@ FRIEND_STATUS_OFFLINE
Definition SocialMgr.h:20
@ FRIEND_STATUS_ONLINE
Definition SocialMgr.h:21
#define sSocialMgr
Definition SocialMgr.h:134
FriendsResult
Results of friend related commands.
Definition SocialMgr.h:56
@ FRIEND_ONLINE
Definition SocialMgr.h:59
@ FRIEND_ADDED_OFFLINE
Definition SocialMgr.h:64
@ FRIEND_ADDED_ONLINE
Definition SocialMgr.h:63
SocialFlag
Definition SocialMgr.h:28
@ SOCIAL_FLAG_FRIEND
Definition SocialMgr.h:29
@ SOCIAL_FLAG_IGNORED
Definition SocialMgr.h:30
#define SOCIALMGR_IGNORE_LIMIT
Definition SocialMgr.h:87
#define SOCIALMGR_FRIEND_LIMIT
Definition SocialMgr.h:86
void utf8truncate(std::string &utf8str, size_t len)
Definition Util.cpp:284
Definition Field.h:16
uint8 GetUInt8() const
Definition Field.h:26
std::string GetString() const
Definition Field.h:228
uint32 GetUInt32() const
Definition Field.h:105
static Player * FindPlayer(uint64)
uint64 GetGUID() const
Definition Object.h:119
bool IsInWorld() const
Definition Object.h:114
uint32 GetTeam() const
Definition Player.h:2527
WorldSession * GetSession() const
Definition Player.h:2417
bool IsVisibleGloballyFor(Player const *player) const
Definition Player.cpp:18107
bool isDND() const
Definition Player.h:1337
PlayerSocial * GetSocial()
Definition Player.h:1346
bool isAFK() const
Definition Player.h:1333
bool HasFriend(uint32 friend_guid)
void SetFriendNote(uint32 friendGuid, std::string note)
PlayerSocialMap m_playerSocialMap
Definition SocialMgr.h:107
uint32 GetPlayerGUID() const
Definition SocialMgr.h:103
bool AddToSocialList(uint32 friend_guid, bool ignore)
Definition SocialMgr.cpp:31
uint32 GetNumberOfSocialsWithFlag(SocialFlag flag)
Definition SocialMgr.cpp:21
void SetPlayerGUID(uint32 guid)
Definition SocialMgr.h:104
bool HasIgnore(uint32 ignore_guid)
void RemoveFromSocialList(uint32 friend_guid, bool ignore)
Definition SocialMgr.cpp:79
void SendSocialList(Player *player)
uint32 m_playerGUID
Definition SocialMgr.h:108
void setString(const uint8 index, const std::string &value)
void setUInt32(const uint8 index, const uint32 value)
void setUInt8(const uint8 index, const uint8 value)
void SendFriendStatus(Player *player, FriendsResult result, uint32 friend_guid, bool broadcast)
SocialMap m_socialMap
Definition SocialMgr.h:131
void BroadcastToFriendListers(Player *player, WorldPacket *packet)
PlayerSocial * LoadFromDB(PreparedQueryResult result, uint32 guid)
void GetFriendInfo(Player *player, uint32 friendGUID, FriendInfo &friendInfo)
void MakeFriendStatusPacket(FriendsResult result, uint32 friend_guid, WorldPacket *data)
uint8 getClass() const
Definition Unit.h:1543
uint8 getLevel() const
Definition Unit.h:1528
uint32 GetZoneId() const
Definition Object.cpp:1597
void Initialize(Opcodes opcode, size_t newres=200)
Definition WorldPacket.h:31
Player session in the World.
AccountTypes GetSecurity() const
bool HasPermission(uint32 permissionId)
void SendPacket(WorldPacket const *packet, bool forced=false)
Send a packet to the client.
CharacterDatabaseWorkerPool CharacterDatabase
Accessor to the character database.
Definition Main.cpp:41
@ SMSG_CONTACT_LIST
Definition Opcodes.h:621
@ SMSG_FRIEND_STATUS
Definition Opcodes.h:658
#define sWorld
Definition World.h:910
@ CONFIG_GM_LEVEL_IN_WHO_LIST
Definition World.h:252
@ RBAC_PERM_WHO_SEE_ALL_SEC_LEVELS
Definition RBAC.h:75
@ RBAC_PERM_TWO_SIDE_WHO_LIST
Definition RBAC.h:68
FriendStatus Status
Definition SocialMgr.h:37
uint8 Level
Definition SocialMgr.h:40
uint8 Class
Definition SocialMgr.h:41
std::string Note
Definition SocialMgr.h:42
uint8 Flags
Definition SocialMgr.h:38
uint32 Area
Definition SocialMgr.h:39