TrinityCore
ChannelHandler.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 "WorldSession.h"
19#include "Channel.h"
20#include "ChannelMgr.h"
21#include "ChannelPackets.h"
22#include "DB2Stores.h"
23#include "Log.h"
24#include "ObjectMgr.h" // for normalizePlayerName
25#include "Player.h"
26#include <cctype>
27
28static size_t const MAX_CHANNEL_NAME_STR = 31;
29static size_t const MAX_CHANNEL_PASS_STR = 127;
30
32{
33 TC_LOG_DEBUG("chat.system", "CMSG_JOIN_CHANNEL {} ChatChannelId: {}, CreateVoiceSession: {}, Internal: {}, ChannelName: {}, Password: {}",
34 GetPlayerInfo(), packet.ChatChannelId, packet.CreateVoiceSession, packet.Internal, packet.ChannelName, packet.Password);
35
36 AreaTableEntry const* zone = sAreaTableStore.LookupEntry(GetPlayer()->GetZoneId());
37 if (packet.ChatChannelId)
38 {
39 ChatChannelsEntry const* channel = sChatChannelsStore.LookupEntry(packet.ChatChannelId);
40 if (!channel)
41 return;
42
43 if (!zone || !GetPlayer()->CanJoinConstantChannelInZone(channel, zone))
44 return;
45 }
46
47 ChannelMgr* cMgr = ChannelMgr::ForTeam(GetPlayer()->GetTeam());
48 if (!cMgr)
49 return;
50
51 if (packet.ChatChannelId)
52 { // system channel
53 if (Channel* channel = cMgr->GetSystemChannel(packet.ChatChannelId, zone))
54 channel->JoinChannel(GetPlayer());
55 }
56 else
57 { // custom channel
58 if (packet.ChannelName.empty() || isdigit((unsigned char)packet.ChannelName[0]))
59 {
61 channelNotify.Type = CHAT_INVALID_NAME_NOTICE;
62 channelNotify._Channel = packet.ChannelName;
63 SendPacket(channelNotify.Write());
64 return;
65 }
66
68 {
70 channelNotify.Type = CHAT_INVALID_NAME_NOTICE;
71 channelNotify._Channel = packet.ChannelName;
72 SendPacket(channelNotify.Write());
73 TC_LOG_ERROR("network", "Player {} tried to create a channel with a name more than {} characters long - blocked", GetPlayer()->GetGUID().ToString(), MAX_CHANNEL_NAME_STR);
74 return;
75 }
76
77 if (packet.Password.length() > MAX_CHANNEL_PASS_STR)
78 {
79 TC_LOG_ERROR("network", "Player {} tried to create a channel with a password more than {} characters long - blocked", GetPlayer()->GetGUID().ToString(), MAX_CHANNEL_PASS_STR);
80 return;
81 }
82
84 return;
85
86 if (Channel* channel = cMgr->GetCustomChannel(packet.ChannelName))
87 channel->JoinChannel(GetPlayer(), packet.Password);
88 else if (Channel* channel = cMgr->CreateCustomChannel(packet.ChannelName))
89 {
90 channel->SetPassword(packet.Password);
91 channel->JoinChannel(GetPlayer(), packet.Password);
92 }
93 }
94}
95
97{
98 TC_LOG_DEBUG("chat.system", "CMSG_LEAVE_CHANNEL {} ChannelName: {}, ZoneChannelID: {}",
99 GetPlayerInfo(), packet.ChannelName, packet.ZoneChannelID);
100
101 if (packet.ChannelName.empty() && !packet.ZoneChannelID)
102 return;
103
104 AreaTableEntry const* zone = sAreaTableStore.LookupEntry(GetPlayer()->GetZoneId());
105 if (packet.ZoneChannelID)
106 {
107 ChatChannelsEntry const* channel = sChatChannelsStore.LookupEntry(packet.ZoneChannelID);
108 if (!channel)
109 return;
110
111 if (!zone || !GetPlayer()->CanJoinConstantChannelInZone(channel, zone))
112 return;
113 }
114
115 if (ChannelMgr* cMgr = ChannelMgr::ForTeam(GetPlayer()->GetTeam()))
116 {
117 if (Channel* channel = cMgr->GetChannel(packet.ZoneChannelID, packet.ChannelName, GetPlayer(), true, zone))
118 channel->LeaveChannel(GetPlayer(), true);
119
120 if (packet.ZoneChannelID)
121 cMgr->LeftChannel(packet.ZoneChannelID, zone);
122 }
123}
124
126{
127 TC_LOG_DEBUG("chat.system", "{} {} ChannelName: {}",
129
131 {
132 switch (packet.GetOpcode())
133 {
135 channel->Announce(GetPlayer());
136 break;
138 channel->DeclineInvite(GetPlayer());
139 break;
142 channel->List(GetPlayer());
143 break;
145 channel->SendWhoOwner(GetPlayer());
146 break;
147 default:
148 break;
149 }
150 }
151}
152
154{
155 if (packet.Name.length() >= MAX_CHANNEL_NAME_STR)
156 {
157 TC_LOG_DEBUG("chat.system", "{} {} ChannelName: {}, Name: {}, Name too long.",
158 GetOpcodeNameForLogging(packet.GetOpcode()), GetPlayerInfo(), packet.ChannelName, packet.Name);
159 return;
160 }
161
162 TC_LOG_DEBUG("chat.system", "{} {} ChannelName: {}, Name: {}",
163 GetOpcodeNameForLogging(packet.GetOpcode()), GetPlayerInfo(), packet.ChannelName, packet.Name);
164
165 if (!normalizePlayerName(packet.Name))
166 return;
167
169 {
170 switch (packet.GetOpcode())
171 {
173 channel->Ban(GetPlayer(), packet.Name);
174 break;
176 channel->Invite(GetPlayer(), packet.Name);
177 break;
179 channel->Kick(GetPlayer(), packet.Name);
180 break;
182 channel->SetModerator(GetPlayer(), packet.Name);
183 break;
185 channel->SetOwner(GetPlayer(), packet.Name);
186 break;
188 channel->SilenceAll(GetPlayer(), packet.Name);
189 break;
191 channel->UnBan(GetPlayer(), packet.Name);
192 break;
194 channel->UnsetModerator(GetPlayer(), packet.Name);
195 break;
197 channel->UnsilenceAll(GetPlayer(), packet.Name);
198 break;
199 default:
200 break;
201 }
202 }
203}
204
206{
207 if (packet.Password.length() > MAX_CHANNEL_PASS_STR)
208 {
209 TC_LOG_DEBUG("chat.system", "{} {} ChannelName: {}, Password: {}, Password too long.",
211 return;
212 }
213
214 TC_LOG_DEBUG("chat.system", "{} {} ChannelName: {}, Password: {}",
216
218 channel->Password(GetPlayer(), packet.Password);
219}
static size_t const MAX_CHANNEL_PASS_STR
static size_t const MAX_CHANNEL_NAME_STR
@ CHAT_INVALID_NAME_NOTICE
Definition: Channel.h:70
DB2Storage< ChatChannelsEntry > sChatChannelsStore("ChatChannels.db2", &ChatChannelsLoadInfo::Instance)
DB2Storage< AreaTableEntry > sAreaTableStore("AreaTable.db2", &AreaTableLoadInfo::Instance)
#define TC_LOG_DEBUG(filterType__,...)
Definition: Log.h:156
#define TC_LOG_ERROR(filterType__,...)
Definition: Log.h:165
bool normalizePlayerName(std::string &name)
Definition: ObjectMgr.cpp:154
size_t utf8length(std::string &utf8str)
Definition: Util.cpp:349
Channel * CreateCustomChannel(std::string const &name)
Definition: ChannelMgr.cpp:181
Channel * GetCustomChannel(std::string const &name) const
Definition: ChannelMgr.cpp:200
static ChannelMgr * ForTeam(uint32 team)
Definition: ChannelMgr.cpp:114
Channel * GetSystemChannel(uint32 channelId, AreaTableEntry const *zoneEntry=nullptr)
Definition: ChannelMgr.cpp:169
static Channel * GetChannelForPlayerByNamePart(std::string const &namePart, Player *playerSearcher)
Definition: ChannelMgr.cpp:131
std::string _Channel
Channel Name.
WorldPacket const * Write() override
OpcodeClient GetOpcode() const
Definition: Packet.h:68
void HandleLeaveChannel(WorldPackets::Channel::LeaveChannel &packet)
bool DisallowHyperlinksAndMaybeKick(std::string const &str)
void HandleJoinChannel(WorldPackets::Channel::JoinChannel &packet)
std::string GetPlayerInfo() const
Player * GetPlayer() const
void HandleChannelPlayerCommand(WorldPackets::Channel::ChannelPlayerCommand &packet)
void HandleChannelCommand(WorldPackets::Channel::ChannelCommand &packet)
void SendPacket(WorldPacket const *packet, bool forced=false)
Send a packet to the client.
void HandleChannelPassword(WorldPackets::Channel::ChannelPassword &channelPassword)
std::string GetOpcodeNameForLogging(OpcodeClient opcode)
Lookup opcode name for human understandable logging.
Definition: Opcodes.cpp:2205
@ CMSG_CHAT_CHANNEL_UNBAN
Definition: Opcodes.h:212
@ CMSG_CHAT_CHANNEL_SILENCE_ALL
Definition: Opcodes.h:211
@ CMSG_CHAT_CHANNEL_DISPLAY_LIST
Definition: Opcodes.h:203
@ CMSG_CHAT_CHANNEL_SET_OWNER
Definition: Opcodes.h:210
@ CMSG_CHAT_CHANNEL_MODERATOR
Definition: Opcodes.h:207
@ CMSG_CHAT_CHANNEL_BAN
Definition: Opcodes.h:201
@ CMSG_CHAT_CHANNEL_DECLINE_INVITE
Definition: Opcodes.h:202
@ CMSG_CHAT_CHANNEL_INVITE
Definition: Opcodes.h:204
@ CMSG_CHAT_CHANNEL_UNMODERATOR
Definition: Opcodes.h:213
@ CMSG_CHAT_CHANNEL_KICK
Definition: Opcodes.h:205
@ CMSG_CHAT_CHANNEL_LIST
Definition: Opcodes.h:206
@ CMSG_CHAT_CHANNEL_OWNER
Definition: Opcodes.h:208
@ CMSG_CHAT_CHANNEL_UNSILENCE_ALL
Definition: Opcodes.h:214
@ CMSG_CHAT_CHANNEL_ANNOUNCEMENTS
Definition: Opcodes.h:200
std::string ToString(Type &&val, Params &&... params)