2 * Copyright (C) 2005-2008 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_name(name
), m_announce(true), m_moderate(false), m_channelId(channel_id
), m_ownerGUID(0), m_password(""), m_flags(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
)
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
)
302 Player
*plr
= objmgr
.GetPlayer(p
);
304 sec
= plr
->GetSession()->GetSecurity();
309 MakeNotMember(&data
);
312 else if(!players
[p
].IsModerator() && sec
< SEC_GAMEMASTER
)
315 MakeNotModerator(&data
);
320 Player
*newp
= objmgr
.GetPlayer(p2n
);
324 MakePlayerNotFound(&data
, p2n
);
329 PlayerInfo inf
= players
[newp
->GetGUID()];
330 if(p
== m_ownerGUID
&& newp
->GetGUID() == m_ownerGUID
&& mod
)
333 if(!IsOn(newp
->GetGUID()))
336 MakePlayerNotFound(&data
, p2n
);
341 // allow make moderator from another team only if both is GMs
342 // at this moment this only way to show channel post for GM from another team
343 if( (plr
->GetSession()->GetSecurity() < SEC_GAMEMASTER
|| newp
->GetSession()->GetSecurity() < SEC_GAMEMASTER
) &&
344 plr
->GetTeam() != newp
->GetTeam() && !sWorld
.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_CHANNEL
) )
347 MakePlayerNotFound(&data
, p2n
);
352 if(m_ownerGUID
== newp
->GetGUID() && m_ownerGUID
!= p
)
361 SetModerator(newp
->GetGUID(), set
);
363 SetMute(newp
->GetGUID(), set
);
367 void Channel::SetOwner(uint64 p
, const char *newname
)
370 Player
*plr
= objmgr
.GetPlayer(p
);
372 sec
= plr
->GetSession()->GetSecurity();
377 MakeNotMember(&data
);
382 if(sec
< SEC_GAMEMASTER
&& p
!= m_ownerGUID
)
390 Player
*newp
= objmgr
.GetPlayer(newname
);
391 if(newp
== NULL
|| !IsOn(newp
->GetGUID()))
394 MakePlayerNotFound(&data
, newname
);
399 if(newp
->GetTeam() != plr
->GetTeam() && !sWorld
.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_CHANNEL
))
402 MakePlayerNotFound(&data
, newname
);
407 players
[newp
->GetGUID()].SetModerator(true);
408 SetOwner(newp
->GetGUID());
411 void Channel::SendWhoOwner(uint64 p
)
416 MakeNotMember(&data
);
422 MakeChannelOwner(&data
);
427 void Channel::List(Player
* player
)
429 uint64 p
= player
->GetGUID();
434 MakeNotMember(&data
);
439 WorldPacket
data(SMSG_CHANNEL_LIST
, 1+(GetName().size()+1)+1+4+players
.size()*(8+1));
440 data
<< uint8(1); // channel type?
441 data
<< GetName(); // channel name
442 data
<< uint8(GetFlags()); // channel flags?
444 size_t pos
= data
.wpos();
445 data
<< uint32(0); // size of list, placeholder
447 bool gmInWhoList
= sWorld
.getConfig(CONFIG_GM_IN_WHO_LIST
) || player
->GetSession()->GetSecurity() > SEC_PLAYER
;
450 for(PlayerList::iterator i
= players
.begin(); i
!= players
.end(); ++i
)
452 Player
*plr
= objmgr
.GetPlayer(i
->first
);
454 // PLAYER can't see MODERATOR, GAME MASTER, ADMINISTRATOR characters
455 // MODERATOR, GAME MASTER, ADMINISTRATOR can see all
456 if( plr
&& ( plr
->GetSession()->GetSecurity() == SEC_PLAYER
|| gmInWhoList
&& plr
->IsVisibleGloballyFor(player
) ) )
458 data
<< uint64(i
->first
);
459 data
<< uint8(i
->second
.flags
); // flags seems to be changed...
464 data
.put
<uint32
>(pos
,count
);
470 void Channel::Announce(uint64 p
)
473 Player
*plr
= objmgr
.GetPlayer(p
);
475 sec
= plr
->GetSession()->GetSecurity();
480 MakeNotMember(&data
);
483 else if(!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(uint64 p
)
505 Player
*plr
= objmgr
.GetPlayer(p
);
507 sec
= plr
->GetSession()->GetSecurity();
512 MakeNotMember(&data
);
515 else if(!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(uint64 p
, const char *what
, uint32 lang
)
538 if (sWorld
.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_CHANNEL
))
539 lang
= LANG_UNIVERSAL
;
542 Player
*plr
= objmgr
.GetPlayer(p
);
544 sec
= plr
->GetSession()->GetSecurity();
549 MakeNotMember(&data
);
552 else if(players
[p
].IsMuted())
558 else if(m_moderate
&& !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
;
572 data
<< uint32(0); // 2.1.0
575 data
<< messageLength
;
577 data
<< uint8(plr
? plr
->chatTag() : 0);
579 SendToAll(&data
, !players
[p
].IsModerator() ? p
: false);
583 void Channel::Invite(uint64 p
, const char *newname
)
588 MakeNotMember(&data
);
593 Player
*newp
= objmgr
.GetPlayer(newname
);
597 MakePlayerNotFound(&data
, newname
);
602 Player
*plr
= objmgr
.GetPlayer(p
);
606 if (newp
->GetTeam() != plr
->GetTeam() && !sWorld
.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_CHANNEL
))
609 MakeInviteWrongFaction(&data
);
614 if(IsOn(newp
->GetGUID()))
617 MakePlayerAlreadyMember(&data
, newp
->GetGUID());
623 if(!newp
->GetSocial()->HasIgnore(GUID_LOPART(p
)))
625 MakeInvite(&data
, p
);
626 SendToOne(&data
, newp
->GetGUID());
629 MakePlayerInvited(&data
, newp
->GetName());
633 void Channel::SetOwner(uint64 guid
, bool exclaim
)
637 // [] will re-add player after it possible removed
638 PlayerList::iterator p_itr
= players
.find(m_ownerGUID
);
639 if(p_itr
!= players
.end())
640 p_itr
->second
.SetOwner(false);
646 uint8 oldFlag
= GetPlayerFlags(m_ownerGUID
);
647 players
[m_ownerGUID
].SetOwner(true);
650 MakeModeChange(&data
, m_ownerGUID
, oldFlag
);
655 MakeOwnerChanged(&data
, m_ownerGUID
);
661 void Channel::SendToAll(WorldPacket
*data
, uint64 p
)
663 for(PlayerList::iterator i
= players
.begin(); i
!= players
.end(); ++i
)
665 Player
*plr
= objmgr
.GetPlayer(i
->first
);
668 if(!p
|| !plr
->GetSocial()->HasIgnore(GUID_LOPART(p
)))
669 plr
->GetSession()->SendPacket(data
);
674 void Channel::SendToAllButOne(WorldPacket
*data
, uint64 who
)
676 for(PlayerList::iterator i
= players
.begin(); i
!= players
.end(); ++i
)
680 Player
*plr
= objmgr
.GetPlayer(i
->first
);
682 plr
->GetSession()->SendPacket(data
);
687 void Channel::SendToOne(WorldPacket
*data
, uint64 who
)
689 Player
*plr
= objmgr
.GetPlayer(who
);
691 plr
->GetSession()->SendPacket(data
);
694 void Channel::Voice(uint64 guid1
, uint64 guid2
)
699 void Channel::DeVoice(uint64 guid1
, uint64 guid2
)
705 void Channel::MakeNotifyPacket(WorldPacket
*data
, uint8 notify_type
)
707 data
->Initialize(SMSG_CHANNEL_NOTIFY
, 1+m_name
.size()+1);
708 *data
<< uint8(notify_type
);
713 void Channel::MakeJoined(WorldPacket
*data
, uint64 guid
)
715 MakeNotifyPacket(data
, CHAT_JOINED_NOTICE
);
716 *data
<< uint64(guid
);
720 void Channel::MakeLeft(WorldPacket
*data
, uint64 guid
)
722 MakeNotifyPacket(data
, CHAT_LEFT_NOTICE
);
723 *data
<< uint64(guid
);
727 void Channel::MakeYouJoined(WorldPacket
*data
)
729 MakeNotifyPacket(data
, CHAT_YOU_JOINED_NOTICE
);
730 *data
<< uint8(GetFlags());
731 *data
<< uint32(GetChannelId());
736 void Channel::MakeYouLeft(WorldPacket
*data
)
738 MakeNotifyPacket(data
, CHAT_YOU_LEFT_NOTICE
);
739 *data
<< uint32(GetChannelId());
740 *data
<< uint8(0); // can be 0x00 and 0x01
744 void Channel::MakeWrongPassword(WorldPacket
*data
)
746 MakeNotifyPacket(data
, CHAT_WRONG_PASSWORD_NOTICE
);
750 void Channel::MakeNotMember(WorldPacket
*data
)
752 MakeNotifyPacket(data
, CHAT_NOT_MEMBER_NOTICE
);
756 void Channel::MakeNotModerator(WorldPacket
*data
)
758 MakeNotifyPacket(data
, CHAT_NOT_MODERATOR_NOTICE
);
762 void Channel::MakePasswordChanged(WorldPacket
*data
, uint64 guid
)
764 MakeNotifyPacket(data
, CHAT_PASSWORD_CHANGED_NOTICE
);
765 *data
<< uint64(guid
);
769 void Channel::MakeOwnerChanged(WorldPacket
*data
, uint64 guid
)
771 MakeNotifyPacket(data
, CHAT_OWNER_CHANGED_NOTICE
);
772 *data
<< uint64(guid
);
776 void Channel::MakePlayerNotFound(WorldPacket
*data
, const std::string
& name
)
778 MakeNotifyPacket(data
, CHAT_PLAYER_NOT_FOUND_NOTICE
);
783 void Channel::MakeNotOwner(WorldPacket
*data
)
785 MakeNotifyPacket(data
, CHAT_NOT_OWNER_NOTICE
);
789 void Channel::MakeChannelOwner(WorldPacket
*data
)
791 std::string name
= "";
793 if(!objmgr
.GetPlayerNameByGUID(m_ownerGUID
, name
) || name
.empty())
794 name
= "PLAYER_NOT_FOUND";
796 MakeNotifyPacket(data
, CHAT_CHANNEL_OWNER_NOTICE
);
797 *data
<< ((IsConstant() || !m_ownerGUID
) ? "Nobody" : name
);
801 void Channel::MakeModeChange(WorldPacket
*data
, uint64 guid
, uint8 oldflags
)
803 MakeNotifyPacket(data
, CHAT_MODE_CHANGE_NOTICE
);
804 *data
<< uint64(guid
);
805 *data
<< uint8(oldflags
);
806 *data
<< uint8(GetPlayerFlags(guid
));
810 void Channel::MakeAnnouncementsOn(WorldPacket
*data
, uint64 guid
)
812 MakeNotifyPacket(data
, CHAT_ANNOUNCEMENTS_ON_NOTICE
);
813 *data
<< uint64(guid
);
817 void Channel::MakeAnnouncementsOff(WorldPacket
*data
, uint64 guid
)
819 MakeNotifyPacket(data
, CHAT_ANNOUNCEMENTS_OFF_NOTICE
);
820 *data
<< uint64(guid
);
824 void Channel::MakeModerationOn(WorldPacket
*data
, uint64 guid
)
826 MakeNotifyPacket(data
, CHAT_MODERATION_ON_NOTICE
);
827 *data
<< uint64(guid
);
831 void Channel::MakeModerationOff(WorldPacket
*data
, uint64 guid
)
833 MakeNotifyPacket(data
, CHAT_MODERATION_OFF_NOTICE
);
834 *data
<< uint64(guid
);
838 void Channel::MakeMuted(WorldPacket
*data
)
840 MakeNotifyPacket(data
, CHAT_MUTED_NOTICE
);
844 void Channel::MakePlayerKicked(WorldPacket
*data
, uint64 bad
, uint64 good
)
846 MakeNotifyPacket(data
, CHAT_PLAYER_KICKED_NOTICE
);
847 *data
<< uint64(bad
);
848 *data
<< uint64(good
);
852 void Channel::MakeBanned(WorldPacket
*data
)
854 MakeNotifyPacket(data
, CHAT_BANNED_NOTICE
);
858 void Channel::MakePlayerBanned(WorldPacket
*data
, uint64 bad
, uint64 good
)
860 MakeNotifyPacket(data
, CHAT_PLAYER_BANNED_NOTICE
);
861 *data
<< uint64(bad
);
862 *data
<< uint64(good
);
866 void Channel::MakePlayerUnbanned(WorldPacket
*data
, uint64 bad
, uint64 good
)
868 MakeNotifyPacket(data
, CHAT_PLAYER_UNBANNED_NOTICE
);
869 *data
<< uint64(bad
);
870 *data
<< uint64(good
);
874 void Channel::MakePlayerNotBanned(WorldPacket
*data
, uint64 guid
)
876 MakeNotifyPacket(data
, CHAT_PLAYER_NOT_BANNED_NOTICE
);
877 *data
<< uint64(guid
);
881 void Channel::MakePlayerAlreadyMember(WorldPacket
*data
, uint64 guid
)
883 MakeNotifyPacket(data
, CHAT_PLAYER_ALREADY_MEMBER_NOTICE
);
884 *data
<< uint64(guid
);
888 void Channel::MakeInvite(WorldPacket
*data
, uint64 guid
)
890 MakeNotifyPacket(data
, CHAT_INVITE_NOTICE
);
891 *data
<< uint64(guid
);
895 void Channel::MakeInviteWrongFaction(WorldPacket
*data
)
897 MakeNotifyPacket(data
, CHAT_INVITE_WRONG_FACTION_NOTICE
);
901 void Channel::MakeWrongFaction(WorldPacket
*data
)
903 MakeNotifyPacket(data
, CHAT_WRONG_FACTION_NOTICE
);
907 void Channel::MakeInvalidName(WorldPacket
*data
)
909 MakeNotifyPacket(data
, CHAT_INVALID_NAME_NOTICE
);
913 void Channel::MakeNotModerated(WorldPacket
*data
)
915 MakeNotifyPacket(data
, CHAT_NOT_MODERATED_NOTICE
);
919 void Channel::MakePlayerInvited(WorldPacket
*data
, const std::string
& name
)
921 MakeNotifyPacket(data
, CHAT_PLAYER_INVITED_NOTICE
);
926 void Channel::MakePlayerInviteBanned(WorldPacket
*data
, uint64 guid
)
928 MakeNotifyPacket(data
, CHAT_PLAYER_INVITE_BANNED_NOTICE
);
929 *data
<< uint64(guid
);
933 void Channel::MakeThrottled(WorldPacket
*data
)
935 MakeNotifyPacket(data
, CHAT_THROTTLED_NOTICE
);
939 void Channel::MakeNotInArea(WorldPacket
*data
)
941 MakeNotifyPacket(data
, CHAT_NOT_IN_AREA_NOTICE
);
945 void Channel::MakeNotInLfg(WorldPacket
*data
)
947 MakeNotifyPacket(data
, CHAT_NOT_IN_LFG_NOTICE
);
951 void Channel::MakeVoiceOn(WorldPacket
*data
, uint64 guid
)
953 MakeNotifyPacket(data
, CHAT_VOICE_ON_NOTICE
);
954 *data
<< uint64(guid
);
958 void Channel::MakeVoiceOff(WorldPacket
*data
, uint64 guid
)
960 MakeNotifyPacket(data
, CHAT_VOICE_OFF_NOTICE
);
961 *data
<< uint64(guid
);
964 void Channel::JoinNotify(uint64 guid
)
969 data
.Initialize(SMSG_USERLIST_ADD
, 8+1+1+4+GetName().size()+1);
971 data
.Initialize(SMSG_USERLIST_UPDATE
, 8+1+1+4+GetName().size()+1);
973 data
<< uint64(guid
);
974 data
<< uint8(GetPlayerFlags(guid
));
975 data
<< uint8(GetFlags());
976 data
<< uint32(GetNumPlayers());
981 void Channel::LeaveNotify(uint64 guid
)
983 WorldPacket
data(SMSG_USERLIST_REMOVE
, 8+1+4+GetName().size()+1);
984 data
<< uint64(guid
);
985 data
<< uint8(GetFlags());
986 data
<< uint32(GetNumPlayers());