TrinityCore
Loading...
Searching...
No Matches
Channel.cpp
Go to the documentation of this file.
1/*
2 * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#include "Channel.h"
19#include "AccountMgr.h"
20#include "ChannelAppenders.h"
21#include "Chat.h"
22#include "DatabaseEnv.h"
23#include "DBCStores.h"
24#include "GameTime.h"
25#include "GridNotifiers.h"
26#include "GridNotifiersImpl.h"
27#include "Language.h"
28#include "Log.h"
29#include "ObjectAccessor.h"
30#include "ObjectMgr.h"
31#include "Player.h"
32#include "SocialMgr.h"
33#include "StringConvert.h"
34#include "World.h"
35
36Channel::Channel(uint32 channelId, uint32 team /*= 0*/, AreaTableEntry const* zoneEntry /*= nullptr*/) :
37 _isDirty(false),
38 _nextActivityUpdateTime(0),
39 _announceEnabled(false), // no join/leave announces
40 _ownershipEnabled(false), // no ownership handout
41 _isOwnerInvisible(false),
42 _channelFlags(CHANNEL_FLAG_GENERAL), // for all built-in channels
43 _channelId(channelId),
44 _channelTeam(team),
45 _ownerGuid(),
46 _channelName(),
47 _channelPassword(),
48 _zoneEntry(zoneEntry)
49{
50 ChatChannelsEntry const* channelEntry = sChatChannelsStore.AssertEntry(channelId);
51 if (channelEntry->Flags & CHANNEL_DBC_FLAG_TRADE) // for trade channel
53
54 if (channelEntry->Flags & CHANNEL_DBC_FLAG_CITY_ONLY2) // for city only channels
56
57 if (channelEntry->Flags & CHANNEL_DBC_FLAG_LFG) // for LFG channel
59 else // for all other channels
61}
62
63Channel::Channel(std::string const& name, uint32 team /*= 0*/, std::string const& banList) :
64 _isDirty(false),
65 _nextActivityUpdateTime(0),
66 _announceEnabled(true),
67 _ownershipEnabled(true),
68 _isOwnerInvisible(false),
69 _channelFlags(CHANNEL_FLAG_CUSTOM),
70 _channelId(0),
71 _channelTeam(team),
72 _ownerGuid(),
73 _channelName(name),
74 _channelPassword(),
75 _zoneEntry(nullptr)
76{
77 for (std::string_view guid : Trinity::Tokenize(banList, ' ', false))
78 {
79 ObjectGuid banned;
80 banned.SetRawValue(Trinity::StringTo<uint64>(guid).value_or(0));
81 if (!banned)
82 continue;
83
84 TC_LOG_DEBUG("chat.system", "Channel({}) loaded player {} into bannedStore", name, banned.ToString());
85 _bannedStore.insert(banned);
86 }
87}
88
89Channel::~Channel() = default;
90
91void Channel::GetChannelName(std::string& channelName, uint32 channelId, LocaleConstant locale, AreaTableEntry const* zoneEntry)
92{
93 if (channelId)
94 {
95 ChatChannelsEntry const* channelEntry = sChatChannelsStore.AssertEntry(channelId);
96 if (!(channelEntry->Flags & CHANNEL_DBC_FLAG_GLOBAL))
97 {
98 if (channelEntry->Flags & CHANNEL_DBC_FLAG_CITY_ONLY)
99 channelName = ChatHandler::PGetParseString(channelEntry->Name[locale], sObjectMgr->GetTrinityString(LANG_CHANNEL_CITY, locale));
100 else
101 channelName = ChatHandler::PGetParseString(channelEntry->Name[locale], ASSERT_NOTNULL(zoneEntry)->AreaName[locale]);
102 }
103 else
104 channelName = channelEntry->Name[locale];
105 }
106}
107
108std::string Channel::GetName(LocaleConstant locale /*= DEFAULT_LOCALE*/) const
109{
110 std::string result = _channelName;
112
113 return result;
114}
115
117{
118 time_t const now = GameTime::GetGameTime();
119 if (_isDirty)
120 {
121 std::ostringstream banlist;
122 for (BannedContainer::const_iterator iter = _bannedStore.begin(); iter != _bannedStore.end(); ++iter)
123 banlist << iter->GetRawValue() << ' ';
124
125 std::string banListStr = banlist.str();
126
128 stmt->setString(0, _channelName);
129 stmt->setUInt32(1, _channelTeam);
130 stmt->setBool(2, _announceEnabled);
131 stmt->setBool(3, _ownershipEnabled);
132 stmt->setString(4, _channelPassword);
133 stmt->setString(5, banListStr);
134 CharacterDatabase.Execute(stmt);
135 }
136 else if (_nextActivityUpdateTime <= now)
137 {
138 if (!_playersStore.empty())
139 {
141 stmt->setString(0, _channelName);
142 stmt->setUInt32(1, _channelTeam);
143 CharacterDatabase.Execute(stmt);
144 }
145 }
146 else
147 return;
148
149 _isDirty = false;
150 _nextActivityUpdateTime = now + urand(1 * MINUTE, 6 * MINUTE) * std::max(1u, sWorld->getIntConfig(CONFIG_PRESERVE_CUSTOM_CHANNEL_INTERVAL));
151}
152
153void Channel::JoinChannel(Player* player, std::string const& pass)
154{
155 ObjectGuid guid = player->GetGUID();
156 if (IsOn(guid))
157 {
158 // Do not send error message for built-in channels
159 if (!IsConstant())
160 {
161 PlayerAlreadyMemberAppend appender(guid);
162 ChannelNameBuilder<PlayerAlreadyMemberAppend> builder(this, appender);
163 SendToOne(builder, guid);
164 }
165 return;
166 }
167
168 if (IsBanned(guid))
169 {
170 BannedAppend appender;
171 ChannelNameBuilder<BannedAppend> builder(this, appender);
172 SendToOne(builder, guid);
173 return;
174 }
175
176 if (!CheckPassword(pass))
177 {
178 WrongPasswordAppend appender;
179 ChannelNameBuilder<WrongPasswordAppend> builder(this, appender);
180 SendToOne(builder, guid);
181 return;
182 }
183
185 sWorld->getBoolConfig(CONFIG_RESTRICTED_LFG_CHANNEL) &&
186 AccountMgr::IsPlayerAccount(player->GetSession()->GetSecurity()) && //FIXME: Move to RBAC
187 player->GetGroup())
188 {
189 NotInLFGAppend appender;
190 ChannelNameBuilder<NotInLFGAppend> builder(this, appender);
191 SendToOne(builder, guid);
192 return;
193 }
194
195 player->JoinedChannel(this);
196
198 {
199 JoinedAppend appender(guid);
200 ChannelNameBuilder<JoinedAppend> builder(this, appender);
201 SendToAll(builder);
202 }
203
204 bool newChannel = _playersStore.empty();
205 if (newChannel)
206 _nextActivityUpdateTime = 0; // force activity update on next channel tick
207
208 PlayerInfo& pinfo = _playersStore[guid];
209 pinfo.flags = MEMBER_FLAG_NONE;
210 pinfo.invisible = !player->isGMVisible();
211
212 YouJoinedAppend appender(this);
213 ChannelNameBuilder<YouJoinedAppend> builder(this, appender);
214 SendToOne(builder, guid);
215
216 JoinNotify(guid);
217
218 // Custom channel handling
219 if (!IsConstant())
220 {
221 // If the channel has no owner yet and ownership is allowed, set the new owner.
222 // or if the owner was a GM with .gm visible off
223 // don't do this if the new player is, too, an invis GM, unless the channel was empty
224 if (_ownershipEnabled && (newChannel || !pinfo.IsInvisible()) && (!_ownerGuid || _isOwnerInvisible))
225 {
227
228 SetOwner(guid, !newChannel && !_isOwnerInvisible);
229 pinfo.SetModerator(true);
230 }
231 }
232}
233
234void Channel::LeaveChannel(Player* player, bool send)
235{
236 ObjectGuid guid = player->GetGUID();
237 if (!IsOn(guid))
238 {
239 if (send)
240 {
241 NotMemberAppend appender;
242 ChannelNameBuilder<NotMemberAppend> builder(this, appender);
243 SendToOne(builder, guid);
244 }
245 return;
246 }
247
248 if (send)
249 {
250 YouLeftAppend appender(this);
251 ChannelNameBuilder<YouLeftAppend> builder(this, appender);
252 SendToOne(builder, guid);
253
254 player->LeftChannel(this);
255 }
256
257 PlayerInfo& info = _playersStore.at(guid);
258 bool changeowner = info.IsOwner();
259 _playersStore.erase(guid);
260
262 {
263 LeftAppend appender(guid);
264 ChannelNameBuilder<LeftAppend> builder(this, appender);
265 SendToAll(builder);
266 }
267
268 LeaveNotify(guid);
269
270 if (!IsConstant())
271 {
272 // If the channel owner left and there are players still inside, pick a new owner
273 // do not pick invisible gm owner unless there are only invisible gms in that channel (rare)
274 if (changeowner && _ownershipEnabled && !_playersStore.empty())
275 {
276 PlayerContainer::iterator itr;
277 for (itr = _playersStore.begin(); itr != _playersStore.end(); ++itr)
278 {
279 if (!itr->second.IsInvisible())
280 break;
281 }
282
283 if (itr == _playersStore.end())
284 itr = _playersStore.begin();
285
286 ObjectGuid newOwner = itr->first;
287 itr->second.SetModerator(true);
288
289 SetOwner(newOwner);
290
291 // if the new owner is invisible gm, set flag to automatically choose a new owner
292 if (itr->second.IsInvisible())
293 _isOwnerInvisible = true;
294 }
295 }
296}
297
298void Channel::KickOrBan(Player const* player, std::string const& badname, bool ban)
299{
300 ObjectGuid good = player->GetGUID();
301
302 if (!IsOn(good))
303 {
304 NotMemberAppend appender;
305 ChannelNameBuilder<NotMemberAppend> builder(this, appender);
306 SendToOne(builder, good);
307 return;
308 }
309
310 PlayerInfo& info = _playersStore.at(good);
312 {
313 NotModeratorAppend appender;
314 ChannelNameBuilder<NotModeratorAppend> builder(this, appender);
315 SendToOne(builder, good);
316 return;
317 }
318
320 ObjectGuid victim = bad ? bad->GetGUID() : ObjectGuid::Empty;
321 if (!bad || !victim || !IsOn(victim))
322 {
323 PlayerNotFoundAppend appender(badname);
324 ChannelNameBuilder<PlayerNotFoundAppend> builder(this, appender);
325 SendToOne(builder, good);
326 return;
327 }
328
329 bool changeowner = _ownerGuid == victim;
330
331 if (!player->GetSession()->HasPermission(rbac::RBAC_PERM_CHANGE_CHANNEL_NOT_MODERATOR) && changeowner && good != _ownerGuid)
332 {
333 NotOwnerAppend appender;
334 ChannelNameBuilder<NotOwnerAppend> builder(this, appender);
335 SendToOne(builder, good);
336 return;
337 }
338
339 if (ban && !IsBanned(victim))
340 {
341 _bannedStore.insert(victim);
342 _isDirty = true;
343
345 {
346 PlayerBannedAppend appender(good, victim);
347 ChannelNameBuilder<PlayerBannedAppend> builder(this, appender);
348 SendToAll(builder);
349 }
350 }
352 {
353 PlayerKickedAppend appender(good, victim);
354 ChannelNameBuilder<PlayerKickedAppend> builder(this, appender);
355 SendToAll(builder);
356 }
357
358 _playersStore.erase(victim);
359 bad->LeftChannel(this);
360
361 if (changeowner && _ownershipEnabled && !_playersStore.empty())
362 {
363 ObjectGuid newowner = good;
364 info.SetModerator(true);
365 SetOwner(newowner);
366 }
367}
368
369void Channel::UnBan(Player const* player, std::string const& badname)
370{
371 ObjectGuid good = player->GetGUID();
372
373 if (!IsOn(good))
374 {
375 NotMemberAppend appender;
376 ChannelNameBuilder<NotMemberAppend> builder(this, appender);
377 SendToOne(builder, good);
378 return;
379 }
380
381 PlayerInfo& info = _playersStore.at(good);
383 {
384 NotModeratorAppend appender;
385 ChannelNameBuilder<NotModeratorAppend> builder(this, appender);
386 SendToOne(builder, good);
387 return;
388 }
389
391 ObjectGuid victim = bad ? bad->GetGUID() : ObjectGuid::Empty;
392
393 if (!victim || !IsBanned(victim))
394 {
395 PlayerNotFoundAppend appender(badname);
396 ChannelNameBuilder<PlayerNotFoundAppend> builder(this, appender);
397 SendToOne(builder, good);
398 return;
399 }
400
401 _bannedStore.erase(victim);
402
403 PlayerUnbannedAppend appender(good, victim);
404 ChannelNameBuilder<PlayerUnbannedAppend> builder(this, appender);
405 SendToAll(builder);
406
407 _isDirty = true;
408}
409
410void Channel::Password(Player const* player, std::string const& pass)
411{
412 ObjectGuid guid = player->GetGUID();
413
414 ChatHandler chat(player->GetSession());
415 if (!IsOn(guid))
416 {
417 NotMemberAppend appender;
418 ChannelNameBuilder<NotMemberAppend> builder(this, appender);
419 SendToOne(builder, guid);
420 return;
421 }
422
423 PlayerInfo& info = _playersStore.at(guid);
425 {
426 NotModeratorAppend appender;
427 ChannelNameBuilder<NotModeratorAppend> builder(this, appender);
428 SendToOne(builder, guid);
429 return;
430 }
431
432 _channelPassword = pass;
433
434 PasswordChangedAppend appender(guid);
435 ChannelNameBuilder<PasswordChangedAppend> builder(this, appender);
436 SendToAll(builder);
437
438 _isDirty = true;
439}
440
441void Channel::SetMode(Player const* player, std::string const& p2n, bool mod, bool set)
442{
443 ObjectGuid guid = player->GetGUID();
444
445 if (!IsOn(guid))
446 {
447 NotMemberAppend appender;
448 ChannelNameBuilder<NotMemberAppend> builder(this, appender);
449 SendToOne(builder, guid);
450 return;
451 }
452
453 PlayerInfo& info = _playersStore.at(guid);
455 {
456 NotModeratorAppend appender;
457 ChannelNameBuilder<NotModeratorAppend> builder(this, appender);
458 SendToOne(builder, guid);
459 return;
460 }
461
462 if (guid == _ownerGuid && std::string(p2n) == player->GetName() && mod)
463 return;
464
466 ObjectGuid victim = newp ? newp->GetGUID() : ObjectGuid::Empty;
467
468 if (!newp || !victim || !IsOn(victim) ||
469 (player->GetTeam() != newp->GetTeam() &&
472 {
473 PlayerNotFoundAppend appender(p2n);
474 ChannelNameBuilder<PlayerNotFoundAppend> builder(this, appender);
475 SendToOne(builder, guid);
476 return;
477 }
478
479 if (_ownerGuid == victim && _ownerGuid != guid)
480 {
481 NotOwnerAppend appender;
482 ChannelNameBuilder<NotOwnerAppend> builder(this, appender);
483 SendToOne(builder, guid);
484 return;
485 }
486
487 if (mod)
488 SetModerator(newp->GetGUID(), set);
489 else
490 SetMute(newp->GetGUID(), set);
491}
492
493void Channel::SetInvisible(Player const* player, bool on)
494{
495 auto itr = _playersStore.find(player->GetGUID());
496 if (itr == _playersStore.end())
497 return;
498
499 itr->second.SetInvisible(on);
500
501 // we happen to be owner too, update flag
502 if (_ownerGuid == player->GetGUID())
504}
505
507{
508 if (!IsOn(guid))
509 return;
510
511 PlayerInfo& playerInfo = _playersStore.at(guid);
512 if (playerInfo.IsModerator() != set)
513 {
514 uint8 oldFlag = GetPlayerFlags(guid);
515 playerInfo.SetModerator(set);
516
517 ModeChangeAppend appender(guid, oldFlag, GetPlayerFlags(guid));
518 ChannelNameBuilder<ModeChangeAppend> builder(this, appender);
519 SendToAll(builder);
520 }
521}
522
523void Channel::SetMute(ObjectGuid guid, bool set)
524{
525 if (!IsOn(guid))
526 return;
527
528 PlayerInfo& playerInfo = _playersStore.at(guid);
529 if (playerInfo.IsMuted() != set)
530 {
531 uint8 oldFlag = GetPlayerFlags(guid);
532 playerInfo.SetMuted(set);
533
534 ModeChangeAppend appender(guid, oldFlag, GetPlayerFlags(guid));
535 ChannelNameBuilder<ModeChangeAppend> builder(this, appender);
536 SendToAll(builder);
537 }
538}
539
540void Channel::SetOwner(Player const* player, std::string const& newname)
541{
542 ObjectGuid guid = player->GetGUID();
543
544 if (!IsOn(guid))
545 {
546 NotMemberAppend appender;
547 ChannelNameBuilder<NotMemberAppend> builder(this, appender);
548 SendToOne(builder, guid);
549 return;
550 }
551
553 {
554 NotOwnerAppend appender;
555 ChannelNameBuilder<NotOwnerAppend> builder(this, appender);
556 SendToOne(builder, guid);
557 return;
558 }
559
561 ObjectGuid victim = newp ? newp->GetGUID() : ObjectGuid::Empty;
562
563 if (!newp || !victim || !IsOn(victim) ||
564 (player->GetTeam() != newp->GetTeam() &&
567 {
568 PlayerNotFoundAppend appender(newname);
569 ChannelNameBuilder<PlayerNotFoundAppend> builder(this, appender);
570 SendToOne(builder, guid);
571 return;
572 }
573
574 PlayerInfo& info = _playersStore.at(victim);
575 info.SetModerator(true);
576 SetOwner(victim);
577}
578
580{
581 if (IsOn(guid))
582 {
583 ChannelOwnerAppend appender(this, _ownerGuid);
584 ChannelNameBuilder<ChannelOwnerAppend> builder(this, appender);
585 SendToOne(builder, guid);
586 }
587 else
588 {
589 NotMemberAppend appender;
590 ChannelNameBuilder<NotMemberAppend> builder(this, appender);
591 SendToOne(builder, guid);
592 }
593}
594
595void Channel::List(Player const* player) const
596{
597 ObjectGuid guid = player->GetGUID();
598
599 if (!IsOn(guid))
600 {
601 NotMemberAppend appender;
602 ChannelNameBuilder<NotMemberAppend> builder(this, appender);
603 SendToOne(builder, guid);
604 return;
605 }
606
607 std::string channelName = GetName(player->GetSession()->GetSessionDbcLocale());
608 TC_LOG_DEBUG("chat.system", "SMSG_CHANNEL_LIST {} Channel: {}",
609 player->GetSession()->GetPlayerInfo(), channelName);
610
611 WorldPacket data(SMSG_CHANNEL_LIST, 1 + (channelName.size() + 1) + 1 + 4 + _playersStore.size() * (8 + 1));
612 data << uint8(1); // channel type?
613 data << channelName; // channel name
614 data << uint8(GetFlags()); // channel flags?
615
616 size_t pos = data.wpos();
617 data << uint32(0); // size of list, placeholder
618
619 uint32 gmLevelInWhoList = sWorld->getIntConfig(CONFIG_GM_LEVEL_IN_WHO_LIST);
620
621 uint32 count = 0;
622 for (PlayerContainer::const_iterator i = _playersStore.begin(); i != _playersStore.end(); ++i)
623 {
625
626 // PLAYER can't see MODERATOR, GAME MASTER, ADMINISTRATOR characters
627 // MODERATOR, GAME MASTER, ADMINISTRATOR can see all
628 if (member &&
630 member->GetSession()->GetSecurity() <= AccountTypes(gmLevelInWhoList)) &&
631 member->IsVisibleGloballyFor(player))
632 {
633 data << i->first;
634 data << uint8(i->second.flags); // flags seems to be changed...
635 ++count;
636 }
637 }
638
639 data.put<uint32>(pos, count);
640 player->SendDirectMessage(&data);
641}
642
643void Channel::Announce(Player const* player)
644{
645 ObjectGuid guid = player->GetGUID();
646
647 if (!IsOn(guid))
648 {
649 NotMemberAppend appender;
650 ChannelNameBuilder<NotMemberAppend> builder(this, appender);
651 SendToOne(builder, guid);
652 return;
653 }
654
655 PlayerInfo& info = _playersStore.at(guid);
657 {
658 NotModeratorAppend appender;
659 ChannelNameBuilder<NotModeratorAppend> builder(this, appender);
660 SendToOne(builder, guid);
661 return;
662 }
663
665
667 {
668 AnnouncementsOnAppend appender(guid);
669 ChannelNameBuilder<AnnouncementsOnAppend> builder(this, appender);
670 SendToAll(builder);
671 }
672 else
673 {
674 AnnouncementsOffAppend appender(guid);
675 ChannelNameBuilder<AnnouncementsOffAppend> builder(this, appender);
676 SendToAll(builder);
677 }
678
679 _isDirty = true;
680}
681
682void Channel::Say(ObjectGuid guid, std::string const& what, uint32 lang) const
683{
684 if (what.empty())
685 return;
686
687 // TODO: Add proper RBAC check
689 lang = LANG_UNIVERSAL;
690
691 if (!IsOn(guid))
692 {
693 NotMemberAppend appender;
694 ChannelNameBuilder<NotMemberAppend> builder(this, appender);
695 SendToOne(builder, guid);
696 return;
697 }
698
699 PlayerInfo const& info = _playersStore.at(guid);
700 if (info.IsMuted())
701 {
702 MutedAppend appender;
703 ChannelNameBuilder<MutedAppend> builder(this, appender);
704 SendToOne(builder, guid);
705 return;
706 }
707
708 auto builder = [&](WorldPacket& data, LocaleConstant locale)
709 {
710 LocaleConstant localeIdx = sWorld->GetAvailableDbcLocale(locale);
711
713 ChatHandler::BuildChatPacket(data, CHAT_MSG_CHANNEL, Language(lang), player, player, what, 0, GetName(localeIdx));
714 else
715 ChatHandler::BuildChatPacket(data, CHAT_MSG_CHANNEL, Language(lang), guid, guid, what, 0, "", "", 0, false, GetName(localeIdx));
716 };
717
718 SendToAll(builder, !info.IsModerator() ? guid : ObjectGuid::Empty);
719}
720
721void Channel::Invite(Player const* player, std::string const& newname)
722{
723 ObjectGuid guid = player->GetGUID();
724
725 if (!IsOn(guid))
726 {
727 NotMemberAppend appender;
728 ChannelNameBuilder<NotMemberAppend> builder(this, appender);
729 SendToOne(builder, guid);
730 return;
731 }
732
734 if (!newp || !newp->isGMVisible())
735 {
736 PlayerNotFoundAppend appender(newname);
737 ChannelNameBuilder<PlayerNotFoundAppend> builder(this, appender);
738 SendToOne(builder, guid);
739 return;
740 }
741
742 if (IsBanned(newp->GetGUID()))
743 {
744 PlayerInviteBannedAppend appender(newname);
745 ChannelNameBuilder<PlayerInviteBannedAppend> builder(this, appender);
746 SendToOne(builder, guid);
747 return;
748 }
749
750 if (newp->GetTeam() != player->GetTeam() &&
753 {
755 ChannelNameBuilder<InviteWrongFactionAppend> builder(this, appender);
756 SendToOne(builder, guid);
757 return;
758 }
759
760 if (IsOn(newp->GetGUID()))
761 {
762 PlayerAlreadyMemberAppend appender(newp->GetGUID());
763 ChannelNameBuilder<PlayerAlreadyMemberAppend> builder(this, appender);
764 SendToOne(builder, guid);
765 return;
766 }
767
768 if (!newp->GetSocial()->HasIgnore(guid))
769 {
770 InviteAppend appender(guid);
771 ChannelNameBuilder<InviteAppend> builder(this, appender);
772 SendToOne(builder, newp->GetGUID());
773 }
774
775 PlayerInvitedAppend appender(newp->GetName());
776 ChannelNameBuilder<PlayerInvitedAppend> builder(this, appender);
777 SendToOne(builder, guid);
778}
779
780void Channel::SetOwner(ObjectGuid guid, bool exclaim)
781{
782 if (!_ownerGuid.IsEmpty())
783 {
784 auto itr = _playersStore.find(_ownerGuid);
785 if (itr != _playersStore.end())
786 itr->second.SetOwner(false);
787 }
788
789 _ownerGuid = guid;
790 if (!_ownerGuid.IsEmpty())
791 {
793 auto itr = _playersStore.find(_ownerGuid);
794 if (itr == _playersStore.end())
795 return;
796
797 itr->second.SetModerator(true);
798 itr->second.SetOwner(true);
799
801 ChannelNameBuilder<ModeChangeAppend> builder(this, appender);
802 SendToAll(builder);
803
804 if (exclaim)
805 {
806 OwnerChangedAppend ownerAppender(_ownerGuid);
807 ChannelNameBuilder<OwnerChangedAppend> ownerBuilder(this, ownerAppender);
808 SendToAll(ownerBuilder);
809 }
810
811 _isDirty = true;
812 }
813}
814
815void Channel::Voice(ObjectGuid /*guid1*/, ObjectGuid /*guid2*/) const
816{
817
818}
819
820void Channel::DeVoice(ObjectGuid /*guid1*/, ObjectGuid /*guid2*/) const
821{
822
823}
824
826{
827 auto builder = [&](WorldPacket& data, LocaleConstant locale)
828 {
829 LocaleConstant localeIdx = sWorld->GetAvailableDbcLocale(locale);
830
831 data.Initialize(IsConstant() ? SMSG_USERLIST_ADD : SMSG_USERLIST_UPDATE, 8 + 1 + 1 + 4 + 30 /*channelName buffer*/);
832 data << guid;
833 data << uint8(GetPlayerFlags(guid));
834 data << uint8(GetFlags());
835 data << uint32(GetNumPlayers());
836 data << GetName(localeIdx);
837 };
838
839 if (IsConstant())
840 SendToAllButOne(builder, guid);
841 else
842 SendToAll(builder);
843}
844
846{
847 auto builder = [&](WorldPacket& data, LocaleConstant locale)
848 {
849 LocaleConstant localeIdx = sWorld->GetAvailableDbcLocale(locale);
850
851 data.Initialize(SMSG_USERLIST_REMOVE, 8 + 1 + 4 + 30 /*channelName buffer*/);
852 data << guid;
853 data << uint8(GetFlags());
854 data << uint32(GetNumPlayers());
855 data << GetName(localeIdx);
856 };
857
858 if (IsConstant())
859 SendToAllButOne(builder, guid);
860 else
861 SendToAll(builder);
862}
863
864template<class Builder>
865void Channel::SendToAll(Builder& builder, ObjectGuid guid /*= ObjectGuid::Empty*/) const
866{
867 Trinity::LocalizedPacketDo<Builder> localizer(builder);
868
869 for (PlayerContainer::const_iterator i = _playersStore.begin(); i != _playersStore.end(); ++i)
870 if (Player* player = ObjectAccessor::FindConnectedPlayer(i->first))
871 if (!guid || !player->GetSocial()->HasIgnore(guid))
872 localizer(player);
873}
874
875template<class Builder>
876void Channel::SendToAllButOne(Builder& builder, ObjectGuid who) const
877{
878 Trinity::LocalizedPacketDo<Builder> localizer(builder);
879
880 for (PlayerContainer::const_iterator i = _playersStore.begin(); i != _playersStore.end(); ++i)
881 if (i->first != who)
882 if (Player* player = ObjectAccessor::FindConnectedPlayer(i->first))
883 localizer(player);
884}
885
886template<class Builder>
887void Channel::SendToOne(Builder& builder, ObjectGuid who) const
888{
889 Trinity::LocalizedPacketDo<Builder> localizer(builder);
890
892 localizer(player);
893}
@ CHANNEL_FLAG_TRADE
Definition Channel.h:78
@ CHANNEL_FLAG_NOT_LFG
Definition Channel.h:79
@ CHANNEL_FLAG_GENERAL
Definition Channel.h:80
@ CHANNEL_FLAG_CUSTOM
Definition Channel.h:76
@ CHANNEL_FLAG_LFG
Definition Channel.h:82
@ CHANNEL_FLAG_CITY
Definition Channel.h:81
@ MEMBER_FLAG_NONE
Definition Channel.h:108
@ CHANNEL_DBC_FLAG_TRADE
Definition Channel.h:97
@ CHANNEL_DBC_FLAG_CITY_ONLY
Definition Channel.h:98
@ CHANNEL_DBC_FLAG_GLOBAL
Definition Channel.h:96
@ CHANNEL_DBC_FLAG_CITY_ONLY2
Definition Channel.h:99
@ CHANNEL_DBC_FLAG_LFG
Definition Channel.h:102
@ CHAR_UPD_CHANNEL
@ CHAR_UPD_CHANNEL_USAGE
LocaleConstant
Definition Common.h:48
@ MINUTE
Definition Common.h:29
AccountTypes
Definition Common.h:39
DBCStorage< ChatChannelsEntry > sChatChannelsStore(ChatChannelsEntryfmt)
DatabaseWorkerPool< CharacterDatabaseConnection > CharacterDatabase
Accessor to the character database.
uint8_t uint8
Definition Define.h:135
uint32_t uint32
Definition Define.h:133
#define ASSERT_NOTNULL(pointer)
Definition Errors.h:84
@ LANG_CHANNEL_CITY
Definition Language.h:776
#define TC_LOG_DEBUG(filterType__,...)
Definition Log.h:156
#define sObjectMgr
Definition ObjectMgr.h:1721
uint32 urand(uint32 min, uint32 max)
Definition Random.cpp:42
Language
@ LANG_UNIVERSAL
@ CHAT_MSG_CHANNEL
static bool IsPlayerAccount(uint32 gmlevel)
size_t wpos() const
Definition ByteBuffer.h:321
void put(std::size_t pos, T value)
Definition ByteBuffer.h:137
void JoinNotify(ObjectGuid guid) const
Definition Channel.cpp:825
void List(Player const *player) const
Definition Channel.cpp:595
bool IsConstant() const
Definition Channel.h:169
void Password(Player const *player, std::string const &pass)
Definition Channel.cpp:410
uint32 _channelId
Definition Channel.h:255
void Voice(ObjectGuid guid1, ObjectGuid guid2) const
Definition Channel.cpp:815
BannedContainer _bannedStore
Definition Channel.h:261
void JoinChannel(Player *player, std::string const &pass="")
Definition Channel.cpp:153
std::string GetName(LocaleConstant locale=DEFAULT_LOCALE) const
Definition Channel.cpp:108
bool _ownershipEnabled
Definition Channel.h:251
bool _announceEnabled
Definition Channel.h:250
bool HasFlag(uint8 flag) const
Definition Channel.h:185
uint32 _channelTeam
Definition Channel.h:256
Channel(uint32 channelId, uint32 team=0, AreaTableEntry const *zoneEntry=nullptr)
Definition Channel.cpp:36
time_t _nextActivityUpdateTime
Definition Channel.h:248
uint8 _channelFlags
Definition Channel.h:254
std::string _channelName
Definition Channel.h:258
void SendToAllButOne(Builder &builder, ObjectGuid who) const
Definition Channel.cpp:876
void SetMute(Player const *player, std::string const &newname)
Definition Channel.h:202
void SetModerator(Player const *player, std::string const &newname)
Definition Channel.h:200
void KickOrBan(Player const *player, std::string const &badname, bool ban)
Definition Channel.cpp:298
void LeaveNotify(ObjectGuid guid) const
Definition Channel.cpp:845
bool _isOwnerInvisible
Definition Channel.h:252
bool CheckPassword(std::string const &password) const
Definition Channel.h:180
void SetOwner(ObjectGuid guid, bool exclaim=true)
Definition Channel.cpp:780
bool IsOn(ObjectGuid who) const
Definition Channel.h:232
void Say(ObjectGuid guid, std::string const &what, uint32 lang) const
Definition Channel.cpp:682
void SendWhoOwner(ObjectGuid guid)
Definition Channel.cpp:579
void LeaveChannel(Player *player, bool send=true)
Definition Channel.cpp:234
void UnBan(Player const *player, std::string const &badname)
Definition Channel.cpp:369
bool _isDirty
Definition Channel.h:247
void SetMode(Player const *player, std::string const &p2n, bool mod, bool set)
Definition Channel.cpp:441
static void GetChannelName(std::string &channelName, uint32 channelId, LocaleConstant locale, AreaTableEntry const *zoneEntry)
Definition Channel.cpp:91
void SetInvisible(Player const *player, bool on)
Definition Channel.cpp:493
void UpdateChannelInDB()
Definition Channel.cpp:116
void Announce(Player const *player)
Definition Channel.cpp:643
uint8 GetPlayerFlags(ObjectGuid guid) const
Definition Channel.h:235
void SendToAll(Builder &, ObjectGuid guid=ObjectGuid::Empty) const
Definition Channel.cpp:865
void Invite(Player const *player, std::string const &newp)
Definition Channel.cpp:721
uint32 GetNumPlayers() const
Definition Channel.h:182
bool IsBanned(ObjectGuid guid) const
Definition Channel.h:233
AreaTableEntry const * _zoneEntry
Definition Channel.h:263
ObjectGuid _ownerGuid
Definition Channel.h:257
void SendToOne(Builder &builder, ObjectGuid who) const
Definition Channel.cpp:887
void DeVoice(ObjectGuid guid1, ObjectGuid guid2) const
Definition Channel.cpp:820
std::string _channelPassword
Definition Channel.h:259
uint8 GetFlags() const
Definition Channel.h:184
PlayerContainer _playersStore
Definition Channel.h:260
static std::string PGetParseString(std::string_view fmt, Args &&... args)
Definition Chat.h:81
static size_t BuildChatPacket(WorldPacket &data, ChatMsg chatType, Language language, ObjectGuid senderGUID, ObjectGuid receiverGUID, std::string_view message, uint8 chatTag, std::string const &senderName="", std::string const &receiverName="", uint32 achievementId=0, bool gmMessage=false, std::string const &channelName="")
Definition Chat.cpp:193
static ObjectGuid const Empty
Definition ObjectGuid.h:140
bool IsEmpty() const
Definition ObjectGuid.h:172
void SetRawValue(uint64 guid)
Definition ObjectGuid.h:149
std::string ToString() const
static ObjectGuid GetGUID(Object const *o)
Definition Object.h:78
bool HasIgnore(ObjectGuid const &ignoreGuid)
uint32 GetTeam() const
Definition Player.h:1832
bool isGMVisible() const
Definition Player.h:1006
void SendDirectMessage(WorldPacket const *data) const
Definition Player.cpp:6161
WorldSession * GetSession() const
Definition Player.h:1719
Group * GetGroup()
Definition Player.h:2171
bool IsVisibleGloballyFor(Player const *player) const
Definition Player.cpp:22113
PlayerSocial * GetSocial()
Definition Player.h:982
void LeftChannel(Channel *c)
Definition Player.cpp:4842
void JoinedChannel(Channel *c)
Definition Player.cpp:4837
void setUInt32(uint8 index, uint32 value)
void setBool(uint8 index, bool value)
void setString(uint8 index, std::string const &value)
std::string const & GetName() const
Definition Object.h:382
void Initialize(uint16 opcode, size_t newres=200)
Definition WorldPacket.h:73
AccountTypes GetSecurity() const
LocaleConstant GetSessionDbcLocale() const
std::string GetPlayerInfo() const
bool HasPermission(uint32 permissionId)
@ SMSG_CHANNEL_LIST
Definition Opcodes.h:184
@ SMSG_USERLIST_REMOVE
Definition Opcodes.h:1038
@ SMSG_USERLIST_UPDATE
Definition Opcodes.h:1039
@ SMSG_USERLIST_ADD
Definition Opcodes.h:1037
#define sWorld
Definition World.h:900
@ CONFIG_PRESERVE_CUSTOM_CHANNEL_INTERVAL
Definition World.h:353
@ CONFIG_GM_LEVEL_IN_WHO_LIST
Definition World.h:264
@ CONFIG_RESTRICTED_LFG_CHANNEL
Definition World.h:116
@ CONFIG_ALLOW_TWO_SIDE_INTERACTION_CHANNEL
Definition World.h:97
time_t GetGameTime()
Definition GameTime.cpp:42
TC_GAME_API Player * FindConnectedPlayerByName(std::string_view name)
TC_GAME_API Player * FindConnectedPlayer(ObjectGuid const &)
TC_COMMON_API std::vector< std::string_view > Tokenize(std::string_view str, char sep, bool keepEmpty)
Definition Util.cpp:56
@ RBAC_PERM_SILENTLY_JOIN_CHANNEL
Definition RBAC.h:98
@ RBAC_PERM_WHO_SEE_ALL_SEC_LEVELS
Definition RBAC.h:88
@ RBAC_PERM_CHANGE_CHANNEL_NOT_MODERATOR
Definition RBAC.h:99
@ RBAC_PERM_TWO_SIDE_INTERACTION_CHANNEL
Definition RBAC.h:79
void SetModerator(bool state)
Definition Channel.h:140
bool IsOwner() const
Definition Channel.h:132
bool IsMuted() const
Definition Channel.h:146
bool IsInvisible() const
Definition Channel.h:126
void SetMuted(bool state)
Definition Channel.h:147
bool IsModerator() const
Definition Channel.h:139
char const * Name[16]