2 * Copyright (C) 2005-2009 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
), m_ownerGUID(0)
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(uint64 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
= objmgr
.GetPlayer(p
);
84 if(HasFlag(CHANNEL_FLAG_LFG
) &&
85 sWorld
.getConfig(CONFIG_RESTRICTED_LFG_CHANNEL
) && plr
->GetSession()->GetSecurity() == SEC_PLAYER
&&
86 (plr
->GetGroup() || plr
->m_lookingForGroup
.Empty()) )
93 if(plr
->GetGuildId() && (GetFlags() == 0x38))
96 plr
->JoinedChannel(this);
99 if(m_announce
&& (!plr
|| plr
->GetSession()->GetSecurity() < SEC_GAMEMASTER
|| !sWorld
.getConfig(CONFIG_SILENTLY_GM_JOIN_TO_CHANNEL
) ))
101 MakeJoined(&data
, p
);
112 MakeYouJoined(&data
);
117 // if no owner first logged will become
118 if(!IsConstant() && !m_ownerGUID
)
120 SetOwner(p
, (players
.size() > 1 ? true : false));
121 players
[p
].SetModerator(true);
125 void Channel::Leave(uint64 p
, bool send
)
132 MakeNotMember(&data
);
138 Player
*plr
= objmgr
.GetPlayer(p
);
146 plr
->LeftChannel(this);
150 bool changeowner
= players
[p
].IsOwner();
153 if(m_announce
&& (!plr
|| plr
->GetSession()->GetSecurity() < SEC_GAMEMASTER
|| !sWorld
.getConfig(CONFIG_SILENTLY_GM_JOIN_TO_CHANNEL
) ))
164 uint64 newowner
= !players
.empty() ? players
.begin()->second
.player
: 0;
170 void Channel::KickOrBan(uint64 good
, const char *badname
, bool ban
)
172 AccountTypes sec
= SEC_PLAYER
;
173 Player
*gplr
= objmgr
.GetPlayer(good
);
175 sec
= gplr
->GetSession()->GetSecurity();
180 MakeNotMember(&data
);
181 SendToOne(&data
, good
);
183 else if(!players
[good
].IsModerator() && sec
< SEC_GAMEMASTER
)
186 MakeNotModerator(&data
);
187 SendToOne(&data
, good
);
191 Player
*bad
= objmgr
.GetPlayer(badname
);
192 if(bad
== NULL
|| !IsOn(bad
->GetGUID()))
195 MakePlayerNotFound(&data
, badname
);
196 SendToOne(&data
, good
);
198 else if(sec
< SEC_GAMEMASTER
&& bad
->GetGUID() == m_ownerGUID
&& good
!= m_ownerGUID
)
202 SendToOne(&data
, good
);
206 bool changeowner
= (m_ownerGUID
== bad
->GetGUID());
210 if(ban
&& !IsBanned(bad
->GetGUID()))
212 banned
.insert(bad
->GetGUID());
213 MakePlayerBanned(&data
, bad
->GetGUID(), good
);
216 MakePlayerKicked(&data
, bad
->GetGUID(), good
);
219 players
.erase(bad
->GetGUID());
220 bad
->LeftChannel(this);
224 uint64 newowner
= !players
.empty() ? good
: false;
231 void Channel::UnBan(uint64 good
, const char *badname
)
234 Player
*gplr
= objmgr
.GetPlayer(good
);
236 sec
= gplr
->GetSession()->GetSecurity();
241 MakeNotMember(&data
);
242 SendToOne(&data
, good
);
244 else if(!players
[good
].IsModerator() && sec
< SEC_GAMEMASTER
)
247 MakeNotModerator(&data
);
248 SendToOne(&data
, good
);
252 Player
*bad
= objmgr
.GetPlayer(badname
);
253 if(bad
== NULL
|| !IsBanned(bad
->GetGUID()))
256 MakePlayerNotFound(&data
, badname
);
257 SendToOne(&data
, good
);
261 banned
.erase(bad
->GetGUID());
264 MakePlayerUnbanned(&data
, bad
->GetGUID(), good
);
270 void Channel::Password(uint64 p
, const char *pass
)
273 Player
*plr
= objmgr
.GetPlayer(p
);
275 sec
= plr
->GetSession()->GetSecurity();
280 MakeNotMember(&data
);
283 else if(!players
[p
].IsModerator() && sec
< SEC_GAMEMASTER
)
286 MakeNotModerator(&data
);
294 MakePasswordChanged(&data
, p
);
299 void Channel::SetMode(uint64 p
, const char *p2n
, bool mod
, bool set
)
301 Player
*plr
= objmgr
.GetPlayer(p
);
305 uint32 sec
= plr
->GetSession()->GetSecurity();
310 MakeNotMember(&data
);
313 else if(!players
[p
].IsModerator() && sec
< SEC_GAMEMASTER
)
316 MakeNotModerator(&data
);
321 Player
*newp
= objmgr
.GetPlayer(p2n
);
325 MakePlayerNotFound(&data
, p2n
);
330 PlayerInfo inf
= players
[newp
->GetGUID()];
331 if(p
== m_ownerGUID
&& newp
->GetGUID() == m_ownerGUID
&& mod
)
334 if(!IsOn(newp
->GetGUID()))
337 MakePlayerNotFound(&data
, p2n
);
342 // allow make moderator from another team only if both is GMs
343 // at this moment this only way to show channel post for GM from another team
344 if( (plr
->GetSession()->GetSecurity() < SEC_GAMEMASTER
|| newp
->GetSession()->GetSecurity() < SEC_GAMEMASTER
) &&
345 plr
->GetTeam() != newp
->GetTeam() && !sWorld
.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_CHANNEL
) )
348 MakePlayerNotFound(&data
, p2n
);
353 if(m_ownerGUID
== newp
->GetGUID() && m_ownerGUID
!= p
)
362 SetModerator(newp
->GetGUID(), set
);
364 SetMute(newp
->GetGUID(), set
);
368 void Channel::SetOwner(uint64 p
, const char *newname
)
370 Player
*plr
= objmgr
.GetPlayer(p
);
374 uint32 sec
= plr
->GetSession()->GetSecurity();
379 MakeNotMember(&data
);
384 if(sec
< SEC_GAMEMASTER
&& p
!= m_ownerGUID
)
392 Player
*newp
= objmgr
.GetPlayer(newname
);
393 if(newp
== NULL
|| !IsOn(newp
->GetGUID()))
396 MakePlayerNotFound(&data
, newname
);
401 if(newp
->GetTeam() != plr
->GetTeam() && !sWorld
.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_CHANNEL
))
404 MakePlayerNotFound(&data
, newname
);
409 players
[newp
->GetGUID()].SetModerator(true);
410 SetOwner(newp
->GetGUID());
413 void Channel::SendWhoOwner(uint64 p
)
418 MakeNotMember(&data
);
424 MakeChannelOwner(&data
);
429 void Channel::List(Player
* player
)
431 uint64 p
= player
->GetGUID();
436 MakeNotMember(&data
);
441 WorldPacket
data(SMSG_CHANNEL_LIST
, 1+(GetName().size()+1)+1+4+players
.size()*(8+1));
442 data
<< uint8(1); // channel type?
443 data
<< GetName(); // channel name
444 data
<< uint8(GetFlags()); // channel flags?
446 size_t pos
= data
.wpos();
447 data
<< uint32(0); // size of list, placeholder
449 bool gmInWhoList
= sWorld
.getConfig(CONFIG_GM_IN_WHO_LIST
) || player
->GetSession()->GetSecurity() > SEC_PLAYER
;
452 for(PlayerList::const_iterator i
= players
.begin(); i
!= players
.end(); ++i
)
454 Player
*plr
= objmgr
.GetPlayer(i
->first
);
456 // PLAYER can't see MODERATOR, GAME MASTER, ADMINISTRATOR characters
457 // MODERATOR, GAME MASTER, ADMINISTRATOR can see all
458 if (plr
&& ( plr
->GetSession()->GetSecurity() == SEC_PLAYER
|| (gmInWhoList
&& plr
->IsVisibleGloballyFor(player
))))
460 data
<< uint64(i
->first
);
461 data
<< uint8(i
->second
.flags
); // flags seems to be changed...
466 data
.put
<uint32
>(pos
,count
);
472 void Channel::Announce(uint64 p
)
475 Player
*plr
= objmgr
.GetPlayer(p
);
477 sec
= plr
->GetSession()->GetSecurity();
482 MakeNotMember(&data
);
485 else if(!players
[p
].IsModerator() && sec
< SEC_GAMEMASTER
)
488 MakeNotModerator(&data
);
493 m_announce
= !m_announce
;
497 MakeAnnouncementsOn(&data
, p
);
499 MakeAnnouncementsOff(&data
, p
);
504 void Channel::Moderate(uint64 p
)
507 Player
*plr
= objmgr
.GetPlayer(p
);
509 sec
= plr
->GetSession()->GetSecurity();
514 MakeNotMember(&data
);
517 else if(!players
[p
].IsModerator() && sec
< SEC_GAMEMASTER
)
520 MakeNotModerator(&data
);
525 m_moderate
= !m_moderate
;
529 MakeModerationOn(&data
, p
);
531 MakeModerationOff(&data
, p
);
536 void Channel::Say(uint64 p
, const char *what
, uint32 lang
)
540 if (sWorld
.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_CHANNEL
))
541 lang
= LANG_UNIVERSAL
;
544 Player
*plr
= objmgr
.GetPlayer(p
);
546 sec
= plr
->GetSession()->GetSecurity();
551 MakeNotMember(&data
);
554 else if(players
[p
].IsMuted())
560 else if(m_moderate
&& !players
[p
].IsModerator() && sec
< SEC_GAMEMASTER
)
563 MakeNotModerator(&data
);
568 uint32 messageLength
= strlen(what
) + 1;
570 WorldPacket
data(SMSG_MESSAGECHAT
, 1+4+8+4+m_name
.size()+1+8+4+messageLength
+1);
571 data
<< (uint8
)CHAT_MSG_CHANNEL
;
572 data
<< (uint32
)lang
;
574 data
<< uint32(0); // 2.1.0
577 data
<< messageLength
;
579 data
<< uint8(plr
? plr
->chatTag() : 0);
581 SendToAll(&data
, !players
[p
].IsModerator() ? p
: false);
585 void Channel::Invite(uint64 p
, const char *newname
)
590 MakeNotMember(&data
);
595 Player
*newp
= objmgr
.GetPlayer(newname
);
599 MakePlayerNotFound(&data
, newname
);
604 Player
*plr
= objmgr
.GetPlayer(p
);
608 if (newp
->GetTeam() != plr
->GetTeam() && !sWorld
.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_CHANNEL
))
611 MakeInviteWrongFaction(&data
);
616 if(IsOn(newp
->GetGUID()))
619 MakePlayerAlreadyMember(&data
, newp
->GetGUID());
625 if(!newp
->GetSocial()->HasIgnore(GUID_LOPART(p
)))
627 MakeInvite(&data
, p
);
628 SendToOne(&data
, newp
->GetGUID());
631 MakePlayerInvited(&data
, newp
->GetName());
635 void Channel::SetOwner(uint64 guid
, bool exclaim
)
639 // [] will re-add player after it possible removed
640 PlayerList::iterator p_itr
= players
.find(m_ownerGUID
);
641 if(p_itr
!= players
.end())
642 p_itr
->second
.SetOwner(false);
648 uint8 oldFlag
= GetPlayerFlags(m_ownerGUID
);
649 players
[m_ownerGUID
].SetOwner(true);
652 MakeModeChange(&data
, m_ownerGUID
, oldFlag
);
657 MakeOwnerChanged(&data
, m_ownerGUID
);
663 void Channel::SendToAll(WorldPacket
*data
, uint64 p
)
665 for(PlayerList::const_iterator i
= players
.begin(); i
!= players
.end(); ++i
)
667 Player
*plr
= objmgr
.GetPlayer(i
->first
);
670 if(!p
|| !plr
->GetSocial()->HasIgnore(GUID_LOPART(p
)))
671 plr
->GetSession()->SendPacket(data
);
676 void Channel::SendToAllButOne(WorldPacket
*data
, uint64 who
)
678 for(PlayerList::const_iterator i
= players
.begin(); i
!= players
.end(); ++i
)
682 Player
*plr
= objmgr
.GetPlayer(i
->first
);
684 plr
->GetSession()->SendPacket(data
);
689 void Channel::SendToOne(WorldPacket
*data
, uint64 who
)
691 Player
*plr
= objmgr
.GetPlayer(who
);
693 plr
->GetSession()->SendPacket(data
);
696 void Channel::Voice(uint64
/*guid1*/, uint64
/*guid2*/)
701 void Channel::DeVoice(uint64
/*guid1*/, uint64
/*guid2*/)
707 void Channel::MakeNotifyPacket(WorldPacket
*data
, uint8 notify_type
)
709 data
->Initialize(SMSG_CHANNEL_NOTIFY
, 1+m_name
.size()+1);
710 *data
<< uint8(notify_type
);
715 void Channel::MakeJoined(WorldPacket
*data
, uint64 guid
)
717 MakeNotifyPacket(data
, CHAT_JOINED_NOTICE
);
718 *data
<< uint64(guid
);
722 void Channel::MakeLeft(WorldPacket
*data
, uint64 guid
)
724 MakeNotifyPacket(data
, CHAT_LEFT_NOTICE
);
725 *data
<< uint64(guid
);
729 void Channel::MakeYouJoined(WorldPacket
*data
)
731 MakeNotifyPacket(data
, CHAT_YOU_JOINED_NOTICE
);
732 *data
<< uint8(GetFlags());
733 *data
<< uint32(GetChannelId());
738 void Channel::MakeYouLeft(WorldPacket
*data
)
740 MakeNotifyPacket(data
, CHAT_YOU_LEFT_NOTICE
);
741 *data
<< uint32(GetChannelId());
742 *data
<< uint8(0); // can be 0x00 and 0x01
746 void Channel::MakeWrongPassword(WorldPacket
*data
)
748 MakeNotifyPacket(data
, CHAT_WRONG_PASSWORD_NOTICE
);
752 void Channel::MakeNotMember(WorldPacket
*data
)
754 MakeNotifyPacket(data
, CHAT_NOT_MEMBER_NOTICE
);
758 void Channel::MakeNotModerator(WorldPacket
*data
)
760 MakeNotifyPacket(data
, CHAT_NOT_MODERATOR_NOTICE
);
764 void Channel::MakePasswordChanged(WorldPacket
*data
, uint64 guid
)
766 MakeNotifyPacket(data
, CHAT_PASSWORD_CHANGED_NOTICE
);
767 *data
<< uint64(guid
);
771 void Channel::MakeOwnerChanged(WorldPacket
*data
, uint64 guid
)
773 MakeNotifyPacket(data
, CHAT_OWNER_CHANGED_NOTICE
);
774 *data
<< uint64(guid
);
778 void Channel::MakePlayerNotFound(WorldPacket
*data
, const std::string
& name
)
780 MakeNotifyPacket(data
, CHAT_PLAYER_NOT_FOUND_NOTICE
);
785 void Channel::MakeNotOwner(WorldPacket
*data
)
787 MakeNotifyPacket(data
, CHAT_NOT_OWNER_NOTICE
);
791 void Channel::MakeChannelOwner(WorldPacket
*data
)
793 std::string name
= "";
795 if(!objmgr
.GetPlayerNameByGUID(m_ownerGUID
, name
) || name
.empty())
796 name
= "PLAYER_NOT_FOUND";
798 MakeNotifyPacket(data
, CHAT_CHANNEL_OWNER_NOTICE
);
799 *data
<< ((IsConstant() || !m_ownerGUID
) ? "Nobody" : name
);
803 void Channel::MakeModeChange(WorldPacket
*data
, uint64 guid
, uint8 oldflags
)
805 MakeNotifyPacket(data
, CHAT_MODE_CHANGE_NOTICE
);
806 *data
<< uint64(guid
);
807 *data
<< uint8(oldflags
);
808 *data
<< uint8(GetPlayerFlags(guid
));
812 void Channel::MakeAnnouncementsOn(WorldPacket
*data
, uint64 guid
)
814 MakeNotifyPacket(data
, CHAT_ANNOUNCEMENTS_ON_NOTICE
);
815 *data
<< uint64(guid
);
819 void Channel::MakeAnnouncementsOff(WorldPacket
*data
, uint64 guid
)
821 MakeNotifyPacket(data
, CHAT_ANNOUNCEMENTS_OFF_NOTICE
);
822 *data
<< uint64(guid
);
826 void Channel::MakeModerationOn(WorldPacket
*data
, uint64 guid
)
828 MakeNotifyPacket(data
, CHAT_MODERATION_ON_NOTICE
);
829 *data
<< uint64(guid
);
833 void Channel::MakeModerationOff(WorldPacket
*data
, uint64 guid
)
835 MakeNotifyPacket(data
, CHAT_MODERATION_OFF_NOTICE
);
836 *data
<< uint64(guid
);
840 void Channel::MakeMuted(WorldPacket
*data
)
842 MakeNotifyPacket(data
, CHAT_MUTED_NOTICE
);
846 void Channel::MakePlayerKicked(WorldPacket
*data
, uint64 bad
, uint64 good
)
848 MakeNotifyPacket(data
, CHAT_PLAYER_KICKED_NOTICE
);
849 *data
<< uint64(bad
);
850 *data
<< uint64(good
);
854 void Channel::MakeBanned(WorldPacket
*data
)
856 MakeNotifyPacket(data
, CHAT_BANNED_NOTICE
);
860 void Channel::MakePlayerBanned(WorldPacket
*data
, uint64 bad
, uint64 good
)
862 MakeNotifyPacket(data
, CHAT_PLAYER_BANNED_NOTICE
);
863 *data
<< uint64(bad
);
864 *data
<< uint64(good
);
868 void Channel::MakePlayerUnbanned(WorldPacket
*data
, uint64 bad
, uint64 good
)
870 MakeNotifyPacket(data
, CHAT_PLAYER_UNBANNED_NOTICE
);
871 *data
<< uint64(bad
);
872 *data
<< uint64(good
);
876 void Channel::MakePlayerNotBanned(WorldPacket
*data
, uint64 guid
)
878 MakeNotifyPacket(data
, CHAT_PLAYER_NOT_BANNED_NOTICE
);
879 *data
<< uint64(guid
);
883 void Channel::MakePlayerAlreadyMember(WorldPacket
*data
, uint64 guid
)
885 MakeNotifyPacket(data
, CHAT_PLAYER_ALREADY_MEMBER_NOTICE
);
886 *data
<< uint64(guid
);
890 void Channel::MakeInvite(WorldPacket
*data
, uint64 guid
)
892 MakeNotifyPacket(data
, CHAT_INVITE_NOTICE
);
893 *data
<< uint64(guid
);
897 void Channel::MakeInviteWrongFaction(WorldPacket
*data
)
899 MakeNotifyPacket(data
, CHAT_INVITE_WRONG_FACTION_NOTICE
);
903 void Channel::MakeWrongFaction(WorldPacket
*data
)
905 MakeNotifyPacket(data
, CHAT_WRONG_FACTION_NOTICE
);
909 void Channel::MakeInvalidName(WorldPacket
*data
)
911 MakeNotifyPacket(data
, CHAT_INVALID_NAME_NOTICE
);
915 void Channel::MakeNotModerated(WorldPacket
*data
)
917 MakeNotifyPacket(data
, CHAT_NOT_MODERATED_NOTICE
);
921 void Channel::MakePlayerInvited(WorldPacket
*data
, const std::string
& name
)
923 MakeNotifyPacket(data
, CHAT_PLAYER_INVITED_NOTICE
);
928 void Channel::MakePlayerInviteBanned(WorldPacket
*data
, uint64 guid
)
930 MakeNotifyPacket(data
, CHAT_PLAYER_INVITE_BANNED_NOTICE
);
931 *data
<< uint64(guid
);
935 void Channel::MakeThrottled(WorldPacket
*data
)
937 MakeNotifyPacket(data
, CHAT_THROTTLED_NOTICE
);
941 void Channel::MakeNotInArea(WorldPacket
*data
)
943 MakeNotifyPacket(data
, CHAT_NOT_IN_AREA_NOTICE
);
947 void Channel::MakeNotInLfg(WorldPacket
*data
)
949 MakeNotifyPacket(data
, CHAT_NOT_IN_LFG_NOTICE
);
953 void Channel::MakeVoiceOn(WorldPacket
*data
, uint64 guid
)
955 MakeNotifyPacket(data
, CHAT_VOICE_ON_NOTICE
);
956 *data
<< uint64(guid
);
960 void Channel::MakeVoiceOff(WorldPacket
*data
, uint64 guid
)
962 MakeNotifyPacket(data
, CHAT_VOICE_OFF_NOTICE
);
963 *data
<< uint64(guid
);
966 void Channel::JoinNotify(uint64 guid
)
971 data
.Initialize(SMSG_USERLIST_ADD
, 8+1+1+4+GetName().size()+1);
973 data
.Initialize(SMSG_USERLIST_UPDATE
, 8+1+1+4+GetName().size()+1);
975 data
<< uint64(guid
);
976 data
<< uint8(GetPlayerFlags(guid
));
977 data
<< uint8(GetFlags());
978 data
<< uint32(GetNumPlayers());
983 void Channel::LeaveNotify(uint64 guid
)
985 WorldPacket
data(SMSG_USERLIST_REMOVE
, 8+1+4+GetName().size()+1);
986 data
<< uint64(guid
);
987 data
<< uint8(GetFlags());
988 data
<< uint32(GetNumPlayers());