2 * Copyright (C) 2005-2010 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
= sObjectMgr
.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
= sObjectMgr
.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
= sObjectMgr
.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
= sObjectMgr
.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
= sObjectMgr
.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
= sObjectMgr
.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
= sObjectMgr
.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
= sObjectMgr
.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
= sObjectMgr
.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
= sObjectMgr
.GetPlayer(p
);
374 uint32 sec
= plr
->GetSession()->GetSecurity();
379 MakeNotMember(&data
);
384 if(sec
< SEC_GAMEMASTER
&& p
!= m_ownerGUID
)
392 Player
*newp
= sObjectMgr
.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 AccountTypes gmLevelInWhoList
= (AccountTypes
)sWorld
.getConfig(CONFIG_GM_LEVEL_IN_WHO_LIST
);
452 for(PlayerList::const_iterator i
= players
.begin(); i
!= players
.end(); ++i
)
454 Player
*plr
= sObjectMgr
.GetPlayer(i
->first
);
456 // PLAYER can't see MODERATOR, GAME MASTER, ADMINISTRATOR characters
457 // MODERATOR, GAME MASTER, ADMINISTRATOR can see all
458 if (plr
&& (player
->GetSession()->GetSecurity() > SEC_PLAYER
|| plr
->GetSession()->GetSecurity() <= gmLevelInWhoList
) &&
459 plr
->IsVisibleGloballyFor(player
))
461 data
<< uint64(i
->first
);
462 data
<< uint8(i
->second
.flags
); // flags seems to be changed...
467 data
.put
<uint32
>(pos
,count
);
473 void Channel::Announce(uint64 p
)
476 Player
*plr
= sObjectMgr
.GetPlayer(p
);
478 sec
= plr
->GetSession()->GetSecurity();
483 MakeNotMember(&data
);
486 else if(!players
[p
].IsModerator() && sec
< SEC_GAMEMASTER
)
489 MakeNotModerator(&data
);
494 m_announce
= !m_announce
;
498 MakeAnnouncementsOn(&data
, p
);
500 MakeAnnouncementsOff(&data
, p
);
505 void Channel::Moderate(uint64 p
)
508 Player
*plr
= sObjectMgr
.GetPlayer(p
);
510 sec
= plr
->GetSession()->GetSecurity();
515 MakeNotMember(&data
);
518 else if(!players
[p
].IsModerator() && sec
< SEC_GAMEMASTER
)
521 MakeNotModerator(&data
);
526 m_moderate
= !m_moderate
;
530 MakeModerationOn(&data
, p
);
532 MakeModerationOff(&data
, p
);
537 void Channel::Say(uint64 p
, const char *what
, uint32 lang
)
541 if (sWorld
.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_CHANNEL
))
542 lang
= LANG_UNIVERSAL
;
545 Player
*plr
= sObjectMgr
.GetPlayer(p
);
547 sec
= plr
->GetSession()->GetSecurity();
552 MakeNotMember(&data
);
555 else if(players
[p
].IsMuted())
561 else if(m_moderate
&& !players
[p
].IsModerator() && sec
< SEC_GAMEMASTER
)
564 MakeNotModerator(&data
);
569 uint32 messageLength
= strlen(what
) + 1;
571 WorldPacket
data(SMSG_MESSAGECHAT
, 1+4+8+4+m_name
.size()+1+8+4+messageLength
+1);
572 data
<< (uint8
)CHAT_MSG_CHANNEL
;
573 data
<< (uint32
)lang
;
575 data
<< uint32(0); // 2.1.0
578 data
<< messageLength
;
580 data
<< uint8(plr
? plr
->chatTag() : 0);
582 SendToAll(&data
, !players
[p
].IsModerator() ? p
: false);
586 void Channel::Invite(uint64 p
, const char *newname
)
591 MakeNotMember(&data
);
596 Player
*newp
= sObjectMgr
.GetPlayer(newname
);
600 MakePlayerNotFound(&data
, newname
);
605 Player
*plr
= sObjectMgr
.GetPlayer(p
);
609 if (newp
->GetTeam() != plr
->GetTeam() && !sWorld
.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_CHANNEL
))
612 MakeInviteWrongFaction(&data
);
617 if(IsOn(newp
->GetGUID()))
620 MakePlayerAlreadyMember(&data
, newp
->GetGUID());
626 if(!newp
->GetSocial()->HasIgnore(GUID_LOPART(p
)))
628 MakeInvite(&data
, p
);
629 SendToOne(&data
, newp
->GetGUID());
632 MakePlayerInvited(&data
, newp
->GetName());
636 void Channel::SetOwner(uint64 guid
, bool exclaim
)
640 // [] will re-add player after it possible removed
641 PlayerList::iterator p_itr
= players
.find(m_ownerGUID
);
642 if(p_itr
!= players
.end())
643 p_itr
->second
.SetOwner(false);
649 uint8 oldFlag
= GetPlayerFlags(m_ownerGUID
);
650 players
[m_ownerGUID
].SetOwner(true);
653 MakeModeChange(&data
, m_ownerGUID
, oldFlag
);
658 MakeOwnerChanged(&data
, m_ownerGUID
);
664 void Channel::SendToAll(WorldPacket
*data
, uint64 p
)
666 for(PlayerList::const_iterator i
= players
.begin(); i
!= players
.end(); ++i
)
668 Player
*plr
= sObjectMgr
.GetPlayer(i
->first
);
671 if(!p
|| !plr
->GetSocial()->HasIgnore(GUID_LOPART(p
)))
672 plr
->GetSession()->SendPacket(data
);
677 void Channel::SendToAllButOne(WorldPacket
*data
, uint64 who
)
679 for(PlayerList::const_iterator i
= players
.begin(); i
!= players
.end(); ++i
)
683 Player
*plr
= sObjectMgr
.GetPlayer(i
->first
);
685 plr
->GetSession()->SendPacket(data
);
690 void Channel::SendToOne(WorldPacket
*data
, uint64 who
)
692 Player
*plr
= sObjectMgr
.GetPlayer(who
);
694 plr
->GetSession()->SendPacket(data
);
697 void Channel::Voice(uint64
/*guid1*/, uint64
/*guid2*/)
702 void Channel::DeVoice(uint64
/*guid1*/, uint64
/*guid2*/)
708 void Channel::MakeNotifyPacket(WorldPacket
*data
, uint8 notify_type
)
710 data
->Initialize(SMSG_CHANNEL_NOTIFY
, 1+m_name
.size()+1);
711 *data
<< uint8(notify_type
);
716 void Channel::MakeJoined(WorldPacket
*data
, uint64 guid
)
718 MakeNotifyPacket(data
, CHAT_JOINED_NOTICE
);
719 *data
<< uint64(guid
);
723 void Channel::MakeLeft(WorldPacket
*data
, uint64 guid
)
725 MakeNotifyPacket(data
, CHAT_LEFT_NOTICE
);
726 *data
<< uint64(guid
);
730 void Channel::MakeYouJoined(WorldPacket
*data
)
732 MakeNotifyPacket(data
, CHAT_YOU_JOINED_NOTICE
);
733 *data
<< uint8(GetFlags());
734 *data
<< uint32(GetChannelId());
739 void Channel::MakeYouLeft(WorldPacket
*data
)
741 MakeNotifyPacket(data
, CHAT_YOU_LEFT_NOTICE
);
742 *data
<< uint32(GetChannelId());
743 *data
<< uint8(0); // can be 0x00 and 0x01
747 void Channel::MakeWrongPassword(WorldPacket
*data
)
749 MakeNotifyPacket(data
, CHAT_WRONG_PASSWORD_NOTICE
);
753 void Channel::MakeNotMember(WorldPacket
*data
)
755 MakeNotifyPacket(data
, CHAT_NOT_MEMBER_NOTICE
);
759 void Channel::MakeNotModerator(WorldPacket
*data
)
761 MakeNotifyPacket(data
, CHAT_NOT_MODERATOR_NOTICE
);
765 void Channel::MakePasswordChanged(WorldPacket
*data
, uint64 guid
)
767 MakeNotifyPacket(data
, CHAT_PASSWORD_CHANGED_NOTICE
);
768 *data
<< uint64(guid
);
772 void Channel::MakeOwnerChanged(WorldPacket
*data
, uint64 guid
)
774 MakeNotifyPacket(data
, CHAT_OWNER_CHANGED_NOTICE
);
775 *data
<< uint64(guid
);
779 void Channel::MakePlayerNotFound(WorldPacket
*data
, const std::string
& name
)
781 MakeNotifyPacket(data
, CHAT_PLAYER_NOT_FOUND_NOTICE
);
786 void Channel::MakeNotOwner(WorldPacket
*data
)
788 MakeNotifyPacket(data
, CHAT_NOT_OWNER_NOTICE
);
792 void Channel::MakeChannelOwner(WorldPacket
*data
)
794 std::string name
= "";
796 if(!sObjectMgr
.GetPlayerNameByGUID(m_ownerGUID
, name
) || name
.empty())
797 name
= "PLAYER_NOT_FOUND";
799 MakeNotifyPacket(data
, CHAT_CHANNEL_OWNER_NOTICE
);
800 *data
<< ((IsConstant() || !m_ownerGUID
) ? "Nobody" : name
);
804 void Channel::MakeModeChange(WorldPacket
*data
, uint64 guid
, uint8 oldflags
)
806 MakeNotifyPacket(data
, CHAT_MODE_CHANGE_NOTICE
);
807 *data
<< uint64(guid
);
808 *data
<< uint8(oldflags
);
809 *data
<< uint8(GetPlayerFlags(guid
));
813 void Channel::MakeAnnouncementsOn(WorldPacket
*data
, uint64 guid
)
815 MakeNotifyPacket(data
, CHAT_ANNOUNCEMENTS_ON_NOTICE
);
816 *data
<< uint64(guid
);
820 void Channel::MakeAnnouncementsOff(WorldPacket
*data
, uint64 guid
)
822 MakeNotifyPacket(data
, CHAT_ANNOUNCEMENTS_OFF_NOTICE
);
823 *data
<< uint64(guid
);
827 void Channel::MakeModerationOn(WorldPacket
*data
, uint64 guid
)
829 MakeNotifyPacket(data
, CHAT_MODERATION_ON_NOTICE
);
830 *data
<< uint64(guid
);
834 void Channel::MakeModerationOff(WorldPacket
*data
, uint64 guid
)
836 MakeNotifyPacket(data
, CHAT_MODERATION_OFF_NOTICE
);
837 *data
<< uint64(guid
);
841 void Channel::MakeMuted(WorldPacket
*data
)
843 MakeNotifyPacket(data
, CHAT_MUTED_NOTICE
);
847 void Channel::MakePlayerKicked(WorldPacket
*data
, uint64 bad
, uint64 good
)
849 MakeNotifyPacket(data
, CHAT_PLAYER_KICKED_NOTICE
);
850 *data
<< uint64(bad
);
851 *data
<< uint64(good
);
855 void Channel::MakeBanned(WorldPacket
*data
)
857 MakeNotifyPacket(data
, CHAT_BANNED_NOTICE
);
861 void Channel::MakePlayerBanned(WorldPacket
*data
, uint64 bad
, uint64 good
)
863 MakeNotifyPacket(data
, CHAT_PLAYER_BANNED_NOTICE
);
864 *data
<< uint64(bad
);
865 *data
<< uint64(good
);
869 void Channel::MakePlayerUnbanned(WorldPacket
*data
, uint64 bad
, uint64 good
)
871 MakeNotifyPacket(data
, CHAT_PLAYER_UNBANNED_NOTICE
);
872 *data
<< uint64(bad
);
873 *data
<< uint64(good
);
877 void Channel::MakePlayerNotBanned(WorldPacket
*data
, uint64 guid
)
879 MakeNotifyPacket(data
, CHAT_PLAYER_NOT_BANNED_NOTICE
);
880 *data
<< uint64(guid
);
884 void Channel::MakePlayerAlreadyMember(WorldPacket
*data
, uint64 guid
)
886 MakeNotifyPacket(data
, CHAT_PLAYER_ALREADY_MEMBER_NOTICE
);
887 *data
<< uint64(guid
);
891 void Channel::MakeInvite(WorldPacket
*data
, uint64 guid
)
893 MakeNotifyPacket(data
, CHAT_INVITE_NOTICE
);
894 *data
<< uint64(guid
);
898 void Channel::MakeInviteWrongFaction(WorldPacket
*data
)
900 MakeNotifyPacket(data
, CHAT_INVITE_WRONG_FACTION_NOTICE
);
904 void Channel::MakeWrongFaction(WorldPacket
*data
)
906 MakeNotifyPacket(data
, CHAT_WRONG_FACTION_NOTICE
);
910 void Channel::MakeInvalidName(WorldPacket
*data
)
912 MakeNotifyPacket(data
, CHAT_INVALID_NAME_NOTICE
);
916 void Channel::MakeNotModerated(WorldPacket
*data
)
918 MakeNotifyPacket(data
, CHAT_NOT_MODERATED_NOTICE
);
922 void Channel::MakePlayerInvited(WorldPacket
*data
, const std::string
& name
)
924 MakeNotifyPacket(data
, CHAT_PLAYER_INVITED_NOTICE
);
929 void Channel::MakePlayerInviteBanned(WorldPacket
*data
, uint64 guid
)
931 MakeNotifyPacket(data
, CHAT_PLAYER_INVITE_BANNED_NOTICE
);
932 *data
<< uint64(guid
);
936 void Channel::MakeThrottled(WorldPacket
*data
)
938 MakeNotifyPacket(data
, CHAT_THROTTLED_NOTICE
);
942 void Channel::MakeNotInArea(WorldPacket
*data
)
944 MakeNotifyPacket(data
, CHAT_NOT_IN_AREA_NOTICE
);
948 void Channel::MakeNotInLfg(WorldPacket
*data
)
950 MakeNotifyPacket(data
, CHAT_NOT_IN_LFG_NOTICE
);
954 void Channel::MakeVoiceOn(WorldPacket
*data
, uint64 guid
)
956 MakeNotifyPacket(data
, CHAT_VOICE_ON_NOTICE
);
957 *data
<< uint64(guid
);
961 void Channel::MakeVoiceOff(WorldPacket
*data
, uint64 guid
)
963 MakeNotifyPacket(data
, CHAT_VOICE_OFF_NOTICE
);
964 *data
<< uint64(guid
);
967 void Channel::JoinNotify(uint64 guid
)
972 data
.Initialize(SMSG_USERLIST_ADD
, 8+1+1+4+GetName().size()+1);
974 data
.Initialize(SMSG_USERLIST_UPDATE
, 8+1+1+4+GetName().size()+1);
976 data
<< uint64(guid
);
977 data
<< uint8(GetPlayerFlags(guid
));
978 data
<< uint8(GetFlags());
979 data
<< uint32(GetNumPlayers());
984 void Channel::LeaveNotify(uint64 guid
)
986 WorldPacket
data(SMSG_USERLIST_REMOVE
, 8+1+4+GetName().size()+1);
987 data
<< uint64(guid
);
988 data
<< uint8(GetFlags());
989 data
<< uint32(GetNumPlayers());