2 * Copyright (C) 2005-2013 MaNGOS <http://getmangos.com/>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 #include "ObjectMgr.h"
22 #include "SocialMgr.h"
24 Channel::Channel(const std::string
& name
, uint32 channel_id
)
25 : m_announce(true), m_moderate(false), m_name(name
), m_flags(0), m_channelId(channel_id
)
27 // set special flags if built-in channel
28 ChatChannelsEntry
const* ch
= GetChannelEntryFor(channel_id
);
29 if (ch
) // it's built-in channel
31 channel_id
= ch
->ChannelID
; // built-in channel
32 m_announce
= false; // no join/leave announces
34 m_flags
|= CHANNEL_FLAG_GENERAL
; // for all built-in channels
36 if (ch
->flags
& CHANNEL_DBC_FLAG_TRADE
) // for trade channel
37 m_flags
|= CHANNEL_FLAG_TRADE
;
39 if (ch
->flags
& CHANNEL_DBC_FLAG_CITY_ONLY2
) // for city only channels
40 m_flags
|= CHANNEL_FLAG_CITY
;
42 if (ch
->flags
& CHANNEL_DBC_FLAG_LFG
) // for LFG channel
43 m_flags
|= CHANNEL_FLAG_LFG
;
44 else // for all other channels
45 m_flags
|= CHANNEL_FLAG_NOT_LFG
;
47 else // it's custom channel
49 m_flags
|= CHANNEL_FLAG_CUSTOM
;
53 void Channel::Join(ObjectGuid p
, const char* pass
)
58 if (!IsConstant()) // non send error message for built-in channels
60 MakePlayerAlreadyMember(&data
, p
);
73 if (m_password
.length() > 0 && strcmp(pass
, m_password
.c_str()))
75 MakeWrongPassword(&data
);
80 Player
* plr
= sObjectMgr
.GetPlayer(p
);
84 if (HasFlag(CHANNEL_FLAG_LFG
) && sWorld
.getConfig(CONFIG_BOOL_RESTRICTED_LFG_CHANNEL
) && plr
->GetSession()->GetSecurity() == SEC_PLAYER
)
91 if (plr
->GetGuildId() && (GetFlags() == 0x38))
94 plr
->JoinedChannel(this);
97 if (m_announce
&& (!plr
|| plr
->GetSession()->GetSecurity() < SEC_GAMEMASTER
|| !sWorld
.getConfig(CONFIG_BOOL_SILENTLY_GM_JOIN_TO_CHANNEL
)))
105 PlayerInfo
& pinfo
= m_players
[p
];
109 MakeYouJoined(&data
);
114 // if no owner first logged will become
115 if (!IsConstant() && !m_ownerGuid
)
117 SetOwner(p
, (m_players
.size() > 1 ? true : false));
118 m_players
[p
].SetModerator(true);
122 void Channel::Leave(ObjectGuid p
, bool send
)
129 MakeNotMember(&data
);
135 Player
* plr
= sObjectMgr
.GetPlayer(p
);
143 plr
->LeftChannel(this);
147 bool changeowner
= m_players
[p
].IsOwner();
150 if (m_announce
&& (!plr
|| plr
->GetSession()->GetSecurity() < SEC_GAMEMASTER
|| !sWorld
.getConfig(CONFIG_BOOL_SILENTLY_GM_JOIN_TO_CHANNEL
)))
161 ObjectGuid newowner
= !m_players
.empty() ? m_players
.begin()->second
.player
: ObjectGuid();
167 void Channel::KickOrBan(ObjectGuid good
, const char* badname
, bool ban
)
169 AccountTypes sec
= SEC_PLAYER
;
170 Player
* gplr
= sObjectMgr
.GetPlayer(good
);
172 sec
= gplr
->GetSession()->GetSecurity();
177 MakeNotMember(&data
);
178 SendToOne(&data
, good
);
180 else if (!m_players
[good
].IsModerator() && sec
< SEC_GAMEMASTER
)
183 MakeNotModerator(&data
);
184 SendToOne(&data
, good
);
188 Player
* bad
= sObjectMgr
.GetPlayer(badname
);
189 if (bad
== NULL
|| !IsOn(bad
->GetObjectGuid()))
192 MakePlayerNotFound(&data
, badname
);
193 SendToOne(&data
, good
);
195 else if (sec
< SEC_GAMEMASTER
&& bad
->GetObjectGuid() == m_ownerGuid
&& good
!= m_ownerGuid
)
199 SendToOne(&data
, good
);
203 bool changeowner
= (m_ownerGuid
== bad
->GetObjectGuid());
207 if (ban
&& !IsBanned(bad
->GetObjectGuid()))
209 m_banned
.insert(bad
->GetObjectGuid());
210 MakePlayerBanned(&data
, bad
->GetObjectGuid(), good
);
213 MakePlayerKicked(&data
, bad
->GetObjectGuid(), good
);
216 m_players
.erase(bad
->GetObjectGuid());
217 bad
->LeftChannel(this);
221 ObjectGuid newowner
= !m_players
.empty() ? good
: ObjectGuid();
228 void Channel::UnBan(ObjectGuid good
, const char* badname
)
231 Player
* gplr
= sObjectMgr
.GetPlayer(good
);
233 sec
= gplr
->GetSession()->GetSecurity();
238 MakeNotMember(&data
);
239 SendToOne(&data
, good
);
241 else if (!m_players
[good
].IsModerator() && sec
< SEC_GAMEMASTER
)
244 MakeNotModerator(&data
);
245 SendToOne(&data
, good
);
249 Player
* bad
= sObjectMgr
.GetPlayer(badname
);
250 if (bad
== NULL
|| !IsBanned(bad
->GetObjectGuid()))
253 MakePlayerNotFound(&data
, badname
);
254 SendToOne(&data
, good
);
258 m_banned
.erase(bad
->GetObjectGuid());
261 MakePlayerUnbanned(&data
, bad
->GetObjectGuid(), good
);
267 void Channel::Password(ObjectGuid p
, const char* pass
)
270 Player
* plr
= sObjectMgr
.GetPlayer(p
);
272 sec
= plr
->GetSession()->GetSecurity();
277 MakeNotMember(&data
);
280 else if (!m_players
[p
].IsModerator() && sec
< SEC_GAMEMASTER
)
283 MakeNotModerator(&data
);
291 MakePasswordChanged(&data
, p
);
296 void Channel::SetMode(ObjectGuid p
, const char* p2n
, bool mod
, bool set
)
298 Player
* plr
= sObjectMgr
.GetPlayer(p
);
302 uint32 sec
= plr
->GetSession()->GetSecurity();
307 MakeNotMember(&data
);
310 else if (!m_players
[p
].IsModerator() && sec
< SEC_GAMEMASTER
)
313 MakeNotModerator(&data
);
318 Player
* newp
= sObjectMgr
.GetPlayer(p2n
);
322 MakePlayerNotFound(&data
, p2n
);
327 PlayerInfo inf
= m_players
[newp
->GetObjectGuid()];
328 if (p
== m_ownerGuid
&& newp
->GetObjectGuid() == m_ownerGuid
&& mod
)
331 if (!IsOn(newp
->GetObjectGuid()))
334 MakePlayerNotFound(&data
, p2n
);
339 // allow make moderator from another team only if both is GMs
340 // at this moment this only way to show channel post for GM from another team
341 if ((plr
->GetSession()->GetSecurity() < SEC_GAMEMASTER
|| newp
->GetSession()->GetSecurity() < SEC_GAMEMASTER
) &&
342 plr
->GetTeam() != newp
->GetTeam() && !sWorld
.getConfig(CONFIG_BOOL_ALLOW_TWO_SIDE_INTERACTION_CHANNEL
))
345 MakePlayerNotFound(&data
, p2n
);
350 if (m_ownerGuid
== newp
->GetObjectGuid() && m_ownerGuid
!= p
)
359 SetModerator(newp
->GetObjectGuid(), set
);
361 SetMute(newp
->GetObjectGuid(), set
);
365 void Channel::SetOwner(ObjectGuid p
, const char* newname
)
367 Player
* plr
= sObjectMgr
.GetPlayer(p
);
371 uint32 sec
= plr
->GetSession()->GetSecurity();
376 MakeNotMember(&data
);
381 if (sec
< SEC_GAMEMASTER
&& p
!= m_ownerGuid
)
389 Player
* newp
= sObjectMgr
.GetPlayer(newname
);
390 if (newp
== NULL
|| !IsOn(newp
->GetObjectGuid()))
393 MakePlayerNotFound(&data
, newname
);
398 if (newp
->GetTeam() != plr
->GetTeam() && !sWorld
.getConfig(CONFIG_BOOL_ALLOW_TWO_SIDE_INTERACTION_CHANNEL
))
401 MakePlayerNotFound(&data
, newname
);
406 m_players
[newp
->GetObjectGuid()].SetModerator(true);
407 SetOwner(newp
->GetObjectGuid());
410 void Channel::SendWhoOwner(ObjectGuid p
)
415 MakeNotMember(&data
);
421 MakeChannelOwner(&data
);
426 void Channel::List(Player
* player
)
428 ObjectGuid p
= player
->GetObjectGuid();
433 MakeNotMember(&data
);
438 WorldPacket
data(SMSG_CHANNEL_LIST
, 1 + (GetName().size() + 1) + 1 + 4 + m_players
.size() * (8 + 1));
439 data
<< uint8(1); // channel type?
440 data
<< GetName(); // channel name
441 data
<< uint8(GetFlags()); // channel flags?
443 size_t pos
= data
.wpos();
444 data
<< uint32(0); // size of list, placeholder
446 AccountTypes gmLevelInWhoList
= (AccountTypes
)sWorld
.getConfig(CONFIG_UINT32_GM_LEVEL_IN_WHO_LIST
);
449 for (PlayerList::const_iterator i
= m_players
.begin(); i
!= m_players
.end(); ++i
)
451 Player
* plr
= sObjectMgr
.GetPlayer(i
->first
);
453 // PLAYER can't see MODERATOR, GAME MASTER, ADMINISTRATOR characters
454 // MODERATOR, GAME MASTER, ADMINISTRATOR can see all
455 if (plr
&& (player
->GetSession()->GetSecurity() > SEC_PLAYER
|| plr
->GetSession()->GetSecurity() <= gmLevelInWhoList
) &&
456 plr
->IsVisibleGloballyFor(player
))
458 data
<< ObjectGuid(i
->first
);
459 data
<< uint8(i
->second
.flags
); // flags seems to be changed...
464 data
.put
<uint32
>(pos
, count
);
470 void Channel::Announce(ObjectGuid p
)
473 Player
* plr
= sObjectMgr
.GetPlayer(p
);
475 sec
= plr
->GetSession()->GetSecurity();
480 MakeNotMember(&data
);
483 else if (!m_players
[p
].IsModerator() && sec
< SEC_GAMEMASTER
)
486 MakeNotModerator(&data
);
491 m_announce
= !m_announce
;
495 MakeAnnouncementsOn(&data
, p
);
497 MakeAnnouncementsOff(&data
, p
);
502 void Channel::Moderate(ObjectGuid p
)
505 Player
* plr
= sObjectMgr
.GetPlayer(p
);
507 sec
= plr
->GetSession()->GetSecurity();
512 MakeNotMember(&data
);
515 else if (!m_players
[p
].IsModerator() && sec
< SEC_GAMEMASTER
)
518 MakeNotModerator(&data
);
523 m_moderate
= !m_moderate
;
527 MakeModerationOn(&data
, p
);
529 MakeModerationOff(&data
, p
);
534 void Channel::Say(ObjectGuid p
, const char* what
, uint32 lang
)
538 if (sWorld
.getConfig(CONFIG_BOOL_ALLOW_TWO_SIDE_INTERACTION_CHANNEL
))
539 lang
= LANG_UNIVERSAL
;
542 Player
* plr
= sObjectMgr
.GetPlayer(p
);
544 sec
= plr
->GetSession()->GetSecurity();
549 MakeNotMember(&data
);
552 else if (m_players
[p
].IsMuted())
558 else if (m_moderate
&& !m_players
[p
].IsModerator() && sec
< SEC_GAMEMASTER
)
561 MakeNotModerator(&data
);
566 uint32 messageLength
= strlen(what
) + 1;
568 WorldPacket
data(SMSG_MESSAGECHAT
, 1 + 4 + 8 + 4 + m_name
.size() + 1 + 8 + 4 + messageLength
+ 1);
569 data
<< uint8(CHAT_MSG_CHANNEL
);
570 data
<< uint32(lang
);
571 data
<< ObjectGuid(p
); // 2.1.0
572 data
<< uint32(0); // 2.1.0
574 data
<< ObjectGuid(p
);
575 data
<< uint32(messageLength
);
577 data
<< uint8(plr
? plr
->GetChatTag() : uint8(CHAT_TAG_NONE
));
579 SendToAll(&data
, !m_players
[p
].IsModerator() ? p
: ObjectGuid());
583 void Channel::Invite(ObjectGuid p
, const char* newname
)
588 MakeNotMember(&data
);
593 Player
* newp
= sObjectMgr
.GetPlayer(newname
);
597 MakePlayerNotFound(&data
, newname
);
602 Player
* plr
= sObjectMgr
.GetPlayer(p
);
606 if (newp
->GetTeam() != plr
->GetTeam() && !sWorld
.getConfig(CONFIG_BOOL_ALLOW_TWO_SIDE_INTERACTION_CHANNEL
))
609 MakeInviteWrongFaction(&data
);
614 if (IsOn(newp
->GetObjectGuid()))
617 MakePlayerAlreadyMember(&data
, newp
->GetObjectGuid());
623 if (!newp
->GetSocial()->HasIgnore(p
))
625 MakeInvite(&data
, p
);
626 SendToOne(&data
, newp
->GetObjectGuid());
629 MakePlayerInvited(&data
, newp
->GetName());
633 void Channel::SetOwner(ObjectGuid guid
, bool exclaim
)
637 // [] will re-add player after it possible removed
638 PlayerList::iterator p_itr
= m_players
.find(m_ownerGuid
);
639 if (p_itr
!= m_players
.end())
640 p_itr
->second
.SetOwner(false);
647 uint8 oldFlag
= GetPlayerFlags(m_ownerGuid
);
648 m_players
[m_ownerGuid
].SetOwner(true);
651 MakeModeChange(&data
, m_ownerGuid
, oldFlag
);
656 MakeOwnerChanged(&data
, m_ownerGuid
);
662 void Channel::SendToAll(WorldPacket
* data
, ObjectGuid p
)
664 for (PlayerList::const_iterator i
= m_players
.begin(); i
!= m_players
.end(); ++i
)
665 if (Player
* plr
= sObjectMgr
.GetPlayer(i
->first
))
666 if (!p
|| !plr
->GetSocial()->HasIgnore(p
))
667 plr
->GetSession()->SendPacket(data
);
670 void Channel::SendToOne(WorldPacket
* data
, ObjectGuid who
)
672 if (Player
* plr
= ObjectMgr::GetPlayer(who
))
673 plr
->GetSession()->SendPacket(data
);
676 void Channel::Voice(ObjectGuid
/*guid1*/, ObjectGuid
/*guid2*/)
681 void Channel::DeVoice(ObjectGuid
/*guid1*/, ObjectGuid
/*guid2*/)
687 void Channel::MakeNotifyPacket(WorldPacket
* data
, uint8 notify_type
)
689 data
->Initialize(SMSG_CHANNEL_NOTIFY
, 1 + m_name
.size() + 1);
690 *data
<< uint8(notify_type
);
695 void Channel::MakeJoined(WorldPacket
* data
, ObjectGuid guid
)
697 MakeNotifyPacket(data
, CHAT_JOINED_NOTICE
);
698 *data
<< ObjectGuid(guid
);
702 void Channel::MakeLeft(WorldPacket
* data
, ObjectGuid guid
)
704 MakeNotifyPacket(data
, CHAT_LEFT_NOTICE
);
705 *data
<< ObjectGuid(guid
);
709 void Channel::MakeYouJoined(WorldPacket
* data
)
711 MakeNotifyPacket(data
, CHAT_YOU_JOINED_NOTICE
);
712 *data
<< uint8(GetFlags());
713 *data
<< uint32(GetChannelId());
718 void Channel::MakeYouLeft(WorldPacket
* data
)
720 MakeNotifyPacket(data
, CHAT_YOU_LEFT_NOTICE
);
721 *data
<< uint32(GetChannelId());
722 *data
<< uint8(0); // can be 0x00 and 0x01
726 void Channel::MakeWrongPassword(WorldPacket
* data
)
728 MakeNotifyPacket(data
, CHAT_WRONG_PASSWORD_NOTICE
);
732 void Channel::MakeNotMember(WorldPacket
* data
)
734 MakeNotifyPacket(data
, CHAT_NOT_MEMBER_NOTICE
);
738 void Channel::MakeNotModerator(WorldPacket
* data
)
740 MakeNotifyPacket(data
, CHAT_NOT_MODERATOR_NOTICE
);
744 void Channel::MakePasswordChanged(WorldPacket
* data
, ObjectGuid guid
)
746 MakeNotifyPacket(data
, CHAT_PASSWORD_CHANGED_NOTICE
);
747 *data
<< ObjectGuid(guid
);
751 void Channel::MakeOwnerChanged(WorldPacket
* data
, ObjectGuid guid
)
753 MakeNotifyPacket(data
, CHAT_OWNER_CHANGED_NOTICE
);
754 *data
<< ObjectGuid(guid
);
758 void Channel::MakePlayerNotFound(WorldPacket
* data
, const std::string
& name
)
760 MakeNotifyPacket(data
, CHAT_PLAYER_NOT_FOUND_NOTICE
);
765 void Channel::MakeNotOwner(WorldPacket
* data
)
767 MakeNotifyPacket(data
, CHAT_NOT_OWNER_NOTICE
);
771 void Channel::MakeChannelOwner(WorldPacket
* data
)
773 std::string name
= "";
775 if (!sObjectMgr
.GetPlayerNameByGUID(m_ownerGuid
, name
) || name
.empty())
776 name
= "PLAYER_NOT_FOUND";
778 MakeNotifyPacket(data
, CHAT_CHANNEL_OWNER_NOTICE
);
779 *data
<< ((IsConstant() || !m_ownerGuid
) ? "Nobody" : name
);
783 void Channel::MakeModeChange(WorldPacket
* data
, ObjectGuid guid
, uint8 oldflags
)
785 MakeNotifyPacket(data
, CHAT_MODE_CHANGE_NOTICE
);
786 *data
<< ObjectGuid(guid
);
787 *data
<< uint8(oldflags
);
788 *data
<< uint8(GetPlayerFlags(guid
));
792 void Channel::MakeAnnouncementsOn(WorldPacket
* data
, ObjectGuid guid
)
794 MakeNotifyPacket(data
, CHAT_ANNOUNCEMENTS_ON_NOTICE
);
795 *data
<< ObjectGuid(guid
);
799 void Channel::MakeAnnouncementsOff(WorldPacket
* data
, ObjectGuid guid
)
801 MakeNotifyPacket(data
, CHAT_ANNOUNCEMENTS_OFF_NOTICE
);
802 *data
<< ObjectGuid(guid
);
806 void Channel::MakeModerationOn(WorldPacket
* data
, ObjectGuid guid
)
808 MakeNotifyPacket(data
, CHAT_MODERATION_ON_NOTICE
);
809 *data
<< ObjectGuid(guid
);
813 void Channel::MakeModerationOff(WorldPacket
* data
, ObjectGuid guid
)
815 MakeNotifyPacket(data
, CHAT_MODERATION_OFF_NOTICE
);
816 *data
<< ObjectGuid(guid
);
820 void Channel::MakeMuted(WorldPacket
* data
)
822 MakeNotifyPacket(data
, CHAT_MUTED_NOTICE
);
826 void Channel::MakePlayerKicked(WorldPacket
* data
, ObjectGuid bad
, ObjectGuid good
)
828 MakeNotifyPacket(data
, CHAT_PLAYER_KICKED_NOTICE
);
829 *data
<< ObjectGuid(bad
);
830 *data
<< ObjectGuid(good
);
834 void Channel::MakeBanned(WorldPacket
* data
)
836 MakeNotifyPacket(data
, CHAT_BANNED_NOTICE
);
840 void Channel::MakePlayerBanned(WorldPacket
* data
, ObjectGuid bad
, ObjectGuid good
)
842 MakeNotifyPacket(data
, CHAT_PLAYER_BANNED_NOTICE
);
843 *data
<< ObjectGuid(bad
);
844 *data
<< ObjectGuid(good
);
848 void Channel::MakePlayerUnbanned(WorldPacket
* data
, ObjectGuid bad
, ObjectGuid good
)
850 MakeNotifyPacket(data
, CHAT_PLAYER_UNBANNED_NOTICE
);
851 *data
<< ObjectGuid(bad
);
852 *data
<< ObjectGuid(good
);
856 void Channel::MakePlayerNotBanned(WorldPacket
* data
, ObjectGuid guid
)
858 MakeNotifyPacket(data
, CHAT_PLAYER_NOT_BANNED_NOTICE
);
859 *data
<< ObjectGuid(guid
); // should be string!!
863 void Channel::MakePlayerAlreadyMember(WorldPacket
* data
, ObjectGuid guid
)
865 MakeNotifyPacket(data
, CHAT_PLAYER_ALREADY_MEMBER_NOTICE
);
866 *data
<< ObjectGuid(guid
);
870 void Channel::MakeInvite(WorldPacket
* data
, ObjectGuid guid
)
872 MakeNotifyPacket(data
, CHAT_INVITE_NOTICE
);
873 *data
<< ObjectGuid(guid
);
877 void Channel::MakeInviteWrongFaction(WorldPacket
* data
)
879 MakeNotifyPacket(data
, CHAT_INVITE_WRONG_FACTION_NOTICE
);
883 void Channel::MakeWrongFaction(WorldPacket
* data
)
885 MakeNotifyPacket(data
, CHAT_WRONG_FACTION_NOTICE
);
889 void Channel::MakeInvalidName(WorldPacket
* data
)
891 MakeNotifyPacket(data
, CHAT_INVALID_NAME_NOTICE
);
895 void Channel::MakeNotModerated(WorldPacket
* data
)
897 MakeNotifyPacket(data
, CHAT_NOT_MODERATED_NOTICE
);
901 void Channel::MakePlayerInvited(WorldPacket
* data
, const std::string
& name
)
903 MakeNotifyPacket(data
, CHAT_PLAYER_INVITED_NOTICE
);
908 void Channel::MakePlayerInviteBanned(WorldPacket
* data
, ObjectGuid guid
)
910 MakeNotifyPacket(data
, CHAT_PLAYER_INVITE_BANNED_NOTICE
);
911 *data
<< ObjectGuid(guid
); // should be string!!
915 void Channel::MakeThrottled(WorldPacket
* data
)
917 MakeNotifyPacket(data
, CHAT_THROTTLED_NOTICE
);
921 void Channel::MakeNotInArea(WorldPacket
* data
)
923 MakeNotifyPacket(data
, CHAT_NOT_IN_AREA_NOTICE
);
927 void Channel::MakeNotInLfg(WorldPacket
* data
)
929 MakeNotifyPacket(data
, CHAT_NOT_IN_LFG_NOTICE
);
933 void Channel::MakeVoiceOn(WorldPacket
* data
, ObjectGuid guid
)
935 MakeNotifyPacket(data
, CHAT_VOICE_ON_NOTICE
);
936 *data
<< ObjectGuid(guid
);
940 void Channel::MakeVoiceOff(WorldPacket
* data
, ObjectGuid guid
)
942 MakeNotifyPacket(data
, CHAT_VOICE_OFF_NOTICE
);
943 *data
<< ObjectGuid(guid
);
946 void Channel::JoinNotify(ObjectGuid guid
)
951 data
.Initialize(SMSG_USERLIST_ADD
, 8 + 1 + 1 + 4 + GetName().size() + 1);
953 data
.Initialize(SMSG_USERLIST_UPDATE
, 8 + 1 + 1 + 4 + GetName().size() + 1);
955 data
<< ObjectGuid(guid
);
956 data
<< uint8(GetPlayerFlags(guid
));
957 data
<< uint8(GetFlags());
958 data
<< uint32(GetNumPlayers());
963 void Channel::LeaveNotify(ObjectGuid guid
)
965 WorldPacket
data(SMSG_USERLIST_REMOVE
, 8 + 1 + 4 + GetName().size() + 1);
966 data
<< ObjectGuid(guid
);
967 data
<< uint8(GetFlags());
968 data
<< uint32(GetNumPlayers());