c9b8f09fbc
Port From (https://github.com/TrinityCore/TrinityCore/commit/0a83f748766c49775d76412d2b98bb9b9dc8c4df)
639 lines
26 KiB
C#
639 lines
26 KiB
C#
/*
|
|
* Copyright (C) 2012-2020 CypherCore <http://github.com/CypherCore>
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
using Framework.Constants;
|
|
using Framework.Dynamic;
|
|
using Game.Chat;
|
|
using Game.DataStorage;
|
|
using Game.Entities;
|
|
using Game.Groups;
|
|
using Game.Guilds;
|
|
using Game.Networking;
|
|
using Game.Networking.Packets;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
|
|
namespace Game
|
|
{
|
|
public partial class WorldSession
|
|
{
|
|
[WorldPacketHandler(ClientOpcodes.ChatMessageGuild)]
|
|
[WorldPacketHandler(ClientOpcodes.ChatMessageOfficer)]
|
|
[WorldPacketHandler(ClientOpcodes.ChatMessageParty)]
|
|
[WorldPacketHandler(ClientOpcodes.ChatMessageRaid)]
|
|
[WorldPacketHandler(ClientOpcodes.ChatMessageRaidWarning)]
|
|
[WorldPacketHandler(ClientOpcodes.ChatMessageSay)]
|
|
[WorldPacketHandler(ClientOpcodes.ChatMessageYell)]
|
|
[WorldPacketHandler(ClientOpcodes.ChatMessageInstanceChat)]
|
|
void HandleChatMessage(ChatMessage packet)
|
|
{
|
|
ChatMsg type;
|
|
|
|
switch (packet.GetOpcode())
|
|
{
|
|
case ClientOpcodes.ChatMessageSay:
|
|
type = ChatMsg.Say;
|
|
break;
|
|
case ClientOpcodes.ChatMessageYell:
|
|
type = ChatMsg.Yell;
|
|
break;
|
|
case ClientOpcodes.ChatMessageGuild:
|
|
type = ChatMsg.Guild;
|
|
break;
|
|
case ClientOpcodes.ChatMessageOfficer:
|
|
type = ChatMsg.Officer;
|
|
break;
|
|
case ClientOpcodes.ChatMessageParty:
|
|
type = ChatMsg.Party;
|
|
break;
|
|
case ClientOpcodes.ChatMessageRaid:
|
|
type = ChatMsg.Raid;
|
|
break;
|
|
case ClientOpcodes.ChatMessageRaidWarning:
|
|
type = ChatMsg.RaidWarning;
|
|
break;
|
|
case ClientOpcodes.ChatMessageInstanceChat:
|
|
type = ChatMsg.InstanceChat;
|
|
break;
|
|
default:
|
|
Log.outError(LogFilter.Network, "HandleMessagechatOpcode : Unknown chat opcode ({0})", packet.GetOpcode());
|
|
return;
|
|
}
|
|
|
|
HandleChat(type, packet.Language, packet.Text);
|
|
}
|
|
|
|
[WorldPacketHandler(ClientOpcodes.ChatMessageWhisper)]
|
|
void HandleChatMessageWhisper(ChatMessageWhisper packet)
|
|
{
|
|
HandleChat(ChatMsg.Whisper, packet.Language, packet.Text, packet.Target);
|
|
}
|
|
|
|
[WorldPacketHandler(ClientOpcodes.ChatMessageChannel)]
|
|
void HandleChatMessageChannel(ChatMessageChannel packet)
|
|
{
|
|
HandleChat(ChatMsg.Channel, packet.Language, packet.Text, packet.Target, packet.ChannelGUID);
|
|
}
|
|
|
|
[WorldPacketHandler(ClientOpcodes.ChatMessageEmote)]
|
|
void HandleChatMessageEmote(ChatMessageEmote packet)
|
|
{
|
|
HandleChat(ChatMsg.Emote, Language.Universal, packet.Text);
|
|
}
|
|
|
|
void HandleChat(ChatMsg type, Language lang, string msg, string target = "", ObjectGuid channelGuid = default)
|
|
{
|
|
Player sender = GetPlayer();
|
|
|
|
if (lang == Language.Universal && type != ChatMsg.Emote)
|
|
{
|
|
Log.outError(LogFilter.Network, "CMSG_MESSAGECHAT: Possible hacking-attempt: {0} tried to send a message in universal language", GetPlayerInfo());
|
|
SendNotification(CypherStrings.UnknownLanguage);
|
|
return;
|
|
}
|
|
|
|
// prevent talking at unknown language (cheating)
|
|
var languageData = Global.LanguageMgr.GetLanguageDescById(lang);
|
|
if (languageData.Empty())
|
|
{
|
|
SendNotification(CypherStrings.UnknownLanguage);
|
|
return;
|
|
}
|
|
|
|
if (!languageData.Any(langDesc => langDesc.SkillId == 0 || sender.HasSkill((SkillType)langDesc.SkillId)))
|
|
{
|
|
// also check SPELL_AURA_COMPREHEND_LANGUAGE (client offers option to speak in that language)
|
|
if (!sender.HasAuraTypeWithMiscvalue(AuraType.ComprehendLanguage, (int)lang))
|
|
{
|
|
SendNotification(CypherStrings.NotLearnedLanguage);
|
|
return;
|
|
}
|
|
}
|
|
|
|
// send in universal language if player in .gm on mode (ignore spell effects)
|
|
if (sender.IsGameMaster())
|
|
lang = Language.Universal;
|
|
else
|
|
{
|
|
// send in universal language in two side iteration allowed mode
|
|
if (HasPermission(RBACPermissions.TwoSideInteractionChat))
|
|
lang = Language.Universal;
|
|
else
|
|
{
|
|
switch (type)
|
|
{
|
|
case ChatMsg.Party:
|
|
case ChatMsg.Raid:
|
|
case ChatMsg.RaidWarning:
|
|
// allow two side chat at group channel if two side group allowed
|
|
if (WorldConfig.GetBoolValue(WorldCfg.AllowTwoSideInteractionGroup))
|
|
lang = Language.Universal;
|
|
break;
|
|
case ChatMsg.Guild:
|
|
case ChatMsg.Officer:
|
|
// allow two side chat at guild channel if two side guild allowed
|
|
if (WorldConfig.GetBoolValue(WorldCfg.AllowTwoSideInteractionGuild))
|
|
lang = Language.Universal;
|
|
break;
|
|
}
|
|
}
|
|
// but overwrite it by SPELL_AURA_MOD_LANGUAGE auras (only single case used)
|
|
var ModLangAuras = sender.GetAuraEffectsByType(AuraType.ModLanguage);
|
|
if (!ModLangAuras.Empty())
|
|
lang = (Language)ModLangAuras.FirstOrDefault().GetMiscValue();
|
|
}
|
|
|
|
if (!CanSpeak())
|
|
{
|
|
string timeStr = Time.secsToTimeString((ulong)(m_muteTime - GameTime.GetGameTime()));
|
|
SendNotification(CypherStrings.WaitBeforeSpeaking, timeStr);
|
|
return;
|
|
}
|
|
|
|
if (sender.HasAura(1852) && type != ChatMsg.Whisper)
|
|
{
|
|
SendNotification(Global.ObjectMgr.GetCypherString(CypherStrings.GmSilence), sender.GetName());
|
|
return;
|
|
}
|
|
|
|
if (string.IsNullOrEmpty(msg))
|
|
return;
|
|
|
|
if (new CommandHandler(this).ParseCommand(msg))
|
|
return;
|
|
|
|
switch (type)
|
|
{
|
|
case ChatMsg.Say:
|
|
// Prevent cheating
|
|
if (!sender.IsAlive())
|
|
return;
|
|
|
|
if (sender.GetLevel() < WorldConfig.GetIntValue(WorldCfg.ChatSayLevelReq))
|
|
{
|
|
SendNotification(Global.ObjectMgr.GetCypherString(CypherStrings.SayReq), WorldConfig.GetIntValue(WorldCfg.ChatSayLevelReq));
|
|
return;
|
|
}
|
|
|
|
sender.Say(msg, lang);
|
|
break;
|
|
case ChatMsg.Emote:
|
|
// Prevent cheating
|
|
if (!sender.IsAlive())
|
|
return;
|
|
|
|
if (sender.GetLevel() < WorldConfig.GetIntValue(WorldCfg.ChatEmoteLevelReq))
|
|
{
|
|
SendNotification(Global.ObjectMgr.GetCypherString(CypherStrings.SayReq), WorldConfig.GetIntValue(WorldCfg.ChatEmoteLevelReq));
|
|
return;
|
|
}
|
|
|
|
sender.TextEmote(msg);
|
|
break;
|
|
case ChatMsg.Yell:
|
|
// Prevent cheating
|
|
if (!sender.IsAlive())
|
|
return;
|
|
|
|
if (sender.GetLevel() < WorldConfig.GetIntValue(WorldCfg.ChatYellLevelReq))
|
|
{
|
|
SendNotification(Global.ObjectMgr.GetCypherString(CypherStrings.SayReq), WorldConfig.GetIntValue(WorldCfg.ChatYellLevelReq));
|
|
return;
|
|
}
|
|
|
|
sender.Yell(msg, lang);
|
|
break;
|
|
case ChatMsg.Whisper:
|
|
// @todo implement cross realm whispers (someday)
|
|
ExtendedPlayerName extName = ObjectManager.ExtractExtendedPlayerName(target);
|
|
|
|
if (!ObjectManager.NormalizePlayerName(ref extName.Name))
|
|
{
|
|
SendChatPlayerNotfoundNotice(target);
|
|
break;
|
|
}
|
|
|
|
Player receiver = Global.ObjAccessor.FindPlayerByName(extName.Name);
|
|
if (!receiver || (lang != Language.Addon && !receiver.IsAcceptWhispers() && receiver.GetSession().HasPermission(RBACPermissions.CanFilterWhispers) && !receiver.IsInWhisperWhiteList(sender.GetGUID())))
|
|
{
|
|
SendChatPlayerNotfoundNotice(target);
|
|
return;
|
|
}
|
|
if (!sender.IsGameMaster() && sender.GetLevel() < WorldConfig.GetIntValue(WorldCfg.ChatWhisperLevelReq) && !receiver.IsInWhisperWhiteList(sender.GetGUID()))
|
|
{
|
|
SendNotification(Global.ObjectMgr.GetCypherString(CypherStrings.WhisperReq), WorldConfig.GetIntValue(WorldCfg.ChatWhisperLevelReq));
|
|
return;
|
|
}
|
|
|
|
if (GetPlayer().GetTeam() != receiver.GetTeam() && !HasPermission(RBACPermissions.TwoSideInteractionChat) && !receiver.IsInWhisperWhiteList(sender.GetGUID()))
|
|
{
|
|
SendChatPlayerNotfoundNotice(target);
|
|
return;
|
|
}
|
|
|
|
if (GetPlayer().HasAura(1852) && !receiver.IsGameMaster())
|
|
{
|
|
SendNotification(Global.ObjectMgr.GetCypherString(CypherStrings.GmSilence), GetPlayer().GetName());
|
|
return;
|
|
}
|
|
|
|
if (receiver.GetLevel() < WorldConfig.GetIntValue(WorldCfg.ChatWhisperLevelReq) ||
|
|
(HasPermission(RBACPermissions.CanFilterWhispers) && !sender.IsAcceptWhispers() && !sender.IsInWhisperWhiteList(receiver.GetGUID())))
|
|
sender.AddWhisperWhiteList(receiver.GetGUID());
|
|
|
|
GetPlayer().Whisper(msg, lang, receiver);
|
|
break;
|
|
case ChatMsg.Party:
|
|
{
|
|
// if player is in Battleground, he cannot say to Battlegroundmembers by /p
|
|
Group group = GetPlayer().GetOriginalGroup();
|
|
if (!group)
|
|
{
|
|
group = GetPlayer().GetGroup();
|
|
if (!group || group.IsBGGroup())
|
|
return;
|
|
}
|
|
|
|
if (group.IsLeader(GetPlayer().GetGUID()))
|
|
type = ChatMsg.PartyLeader;
|
|
|
|
Global.ScriptMgr.OnPlayerChat(GetPlayer(), type, lang, msg, group);
|
|
|
|
ChatPkt data = new();
|
|
data.Initialize(type, lang, sender, null, msg);
|
|
group.BroadcastPacket(data, false, group.GetMemberGroup(GetPlayer().GetGUID()));
|
|
}
|
|
break;
|
|
case ChatMsg.Guild:
|
|
if (GetPlayer().GetGuildId() != 0)
|
|
{
|
|
Guild guild = Global.GuildMgr.GetGuildById(GetPlayer().GetGuildId());
|
|
if (guild)
|
|
{
|
|
Global.ScriptMgr.OnPlayerChat(GetPlayer(), type, lang, msg, guild);
|
|
|
|
guild.BroadcastToGuild(this, false, msg, lang == Language.Addon ? Language.Addon : Language.Universal);
|
|
}
|
|
}
|
|
break;
|
|
case ChatMsg.Officer:
|
|
if (GetPlayer().GetGuildId() != 0)
|
|
{
|
|
Guild guild = Global.GuildMgr.GetGuildById(GetPlayer().GetGuildId());
|
|
if (guild)
|
|
{
|
|
Global.ScriptMgr.OnPlayerChat(GetPlayer(), type, lang, msg, guild);
|
|
|
|
guild.BroadcastToGuild(this, true, msg, lang == Language.Addon ? Language.Addon : Language.Universal);
|
|
}
|
|
}
|
|
break;
|
|
case ChatMsg.Raid:
|
|
{
|
|
Group group = GetPlayer().GetGroup();
|
|
if (!group || !group.IsRaidGroup() || group.IsBGGroup())
|
|
return;
|
|
|
|
if (group.IsLeader(GetPlayer().GetGUID()))
|
|
type = ChatMsg.RaidLeader;
|
|
|
|
Global.ScriptMgr.OnPlayerChat(GetPlayer(), type, lang, msg, group);
|
|
|
|
ChatPkt data = new();
|
|
data.Initialize(type, lang, sender, null, msg);
|
|
group.BroadcastPacket(data, false);
|
|
}
|
|
break;
|
|
case ChatMsg.RaidWarning:
|
|
{
|
|
Group group = GetPlayer().GetGroup();
|
|
if (!group || !(group.IsRaidGroup() || WorldConfig.GetBoolValue(WorldCfg.ChatPartyRaidWarnings)) || !(group.IsLeader(GetPlayer().GetGUID()) || group.IsAssistant(GetPlayer().GetGUID())) || group.IsBGGroup())
|
|
return;
|
|
|
|
Global.ScriptMgr.OnPlayerChat(GetPlayer(), type, lang, msg, group);
|
|
|
|
ChatPkt data = new();
|
|
//in Battleground, raid warning is sent only to players in Battleground - code is ok
|
|
data.Initialize(ChatMsg.RaidWarning, lang, sender, null, msg);
|
|
group.BroadcastPacket(data, false);
|
|
}
|
|
break;
|
|
case ChatMsg.Channel:
|
|
if (!HasPermission(RBACPermissions.SkipCheckChatChannelReq))
|
|
{
|
|
if (GetPlayer().GetLevel() < WorldConfig.GetIntValue(WorldCfg.ChatChannelLevelReq))
|
|
{
|
|
SendNotification(Global.ObjectMgr.GetCypherString(CypherStrings.ChannelReq), WorldConfig.GetIntValue(WorldCfg.ChatChannelLevelReq));
|
|
return;
|
|
}
|
|
}
|
|
Channel chn = !channelGuid.IsEmpty() ? ChannelManager.GetChannelForPlayerByGuid(channelGuid, sender) : ChannelManager.GetChannelForPlayerByNamePart(target, sender);
|
|
if (chn != null)
|
|
{
|
|
Global.ScriptMgr.OnPlayerChat(GetPlayer(), type, lang, msg, chn);
|
|
chn.Say(GetPlayer().GetGUID(), msg, lang);
|
|
}
|
|
break;
|
|
case ChatMsg.InstanceChat:
|
|
{
|
|
Group group = GetPlayer().GetGroup();
|
|
if (!group)
|
|
return;
|
|
|
|
if (group.IsLeader(GetPlayer().GetGUID()))
|
|
type = ChatMsg.InstanceChatLeader;
|
|
|
|
Global.ScriptMgr.OnPlayerChat(GetPlayer(), type, lang, msg, group);
|
|
|
|
ChatPkt packet = new();
|
|
packet.Initialize(type, lang, sender, null, msg);
|
|
group.BroadcastPacket(packet, false);
|
|
break;
|
|
}
|
|
default:
|
|
Log.outError(LogFilter.ChatSystem, "CHAT: unknown message type {0}, lang: {1}", type, lang);
|
|
break;
|
|
}
|
|
}
|
|
|
|
[WorldPacketHandler(ClientOpcodes.ChatAddonMessage)]
|
|
void HandleChatAddonMessage(ChatAddonMessage chatAddonMessage)
|
|
{
|
|
HandleChatAddon(chatAddonMessage.Params.Type, chatAddonMessage.Params.Prefix, chatAddonMessage.Params.Text, chatAddonMessage.Params.IsLogged);
|
|
}
|
|
|
|
[WorldPacketHandler(ClientOpcodes.ChatAddonMessageTargeted)]
|
|
void HandleChatAddonMessageTargeted(ChatAddonMessageTargeted chatAddonMessageTargeted)
|
|
{
|
|
HandleChatAddon(chatAddonMessageTargeted.Params.Type, chatAddonMessageTargeted.Params.Prefix, chatAddonMessageTargeted.Params.Text, chatAddonMessageTargeted.Params.IsLogged, chatAddonMessageTargeted.Target, chatAddonMessageTargeted.ChannelGUID);
|
|
}
|
|
|
|
void HandleChatAddon(ChatMsg type, string prefix, string text, bool isLogged, string target = "", Optional<ObjectGuid> channelGuid = default)
|
|
{
|
|
Player sender = GetPlayer();
|
|
|
|
if (string.IsNullOrEmpty(prefix) || prefix.Length > 16)
|
|
return;
|
|
|
|
// Disabled addon channel?
|
|
if (!WorldConfig.GetBoolValue(WorldCfg.AddonChannel))
|
|
return;
|
|
|
|
if (prefix == AddonChannelCommandHandler.PREFIX && new AddonChannelCommandHandler(this).ParseCommand(text))
|
|
return;
|
|
|
|
switch (type)
|
|
{
|
|
case ChatMsg.Guild:
|
|
case ChatMsg.Officer:
|
|
if (sender.GetGuildId() != 0)
|
|
{
|
|
Guild guild = Global.GuildMgr.GetGuildById(sender.GetGuildId());
|
|
if (guild)
|
|
guild.BroadcastAddonToGuild(this, type == ChatMsg.Officer, text, prefix, isLogged);
|
|
}
|
|
break;
|
|
case ChatMsg.Whisper:
|
|
// @todo implement cross realm whispers (someday)
|
|
ExtendedPlayerName extName = ObjectManager.ExtractExtendedPlayerName(target);
|
|
|
|
if (!ObjectManager.NormalizePlayerName(ref extName.Name))
|
|
break;
|
|
|
|
Player receiver = Global.ObjAccessor.FindPlayerByName(extName.Name);
|
|
if (!receiver)
|
|
break;
|
|
|
|
sender.WhisperAddon(text, prefix, isLogged, receiver);
|
|
break;
|
|
// Messages sent to "RAID" while in a party will get delivered to "PARTY"
|
|
case ChatMsg.Party:
|
|
case ChatMsg.Raid:
|
|
case ChatMsg.InstanceChat:
|
|
{
|
|
Group group = null;
|
|
int subGroup = -1;
|
|
if (type != ChatMsg.InstanceChat)
|
|
group = sender.GetOriginalGroup();
|
|
|
|
if (!group)
|
|
{
|
|
group = sender.GetGroup();
|
|
if (!group)
|
|
break;
|
|
|
|
if (type == ChatMsg.Party)
|
|
subGroup = sender.GetSubGroup();
|
|
}
|
|
|
|
ChatPkt data = new();
|
|
data.Initialize(type, isLogged ? Language.AddonLogged : Language.Addon, sender, null, text, 0, "", Locale.enUS, prefix);
|
|
group.BroadcastAddonMessagePacket(data, prefix, true, subGroup, sender.GetGUID());
|
|
break;
|
|
}
|
|
case ChatMsg.Channel:
|
|
Channel chn = channelGuid.HasValue ? ChannelManager.GetChannelForPlayerByGuid(channelGuid.Value, sender) : ChannelManager.GetChannelForPlayerByNamePart(target, sender);
|
|
if (chn != null)
|
|
chn.AddonSay(sender.GetGUID(), prefix, text, isLogged);
|
|
break;
|
|
|
|
default:
|
|
Log.outError(LogFilter.Server, "HandleAddonMessagechat: unknown addon message type {0}", type);
|
|
break;
|
|
}
|
|
}
|
|
|
|
[WorldPacketHandler(ClientOpcodes.ChatMessageAfk)]
|
|
void HandleChatMessageAFK(ChatMessageAFK packet)
|
|
{
|
|
Player sender = GetPlayer();
|
|
|
|
if (sender.IsInCombat())
|
|
return;
|
|
|
|
if (sender.HasAura(1852))
|
|
{
|
|
SendNotification(CypherStrings.GmSilence, sender.GetName());
|
|
return;
|
|
}
|
|
|
|
if (sender.IsAFK()) // Already AFK
|
|
{
|
|
if (string.IsNullOrEmpty(packet.Text))
|
|
sender.ToggleAFK(); // Remove AFK
|
|
else
|
|
sender.autoReplyMsg = packet.Text; // Update message
|
|
}
|
|
else // New AFK mode
|
|
{
|
|
sender.autoReplyMsg = string.IsNullOrEmpty(packet.Text) ? Global.ObjectMgr.GetCypherString(CypherStrings.PlayerAfkDefault) : packet.Text;
|
|
|
|
if (sender.IsDND())
|
|
sender.ToggleDND();
|
|
|
|
sender.ToggleAFK();
|
|
}
|
|
|
|
Guild guild = sender.GetGuild();
|
|
if (guild != null)
|
|
guild.SendEventAwayChanged(sender.GetGUID(), sender.IsAFK(), sender.IsDND());
|
|
|
|
Global.ScriptMgr.OnPlayerChat(sender, ChatMsg.Afk, Language.Universal, packet.Text);
|
|
}
|
|
|
|
[WorldPacketHandler(ClientOpcodes.ChatMessageDnd)]
|
|
void HandleChatMessageDND(ChatMessageDND packet)
|
|
{
|
|
Player sender = GetPlayer();
|
|
|
|
if (sender.IsInCombat())
|
|
return;
|
|
|
|
if (sender.HasAura(1852))
|
|
{
|
|
SendNotification(CypherStrings.GmSilence, sender.GetName());
|
|
return;
|
|
}
|
|
|
|
if (sender.IsDND()) // Already DND
|
|
{
|
|
if (string.IsNullOrEmpty(packet.Text))
|
|
sender.ToggleDND(); // Remove DND
|
|
else
|
|
sender.autoReplyMsg = packet.Text; // Update message
|
|
}
|
|
else // New DND mode
|
|
{
|
|
sender.autoReplyMsg = string.IsNullOrEmpty(packet.Text) ? Global.ObjectMgr.GetCypherString(CypherStrings.PlayerDndDefault) : packet.Text;
|
|
|
|
if (sender.IsAFK())
|
|
sender.ToggleAFK();
|
|
|
|
sender.ToggleDND();
|
|
}
|
|
|
|
Guild guild = sender.GetGuild();
|
|
if (guild != null)
|
|
guild.SendEventAwayChanged(sender.GetGUID(), sender.IsAFK(), sender.IsDND());
|
|
|
|
Global.ScriptMgr.OnPlayerChat(sender, ChatMsg.Dnd, Language.Universal, packet.Text);
|
|
}
|
|
|
|
[WorldPacketHandler(ClientOpcodes.Emote, Processing = PacketProcessing.Inplace)]
|
|
void HandleEmote(EmoteClient packet)
|
|
{
|
|
if (!GetPlayer().IsAlive() || GetPlayer().HasUnitState(UnitState.Died))
|
|
return;
|
|
|
|
Global.ScriptMgr.OnPlayerClearEmote(GetPlayer());
|
|
GetPlayer().SetEmoteState(Emote.OneshotNone);
|
|
}
|
|
|
|
[WorldPacketHandler(ClientOpcodes.SendTextEmote, Processing = PacketProcessing.Inplace)]
|
|
void HandleTextEmote(CTextEmote packet)
|
|
{
|
|
if (!GetPlayer().IsAlive())
|
|
return;
|
|
|
|
if (!CanSpeak())
|
|
{
|
|
string timeStr = Time.secsToTimeString((ulong)(m_muteTime - GameTime.GetGameTime()));
|
|
SendNotification(CypherStrings.WaitBeforeSpeaking, timeStr);
|
|
return;
|
|
}
|
|
|
|
Global.ScriptMgr.OnPlayerTextEmote(GetPlayer(), (uint)packet.SoundIndex, (uint)packet.EmoteID, packet.Target);
|
|
|
|
EmotesTextRecord em = CliDB.EmotesTextStorage.LookupByKey(packet.EmoteID);
|
|
if (em == null)
|
|
return;
|
|
|
|
Emote emoteAnim = (Emote)em.EmoteId;
|
|
|
|
switch (emoteAnim)
|
|
{
|
|
case Emote.StateSleep:
|
|
case Emote.StateSit:
|
|
case Emote.StateKneel:
|
|
case Emote.OneshotNone:
|
|
break;
|
|
case Emote.StateDance:
|
|
case Emote.StateRead:
|
|
GetPlayer().SetEmoteState(emoteAnim);
|
|
break;
|
|
default:
|
|
// Only allow text-emotes for "dead" entities (feign death included)
|
|
if (GetPlayer().HasUnitState(UnitState.Died))
|
|
break;
|
|
GetPlayer().HandleEmoteCommand(emoteAnim, packet.SpellVisualKitIDs);
|
|
break;
|
|
}
|
|
|
|
STextEmote textEmote = new();
|
|
textEmote.SourceGUID = GetPlayer().GetGUID();
|
|
textEmote.SourceAccountGUID = GetAccountGUID();
|
|
textEmote.TargetGUID = packet.Target;
|
|
textEmote.EmoteID = packet.EmoteID;
|
|
textEmote.SoundIndex = packet.SoundIndex;
|
|
GetPlayer().SendMessageToSetInRange(textEmote, WorldConfig.GetFloatValue(WorldCfg.ListenRangeTextemote), true);
|
|
|
|
Unit unit = Global.ObjAccessor.GetUnit(GetPlayer(), packet.Target);
|
|
|
|
GetPlayer().UpdateCriteria(CriteriaType.DoEmote, (uint)packet.EmoteID, 0, 0, unit);
|
|
|
|
// Send scripted event call
|
|
if (unit)
|
|
{
|
|
Creature creature = unit.ToCreature();
|
|
if (creature)
|
|
creature.GetAI().ReceiveEmote(GetPlayer(), (TextEmotes)packet.EmoteID);
|
|
}
|
|
|
|
if (emoteAnim != Emote.OneshotNone)
|
|
_player.RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags.Anim);
|
|
}
|
|
|
|
[WorldPacketHandler(ClientOpcodes.ChatReportIgnored)]
|
|
void HandleChatIgnoredOpcode(ChatReportIgnored packet)
|
|
{
|
|
Player player = Global.ObjAccessor.FindPlayer(packet.IgnoredGUID);
|
|
if (!player || player.GetSession() == null)
|
|
return;
|
|
|
|
ChatPkt data = new();
|
|
data.Initialize(ChatMsg.Ignored, Language.Universal, GetPlayer(), GetPlayer(), GetPlayer().GetName());
|
|
player.SendPacket(data);
|
|
}
|
|
|
|
void SendChatPlayerNotfoundNotice(string name)
|
|
{
|
|
SendPacket(new ChatPlayerNotfound(name));
|
|
}
|
|
|
|
void SendPlayerAmbiguousNotice(string name)
|
|
{
|
|
SendPacket(new ChatPlayerAmbiguous(name));
|
|
}
|
|
|
|
void SendChatRestricted(ChatRestrictionType restriction)
|
|
{
|
|
SendPacket(new ChatRestricted(restriction));
|
|
}
|
|
|
|
}
|
|
}
|