Don't like ads? PRO users don't see any ads ;-)
Guest

Untitled

By: a guest on Aug 19th, 2012  |  syntax: None  |  size: 24.75 KB  |  hits: 8  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. /*
  2.  * Copyright (C) 2008-2012 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.  
  28. #include "CellImpl.h"
  29. #include "Chat.h"
  30. #include "ChannelMgr.h"
  31. #include "GridNotifiersImpl.h"
  32. #include "Group.h"
  33. #include "Guild.h"
  34. #include "Language.h"
  35. #include "Log.h"
  36. #include "Opcodes.h"
  37. #include "Player.h"
  38. #include "SpellAuras.h"
  39. #include "SpellAuraEffects.h"
  40. #include "Util.h"
  41. #include "ScriptMgr.h"
  42. #include "AccountMgr.h"
  43.  
  44. bool WorldSession::processChatmessageFurtherAfterSecurityChecks(std::string& msg, uint32 lang)
  45. {
  46.     if (lang != LANG_ADDON)
  47.     {
  48.         // strip invisible characters for non-addon messages
  49.         if (sWorld->getBoolConfig(CONFIG_CHAT_FAKE_MESSAGE_PREVENTING))
  50.             stripLineInvisibleChars(msg);
  51.  
  52.         if (sWorld->getIntConfig(CONFIG_CHAT_STRICT_LINK_CHECKING_SEVERITY) && AccountMgr::IsPlayerAccount(GetSecurity())
  53.                 && !ChatHandler(this).isValidChatMessage(msg.c_str()))
  54.         {
  55.             sLog->outError(LOG_FILTER_NETWORKIO, "Player %s (GUID: %u) sent a chatmessage with an invalid link: %s", GetPlayer()->GetName(),
  56.                     GetPlayer()->GetGUIDLow(), msg.c_str());
  57.             if (sWorld->getIntConfig(CONFIG_CHAT_STRICT_LINK_CHECKING_KICK))
  58.                 KickPlayer();
  59.             return false;
  60.         }
  61.     }
  62.  
  63.     return true;
  64. }
  65.  
  66. void WorldSession::HandleMessagechatOpcode(WorldPacket & recv_data)
  67. {
  68.     uint32 type;
  69.     uint32 lang;
  70.  
  71.     recv_data >> type;
  72.     recv_data >> lang;
  73.  
  74.     if (type >= MAX_CHAT_MSG_TYPE)
  75.     {
  76.         sLog->outError(LOG_FILTER_NETWORKIO, "CHAT: Wrong message type received: %u", type);
  77.         recv_data.rfinish();
  78.         return;
  79.     }
  80.  
  81.     Player* sender = GetPlayer();
  82.  
  83.     //sLog->outDebug("CHAT: packet received. type %u, lang %u", type, lang);
  84.  
  85.     // prevent talking at unknown language (cheating)
  86.     LanguageDesc const* langDesc = GetLanguageDescByID(lang);
  87.     if (!langDesc)
  88.     {
  89.         SendNotification(LANG_UNKNOWN_LANGUAGE);
  90.         recv_data.rfinish();
  91.         return;
  92.     }
  93.     if (langDesc->skill_id != 0 && !sender->HasSkill(langDesc->skill_id))
  94.     {
  95.         // also check SPELL_AURA_COMPREHEND_LANGUAGE (client offers option to speak in that language)
  96.         Unit::AuraEffectList const& langAuras = sender->GetAuraEffectsByType(SPELL_AURA_COMPREHEND_LANGUAGE);
  97.         bool foundAura = false;
  98.         for (Unit::AuraEffectList::const_iterator i = langAuras.begin(); i != langAuras.end(); ++i)
  99.         {
  100.             if ((*i)->GetMiscValue() == int32(lang))
  101.             {
  102.                 foundAura = true;
  103.                 break;
  104.             }
  105.         }
  106.         if (!foundAura)
  107.         {
  108.             SendNotification(LANG_NOT_LEARNED_LANGUAGE);
  109.             recv_data.rfinish();
  110.             return;
  111.         }
  112.     }
  113.  
  114.     if (lang == LANG_ADDON)
  115.     {
  116.         if (sWorld->getBoolConfig(CONFIG_CHATLOG_ADDON))
  117.         {
  118.             std::string msg = "";
  119.             recv_data >> msg;
  120.  
  121.             if (msg.empty())
  122.                 return;
  123.  
  124.             sScriptMgr->OnPlayerChat(sender, uint32(CHAT_MSG_ADDON), lang, msg);
  125.         }
  126.  
  127.         // Disabled addon channel?
  128.         if (!sWorld->getBoolConfig(CONFIG_ADDON_CHANNEL))
  129.             return;
  130.     }
  131.     // LANG_ADDON should not be changed nor be affected by flood control
  132.     else
  133.     {
  134.         // send in universal language if player in .gmon mode (ignore spell effects)
  135.         if (sender->isGameMaster())
  136.             lang = LANG_UNIVERSAL;
  137.         else
  138.         {
  139.             // send in universal language in two side iteration allowed mode
  140.             if (sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_CHAT))
  141.                 lang = LANG_UNIVERSAL;
  142.             else
  143.             {
  144.                 switch (type)
  145.                 {
  146.                     case CHAT_MSG_PARTY:
  147.                     case CHAT_MSG_PARTY_LEADER:
  148.                     case CHAT_MSG_RAID:
  149.                     case CHAT_MSG_RAID_LEADER:
  150.                     case CHAT_MSG_RAID_WARNING:
  151.                         // allow two side chat at group channel if two side group allowed
  152.                         if (sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GROUP))
  153.                             lang = LANG_UNIVERSAL;
  154.                         break;
  155.                     case CHAT_MSG_GUILD:
  156.                     case CHAT_MSG_OFFICER:
  157.                         // allow two side chat at guild channel if two side guild allowed
  158.                         if (sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD))
  159.                             lang = LANG_UNIVERSAL;
  160.                         break;
  161.                 }
  162.             }
  163.  
  164.             // but overwrite it by SPELL_AURA_MOD_LANGUAGE auras (only single case used)
  165.             Unit::AuraEffectList const& ModLangAuras = sender->GetAuraEffectsByType(SPELL_AURA_MOD_LANGUAGE);
  166.             if (!ModLangAuras.empty())
  167.                 lang = ModLangAuras.front()->GetMiscValue();
  168.         }
  169.  
  170.         if (!sender->CanSpeak())
  171.         {
  172.             std::string timeStr = secsToTimeString(m_muteTime - time(NULL));
  173.             SendNotification(GetTrinityString(LANG_WAIT_BEFORE_SPEAKING), timeStr.c_str());
  174.             recv_data.rfinish(); // Prevent warnings
  175.             return;
  176.         }
  177.  
  178.         if (type != CHAT_MSG_AFK && type != CHAT_MSG_DND)
  179.             sender->UpdateSpeakTime();
  180.     }
  181.  
  182.     if (sender->HasAura(1852) && type != CHAT_MSG_WHISPER)
  183.     {
  184.         std::string msg="";
  185.         recv_data >> msg;
  186.  
  187.         SendNotification(GetTrinityString(LANG_GM_SILENCE), sender->GetName());
  188.         return;
  189.     }
  190.  
  191.     std::string to, channel, msg;
  192.     bool ignoreChecks = false;
  193.     switch (type)
  194.     {
  195.         case CHAT_MSG_SAY:
  196.         case CHAT_MSG_EMOTE:
  197.         case CHAT_MSG_YELL:
  198.         case CHAT_MSG_PARTY:
  199.         case CHAT_MSG_PARTY_LEADER:
  200.         case CHAT_MSG_GUILD:
  201.         case CHAT_MSG_OFFICER:
  202.         case CHAT_MSG_RAID:
  203.         case CHAT_MSG_RAID_LEADER:
  204.         case CHAT_MSG_RAID_WARNING:
  205.         case CHAT_MSG_BATTLEGROUND:
  206.         case CHAT_MSG_BATTLEGROUND_LEADER:
  207.             recv_data >> msg;
  208.             break;
  209.         case CHAT_MSG_WHISPER:
  210.             recv_data >> to;
  211.             recv_data >> msg;
  212.             break;
  213.         case CHAT_MSG_CHANNEL:
  214.             recv_data >> channel;
  215.             recv_data >> msg;
  216.             break;
  217.         case CHAT_MSG_AFK:
  218.         case CHAT_MSG_DND:
  219.             recv_data >> msg;
  220.             ignoreChecks = true;
  221.             break;
  222.     }
  223.  
  224.     if (!ignoreChecks)
  225.     {
  226.         if (msg.empty())
  227.             return;
  228.  
  229.         if (ChatHandler(this).ParseCommands(msg.c_str()) > 0)
  230.             return;
  231.  
  232.         if (!processChatmessageFurtherAfterSecurityChecks(msg, lang))
  233.             return;
  234.  
  235.         if (msg.empty())
  236.             return;
  237.     }
  238.  
  239.     switch (type)
  240.     {
  241.         case CHAT_MSG_SAY:
  242.         case CHAT_MSG_EMOTE:
  243.         case CHAT_MSG_YELL:
  244.         {
  245.             if (sender->getLevel() < sWorld->getIntConfig(CONFIG_CHAT_SAY_LEVEL_REQ))
  246.             {
  247.                 SendNotification(GetTrinityString(LANG_SAY_REQ), sWorld->getIntConfig(CONFIG_CHAT_SAY_LEVEL_REQ));
  248.                 return;
  249.             }
  250.  
  251.             if (type == CHAT_MSG_SAY)
  252.                 sender->Say(msg, lang);
  253.             else if (type == CHAT_MSG_EMOTE)
  254.                 sender->TextEmote(msg);
  255.             else if (type == CHAT_MSG_YELL)
  256.                 sender->Yell(msg, lang);
  257.         } break;
  258.         case CHAT_MSG_WHISPER:
  259.         {
  260.             if (sender->getLevel() < sWorld->getIntConfig(CONFIG_CHAT_WHISPER_LEVEL_REQ))
  261.             {
  262.                 SendNotification(GetTrinityString(LANG_WHISPER_REQ), sWorld->getIntConfig(CONFIG_CHAT_WHISPER_LEVEL_REQ));
  263.                 return;
  264.             }
  265.  
  266.             if (!normalizePlayerName(to))
  267.             {
  268.                 SendPlayerNotFoundNotice(to);
  269.                 break;
  270.             }
  271.  
  272.             Player* receiver = sObjectAccessor->FindPlayerByName(to.c_str());
  273.             bool senderIsPlayer = AccountMgr::IsPlayerAccount(GetSecurity());
  274.             bool receiverIsPlayer = AccountMgr::IsPlayerAccount(receiver ? receiver->GetSession()->GetSecurity() : SEC_PLAYER);
  275.             if (!receiver || (senderIsPlayer && !receiverIsPlayer && !receiver->isAcceptWhispers() && !receiver->IsInWhisperWhiteList(sender->GetGUID())))
  276.             {
  277.                 SendPlayerNotFoundNotice(to);
  278.                 return;
  279.             }
  280.  
  281.             if (!sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_CHAT) && senderIsPlayer && receiverIsPlayer)
  282.                 if (GetPlayer()->GetTeam() != receiver->GetTeam())
  283.                 {
  284.                     SendWrongFactionNotice();
  285.                     return;
  286.                 }
  287.  
  288.             if (GetPlayer()->HasAura(1852) && !receiver->isGameMaster())
  289.             {
  290.                 SendNotification(GetTrinityString(LANG_GM_SILENCE), GetPlayer()->GetName());
  291.                 return;
  292.             }
  293.  
  294.             // If player is a Gamemaster and doesn't accept whisper, we auto-whitelist every player that the Gamemaster is talking to
  295.             if (!senderIsPlayer && !sender->isAcceptWhispers() && !sender->IsInWhisperWhiteList(receiver->GetGUID()))
  296.                 sender->AddWhisperWhiteList(receiver->GetGUID());
  297.  
  298.             GetPlayer()->Whisper(msg, lang, receiver->GetGUID());
  299.         } break;
  300.         case CHAT_MSG_PARTY:
  301.         case CHAT_MSG_PARTY_LEADER:
  302.         {
  303.             // if player is in battleground, he cannot say to battleground members by /p
  304.             Group* group = GetPlayer()->GetOriginalGroup();
  305.             if (!group)
  306.             {
  307.                 group = _player->GetGroup();
  308.                 if (!group || group->isBGGroup())
  309.                     return;
  310.             }
  311.  
  312.             if (type == CHAT_MSG_PARTY_LEADER && !group->IsLeader(_player->GetGUID()))
  313.                 return;
  314.  
  315.             sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, group);
  316.  
  317.             WorldPacket data;
  318.             ChatHandler::FillMessageData(&data, this, uint8(type), lang, NULL, 0, msg.c_str(), NULL);
  319.             group->BroadcastPacket(&data, false, group->GetMemberGroup(GetPlayer()->GetGUID()));
  320.         } break;
  321.         case CHAT_MSG_GUILD:
  322.         {
  323.             if (GetPlayer()->GetGuildId())
  324.             {
  325.                 if (Guild* guild = sGuildMgr->GetGuildById(GetPlayer()->GetGuildId()))
  326.                 {
  327.                     sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, guild);
  328.  
  329.                     guild->BroadcastToGuild(this, false, msg, lang == LANG_ADDON ? LANG_ADDON : LANG_UNIVERSAL);
  330.                 }
  331.             }
  332.         } break;
  333.                 case CHAT_MSG_OFFICER:
  334.         {
  335.                         char message[1024];
  336.                         switch(GetPlayer()->GetSession()->GetSecurity())
  337.                         {
  338.                             case SEC_PLAYER:
  339.                                         snprintf(message, 1024, "|cffa335ee[Infusion-WoW]|cffffffff[Player]|cffffffff[%s]: %s", GetPlayer()->GetName(), msg.c_str());
  340.                                         break;
  341.  
  342.                             case 1: // VIP, you can make the #define directives. XD
  343.                                         snprintf(message, 1024, "|cffa335ee[Infusion-WoW]|cffff8000[VIP]|cffffffff[%s]: %s", GetPlayer()->GetName(), msg.c_str());
  344.                                         break;
  345.                                        
  346.                             case 2: // Trial GM, same as above
  347.                                         snprintf(message, 1024, "|cffa335ee[Infusion-WoW]|cff00ffff[GM]|cffffffff[%s]: %s", GetPlayer()->GetName(), msg.c_str());
  348.                                         break;
  349.  
  350.                             case 3: // Junior GM, same as 1
  351.                                         snprintf(message, 1024, "|cffa335ee[Infusion-WoW]|cff00ffff[GM]|cffffffff[%s]: %s", GetPlayer()->GetName(), msg.c_str());
  352.                                         break;
  353.  
  354.                             case 4: // GM, same as 1
  355.                                         snprintf(message, 1024, "|cffa335ee[Infusion-WoW]|cff00ffff[GM]|cffffffff[%s]: %s", GetPlayer()->GetName(), msg.c_str());
  356.                                         break;
  357.  
  358.                             case 5: // Senior GM, same as 1
  359.                                         snprintf(message, 1024, "|cffa335ee[Infusion-WoW]|cff00ffff[GM]|cffffffff[%s]: %s", GetPlayer()->GetName(), msg.c_str());
  360.                                         break;
  361.  
  362.                             case 6: // Administrator, same as 1
  363.                                         snprintf(message, 1024, "|cffa335ee[Infusion-WoW]|cff0070dd[Admin]|cffffffff[%s]: %s", GetPlayer()->GetName(), msg.c_str());
  364.                                         break;
  365.  
  366.                             case 7: // Senior Administrator, same as 1
  367.                                         snprintf(message, 1024, "|cffa335ee[Infusion-WoW]|cff0070dd[Admin]|cffffffff[%s]: %s", GetPlayer()->GetName(), msg.c_str());
  368.                                         break;
  369.  
  370.                             case 8: // Developer, same as 1
  371.                                         snprintf(message, 1024, "|cffa335ee[Infusion-WoW]|cff18be00[Dev]|cffffffff[%s]: %s", GetPlayer()->GetName(), msg.c_str());
  372.                                         break;
  373.  
  374.                             case 9: // Head Developer, same as 1
  375.                                         snprintf(message, 1024, "|cffa335ee[Infusion-WoW]|cff18be00[Head Dev]|cffffffff[%s]: %s", GetPlayer()->GetName(), msg.c_str());
  376.                                         break;
  377.  
  378.                             case 10: // Head Administrator, same as 1
  379.                                         snprintf(message, 1024, "|cffa335ee[Infusion-WoW]|cff0070dd[Head Admin]|cffffffff[%s]: %s", GetPlayer()->GetName(), msg.c_str());
  380.                                         break;
  381.  
  382.                             case 11: // Co-Owner, same as 1
  383.                                         snprintf(message, 1024, "|cffa335ee[Infusion-WoW]|cffff8000[Co-Owner]|cffffffff[%s]: %s", GetPlayer()->GetName(), msg.c_str());
  384.                                         break;
  385.  
  386.                             case 12: // Owner, same as 1
  387.                                         snprintf(message, 1024, "|cffa335ee[Infusion-WoW]|cffff8000[Owner]|cffffffff[%s]: %s", GetPlayer()->GetName(), msg.c_str());
  388.                                         break;
  389.  
  390.                             case 13: // Console, same as 1
  391.                                         snprintf(message, 1024, "|cffa335ee[Infusion-WoW]|cffff8000[Console]|cffffffff[%s]: %s", GetPlayer()->GetName(), msg.c_str());
  392.                                         break;
  393.                         }
  394.                         sWorld->SendGlobalText(message, NULL);
  395.          } break;
  396.          case CHAT_MSG_RAID:
  397.         {
  398.             // if player is in battleground, he cannot say to battleground members by /ra
  399.             Group* group = GetPlayer()->GetOriginalGroup();
  400.             if (!group)
  401.             {
  402.                 group = GetPlayer()->GetGroup();
  403.                 if (!group || group->isBGGroup() || !group->isRaidGroup())
  404.                     return;
  405.             }
  406.  
  407.             sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, group);
  408.  
  409.             WorldPacket data;
  410.             ChatHandler::FillMessageData(&data, this, CHAT_MSG_RAID, lang, "", 0, msg.c_str(), NULL);
  411.             group->BroadcastPacket(&data, false);
  412.         } break;
  413.         case CHAT_MSG_RAID_LEADER:
  414.         {
  415.             // if player is in battleground, he cannot say to battleground members by /ra
  416.             Group* group = GetPlayer()->GetOriginalGroup();
  417.             if (!group)
  418.             {
  419.                 group = GetPlayer()->GetGroup();
  420.                 if (!group || group->isBGGroup() || !group->isRaidGroup() || !group->IsLeader(_player->GetGUID()))
  421.                     return;
  422.             }
  423.  
  424.             sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, group);
  425.  
  426.             WorldPacket data;
  427.             ChatHandler::FillMessageData(&data, this, CHAT_MSG_RAID_LEADER, lang, "", 0, msg.c_str(), NULL);
  428.             group->BroadcastPacket(&data, false);
  429.         } break;
  430.         case CHAT_MSG_RAID_WARNING:
  431.         {
  432.             Group* group = GetPlayer()->GetGroup();
  433.             if (!group || !group->isRaidGroup() || !(group->IsLeader(GetPlayer()->GetGUID()) || group->IsAssistant(GetPlayer()->GetGUID())) || group->isBGGroup())
  434.                 return;
  435.  
  436.             sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, group);
  437.  
  438.             WorldPacket data;
  439.             //in battleground, raid warning is sent only to players in battleground - code is ok
  440.             ChatHandler::FillMessageData(&data, this, CHAT_MSG_RAID_WARNING, lang, "", 0, msg.c_str(), NULL);
  441.             group->BroadcastPacket(&data, false);
  442.         } break;
  443.         case CHAT_MSG_BATTLEGROUND:
  444.         {
  445.             //battleground raid is always in Player->GetGroup(), never in GetOriginalGroup()
  446.             Group* group = GetPlayer()->GetGroup();
  447.             if (!group || !group->isBGGroup())
  448.                 return;
  449.  
  450.             sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, group);
  451.  
  452.             WorldPacket data;
  453.             ChatHandler::FillMessageData(&data, this, CHAT_MSG_BATTLEGROUND, lang, "", 0, msg.c_str(), NULL);
  454.             group->BroadcastPacket(&data, false);
  455.         } break;
  456.         case CHAT_MSG_BATTLEGROUND_LEADER:
  457.         {
  458.             // battleground raid is always in Player->GetGroup(), never in GetOriginalGroup()
  459.             Group* group = GetPlayer()->GetGroup();
  460.             if (!group || !group->isBGGroup() || !group->IsLeader(GetPlayer()->GetGUID()))
  461.                 return;
  462.  
  463.             sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, group);
  464.  
  465.             WorldPacket data;
  466.             ChatHandler::FillMessageData(&data, this, CHAT_MSG_BATTLEGROUND_LEADER, lang, "", 0, msg.c_str(), NULL);
  467.             group->BroadcastPacket(&data, false);
  468.         } break;
  469.         case CHAT_MSG_CHANNEL:
  470.         {
  471.             if (AccountMgr::IsPlayerAccount(GetSecurity()))
  472.             {
  473.                 if (_player->getLevel() < sWorld->getIntConfig(CONFIG_CHAT_CHANNEL_LEVEL_REQ))
  474.                 {
  475.                     SendNotification(GetTrinityString(LANG_CHANNEL_REQ), sWorld->getIntConfig(CONFIG_CHAT_CHANNEL_LEVEL_REQ));
  476.                     return;
  477.                 }
  478.             }
  479.  
  480.             if (ChannelMgr* cMgr = channelMgr(_player->GetTeam()))
  481.             {
  482.  
  483.                 if (Channel* chn = cMgr->GetChannel(channel, _player))
  484.                 {
  485.                     sScriptMgr->OnPlayerChat(_player, type, lang, msg, chn);
  486.  
  487.                     chn->Say(_player->GetGUID(), msg.c_str(), lang);
  488.                 }
  489.             }
  490.         } break;
  491.         case CHAT_MSG_AFK:
  492.         {
  493.             if ((msg.empty() || !_player->isAFK()) && !_player->isInCombat())
  494.             {
  495.                 if (!_player->isAFK())
  496.                 {
  497.                     if (msg.empty())
  498.                         msg  = GetTrinityString(LANG_PLAYER_AFK_DEFAULT);
  499.                     _player->afkMsg = msg;
  500.                 }
  501.  
  502.                 sScriptMgr->OnPlayerChat(_player, type, lang, msg);
  503.  
  504.                 _player->ToggleAFK();
  505.                 if (_player->isAFK() && _player->isDND())
  506.                     _player->ToggleDND();
  507.             }
  508.         } break;
  509.         case CHAT_MSG_DND:
  510.         {
  511.             if (msg.empty() || !_player->isDND())
  512.             {
  513.                 if (!_player->isDND())
  514.                 {
  515.                     if (msg.empty())
  516.                         msg = GetTrinityString(LANG_PLAYER_DND_DEFAULT);
  517.                     _player->dndMsg = msg;
  518.                 }
  519.  
  520.                 sScriptMgr->OnPlayerChat(_player, type, lang, msg);
  521.  
  522.                 _player->ToggleDND();
  523.                 if (_player->isDND() && _player->isAFK())
  524.                     _player->ToggleAFK();
  525.             }
  526.         } break;
  527.         default:
  528.             sLog->outError(LOG_FILTER_NETWORKIO, "CHAT: unknown message type %u, lang: %u", type, lang);
  529.             break;
  530.     }
  531. }
  532.  
  533. void WorldSession::HandleEmoteOpcode(WorldPacket & recv_data)
  534. {
  535.     if (!GetPlayer()->isAlive() || GetPlayer()->HasUnitState(UNIT_STATE_DIED))
  536.         return;
  537.  
  538.     uint32 emote;
  539.     recv_data >> emote;
  540.     sScriptMgr->OnPlayerEmote(GetPlayer(), emote);
  541.     GetPlayer()->HandleEmoteCommand(emote);
  542. }
  543.  
  544. namespace Trinity
  545. {
  546.     class EmoteChatBuilder
  547.     {
  548.         public:
  549.             EmoteChatBuilder(Player const& player, uint32 text_emote, uint32 emote_num, Unit const* target)
  550.                 : i_player(player), i_text_emote(text_emote), i_emote_num(emote_num), i_target(target) {}
  551.  
  552.             void operator()(WorldPacket& data, LocaleConstant loc_idx)
  553.             {
  554.                 char const* nam = i_target ? i_target->GetNameForLocaleIdx(loc_idx) : NULL;
  555.                 uint32 namlen = (nam ? strlen(nam) : 0) + 1;
  556.  
  557.                 data.Initialize(SMSG_TEXT_EMOTE, (20+namlen));
  558.                 data << i_player.GetGUID();
  559.                 data << (uint32)i_text_emote;
  560.                 data << i_emote_num;
  561.                 data << (uint32)namlen;
  562.                 if (namlen > 1)
  563.                     data.append(nam, namlen);
  564.                 else
  565.                     data << (uint8)0x00;
  566.             }
  567.  
  568.         private:
  569.             Player const& i_player;
  570.             uint32        i_text_emote;
  571.             uint32        i_emote_num;
  572.             Unit const*   i_target;
  573.     };
  574. }                                                           // namespace Trinity
  575.  
  576. void WorldSession::HandleTextEmoteOpcode(WorldPacket & recv_data)
  577. {
  578.     if (!GetPlayer()->isAlive())
  579.         return;
  580.  
  581.     if (!GetPlayer()->CanSpeak())
  582.     {
  583.         std::string timeStr = secsToTimeString(m_muteTime - time(NULL));
  584.         SendNotification(GetTrinityString(LANG_WAIT_BEFORE_SPEAKING), timeStr.c_str());
  585.         return;
  586.     }
  587.  
  588.     uint32 text_emote, emoteNum;
  589.     uint64 guid;
  590.  
  591.     recv_data >> text_emote;
  592.     recv_data >> emoteNum;
  593.     recv_data >> guid;
  594.  
  595.     sScriptMgr->OnPlayerTextEmote(GetPlayer(), text_emote, emoteNum, guid);
  596.  
  597.     EmotesTextEntry const* em = sEmotesTextStore.LookupEntry(text_emote);
  598.     if (!em)
  599.         return;
  600.  
  601.     uint32 emote_anim = em->textid;
  602.  
  603.     switch (emote_anim)
  604.     {
  605.         case EMOTE_STATE_SLEEP:
  606.         case EMOTE_STATE_SIT:
  607.         case EMOTE_STATE_KNEEL:
  608.         case EMOTE_ONESHOT_NONE:
  609.             break;
  610.         default:
  611.             // Only allow text-emotes for "dead" entities (feign death included)
  612.             if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
  613.                 break;
  614.              GetPlayer()->HandleEmoteCommand(emote_anim);
  615.              break;
  616.     }
  617.  
  618.     Unit* unit = ObjectAccessor::GetUnit(*_player, guid);
  619.  
  620.     CellCoord p = Trinity::ComputeCellCoord(GetPlayer()->GetPositionX(), GetPlayer()->GetPositionY());
  621.  
  622.     Cell cell(p);
  623.     cell.SetNoCreate();
  624.  
  625.     Trinity::EmoteChatBuilder emote_builder(*GetPlayer(), text_emote, emoteNum, unit);
  626.     Trinity::LocalizedPacketDo<Trinity::EmoteChatBuilder > emote_do(emote_builder);
  627.     Trinity::PlayerDistWorker<Trinity::LocalizedPacketDo<Trinity::EmoteChatBuilder > > emote_worker(GetPlayer(), sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_TEXTEMOTE), emote_do);
  628.     TypeContainerVisitor<Trinity::PlayerDistWorker<Trinity::LocalizedPacketDo<Trinity::EmoteChatBuilder> >, WorldTypeMapContainer> message(emote_worker);
  629.     cell.Visit(p, message, *GetPlayer()->GetMap(), *GetPlayer(), sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_TEXTEMOTE));
  630.  
  631.     GetPlayer()->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_DO_EMOTE, text_emote, 0, unit);
  632.  
  633.     //Send scripted event call
  634.     if (unit && unit->GetTypeId() == TYPEID_UNIT && ((Creature*)unit)->AI())
  635.         ((Creature*)unit)->AI()->ReceiveEmote(GetPlayer(), text_emote);
  636. }
  637.  
  638. void WorldSession::HandleChatIgnoredOpcode(WorldPacket& recv_data)
  639. {
  640.     uint64 iguid;
  641.     uint8 unk;
  642.     //sLog->outDebug(LOG_FILTER_PACKETIO, "WORLD: Received CMSG_CHAT_IGNORED");
  643.  
  644.     recv_data >> iguid;
  645.     recv_data >> unk;                                       // probably related to spam reporting
  646.  
  647.     Player* player = ObjectAccessor::FindPlayer(iguid);
  648.     if (!player || !player->GetSession())
  649.         return;
  650.  
  651.     WorldPacket data;
  652.     ChatHandler::FillMessageData(&data, this, CHAT_MSG_IGNORED, LANG_UNIVERSAL, NULL, GetPlayer()->GetGUID(), GetPlayer()->GetName(), NULL);
  653.     player->GetSession()->SendPacket(&data);
  654. }
  655.  
  656. void WorldSession::HandleChannelDeclineInvite(WorldPacket &recvPacket)
  657. {
  658.     sLog->outDebug(LOG_FILTER_NETWORKIO, "Opcode %u", recvPacket.GetOpcode());
  659. }
  660.  
  661. void WorldSession::SendPlayerNotFoundNotice(std::string name)
  662. {
  663.     WorldPacket data(SMSG_CHAT_PLAYER_NOT_FOUND, name.size()+1);
  664.     data << name;
  665.     SendPacket(&data);
  666. }
  667.  
  668. void WorldSession::SendPlayerAmbiguousNotice(std::string name)
  669. {
  670.     WorldPacket data(SMSG_CHAT_PLAYER_AMBIGUOUS, name.size()+1);
  671.     data << name;
  672.     SendPacket(&data);
  673. }
  674.  
  675. void WorldSession::SendWrongFactionNotice()
  676. {
  677.     WorldPacket data(SMSG_CHAT_WRONG_FACTION, 0);
  678.     SendPacket(&data);
  679. }
  680.  
  681. void WorldSession::SendChatRestrictedNotice(ChatRestrictionType restriction)
  682. {
  683.     WorldPacket data(SMSG_CHAT_RESTRICTED, 1);
  684.     data << uint8(restriction);
  685.     SendPacket(&data);
  686. }