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 "ChatPackets.h"
23#include "DatabaseEnv.h"
24#include "DBCStores.h"
25#include "GameTime.h"
26#include "GridNotifiers.h"
27#include "GridNotifiersImpl.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#include "WorldSession.h"
36#include <sstream>
37
38Channel::Channel(uint32 channelId, uint32 team /*= 0*/, AreaTableEntry const* zoneEntry /*= nullptr*/) :
39 _isDirty(false),
40 _nextActivityUpdateTime(0),
41 _announceEnabled(false), // no join/leave announces
42 _ownershipEnabled(false), // no ownership handout
43 _isOwnerInvisible(false),
44 _channelFlags(CHANNEL_FLAG_GENERAL), // for all built-in channels
45 _channelId(channelId),
46 _channelTeam(team),
47 _zoneEntry(zoneEntry)
48{
49 ChatChannelsEntry const* channelEntry = sChatChannelsStore.AssertEntry(channelId);
50 if (channelEntry->Flags & CHANNEL_DBC_FLAG_TRADE) // for trade channel
52
53 if (channelEntry->Flags & CHANNEL_DBC_FLAG_CITY_ONLY2) // for city only channels
55
56 if (channelEntry->Flags & CHANNEL_DBC_FLAG_LFG) // for LFG channel
58 else // for all other channels
60}
61
62Channel::Channel(std::string const& name, uint32 team /*= 0*/, std::string const& banList) :
63 _isDirty(false),
64 _nextActivityUpdateTime(0),
65 _announceEnabled(true),
66 _ownershipEnabled(true),
67 _isOwnerInvisible(false),
68 _channelFlags(CHANNEL_FLAG_CUSTOM),
69 _channelId(0),
70 _channelTeam(team),
71 _channelName(name),
72 _zoneEntry(nullptr)
73{
74 for (std::string_view guid : Trinity::Tokenize(banList, ' ', false))
75 {
76 ObjectGuid banned;
77 banned.SetRawValue(Trinity::StringTo<uint64>(guid).value_or(0));
78 if (!banned)
79 continue;
80
81 TC_LOG_DEBUG("chat.system", "Channel({}) loaded player {} into bannedStore", name, banned.ToString());
82 _bannedStore.insert(banned);
83 }
84}
85
86Channel::~Channel() = default;
87
88void Channel::GetChannelName(std::string& channelName, uint32 channelId, LocaleConstant locale, AreaTableEntry const* zoneEntry)
89{
90 if (channelId)
91 {
92 ChatChannelsEntry const* channelEntry = sChatChannelsStore.AssertEntry(channelId);
93 if (!(channelEntry->Flags & CHANNEL_DBC_FLAG_GLOBAL))
94 {
95 if (channelEntry->Flags & CHANNEL_DBC_FLAG_CITY_ONLY)
96 channelName = ChatHandler::PGetParseString(channelEntry->Name[locale], sObjectMgr->GetTrinityString(LANG_CHANNEL_CITY, locale));
97 else
98 channelName = ChatHandler::PGetParseString(channelEntry->Name[locale], ASSERT_NOTNULL(zoneEntry)->AreaName[locale]);
99 }
100 else
101 channelName = channelEntry->Name[locale];
102 }
103}
104
105std::string Channel::GetName(LocaleConstant locale /*= DEFAULT_LOCALE*/) const
106{
107 std::string result = _channelName;
109
110 return result;
111}
112
114{
115 time_t const now = GameTime::GetGameTime();
116 if (_isDirty)
117 {
118 std::ostringstream banlist;
119 for (ObjectGuid const& guid : _bannedStore)
120 banlist << guid.GetRawValue() << ' ';
121
123 stmt->setString(0, _channelName);
124 stmt->setUInt32(1, _channelTeam);
125 stmt->setBool(2, _announceEnabled);
126 stmt->setBool(3, _ownershipEnabled);
127 stmt->setString(4, _channelPassword);
128 stmt->setString(5, banlist.str());
129 CharacterDatabase.Execute(stmt);
130 }
131 else if (_nextActivityUpdateTime <= now)
132 {
133 if (!_playersStore.empty())
134 {
136 stmt->setString(0, _channelName);
137 stmt->setUInt32(1, _channelTeam);
138 CharacterDatabase.Execute(stmt);
139 }
140 }
141 else
142 return;
143
144 _isDirty = false;
145 _nextActivityUpdateTime = now + urand(1 * MINUTE, 6 * MINUTE) * std::max(1u, sWorld->getIntConfig(CONFIG_PRESERVE_CUSTOM_CHANNEL_INTERVAL));
146}
147
148void Channel::JoinChannel(Player* player, std::string const& pass)
149{
150 ObjectGuid guid = player->GetGUID();
151 if (IsOn(guid))
152 {
153 // Do not send error message for built-in channels
154 if (!IsConstant())
155 {
156 PlayerAlreadyMemberAppend appender(guid);
157 ChannelNameBuilder<PlayerAlreadyMemberAppend> builder(this, appender);
158 SendToOne(builder, guid);
159 }
160 return;
161 }
162
163 if (IsBanned(guid))
164 {
165 BannedAppend appender;
166 ChannelNameBuilder<BannedAppend> builder(this, appender);
167 SendToOne(builder, guid);
168 return;
169 }
170
171 if (!CheckPassword(pass))
172 {
173 WrongPasswordAppend appender;
174 ChannelNameBuilder<WrongPasswordAppend> builder(this, appender);
175 SendToOne(builder, guid);
176 return;
177 }
178
180 sWorld->getBoolConfig(CONFIG_RESTRICTED_LFG_CHANNEL) &&
181 AccountMgr::IsPlayerAccount(player->GetSession()->GetSecurity()) && //FIXME: Move to RBAC
182 player->GetGroup())
183 {
184 NotInLFGAppend appender;
185 ChannelNameBuilder<NotInLFGAppend> builder(this, appender);
186 SendToOne(builder, guid);
187 return;
188 }
189
190 player->JoinedChannel(this);
191
193 {
194 JoinedAppend appender(guid);
195 ChannelNameBuilder<JoinedAppend> builder(this, appender);
196 SendToAll(builder);
197 }
198
199 bool newChannel = _playersStore.empty();
200 if (newChannel)
201 _nextActivityUpdateTime = 0; // force activity update on next channel tick
202
203 PlayerInfo& playerInfo = _playersStore[guid];
204 playerInfo.SetInvisible(!player->isGMVisible());
205
206 YouJoinedAppend appender(this);
207 ChannelNameBuilder<YouJoinedAppend> builder(this, appender);
208 SendToOne(builder, guid);
209
210 JoinNotify(guid);
211
212 // Custom channel handling
213 if (!IsConstant())
214 {
215 // If the channel has no owner yet and ownership is allowed, set the new owner.
216 // or if the owner was a GM with .gm visible off
217 // don't do this if the new player is, too, an invis GM, unless the channel was empty
218 if (_ownershipEnabled && (newChannel || !playerInfo.IsInvisible()) && (_ownerGuid.IsEmpty() || _isOwnerInvisible))
219 {
220 _isOwnerInvisible = playerInfo.IsInvisible();
221
222 SetOwner(guid, !newChannel && !_isOwnerInvisible);
223 playerInfo.SetModerator(true);
224 }
225 }
226}
227
228void Channel::LeaveChannel(Player* player, bool send, bool suspend)
229{
230 ObjectGuid guid = player->GetGUID();
231 if (!IsOn(guid))
232 {
233 if (send)
234 {
235 NotMemberAppend appender;
236 ChannelNameBuilder<NotMemberAppend> builder(this, appender);
237 SendToOne(builder, guid);
238 }
239 return;
240 }
241
242 if (send)
243 {
244 YouLeftAppend appender(this, suspend);
245 ChannelNameBuilder<YouLeftAppend> builder(this, appender);
246 SendToOne(builder, guid);
247
248 player->LeftChannel(this);
249 }
250
251 PlayerInfo info = _playersStore.extract(guid).mapped();
252 bool changeowner = info.IsOwner();
253
255 {
256 LeftAppend appender(guid);
257 ChannelNameBuilder<LeftAppend> builder(this, appender);
258 SendToAll(builder);
259 }
260
261 LeaveNotify(guid);
262
263 if (!IsConstant())
264 {
265 // If the channel owner left and there are players still inside, pick a new owner
266 // do not pick invisible gm owner unless there are only invisible gms in that channel (rare)
267 if (changeowner && _ownershipEnabled && !_playersStore.empty())
268 {
269 PlayerContainer::iterator itr;
270 for (itr = _playersStore.begin(); itr != _playersStore.end(); ++itr)
271 {
272 if (!itr->second.IsInvisible())
273 break;
274 }
275
276 if (itr == _playersStore.end())
277 itr = _playersStore.begin();
278
279 ObjectGuid newOwner = itr->first;
280 itr->second.SetModerator(true);
281
282 SetOwner(newOwner);
283
284 // if the new owner is invisible gm, set flag to automatically choose a new owner
285 if (itr->second.IsInvisible())
286 _isOwnerInvisible = true;
287 }
288 }
289}
290
291void Channel::KickOrBan(Player const* player, std::string const& badname, bool ban)
292{
293 ObjectGuid good = player->GetGUID();
294
295 if (!IsOn(good))
296 {
297 NotMemberAppend appender;
298 ChannelNameBuilder<NotMemberAppend> builder(this, appender);
299 SendToOne(builder, good);
300 return;
301 }
302
303 PlayerInfo& info = _playersStore.at(good);
305 {
306 NotModeratorAppend appender;
307 ChannelNameBuilder<NotModeratorAppend> builder(this, appender);
308 SendToOne(builder, good);
309 return;
310 }
311
313 ObjectGuid victim = bad ? bad->GetGUID() : ObjectGuid::Empty;
314 if (!bad || !victim || !IsOn(victim))
315 {
316 PlayerNotFoundAppend appender(badname);
317 ChannelNameBuilder<PlayerNotFoundAppend> builder(this, appender);
318 SendToOne(builder, good);
319 return;
320 }
321
322 bool changeowner = _ownerGuid == victim;
323
324 if (!player->GetSession()->HasPermission(rbac::RBAC_PERM_CHANGE_CHANNEL_NOT_MODERATOR) && changeowner && good != _ownerGuid)
325 {
326 NotOwnerAppend appender;
327 ChannelNameBuilder<NotOwnerAppend> builder(this, appender);
328 SendToOne(builder, good);
329 return;
330 }
331
332 if (ban && !IsBanned(victim))
333 {
334 _bannedStore.insert(victim);
335 _isDirty = true;
336
338 {
339 PlayerBannedAppend appender(good, victim);
340 ChannelNameBuilder<PlayerBannedAppend> builder(this, appender);
341 SendToAll(builder);
342 }
343 }
345 {
346 PlayerKickedAppend appender(good, victim);
347 ChannelNameBuilder<PlayerKickedAppend> builder(this, appender);
348 SendToAll(builder);
349 }
350
351 _playersStore.erase(victim);
352 bad->LeftChannel(this);
353
354 if (changeowner && _ownershipEnabled && !_playersStore.empty())
355 {
356 info.SetModerator(true);
357 SetOwner(good);
358 }
359}
360
361void Channel::UnBan(Player const* player, std::string const& badname)
362{
363 ObjectGuid good = player->GetGUID();
364
365 if (!IsOn(good))
366 {
367 NotMemberAppend appender;
368 ChannelNameBuilder<NotMemberAppend> builder(this, appender);
369 SendToOne(builder, good);
370 return;
371 }
372
373 PlayerInfo& info = _playersStore.at(good);
375 {
376 NotModeratorAppend appender;
377 ChannelNameBuilder<NotModeratorAppend> builder(this, appender);
378 SendToOne(builder, good);
379 return;
380 }
381
383 ObjectGuid victim = bad ? bad->GetGUID() : ObjectGuid::Empty;
384
385 if (victim.IsEmpty() || !IsBanned(victim))
386 {
387 PlayerNotFoundAppend appender(badname);
388 ChannelNameBuilder<PlayerNotFoundAppend> builder(this, appender);
389 SendToOne(builder, good);
390 return;
391 }
392
393 _bannedStore.erase(victim);
394
395 PlayerUnbannedAppend appender(good, victim);
396 ChannelNameBuilder<PlayerUnbannedAppend> builder(this, appender);
397 SendToAll(builder);
398
399 _isDirty = true;
400}
401
402void Channel::Password(Player const* player, std::string const& pass)
403{
404 ObjectGuid guid = player->GetGUID();
405
406 if (!IsOn(guid))
407 {
408 NotMemberAppend appender;
409 ChannelNameBuilder<NotMemberAppend> builder(this, appender);
410 SendToOne(builder, guid);
411 return;
412 }
413
414 PlayerInfo& info = _playersStore.at(guid);
416 {
417 NotModeratorAppend appender;
418 ChannelNameBuilder<NotModeratorAppend> builder(this, appender);
419 SendToOne(builder, guid);
420 return;
421 }
422
423 _channelPassword = pass;
424
425 PasswordChangedAppend appender(guid);
426 ChannelNameBuilder<PasswordChangedAppend> builder(this, appender);
427 SendToAll(builder);
428
429 _isDirty = true;
430}
431
432void Channel::SetMode(Player const* player, std::string const& p2n, bool mod, bool set)
433{
434 ObjectGuid guid = player->GetGUID();
435
436 if (!IsOn(guid))
437 {
438 NotMemberAppend appender;
439 ChannelNameBuilder<NotMemberAppend> builder(this, appender);
440 SendToOne(builder, guid);
441 return;
442 }
443
444 PlayerInfo& info = _playersStore.at(guid);
446 {
447 NotModeratorAppend appender;
448 ChannelNameBuilder<NotModeratorAppend> builder(this, appender);
449 SendToOne(builder, guid);
450 return;
451 }
452
453 if (guid == _ownerGuid && p2n == player->GetName() && mod)
454 return;
455
457 ObjectGuid victim = newp ? newp->GetGUID() : ObjectGuid::Empty;
458
459 if (!newp || victim.IsEmpty() || !IsOn(victim) ||
460 (player->GetTeam() != newp->GetTeam() &&
463 {
464 PlayerNotFoundAppend appender(p2n);
465 ChannelNameBuilder<PlayerNotFoundAppend> builder(this, appender);
466 SendToOne(builder, guid);
467 return;
468 }
469
470 if (_ownerGuid == victim && _ownerGuid != guid)
471 {
472 NotOwnerAppend appender;
473 ChannelNameBuilder<NotOwnerAppend> builder(this, appender);
474 SendToOne(builder, guid);
475 return;
476 }
477
478 if (mod)
479 SetModerator(newp->GetGUID(), set);
480 else
481 SetMute(newp->GetGUID(), set);
482}
483
484void Channel::SetInvisible(Player const* player, bool on)
485{
486 auto itr = _playersStore.find(player->GetGUID());
487 if (itr == _playersStore.end())
488 return;
489
490 itr->second.SetInvisible(on);
491
492 // we happen to be owner too, update flag
493 if (_ownerGuid == player->GetGUID())
495}
496
497void Channel::SetModerator(ObjectGuid const& guid, bool set)
498{
499 if (!IsOn(guid))
500 return;
501
502 PlayerInfo& playerInfo = _playersStore.at(guid);
503 if (playerInfo.IsModerator() != set)
504 {
505 uint8 oldFlag = playerInfo.GetFlags();
506 playerInfo.SetModerator(set);
507
508 ModeChangeAppend appender(guid, oldFlag, playerInfo.GetFlags());
509 ChannelNameBuilder<ModeChangeAppend> builder(this, appender);
510 SendToAll(builder);
511 }
512}
513
514void Channel::SetMute(ObjectGuid const& guid, bool set)
515{
516 if (!IsOn(guid))
517 return;
518
519 PlayerInfo& playerInfo = _playersStore.at(guid);
520 if (playerInfo.IsMuted() != set)
521 {
522 uint8 oldFlag = playerInfo.GetFlags();
523 playerInfo.SetMuted(set);
524
525 ModeChangeAppend appender(guid, oldFlag, playerInfo.GetFlags());
526 ChannelNameBuilder<ModeChangeAppend> builder(this, appender);
527 SendToAll(builder);
528 }
529}
530
531void Channel::SetOwner(Player const* player, std::string const& newname)
532{
533 ObjectGuid guid = player->GetGUID();
534
535 if (!IsOn(guid))
536 {
537 NotMemberAppend appender;
538 ChannelNameBuilder<NotMemberAppend> builder(this, appender);
539 SendToOne(builder, guid);
540 return;
541 }
542
544 {
545 NotOwnerAppend appender;
546 ChannelNameBuilder<NotOwnerAppend> builder(this, appender);
547 SendToOne(builder, guid);
548 return;
549 }
550
552 ObjectGuid victim = newp ? newp->GetGUID() : ObjectGuid::Empty;
553
554 if (!newp || !victim || !IsOn(victim) ||
555 (player->GetTeam() != newp->GetTeam() &&
558 {
559 PlayerNotFoundAppend appender(newname);
560 ChannelNameBuilder<PlayerNotFoundAppend> builder(this, appender);
561 SendToOne(builder, guid);
562 return;
563 }
564
565 PlayerInfo& info = _playersStore.at(victim);
566 info.SetModerator(true);
567 SetOwner(victim);
568}
569
570void Channel::SendWhoOwner(Player const* player)
571{
572 ObjectGuid guid = player->GetGUID();
573 if (IsOn(guid))
574 {
575 ChannelOwnerAppend appender(this, _ownerGuid);
576 ChannelNameBuilder<ChannelOwnerAppend> builder(this, appender);
577 SendToOne(builder, guid);
578 }
579 else
580 {
581 NotMemberAppend appender;
582 ChannelNameBuilder<NotMemberAppend> builder(this, appender);
583 SendToOne(builder, guid);
584 }
585}
586
587void Channel::List(Player const* player) const
588{
589 ObjectGuid guid = player->GetGUID();
590 if (!IsOn(guid))
591 {
592 NotMemberAppend appender;
593 ChannelNameBuilder<NotMemberAppend> builder(this, appender);
594 SendToOne(builder, guid);
595 return;
596 }
597
598 std::string channelName = GetName(player->GetSession()->GetSessionDbcLocale());
599 TC_LOG_DEBUG("chat.system", "SMSG_CHANNEL_LIST {} Channel: {}",
600 player->GetSession()->GetPlayerInfo(), channelName);
601
603 list.Display = true;
604 list._Channel = channelName;
605 list._ChannelFlags = GetFlags();
606
607 uint32 gmLevelInWhoList = sWorld->getIntConfig(CONFIG_GM_LEVEL_IN_WHO_LIST);
608
609 list.Members.reserve(_playersStore.size());
610 for (PlayerContainer::value_type const& i : _playersStore)
611 {
613
614 // PLAYER can't see MODERATOR, GAME MASTER, ADMINISTRATOR characters
615 // MODERATOR, GAME MASTER, ADMINISTRATOR can see all
616 if (member &&
618 member->GetSession()->GetSecurity() <= AccountTypes(gmLevelInWhoList)) &&
619 member->IsVisibleGloballyFor(player))
620 {
621 list.Members.emplace_back(i.first, i.second.GetFlags());
622 }
623 }
624
625 player->SendDirectMessage(list.Write());
626}
627
628void Channel::Announce(Player const* player)
629{
630 ObjectGuid guid = player->GetGUID();
631
632 if (!IsOn(guid))
633 {
634 NotMemberAppend appender;
635 ChannelNameBuilder<NotMemberAppend> builder(this, appender);
636 SendToOne(builder, guid);
637 return;
638 }
639
640 PlayerInfo const& playerInfo = _playersStore.at(guid);
642 {
643 NotModeratorAppend appender;
644 ChannelNameBuilder<NotModeratorAppend> builder(this, appender);
645 SendToOne(builder, guid);
646 return;
647 }
648
650
652 {
653 AnnouncementsOnAppend appender(guid);
654 ChannelNameBuilder<AnnouncementsOnAppend> builder(this, appender);
655 SendToAll(builder);
656 }
657 else
658 {
659 AnnouncementsOffAppend appender(guid);
660 ChannelNameBuilder<AnnouncementsOffAppend> builder(this, appender);
661 SendToAll(builder);
662 }
663
664 _isDirty = true;
665}
666
667void Channel::Say(ObjectGuid const& guid, std::string const& what, uint32 lang) const
668{
669 if (what.empty())
670 return;
671
672 // TODO: Add proper RBAC check
674 lang = LANG_UNIVERSAL;
675
676 if (!IsOn(guid))
677 {
678 NotMemberAppend appender;
679 ChannelNameBuilder<NotMemberAppend> builder(this, appender);
680 SendToOne(builder, guid);
681 return;
682 }
683
684 PlayerInfo const& playerInfo = _playersStore.at(guid);
685 if (playerInfo.IsMuted())
686 {
687 MutedAppend appender;
688 ChannelNameBuilder<MutedAppend> builder(this, appender);
689 SendToOne(builder, guid);
690 return;
691 }
692
694
695 auto builder = [&](WorldPacket& data, LocaleConstant locale)
696 {
697 LocaleConstant localeIdx = sWorld->GetAvailableDbcLocale(locale);
698
700 if (player)
701 packet.Initialize(CHAT_MSG_CHANNEL, Language(lang), player, player, what, 0, GetName(localeIdx), DEFAULT_LOCALE);
702 else
703 {
704 packet.Initialize(CHAT_MSG_CHANNEL, Language(lang), nullptr, nullptr, what, 0, GetName(localeIdx), DEFAULT_LOCALE);
705 packet.SenderGUID = guid;
706 packet.TargetGUID = guid;
707 }
708
709 packet.Write();
710
711 data = packet.Move();
712 };
713
714 SendToAll(builder, !playerInfo.IsModerator() ? guid : ObjectGuid::Empty);
715}
716
717void Channel::Invite(Player const* player, std::string const& newname)
718{
719 ObjectGuid guid = player->GetGUID();
720
721 if (!IsOn(guid))
722 {
723 NotMemberAppend appender;
724 ChannelNameBuilder<NotMemberAppend> builder(this, appender);
725 SendToOne(builder, guid);
726 return;
727 }
728
730 if (!newp || !newp->isGMVisible())
731 {
732 PlayerNotFoundAppend appender(newname);
733 ChannelNameBuilder<PlayerNotFoundAppend> builder(this, appender);
734 SendToOne(builder, guid);
735 return;
736 }
737
738 if (IsBanned(newp->GetGUID()))
739 {
740 PlayerInviteBannedAppend appender(newname);
741 ChannelNameBuilder<PlayerInviteBannedAppend> builder(this, appender);
742 SendToOne(builder, guid);
743 return;
744 }
745
746 if (newp->GetTeam() != player->GetTeam() &&
749 {
751 ChannelNameBuilder<InviteWrongFactionAppend> builder(this, appender);
752 SendToOne(builder, guid);
753 return;
754 }
755
756 if (IsOn(newp->GetGUID()))
757 {
758 PlayerAlreadyMemberAppend appender(newp->GetGUID());
759 ChannelNameBuilder<PlayerAlreadyMemberAppend> builder(this, appender);
760 SendToOne(builder, guid);
761 return;
762 }
763
764 if (!newp->GetSocial()->HasIgnore(guid))
765 {
766 InviteAppend appender(guid);
767 ChannelNameBuilder<InviteAppend> builder(this, appender);
768 SendToOne(builder, newp->GetGUID());
769 }
770
771 PlayerInvitedAppend appender(newp->GetName());
772 ChannelNameBuilder<PlayerInvitedAppend> builder(this, appender);
773 SendToOne(builder, guid);
774}
775
776void Channel::SetOwner(ObjectGuid const& guid, bool exclaim)
777{
778 if (!_ownerGuid.IsEmpty())
779 {
780 auto itr = _playersStore.find(_ownerGuid);
781 if (itr != _playersStore.end())
782 itr->second.SetOwner(false);
783 }
784
785 _ownerGuid = guid;
786 if (!_ownerGuid.IsEmpty())
787 {
788 auto itr = _playersStore.find(_ownerGuid);
789 if (itr == _playersStore.end())
790 return;
791
792 uint8 oldFlag = itr->second.GetFlags();
793 itr->second.SetModerator(true);
794 itr->second.SetOwner(true);
795
796 ModeChangeAppend appender(_ownerGuid, oldFlag, itr->second.GetFlags());
797 ChannelNameBuilder<ModeChangeAppend> builder(this, appender);
798 SendToAll(builder);
799
800 if (exclaim)
801 {
802 OwnerChangedAppend ownerAppender(_ownerGuid);
803 ChannelNameBuilder<OwnerChangedAppend> ownerBuilder(this, ownerAppender);
804 SendToAll(ownerBuilder);
805 }
806
807 _isDirty = true;
808 }
809}
810
811void Channel::SilenceAll(Player const* /*player*/, std::string const& /*name*/)
812{
813}
814
815void Channel::SilenceVoice(Player const* /*player*/, std::string const& /*name*/)
816{
817}
818
819void Channel::UnsilenceAll(Player const* /*player*/, std::string const& /*name*/)
820{
821}
822
823void Channel::UnsilenceVoice(Player const* /*player*/, std::string const& /*name*/)
824{
825}
826
827void Channel::DeclineInvite(Player const* /*player*/)
828{
829}
830
831void Channel::JoinNotify(ObjectGuid const& guid) const
832{
833 auto builder = [&](WorldPacket& data, LocaleConstant locale)
834 {
835 LocaleConstant localeIdx = sWorld->GetAvailableDbcLocale(locale);
836
837 data.Initialize(IsConstant() ? SMSG_USERLIST_ADD : SMSG_USERLIST_UPDATE, 8 + 1 + 1 + 4 + 30 /*channelName buffer*/);
838 data << guid;
839 data << uint8(GetPlayerFlags(guid));
840 data << uint8(GetFlags());
841 data << uint32(GetNumPlayers());
842 data << GetName(localeIdx);
843 };
844
845 if (IsConstant())
846 SendToAllButOne(builder, guid);
847 else
848 SendToAll(builder);
849}
850
851void Channel::LeaveNotify(ObjectGuid const& guid) const
852{
853 auto builder = [&](WorldPacket& data, LocaleConstant locale)
854 {
855 LocaleConstant localeIdx = sWorld->GetAvailableDbcLocale(locale);
856
857 data.Initialize(SMSG_USERLIST_REMOVE, 8 + 1 + 4 + 30 /*channelName buffer*/);
858 data << guid;
859 data << uint8(GetFlags());
860 data << uint32(GetNumPlayers());
861 data << GetName(localeIdx);
862 };
863
864 if (IsConstant())
865 SendToAllButOne(builder, guid);
866 else
867 SendToAll(builder);
868}
869
870void Channel::SendMemberCount(Player const* player) const
871{
873 channelMemberCount.ChannelName = GetName(player->GetSession()->GetSessionDbcLocale());
874 channelMemberCount._ChannelFlags = GetFlags();
875 channelMemberCount.MemberCount = GetNumPlayers();
876 player->SendDirectMessage(channelMemberCount.Write());
877}
878
879void Channel::VoiceOn(Player const* /*player*/)
880{
881}
882
883void Channel::VoiceOff(Player const* /*player*/)
884{
885}
886
887template <class Builder>
888void Channel::SendToAll(Builder& builder, ObjectGuid const& guid) const
889{
890 Trinity::LocalizedPacketDo<Builder> localizer(builder);
891
892 for (PlayerContainer::value_type const& i : _playersStore)
893 if (Player* player = ObjectAccessor::FindConnectedPlayer(i.first))
894 if (guid.IsEmpty() || !player->GetSocial()->HasIgnore(guid))
895 localizer(player);
896}
897
898template <class Builder>
899void Channel::SendToAllButOne(Builder& builder, ObjectGuid const& who) const
900{
901 Trinity::LocalizedPacketDo<Builder> localizer(builder);
902
903 for (PlayerContainer::const_iterator i = _playersStore.begin(); i != _playersStore.end(); ++i)
904 if (i->first != who)
905 if (Player* player = ObjectAccessor::FindConnectedPlayer(i->first))
906 localizer(player);
907}
908
909template <class Builder>
910void Channel::SendToOne(Builder& builder, ObjectGuid const& who) const
911{
912 Trinity::LocalizedPacketDo<Builder> localizer(builder);
913
915 localizer(player);
916}
@ 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
@ 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
#define DEFAULT_LOCALE
Definition Common.h:62
@ 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)
void List(Player const *player) const
Definition Channel.cpp:587
bool IsConstant() const
Definition Channel.h:179
void Password(Player const *player, std::string const &pass)
Definition Channel.cpp:402
void SilenceVoice(Player const *player, std::string const &name)
Definition Channel.cpp:815
uint32 _channelId
Definition Channel.h:269
BannedContainer _bannedStore
Definition Channel.h:275
void LeaveNotify(ObjectGuid const &guid) const
Definition Channel.cpp:851
void JoinChannel(Player *player, std::string const &pass="")
Definition Channel.cpp:148
std::string GetName(LocaleConstant locale=DEFAULT_LOCALE) const
Definition Channel.cpp:105
bool _ownershipEnabled
Definition Channel.h:265
bool _announceEnabled
Definition Channel.h:264
void SendToOne(Builder &builder, ObjectGuid const &who) const
Definition Channel.cpp:910
bool HasFlag(uint8 flag) const
Definition Channel.h:195
uint32 _channelTeam
Definition Channel.h:270
void SendToAllButOne(Builder &builder, ObjectGuid const &who) const
Definition Channel.cpp:899
Channel(uint32 channelId, uint32 team=0, AreaTableEntry const *zoneEntry=nullptr)
Definition Channel.cpp:38
void JoinNotify(ObjectGuid const &guid) const
Definition Channel.cpp:831
time_t _nextActivityUpdateTime
Definition Channel.h:262
uint8 _channelFlags
Definition Channel.h:268
std::string _channelName
Definition Channel.h:272
void VoiceOn(Player const *player)
Definition Channel.cpp:879
void SetMute(Player const *player, std::string const &newname)
Definition Channel.h:218
void SetModerator(Player const *player, std::string const &newname)
Definition Channel.h:216
void KickOrBan(Player const *player, std::string const &badname, bool ban)
Definition Channel.cpp:291
bool _isOwnerInvisible
Definition Channel.h:266
void SendWhoOwner(Player const *player)
Definition Channel.cpp:570
void SendToAll(Builder &builder, ObjectGuid const &guid=ObjectGuid::Empty) const
Definition Channel.cpp:888
bool CheckPassword(std::string const &password) const
Definition Channel.h:190
bool IsOn(ObjectGuid who) const
Definition Channel.h:246
void UnsilenceAll(Player const *player, std::string const &name)
Definition Channel.cpp:819
void UnsilenceVoice(Player const *player, std::string const &name)
Definition Channel.cpp:823
void SetOwner(ObjectGuid const &guid, bool exclaim=true)
Definition Channel.cpp:776
void UnBan(Player const *player, std::string const &badname)
Definition Channel.cpp:361
void SilenceAll(Player const *player, std::string const &name)
Definition Channel.cpp:811
uint8 GetPlayerFlags(ObjectGuid const &guid) const
Definition Channel.h:249
bool _isDirty
Definition Channel.h:261
void SetMode(Player const *player, std::string const &p2n, bool mod, bool set)
Definition Channel.cpp:432
void Say(ObjectGuid const &guid, std::string const &what, uint32 lang) const
Definition Channel.cpp:667
static void GetChannelName(std::string &channelName, uint32 channelId, LocaleConstant locale, AreaTableEntry const *zoneEntry)
Definition Channel.cpp:88
void DeclineInvite(Player const *player)
Definition Channel.cpp:827
void SetInvisible(Player const *player, bool on)
Definition Channel.cpp:484
void UpdateChannelInDB()
Definition Channel.cpp:113
void Announce(Player const *player)
Definition Channel.cpp:628
void Invite(Player const *player, std::string const &newp)
Definition Channel.cpp:717
uint32 GetNumPlayers() const
Definition Channel.h:192
void SendMemberCount(Player const *player) const
Definition Channel.cpp:870
bool IsBanned(ObjectGuid guid) const
Definition Channel.h:247
AreaTableEntry const * _zoneEntry
Definition Channel.h:277
ObjectGuid _ownerGuid
Definition Channel.h:271
void VoiceOff(Player const *player)
Definition Channel.cpp:883
std::string _channelPassword
Definition Channel.h:273
void LeaveChannel(Player *player, bool send=true, bool suspend=false)
Definition Channel.cpp:228
uint8 GetFlags() const
Definition Channel.h:194
PlayerContainer _playersStore
Definition Channel.h:274
static std::string PGetParseString(std::string_view fmt, Args &&... args)
Definition Chat.h:73
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:1818
bool isGMVisible() const
Definition Player.h:984
void SendDirectMessage(WorldPacket const *data) const
Definition Player.cpp:6163
WorldSession * GetSession() const
Definition Player.h:1705
Group * GetGroup()
Definition Player.h:2159
bool IsVisibleGloballyFor(Player const *player) const
Definition Player.cpp:22110
PlayerSocial * GetSocial()
Definition Player.h:960
void LeftChannel(Channel *c)
Definition Player.cpp:4861
void JoinedChannel(Channel *c)
Definition Player.cpp:4856
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:384
void Initialize(uint16 opcode, size_t newres=200)
Definition WorldPacket.h:51
std::vector< ChannelPlayer > Members
WorldPacket const * Write() override
WorldPacket const * Write() override
void Initialize(ChatMsg chatType, Language language, WorldObject const *sender, WorldObject const *receiver, std::string_view message, uint32 achievementId=0, std::string_view channelName="", LocaleConstant locale=DEFAULT_LOCALE, std::string_view addonPrefix="")
WorldPacket const * Write() override
WorldPacket && Move()
Definition Packet.h:53
AccountTypes GetSecurity() const
LocaleConstant GetSessionDbcLocale() const
std::string GetPlayerInfo() const
bool HasPermission(uint32 permissionId)
@ 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:901
@ CONFIG_PRESERVE_CUSTOM_CHANNEL_INTERVAL
Definition World.h:354
@ CONFIG_GM_LEVEL_IN_WHO_LIST
Definition World.h:265
@ 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:142
bool IsOwner() const
Definition Channel.h:132
uint8 GetFlags() const
Definition Channel.h:123
bool IsMuted() const
Definition Channel.h:150
bool IsInvisible() const
Definition Channel.h:125
void SetInvisible(bool on)
Definition Channel.h:126
void SetMuted(bool state)
Definition Channel.h:151
bool IsModerator() const
Definition Channel.h:141
char const * Name[16]