Advertisement
Guest User

ChatHandler.cpp

a guest
Dec 12th, 2015
156
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 25.38 KB | None | 0 0
  1. /*
  2.  * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/>
  3.  * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
  4.  *
  5.  * This program is free software; you can redistribute it and/or modify it
  6.  * under the terms of the GNU General Public License as published by the
  7.  * Free Software Foundation; either version 2 of the License, or (at your
  8.  * option) any later version.
  9.  *
  10.  * This program is distributed in the hope that it will be useful, but WITHOUT
  11.  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  12.  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  13.  * more details.
  14.  *
  15.  * You should have received a copy of the GNU General Public License along
  16.  * with this program. If not, see <http://www.gnu.org/licenses/>.
  17.  */
  18.  
  19. #include "Common.h"
  20. #include "ObjectAccessor.h"
  21. #include "ObjectMgr.h"
  22. #include "GuildMgr.h"
  23. #include "World.h"
  24. #include "WorldPacket.h"
  25. #include "WorldSession.h"
  26. #include "DatabaseEnv.h"
  27. #include "CellImpl.h"
  28. #include "Chat.h"
  29. #include "ChannelMgr.h"
  30. #include "GridNotifiersImpl.h"
  31. #include "Group.h"
  32. #include "Guild.h"
  33. #include "Language.h"
  34. #include "Log.h"
  35. #include "Opcodes.h"
  36. #include "Player.h"
  37. #include "SpellAuraEffects.h"
  38. #include "Util.h"
  39. #include "ScriptMgr.h"
  40. #include "AccountMgr.h"
  41. #ifdef ELUNA
  42. #include "LuaEngine.h"
  43. #endif
  44.  
  45. void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData)
  46. {
  47.     uint32 type;
  48.     uint32 lang;
  49.  
  50.     recvData >> type;
  51.     recvData >> lang;
  52.  
  53.     if (type >= MAX_CHAT_MSG_TYPE)
  54.     {
  55.         TC_LOG_ERROR("network", "CHAT: Wrong message type received: %u", type);
  56.         recvData.rfinish();
  57.         return;
  58.     }
  59.  
  60.     if (lang == LANG_UNIVERSAL && type != CHAT_MSG_AFK && type != CHAT_MSG_DND)
  61.     {
  62.         TC_LOG_ERROR("network", "CMSG_MESSAGECHAT: Possible hacking-attempt: %s tried to send a message in universal language", GetPlayerInfo().c_str());
  63.         SendNotification(LANG_UNKNOWN_LANGUAGE);
  64.         recvData.rfinish();
  65.         return;
  66.     }
  67.  
  68.     Player* sender = GetPlayer();
  69.  
  70.     //TC_LOG_DEBUG("CHAT: packet received. type %u, lang %u", type, lang);
  71.  
  72.     // prevent talking at unknown language (cheating)
  73.     LanguageDesc const* langDesc = GetLanguageDescByID(lang);
  74.     if (!langDesc)
  75.     {
  76.         SendNotification(LANG_UNKNOWN_LANGUAGE);
  77.         recvData.rfinish();
  78.         return;
  79.     }
  80.  
  81.     if (langDesc->skill_id != 0 && !sender->HasSkill(langDesc->skill_id))
  82.     {
  83.         // also check SPELL_AURA_COMPREHEND_LANGUAGE (client offers option to speak in that language)
  84.         Unit::AuraEffectList const& langAuras = sender->GetAuraEffectsByType(SPELL_AURA_COMPREHEND_LANGUAGE);
  85.         bool foundAura = false;
  86.         for (Unit::AuraEffectList::const_iterator i = langAuras.begin(); i != langAuras.end(); ++i)
  87.         {
  88.             if ((*i)->GetMiscValue() == int32(lang))
  89.             {
  90.                 foundAura = true;
  91.                 break;
  92.             }
  93.         }
  94.         if (!foundAura)
  95.         {
  96.             SendNotification(LANG_NOT_LEARNED_LANGUAGE);
  97.             recvData.rfinish();
  98.             return;
  99.         }
  100.     }
  101.  
  102.     if (lang == LANG_ADDON)
  103.     {
  104.         // LANG_ADDON is only valid for the following message types
  105.         switch (type)
  106.         {
  107.             case CHAT_MSG_PARTY:
  108.             case CHAT_MSG_RAID:
  109.             case CHAT_MSG_GUILD:
  110.             case CHAT_MSG_BATTLEGROUND:
  111.             case CHAT_MSG_WHISPER:
  112.                 // check if addon messages are disabled
  113.                 if (!sWorld->getBoolConfig(CONFIG_ADDON_CHANNEL))
  114.                 {
  115.                     recvData.rfinish();
  116.                     return;
  117.                 }
  118.                 break;
  119.             default:
  120.                 TC_LOG_ERROR("network", "Player %s (GUID: %u) sent a chatmessage with an invalid language/message type combination",
  121.                                                      GetPlayer()->GetName().c_str(), GetPlayer()->GetGUIDLow());
  122.  
  123.                 recvData.rfinish();
  124.                 return;
  125.         }
  126.     }
  127.     // LANG_ADDON should not be changed nor be affected by flood control
  128.     else
  129.     {
  130.         // send in universal language if player in .gmon mode (ignore spell effects)
  131.         if (sender->IsGameMaster())
  132.             lang = LANG_UNIVERSAL;
  133.         else
  134.         {
  135.             Unit::AuraEffectList const& ModLangAuras = sender->GetAuraEffectsByType(SPELL_AURA_MOD_LANGUAGE);
  136.             if (!ModLangAuras.empty())
  137.                 lang = ModLangAuras.front()->GetMiscValue();
  138.             else if (HasPermission(rbac::RBAC_PERM_TWO_SIDE_INTERACTION_CHAT))
  139.                 lang = LANG_UNIVERSAL;
  140.             else
  141.             {
  142.                 switch (type)
  143.                 {
  144.                     case CHAT_MSG_PARTY:
  145.                     case CHAT_MSG_PARTY_LEADER:
  146.                     case CHAT_MSG_RAID:
  147.                     case CHAT_MSG_RAID_LEADER:
  148.                     case CHAT_MSG_RAID_WARNING:
  149.                         // allow two side chat at group channel if two side group allowed
  150.                         if (sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GROUP))
  151.                             lang = LANG_UNIVERSAL;
  152.                         break;
  153.                     case CHAT_MSG_GUILD:
  154.                     case CHAT_MSG_OFFICER:
  155.                         // allow two side chat at guild channel if two side guild allowed
  156.                         if (sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD))
  157.                             lang = LANG_UNIVERSAL;
  158.                         break;
  159.                 }
  160.             }
  161.         }
  162.  
  163.         if (!sender->CanSpeak())
  164.         {
  165.             std::string timeStr = secsToTimeString(m_muteTime - time(NULL));
  166.             SendNotification(GetTrinityString(LANG_WAIT_BEFORE_SPEAKING), timeStr.c_str());
  167.             recvData.rfinish(); // Prevent warnings
  168.             return;
  169.         }
  170.  
  171.         if (type != CHAT_MSG_AFK && type != CHAT_MSG_DND)
  172.             sender->UpdateSpeakTime();
  173.     }
  174.  
  175.     if (sender->HasAura(1852) && type != CHAT_MSG_WHISPER)
  176.     {
  177.         SendNotification(GetTrinityString(LANG_GM_SILENCE), sender->GetName().c_str());
  178.         recvData.rfinish();
  179.         return;
  180.     }
  181.  
  182.     std::string to, channel, msg;
  183.     bool ignoreChecks = false;
  184.     switch (type)
  185.     {
  186.         case CHAT_MSG_SAY:
  187.         case CHAT_MSG_EMOTE:
  188.         case CHAT_MSG_YELL:
  189.         case CHAT_MSG_PARTY:
  190.         case CHAT_MSG_PARTY_LEADER:
  191.         case CHAT_MSG_GUILD:
  192.         case CHAT_MSG_OFFICER:
  193.         case CHAT_MSG_RAID:
  194.         case CHAT_MSG_RAID_LEADER:
  195.         case CHAT_MSG_RAID_WARNING:
  196.         case CHAT_MSG_BATTLEGROUND:
  197.         case CHAT_MSG_BATTLEGROUND_LEADER:
  198.             recvData >> msg;
  199.             break;
  200.         case CHAT_MSG_WHISPER:
  201.             recvData >> to;
  202.             recvData >> msg;
  203.             break;
  204.         case CHAT_MSG_CHANNEL:
  205.             recvData >> channel;
  206.             recvData >> msg;
  207.             break;
  208.         case CHAT_MSG_AFK:
  209.         case CHAT_MSG_DND:
  210.             recvData >> msg;
  211.             ignoreChecks = true;
  212.             break;
  213.     }
  214.  
  215.     if (!ignoreChecks)
  216.     {
  217.         if (msg.empty())
  218.             return;
  219.  
  220.         if (ChatHandler(this).ParseCommands(msg.c_str()))
  221.             return;
  222.  
  223.         if (lang != LANG_ADDON)
  224.         {
  225.             // Strip invisible characters for non-addon messages
  226.             if (sWorld->getBoolConfig(CONFIG_CHAT_FAKE_MESSAGE_PREVENTING))
  227.                 stripLineInvisibleChars(msg);
  228.  
  229.             if (sWorld->getIntConfig(CONFIG_CHAT_STRICT_LINK_CHECKING_SEVERITY) && !ChatHandler(this).isValidChatMessage(msg.c_str()))
  230.             {
  231.                 TC_LOG_ERROR("network", "Player %s (GUID: %u) sent a chatmessage with an invalid link: %s", GetPlayer()->GetName().c_str(),
  232.                     GetPlayer()->GetGUIDLow(), msg.c_str());
  233.  
  234.                 if (sWorld->getIntConfig(CONFIG_CHAT_STRICT_LINK_CHECKING_KICK))
  235.                     KickPlayer();
  236.  
  237.                 return;
  238.             }
  239.         }
  240.     }
  241.  
  242.     switch (type)
  243.     {
  244.         case CHAT_MSG_SAY:
  245.         case CHAT_MSG_EMOTE:
  246.         case CHAT_MSG_YELL:
  247.         {
  248.             // Prevent cheating
  249.             if (!sender->IsAlive())
  250.                 return;
  251.  
  252.             if (sender->getLevel() < sWorld->getIntConfig(CONFIG_CHAT_SAY_LEVEL_REQ))
  253.             {
  254.                 SendNotification(GetTrinityString(LANG_SAY_REQ), sWorld->getIntConfig(CONFIG_CHAT_SAY_LEVEL_REQ));
  255.                 return;
  256.             }
  257.             if (!GetPlayer()->IsGameMaster())
  258.                 if (GetPlayer()->SendBattleGroundChat(type, msg))
  259.                 return;
  260.  
  261.             if (type == CHAT_MSG_SAY)
  262.             {
  263. #ifdef ELUNA
  264.                 if (!sEluna->OnChat(sender, type, lang, msg))
  265.                     return;
  266. #endif
  267.                 sender->Say(msg, Language(lang));
  268.             }
  269.             else if (type == CHAT_MSG_EMOTE)
  270.             {
  271. #ifdef ELUNA
  272.                 if (!sEluna->OnChat(sender, type, LANG_UNIVERSAL, msg))
  273.                     return;
  274. #endif
  275.                 sender->TextEmote(msg);
  276.             }
  277.             else if (type == CHAT_MSG_YELL)
  278.             {
  279. #ifdef ELUNA
  280.                 if (!sEluna->OnChat(sender, type, lang, msg))
  281.                     return;
  282. #endif
  283.                 sender->Yell(msg, Language(lang));
  284.             }
  285.         } break;
  286.         case CHAT_MSG_WHISPER:
  287.         {
  288.             if (!normalizePlayerName(to))
  289.             {
  290.                 SendPlayerNotFoundNotice(to);
  291.                 break;
  292.             }
  293.  
  294.             Player* receiver = ObjectAccessor::FindConnectedPlayerByName(to);
  295.             if (!receiver || (lang != LANG_ADDON && !receiver->isAcceptWhispers() && receiver->GetSession()->HasPermission(rbac::RBAC_PERM_CAN_FILTER_WHISPERS) && !receiver->IsInWhisperWhiteList(sender->GetGUID())))
  296.             {
  297.                 SendPlayerNotFoundNotice(to);
  298.                 return;
  299.             }
  300.             if (!sender->IsGameMaster() && sender->getLevel() < sWorld->getIntConfig(CONFIG_CHAT_WHISPER_LEVEL_REQ) && !receiver->IsInWhisperWhiteList(sender->GetGUID()))
  301.             {
  302.                 SendNotification(GetTrinityString(LANG_WHISPER_REQ), sWorld->getIntConfig(CONFIG_CHAT_WHISPER_LEVEL_REQ));
  303.                 return;
  304.             }
  305.  
  306.             if (GetPlayer()->GetTeam() != receiver->GetTeam() && !HasPermission(rbac::RBAC_PERM_TWO_SIDE_INTERACTION_CHAT) && !receiver->IsInWhisperWhiteList(sender->GetGUID()))
  307.             {
  308.                 SendWrongFactionNotice();
  309.                 return;
  310.             }
  311.  
  312.             if (GetPlayer()->HasAura(1852) && !receiver->IsGameMaster())
  313.             {
  314.                 SendNotification(GetTrinityString(LANG_GM_SILENCE), GetPlayer()->GetName().c_str());
  315.                 return;
  316.             }
  317.  
  318.             // If player is a Gamemaster and doesn't accept whisper, we auto-whitelist every player that the Gamemaster is talking to
  319.             // We also do that if a player is under the required level for whispers.
  320.             if (receiver->getLevel() < sWorld->getIntConfig(CONFIG_CHAT_WHISPER_LEVEL_REQ) ||
  321.                 (HasPermission(rbac::RBAC_PERM_CAN_FILTER_WHISPERS) && !sender->isAcceptWhispers() && !sender->IsInWhisperWhiteList(receiver->GetGUID())))
  322.                 sender->AddWhisperWhiteList(receiver->GetGUID());
  323.  
  324. #ifdef ELUNA
  325.             if (!sEluna->OnChat(GetPlayer(), type, lang, msg, receiver))
  326.                 return;
  327. #endif
  328.             GetPlayer()->Whisper(msg, Language(lang), receiver);
  329.         } break;
  330.         case CHAT_MSG_PARTY:
  331.         case CHAT_MSG_PARTY_LEADER:
  332.         {
  333.             // if player is in battleground, he cannot say to battleground members by /p
  334.             Group* group = GetPlayer()->GetOriginalGroup();
  335.             if (!group)
  336.             {
  337.                 group = sender->GetGroup();
  338.                 if (!group || group->isBGGroup())
  339.                     return;
  340.             }
  341.  
  342.             if (type == CHAT_MSG_PARTY_LEADER && !group->IsLeader(sender->GetGUID()))
  343.                 return;
  344.  
  345.             sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, group);
  346. #ifdef ELUNA
  347.             if(!sEluna->OnChat(sender, type, lang, msg, group))
  348.                 return;
  349. #endif
  350.  
  351.             WorldPacket data;
  352.             ChatHandler::BuildChatPacket(data, ChatMsg(type), Language(lang), sender, NULL, msg);
  353.             group->BroadcastPacket(&data, false, group->GetMemberGroup(GetPlayer()->GetGUID()));
  354.         } break;
  355.         case CHAT_MSG_GUILD:
  356.         {
  357.             if (GetPlayer()->GetGuildId())
  358.             {
  359.                 if (Guild* guild = sGuildMgr->GetGuildById(GetPlayer()->GetGuildId()))
  360.                 {
  361.                     sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, guild);
  362. #ifdef ELUNA
  363.                     if(!sEluna->OnChat(sender, type, lang, msg, guild))
  364.                         return;
  365. #endif
  366.  
  367.                     guild->BroadcastToGuild(this, false, msg, lang == LANG_ADDON ? LANG_ADDON : LANG_UNIVERSAL);
  368.                 }
  369.             }
  370.         } break;
  371.         case CHAT_MSG_OFFICER:
  372.         {
  373.             if (GetPlayer()->GetGuildId())
  374.             {
  375.                 if (Guild* guild = sGuildMgr->GetGuildById(GetPlayer()->GetGuildId()))
  376.                 {
  377.                     sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, guild);
  378. #ifdef ELUNA
  379.                     if(!sEluna->OnChat(sender, type, lang, msg, guild))
  380.                         return;
  381. #endif
  382.  
  383.                     guild->BroadcastToGuild(this, true, msg, lang == LANG_ADDON ? LANG_ADDON : LANG_UNIVERSAL);
  384.                 }
  385.             }
  386.         } break;
  387.         case CHAT_MSG_RAID:
  388.         {
  389.             // if player is in battleground, he cannot say to battleground members by /ra
  390.             Group* group = GetPlayer()->GetOriginalGroup();
  391.             if (!group)
  392.             {
  393.                 group = GetPlayer()->GetGroup();
  394.                 if (!group || group->isBGGroup() || !group->isRaidGroup())
  395.                     return;
  396.             }
  397.  
  398.             sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, group);
  399. #ifdef ELUNA
  400.             if(!sEluna->OnChat(sender, type, lang, msg, group))
  401.                 return;
  402. #endif
  403.  
  404.             WorldPacket data;
  405.             ChatHandler::BuildChatPacket(data, CHAT_MSG_RAID, Language(lang), sender, NULL, msg);
  406.             group->BroadcastPacket(&data, false);
  407.         } break;
  408.         case CHAT_MSG_RAID_LEADER:
  409.         {
  410.             // if player is in battleground, he cannot say to battleground members by /ra
  411.             Group* group = GetPlayer()->GetOriginalGroup();
  412.             if (!group)
  413.             {
  414.                 group = GetPlayer()->GetGroup();
  415.                 if (!group || group->isBGGroup() || !group->isRaidGroup() || !group->IsLeader(sender->GetGUID()))
  416.                     return;
  417.             }
  418.  
  419.             sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, group);
  420. #ifdef ELUNA
  421.             if(!sEluna->OnChat(sender, type, lang, msg, group))
  422.                 return;
  423. #endif
  424.  
  425.             WorldPacket data;
  426.             ChatHandler::BuildChatPacket(data, CHAT_MSG_RAID_LEADER, Language(lang), sender, NULL, msg);
  427.             group->BroadcastPacket(&data, false);
  428.         } break;
  429.         case CHAT_MSG_RAID_WARNING:
  430.         {
  431.             Group* group = GetPlayer()->GetGroup();
  432.             if (!group || !group->isRaidGroup() || !(group->IsLeader(GetPlayer()->GetGUID()) || group->IsAssistant(GetPlayer()->GetGUID())) || group->isBGGroup())
  433.                 return;
  434.  
  435.             sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, group);
  436. #ifdef ELUNA
  437.             if(!sEluna->OnChat(sender, type, lang, msg, group))
  438.                 return;
  439. #endif
  440.  
  441.             WorldPacket data;
  442.             //in battleground, raid warning is sent only to players in battleground - code is ok
  443.             ChatHandler::BuildChatPacket(data, CHAT_MSG_RAID_WARNING, Language(lang), sender, NULL, msg);
  444.             group->BroadcastPacket(&data, false);
  445.         } break;
  446.         case CHAT_MSG_BATTLEGROUND:
  447.         {
  448.             //battleground raid is always in Player->GetGroup(), never in GetOriginalGroup()
  449.             Group* group = GetPlayer()->GetGroup();
  450.             if (!group || !group->isBGGroup())
  451.                 return;
  452.  
  453.             sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, group);
  454. #ifdef ELUNA
  455.             if(!sEluna->OnChat(sender, type, lang, msg, group))
  456.                 return;
  457. #endif
  458.  
  459.             WorldPacket data;
  460.             ChatHandler::BuildChatPacket(data, CHAT_MSG_BATTLEGROUND, Language(lang), sender, NULL, msg);
  461.             group->BroadcastPacket(&data, false);
  462.         } break;
  463.         case CHAT_MSG_BATTLEGROUND_LEADER:
  464.         {
  465.             // battleground raid is always in Player->GetGroup(), never in GetOriginalGroup()
  466.             Group* group = GetPlayer()->GetGroup();
  467.             if (!group || !group->isBGGroup() || !group->IsLeader(GetPlayer()->GetGUID()))
  468.                 return;
  469.  
  470.             sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, group);
  471. #ifdef ELUNA
  472.             if(!sEluna->OnChat(sender, type, lang, msg, group))
  473.                 return;
  474. #endif
  475.  
  476.             WorldPacket data;
  477.             ChatHandler::BuildChatPacket(data, CHAT_MSG_BATTLEGROUND_LEADER, Language(lang), sender, NULL, msg);;
  478.             group->BroadcastPacket(&data, false);
  479.         } break;
  480.         case CHAT_MSG_CHANNEL:
  481.         {
  482.             if (!HasPermission(rbac::RBAC_PERM_SKIP_CHECK_CHAT_CHANNEL_REQ))
  483.             {
  484.                 if (sender->getLevel() < sWorld->getIntConfig(CONFIG_CHAT_CHANNEL_LEVEL_REQ))
  485.                 {
  486.                     SendNotification(GetTrinityString(LANG_CHANNEL_REQ), sWorld->getIntConfig(CONFIG_CHAT_CHANNEL_LEVEL_REQ));
  487.                     return;
  488.                 }
  489.             }
  490.  
  491.             if (ChannelMgr* cMgr = ChannelMgr::forTeam(sender->GetTeam()))
  492.             {
  493.                 if (Channel* chn = cMgr->GetChannel(channel, sender))
  494.                 {
  495.                     sScriptMgr->OnPlayerChat(sender, type, lang, msg, chn);
  496. #ifdef ELUNA
  497.                     if(!sEluna->OnChat(sender, type, lang, msg, chn))
  498.                         return;
  499. #endif
  500.                     chn->Say(sender->GetGUID(), msg.c_str(), lang);
  501.                 }
  502.             }
  503.         } break;
  504.         case CHAT_MSG_AFK:
  505.         {
  506.             if (!sender->IsInCombat())
  507.             {
  508.                 if (sender->isAFK())                       // Already AFK
  509.                 {
  510.                     if (msg.empty())
  511.                         sender->ToggleAFK();               // Remove AFK
  512.                     else
  513.                         sender->autoReplyMsg = msg;        // Update message
  514.                 }
  515.                 else                                        // New AFK mode
  516.                 {
  517.                     sender->autoReplyMsg = msg.empty() ? GetTrinityString(LANG_PLAYER_AFK_DEFAULT) : msg;
  518.  
  519.                     if (sender->isDND())
  520.                         sender->ToggleDND();
  521.  
  522.                     sender->ToggleAFK();
  523.                 }
  524.  
  525.                 sScriptMgr->OnPlayerChat(sender, type, lang, msg);
  526. #ifdef ELUNA
  527.                 if(!sEluna->OnChat(sender, type, lang, msg))
  528.                     return;
  529. #endif
  530.             }
  531.             break;
  532.         }
  533.         case CHAT_MSG_DND:
  534.         {
  535.             if (sender->isDND())                           // Already DND
  536.             {
  537.                 if (msg.empty())
  538.                     sender->ToggleDND();                   // Remove DND
  539.                 else
  540.                     sender->autoReplyMsg = msg;            // Update message
  541.             }
  542.             else                                            // New DND mode
  543.             {
  544.                 sender->autoReplyMsg = msg.empty() ? GetTrinityString(LANG_PLAYER_DND_DEFAULT) : msg;
  545.  
  546.                 if (sender->isAFK())
  547.                     sender->ToggleAFK();
  548.  
  549.                 sender->ToggleDND();
  550.             }
  551.  
  552.             sScriptMgr->OnPlayerChat(sender, type, lang, msg);
  553. #ifdef ELUNA
  554.             if(!sEluna->OnChat(sender, type, lang, msg))
  555.                 return;
  556. #endif
  557.             break;
  558.         }
  559.         default:
  560.             TC_LOG_ERROR("network", "CHAT: unknown message type %u, lang: %u", type, lang);
  561.             break;
  562.     }
  563. }
  564.  
  565. void WorldSession::HandleEmoteOpcode(WorldPacket& recvData)
  566. {
  567.     if (!GetPlayer()->IsAlive() || GetPlayer()->HasUnitState(UNIT_STATE_DIED))
  568.         return;
  569.  
  570.     uint32 emote;
  571.     recvData >> emote;
  572.     sScriptMgr->OnPlayerEmote(GetPlayer(), emote);
  573.     GetPlayer()->HandleEmoteCommand(emote);
  574. }
  575.  
  576. namespace Trinity
  577. {
  578.     class EmoteChatBuilder
  579.     {
  580.         public:
  581.             EmoteChatBuilder(Player const& player, uint32 text_emote, uint32 emote_num, Unit const* target)
  582.                 : i_player(player), i_text_emote(text_emote), i_emote_num(emote_num), i_target(target) { }
  583.  
  584.             void operator()(WorldPacket& data, LocaleConstant loc_idx)
  585.             {
  586.                 std::string const name(i_target ? i_target->GetNameForLocaleIdx(loc_idx) : "");
  587.                 uint32 namlen = name.size();
  588.  
  589.                 data.Initialize(SMSG_TEXT_EMOTE, 20 + namlen);
  590.                 data << i_player.GetGUID();
  591.                 data << uint32(i_text_emote);
  592.                 data << uint32(i_emote_num);
  593.                 data << uint32(namlen);
  594.                 if (namlen > 1)
  595.                     data << name;
  596.                 else
  597.                     data << uint8(0x00);
  598.             }
  599.  
  600.         private:
  601.             Player const& i_player;
  602.             uint32        i_text_emote;
  603.             uint32        i_emote_num;
  604.             Unit const*   i_target;
  605.     };
  606. }                                                           // namespace Trinity
  607.  
  608. void WorldSession::HandleTextEmoteOpcode(WorldPacket& recvData)
  609. {
  610.     if (!GetPlayer()->IsAlive())
  611.         return;
  612.  
  613.     if (!GetPlayer()->CanSpeak())
  614.     {
  615.         std::string timeStr = secsToTimeString(m_muteTime - time(NULL));
  616.         SendNotification(GetTrinityString(LANG_WAIT_BEFORE_SPEAKING), timeStr.c_str());
  617.         return;
  618.     }
  619.  
  620.     uint32 text_emote, emoteNum;
  621.     ObjectGuid guid;
  622.  
  623.     recvData >> text_emote;
  624.     recvData >> emoteNum;
  625.     recvData >> guid;
  626.    
  627.         if (GetPlayer()->IsSpectator())
  628.          {
  629.         SendNotification(LANG_SPEC_CAN_NOT_CHAT);
  630.         return;
  631.         }
  632.     sScriptMgr->OnPlayerTextEmote(GetPlayer(), text_emote, emoteNum, guid);
  633.  
  634.     EmotesTextEntry const* em = sEmotesTextStore.LookupEntry(text_emote);
  635.     if (!em)
  636.         return;
  637.  
  638.     uint32 emote_anim = em->textid;
  639.  
  640.     switch (emote_anim)
  641.     {
  642.         case EMOTE_STATE_SLEEP:
  643.         case EMOTE_STATE_SIT:
  644.         case EMOTE_STATE_KNEEL:
  645.         case EMOTE_ONESHOT_NONE:
  646.             break;
  647.         default:
  648.             // Only allow text-emotes for "dead" entities (feign death included)
  649.             if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
  650.                 break;
  651.             GetPlayer()->HandleEmoteCommand(emote_anim);
  652.             break;
  653.     }
  654.  
  655.     Unit* unit = ObjectAccessor::GetUnit(*_player, guid);
  656.  
  657.     CellCoord p = Trinity::ComputeCellCoord(GetPlayer()->GetPositionX(), GetPlayer()->GetPositionY());
  658.  
  659.     Cell cell(p);
  660.     cell.SetNoCreate();
  661.  
  662.     Trinity::EmoteChatBuilder emote_builder(*GetPlayer(), text_emote, emoteNum, unit);
  663.     Trinity::LocalizedPacketDo<Trinity::EmoteChatBuilder > emote_do(emote_builder);
  664.     Trinity::PlayerDistWorker<Trinity::LocalizedPacketDo<Trinity::EmoteChatBuilder > > emote_worker(GetPlayer(), sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_TEXTEMOTE), emote_do);
  665.     TypeContainerVisitor<Trinity::PlayerDistWorker<Trinity::LocalizedPacketDo<Trinity::EmoteChatBuilder> >, WorldTypeMapContainer> message(emote_worker);
  666.     cell.Visit(p, message, *GetPlayer()->GetMap(), *GetPlayer(), sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_TEXTEMOTE));
  667.  
  668.     GetPlayer()->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_DO_EMOTE, text_emote, 0, unit);
  669.  
  670.     //Send scripted event call
  671.     if (unit && unit->GetTypeId() == TYPEID_UNIT && ((Creature*)unit)->AI())
  672.         ((Creature*)unit)->AI()->ReceiveEmote(GetPlayer(), text_emote);
  673. }
  674.  
  675. void WorldSession::HandleChatIgnoredOpcode(WorldPacket& recvData)
  676. {
  677.     ObjectGuid iguid;
  678.     uint8 unk;
  679.     //TC_LOG_DEBUG("network", "WORLD: Received CMSG_CHAT_IGNORED");
  680.  
  681.     recvData >> iguid;
  682.     recvData >> unk;                                       // probably related to spam reporting
  683.  
  684.     Player* player = ObjectAccessor::FindConnectedPlayer(iguid);
  685.     if (!player || !player->GetSession())
  686.         return;
  687.  
  688.     WorldPacket data;
  689.     ChatHandler::BuildChatPacket(data, CHAT_MSG_IGNORED, LANG_UNIVERSAL, _player, _player, GetPlayer()->GetName());
  690.     player->GetSession()->SendPacket(&data);
  691. }
  692.  
  693. void WorldSession::HandleChannelDeclineInvite(WorldPacket &recvPacket)
  694. {
  695.     TC_LOG_DEBUG("network", "Opcode %u", recvPacket.GetOpcode());
  696. }
  697.  
  698. void WorldSession::SendPlayerNotFoundNotice(std::string const& name)
  699. {
  700.     WorldPacket data(SMSG_CHAT_PLAYER_NOT_FOUND, name.size()+1);
  701.     data << name;
  702.     SendPacket(&data);
  703. }
  704.  
  705. void WorldSession::SendPlayerAmbiguousNotice(std::string const& name)
  706. {
  707.     WorldPacket data(SMSG_CHAT_PLAYER_AMBIGUOUS, name.size()+1);
  708.     data << name;
  709.     SendPacket(&data);
  710. }
  711.  
  712. void WorldSession::SendWrongFactionNotice()
  713. {
  714.     WorldPacket data(SMSG_CHAT_WRONG_FACTION, 0);
  715.     SendPacket(&data);
  716. }
  717.  
  718. void WorldSession::SendChatRestrictedNotice(ChatRestrictionType restriction)
  719. {
  720.     WorldPacket data(SMSG_CHAT_RESTRICTED, 1);
  721.     data << uint8(restriction);
  722.     SendPacket(&data);
  723. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement