Advertisement
EmuDevs

Mischandler

Oct 17th, 2013
146
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 62.50 KB | None | 0 0
  1. /*
  2.  * Copyright (C) 2008-2013 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 "Language.h"
  21. #include "DatabaseEnv.h"
  22. #include "WorldPacket.h"
  23. #include "Opcodes.h"
  24. #include "Log.h"
  25. #include "Player.h"
  26. #include "GossipDef.h"
  27. #include "World.h"
  28. #include "ObjectMgr.h"
  29. #include "GuildMgr.h"
  30. #include "WorldSession.h"
  31. #include "BigNumber.h"
  32. #include "SHA1.h"
  33. #include "UpdateData.h"
  34. #include "LootMgr.h"
  35. #include "Chat.h"
  36. #include "zlib.h"
  37. #include "ObjectAccessor.h"
  38. #include "Object.h"
  39. #include "Battleground.h"
  40. #include "OutdoorPvP.h"
  41. #include "Pet.h"
  42. #include "SocialMgr.h"
  43. #include "CellImpl.h"
  44. #include "AccountMgr.h"
  45. #include "Vehicle.h"
  46. #include "CreatureAI.h"
  47. #include "DBCEnums.h"
  48. #include "ScriptMgr.h"
  49. #include "MapManager.h"
  50. #include "InstanceScript.h"
  51. #include "GameObjectAI.h"
  52. #include "Group.h"
  53. #include "AccountMgr.h"
  54. #include "Spell.h"
  55. #include "BattlegroundMgr.h"
  56. #include "Battlefield.h"
  57. #include "BattlefieldMgr.h"
  58.  
  59. void WorldSession::HandleRepopRequestOpcode(WorldPacket& recvData)
  60. {
  61.     sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Recvd CMSG_REPOP_REQUEST Message");
  62.  
  63.     recvData.read_skip<uint8>();
  64.  
  65.     if (GetPlayer()->isAlive() || GetPlayer()->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_GHOST))
  66.         return;
  67.  
  68.     if (GetPlayer()->HasAuraType(SPELL_AURA_PREVENT_RESURRECTION))
  69.         return; // silently return, client should display the error by itself
  70.  
  71.     // the world update order is sessions, players, creatures
  72.     // the netcode runs in parallel with all of these
  73.     // creatures can kill players
  74.     // so if the server is lagging enough the player can
  75.     // release spirit after he's killed but before he is updated
  76.     if (GetPlayer()->getDeathState() == JUST_DIED)
  77.     {
  78.         sLog->outDebug(LOG_FILTER_NETWORKIO, "HandleRepopRequestOpcode: got request after player %s(%d) was killed and before he was updated",
  79.             GetPlayer()->GetName().c_str(), GetPlayer()->GetGUIDLow());
  80.         GetPlayer()->KillPlayer();
  81.     }
  82.  
  83.     //this is spirit release confirm?
  84.     GetPlayer()->RemovePet(NULL, PET_SAVE_NOT_IN_SLOT, true);
  85.     GetPlayer()->BuildPlayerRepop();
  86.     GetPlayer()->RepopAtGraveyard();
  87. }
  88.  
  89. void WorldSession::HandleGossipSelectOptionOpcode(WorldPacket& recvData)
  90. {
  91.     sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: CMSG_GOSSIP_SELECT_OPTION");
  92.  
  93.     uint32 gossipListId;
  94.     uint32 menuId;
  95.     uint64 guid;
  96.     std::string code = "";
  97.  
  98.     recvData >> guid >> menuId >> gossipListId;
  99.  
  100.     if (_player->PlayerTalkClass->IsGossipOptionCoded(gossipListId))
  101.         recvData >> code;
  102.  
  103.     Creature* unit = NULL;
  104.     GameObject* go = NULL;
  105.     if (IS_CRE_OR_VEH_GUID(guid))
  106.     {
  107.         unit = GetPlayer()->GetNPCIfCanInteractWith(guid, UNIT_NPC_FLAG_NONE);
  108.         if (!unit)
  109.         {
  110.             sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: HandleGossipSelectOptionOpcode - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(guid)));
  111.             return;
  112.         }
  113.     }
  114.      else if (IS_PLAYER_GUID(guid))
  115.      {
  116.          if(_player->GetGUID() == guid && _player->PlayerTalkClass->GetGossipMenu().GetMenuId() == menuId)
  117.          {
  118.              if(code.empty())
  119.                  sScriptMgr->OnGossipSelect(_player, menuId, _player->PlayerTalkClass->GetGossipOptionSender(gossipListId), _player->PlayerTalkClass->GetGossipOptionAction(gossipListId));
  120.              else
  121.                  sScriptMgr->OnGossipSelectCode(_player, menuId, _player->PlayerTalkClass->GetGossipOptionSender(gossipListId), _player->PlayerTalkClass->GetGossipOptionAction(gossipListId), code.c_str());
  122.          }
  123.          return;
  124.      }
  125.      else if(IS_ITEM_GUID(guid))
  126.      {
  127.          if(Item* item = _player->GetItemByGuid(guid))
  128.          {
  129.              if(code.empty())
  130.                  sScriptMgr->OnGossipSelect(_player, item, _player->PlayerTalkClass->GetGossipOptionSender(gossipListId), _player->PlayerTalkClass->GetGossipOptionAction(gossipListId));
  131.              else
  132.                  sScriptMgr->OnGossipSelectCode(_player, item, _player->PlayerTalkClass->GetGossipOptionSender(gossipListId), _player->PlayerTalkClass->GetGossipOptionAction(gossipListId), code.c_str());
  133.          }
  134.          return;
  135.      }
  136.     else if (IS_GAMEOBJECT_GUID(guid))
  137.     {
  138.         go = _player->GetMap()->GetGameObject(guid);
  139.         if (!go)
  140.         {
  141.             sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: HandleGossipSelectOptionOpcode - GameObject (GUID: %u) not found.", uint32(GUID_LOPART(guid)));
  142.             return;
  143.         }
  144.     }
  145.     else
  146.     {
  147.         sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: HandleGossipSelectOptionOpcode - unsupported GUID type for highguid %u. lowpart %u.", uint32(GUID_HIPART(guid)), uint32(GUID_LOPART(guid)));
  148.         return;
  149.     }
  150.  
  151.     // remove fake death
  152.     if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
  153.         GetPlayer()->RemoveAurasByType(SPELL_AURA_FEIGN_DEATH);
  154.  
  155.     if ((unit && unit->GetCreatureTemplate()->ScriptID != unit->LastUsedScriptID) || (go && go->GetGOInfo()->ScriptId != go->LastUsedScriptID))
  156.     {
  157.         sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: HandleGossipSelectOptionOpcode - Script reloaded while in use, ignoring and set new scipt id");
  158.         if (unit)
  159.             unit->LastUsedScriptID = unit->GetCreatureTemplate()->ScriptID;
  160.         if (go)
  161.             go->LastUsedScriptID = go->GetGOInfo()->ScriptId;
  162.         _player->PlayerTalkClass->SendCloseGossip();
  163.         return;
  164.     }
  165.     if (!code.empty())
  166.     {
  167.         if (unit)
  168.         {
  169.             unit->AI()->sGossipSelectCode(_player, menuId, gossipListId, code.c_str());
  170.             if (!sScriptMgr->OnGossipSelectCode(_player, unit, _player->PlayerTalkClass->GetGossipOptionSender(gossipListId), _player->PlayerTalkClass->GetGossipOptionAction(gossipListId), code.c_str()))
  171.                 _player->OnGossipSelect(unit, gossipListId, menuId);
  172.         }
  173.         else
  174.         {
  175.             go->AI()->GossipSelectCode(_player, menuId, gossipListId, code.c_str());
  176.             sScriptMgr->OnGossipSelectCode(_player, go, _player->PlayerTalkClass->GetGossipOptionSender(gossipListId), _player->PlayerTalkClass->GetGossipOptionAction(gossipListId), code.c_str());
  177.         }
  178.     }
  179.     else
  180.     {
  181.         if (unit)
  182.         {
  183.             unit->AI()->sGossipSelect(_player, menuId, gossipListId);
  184.             if (!sScriptMgr->OnGossipSelect(_player, unit, _player->PlayerTalkClass->GetGossipOptionSender(gossipListId), _player->PlayerTalkClass->GetGossipOptionAction(gossipListId)))
  185.                 _player->OnGossipSelect(unit, gossipListId, menuId);
  186.         }
  187.         else
  188.         {
  189.             go->AI()->GossipSelect(_player, menuId, gossipListId);
  190.             if (!sScriptMgr->OnGossipSelect(_player, go, _player->PlayerTalkClass->GetGossipOptionSender(gossipListId), _player->PlayerTalkClass->GetGossipOptionAction(gossipListId)))
  191.                 _player->OnGossipSelect(go, gossipListId, menuId);
  192.         }
  193.     }
  194. }
  195.  
  196. void WorldSession::HandleWhoOpcode(WorldPacket& recvData)
  197. {
  198.     sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Recvd CMSG_WHO Message");
  199.  
  200.     time_t now = time(NULL);
  201.     if (now - timeLastWhoCommand < 5)
  202.         return;
  203.     else timeLastWhoCommand = now;
  204.  
  205.     uint32 matchcount = 0;
  206.  
  207.     uint32 level_min, level_max, racemask, classmask, zones_count, str_count;
  208.     uint32 zoneids[10];                                     // 10 is client limit
  209.     std::string player_name, guild_name;
  210.  
  211.     recvData >> level_min;                                 // maximal player level, default 0
  212.     recvData >> level_max;                                 // minimal player level, default 100 (MAX_LEVEL)
  213.     recvData >> player_name;                               // player name, case sensitive...
  214.  
  215.     recvData >> guild_name;                                // guild name, case sensitive...
  216.  
  217.     recvData >> racemask;                                  // race mask
  218.     recvData >> classmask;                                 // class mask
  219.     recvData >> zones_count;                               // zones count, client limit = 10 (2.0.10)
  220.  
  221.     if (zones_count > 10)
  222.         return;                                             // can't be received from real client or broken packet
  223.  
  224.     for (uint32 i = 0; i < zones_count; ++i)
  225.     {
  226.         uint32 temp;
  227.         recvData >> temp;                                  // zone id, 0 if zone is unknown...
  228.         zoneids[i] = temp;
  229.         sLog->outDebug(LOG_FILTER_NETWORKIO, "Zone %u: %u", i, zoneids[i]);
  230.     }
  231.  
  232.     recvData >> str_count;                                 // user entered strings count, client limit=4 (checked on 2.0.10)
  233.  
  234.     if (str_count > 4)
  235.         return;                                             // can't be received from real client or broken packet
  236.  
  237.     sLog->outDebug(LOG_FILTER_NETWORKIO, "Minlvl %u, maxlvl %u, name %s, guild %s, racemask %u, classmask %u, zones %u, strings %u", level_min, level_max, player_name.c_str(), guild_name.c_str(), racemask, classmask, zones_count, str_count);
  238.  
  239.     std::wstring str[4];                                    // 4 is client limit
  240.     for (uint32 i = 0; i < str_count; ++i)
  241.     {
  242.         std::string temp;
  243.         recvData >> temp;                                  // user entered string, it used as universal search pattern(guild+player name)?
  244.  
  245.         if (!Utf8toWStr(temp, str[i]))
  246.             continue;
  247.  
  248.         wstrToLower(str[i]);
  249.  
  250.         sLog->outDebug(LOG_FILTER_NETWORKIO, "String %u: %s", i, temp.c_str());
  251.     }
  252.  
  253.     std::wstring wplayer_name;
  254.     std::wstring wguild_name;
  255.     if (!(Utf8toWStr(player_name, wplayer_name) && Utf8toWStr(guild_name, wguild_name)))
  256.         return;
  257.     wstrToLower(wplayer_name);
  258.     wstrToLower(wguild_name);
  259.  
  260.     // client send in case not set max level value 100 but Trinity supports 255 max level,
  261.     // update it to show GMs with characters after 100 level
  262.     if (level_max >= MAX_LEVEL)
  263.         level_max = STRONG_MAX_LEVEL;
  264.  
  265.     uint32 team = _player->GetTeam();
  266.     uint32 security = GetSecurity();
  267.     bool allowTwoSideWhoList = sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_WHO_LIST);
  268.     uint32 gmLevelInWhoList  = sWorld->getIntConfig(CONFIG_GM_LEVEL_IN_WHO_LIST);
  269.     uint32 displaycount = 0;
  270.  
  271.     WorldPacket data(SMSG_WHO, 50);                       // guess size
  272.     data << uint32(matchcount);                           // placeholder, count of players matching criteria
  273.     data << uint32(displaycount);                         // placeholder, count of players displayed
  274.  
  275.     TRINITY_READ_GUARD(HashMapHolder<Player>::LockType, *HashMapHolder<Player>::GetLock());
  276.     HashMapHolder<Player>::MapType const& m = sObjectAccessor->GetPlayers();
  277.     for (HashMapHolder<Player>::MapType::const_iterator itr = m.begin(); itr != m.end(); ++itr)
  278.     {
  279.         if (AccountMgr::IsPlayerAccount(security))
  280.         {
  281.             // player can see member of other team only if CONFIG_ALLOW_TWO_SIDE_WHO_LIST
  282.             if (itr->second->GetTeam() != team && !allowTwoSideWhoList)
  283.                 continue;
  284.  
  285.             // player can see MODERATOR, GAME MASTER, ADMINISTRATOR only if CONFIG_GM_IN_WHO_LIST
  286.             if ((itr->second->GetSession()->GetSecurity() > AccountTypes(gmLevelInWhoList)))
  287.                 continue;
  288.         }
  289.  
  290.         //do not process players which are not in world
  291.         if (!(itr->second->IsInWorld()))
  292.             continue;
  293.  
  294.         // check if target is globally visible for player
  295.         if (!(itr->second->IsVisibleGloballyFor(_player)))
  296.             continue;
  297.  
  298.         // check if target's level is in level range
  299.         uint8 lvl = itr->second->getLevel();
  300.         if (lvl < level_min || lvl > level_max)
  301.             continue;
  302.  
  303.         // check if class matches classmask
  304.         uint32 class_ = itr->second->getClass();
  305.         if (!(classmask & (1 << class_)))
  306.             continue;
  307.  
  308.         // check if race matches racemask
  309.         uint32 race = itr->second->getRace();
  310.         if (!(racemask & (1 << race)))
  311.             continue;
  312.  
  313.         uint32 pzoneid = itr->second->GetZoneId();
  314.         uint8 gender = itr->second->getGender();
  315.  
  316.         bool z_show = true;
  317.         for (uint32 i = 0; i < zones_count; ++i)
  318.         {
  319.             if (zoneids[i] == pzoneid)
  320.             {
  321.                 z_show = true;
  322.                 break;
  323.             }
  324.  
  325.             z_show = false;
  326.         }
  327.         if (!z_show)
  328.             continue;
  329.  
  330.         std::string pname = itr->second->GetName();
  331.         std::wstring wpname;
  332.         if (!Utf8toWStr(pname, wpname))
  333.             continue;
  334.         wstrToLower(wpname);
  335.  
  336.         if (!(wplayer_name.empty() || wpname.find(wplayer_name) != std::wstring::npos))
  337.             continue;
  338.  
  339.         std::string gname = sGuildMgr->GetGuildNameById(itr->second->GetGuildId());
  340.         std::wstring wgname;
  341.         if (!Utf8toWStr(gname, wgname))
  342.             continue;
  343.         wstrToLower(wgname);
  344.  
  345.         if (!(wguild_name.empty() || wgname.find(wguild_name) != std::wstring::npos))
  346.             continue;
  347.  
  348.         std::string aname;
  349.         if (AreaTableEntry const* areaEntry = GetAreaEntryByAreaID(itr->second->GetZoneId()))
  350.             aname = areaEntry->area_name[GetSessionDbcLocale()];
  351.  
  352.         bool s_show = true;
  353.         for (uint32 i = 0; i < str_count; ++i)
  354.         {
  355.             if (!str[i].empty())
  356.             {
  357.                 if (wgname.find(str[i]) != std::wstring::npos ||
  358.                     wpname.find(str[i]) != std::wstring::npos ||
  359.                     Utf8FitTo(aname, str[i]))
  360.                 {
  361.                     s_show = true;
  362.                     break;
  363.                 }
  364.                 s_show = false;
  365.             }
  366.         }
  367.         if (!s_show)
  368.             continue;
  369.  
  370.         // 49 is maximum player count sent to client - can be overridden
  371.         // through config, but is unstable
  372.         if ((matchcount++) >= sWorld->getIntConfig(CONFIG_MAX_WHO))
  373.             continue;
  374.  
  375.         data << pname;                                    // player name
  376.         data << gname;                                    // guild name
  377.         data << uint32(lvl);                              // player level
  378.         data << uint32(class_);                           // player class
  379.         data << uint32(race);                             // player race
  380.         data << uint8(gender);                            // player gender
  381.         data << uint32(pzoneid);                          // player zone id
  382.  
  383.         ++displaycount;
  384.     }
  385.  
  386.     data.put(0, displaycount);                            // insert right count, count displayed
  387.     data.put(4, matchcount);                              // insert right count, count of matches
  388.  
  389.     SendPacket(&data);
  390.     sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Send SMSG_WHO Message");
  391. }
  392.  
  393. void WorldSession::HandleLogoutRequestOpcode(WorldPacket& /*recvData*/)
  394. {
  395.     sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Recvd CMSG_LOGOUT_REQUEST Message, security - %u", GetSecurity());
  396.  
  397.     if (uint64 lguid = GetPlayer()->GetLootGUID())
  398.         DoLootRelease(lguid);
  399.  
  400.     uint8 reason = 0;
  401.  
  402.     if (GetPlayer()->isInCombat())
  403.         reason = 1;
  404.     else if (GetPlayer()->m_movementInfo.HasMovementFlag(MOVEMENTFLAG_FALLING | MOVEMENTFLAG_FALLING_FAR))
  405.         reason = 3;                                         // is jumping or falling
  406.     else if (GetPlayer()->duel || GetPlayer()->HasAura(9454)) // is dueling or frozen by GM via freeze command
  407.         reason = 2;                                         // FIXME - Need the correct value
  408.  
  409.     if (reason)
  410.     {
  411.         WorldPacket data(SMSG_LOGOUT_RESPONSE, 1+4);
  412.         data << uint8(reason);
  413.         data << uint32(0);
  414.         SendPacket(&data);
  415.         LogoutRequest(0);
  416.         return;
  417.     }
  418.  
  419.     //instant logout in taverns/cities or on taxi or for admins, gm's, mod's if its enabled in worldserver.conf
  420.     if (GetPlayer()->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_RESTING) || GetPlayer()->isInFlight() ||
  421.         GetSecurity() >= AccountTypes(sWorld->getIntConfig(CONFIG_INSTANT_LOGOUT)))
  422.     {
  423.         WorldPacket data(SMSG_LOGOUT_RESPONSE, 1+4);
  424.         data << uint8(0);
  425.         data << uint32(16777216);
  426.         SendPacket(&data);
  427.         LogoutPlayer(true);
  428.         return;
  429.     }
  430.  
  431.     // not set flags if player can't free move to prevent lost state at logout cancel
  432.     if (GetPlayer()->CanFreeMove())
  433.     {
  434.         GetPlayer()->SetStandState(UNIT_STAND_STATE_SIT);
  435.  
  436.         WorldPacket data(SMSG_FORCE_MOVE_ROOT, (8+4));    // guess size
  437.         data.append(GetPlayer()->GetPackGUID());
  438.         data << (uint32)2;
  439.         SendPacket(&data);
  440.         GetPlayer()->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED);
  441.     }
  442.  
  443.     WorldPacket data(SMSG_LOGOUT_RESPONSE, 1+4);
  444.     data << uint8(0);
  445.     data << uint32(0);
  446.     SendPacket(&data);
  447.     LogoutRequest(time(NULL));
  448. }
  449.  
  450. void WorldSession::HandlePlayerLogoutOpcode(WorldPacket& /*recvData*/)
  451. {
  452.     sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Recvd CMSG_PLAYER_LOGOUT Message");
  453. }
  454.  
  455. void WorldSession::HandleLogoutCancelOpcode(WorldPacket& /*recvData*/)
  456. {
  457.     sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Recvd CMSG_LOGOUT_CANCEL Message");
  458.  
  459.     // Player have already logged out serverside, too late to cancel
  460.     if (!GetPlayer())
  461.         return;
  462.  
  463.     LogoutRequest(0);
  464.  
  465.     WorldPacket data(SMSG_LOGOUT_CANCEL_ACK, 0);
  466.     SendPacket(&data);
  467.  
  468.     // not remove flags if can't free move - its not set in Logout request code.
  469.     if (GetPlayer()->CanFreeMove())
  470.     {
  471.         //!we can move again
  472.         data.Initialize(SMSG_FORCE_MOVE_UNROOT, 8);       // guess size
  473.         data.append(GetPlayer()->GetPackGUID());
  474.         data << uint32(0);
  475.         SendPacket(&data);
  476.  
  477.         //! Stand Up
  478.         GetPlayer()->SetStandState(UNIT_STAND_STATE_STAND);
  479.  
  480.         //! DISABLE_ROTATE
  481.         GetPlayer()->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED);
  482.     }
  483.  
  484.     sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Sent SMSG_LOGOUT_CANCEL_ACK Message");
  485. }
  486.  
  487. void WorldSession::HandleTogglePvP(WorldPacket& recvData)
  488. {
  489.     // this opcode can be used in two ways: Either set explicit new status or toggle old status
  490.     if (recvData.size() == 1)
  491.     {
  492.         bool newPvPStatus;
  493.         recvData >> newPvPStatus;
  494.         GetPlayer()->ApplyModFlag(PLAYER_FLAGS, PLAYER_FLAGS_IN_PVP, newPvPStatus);
  495.         GetPlayer()->ApplyModFlag(PLAYER_FLAGS, PLAYER_FLAGS_PVP_TIMER, !newPvPStatus);
  496.     }
  497.     else
  498.     {
  499.         GetPlayer()->ToggleFlag(PLAYER_FLAGS, PLAYER_FLAGS_IN_PVP);
  500.         GetPlayer()->ToggleFlag(PLAYER_FLAGS, PLAYER_FLAGS_PVP_TIMER);
  501.     }
  502.  
  503.     if (GetPlayer()->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_IN_PVP))
  504.     {
  505.         if (!GetPlayer()->IsPvP() || GetPlayer()->pvpInfo.endTimer != 0)
  506.             GetPlayer()->UpdatePvP(true, true);
  507.     }
  508.     else
  509.     {
  510.         if (!GetPlayer()->pvpInfo.inHostileArea && GetPlayer()->IsPvP())
  511.             GetPlayer()->pvpInfo.endTimer = time(NULL);     // start toggle-off
  512.     }
  513.  
  514.     //if (OutdoorPvP* pvp = _player->GetOutdoorPvP())
  515.     //    pvp->HandlePlayerActivityChanged(_player);
  516. }
  517.  
  518. void WorldSession::HandleZoneUpdateOpcode(WorldPacket& recvData)
  519. {
  520.     uint32 newZone;
  521.     recvData >> newZone;
  522.  
  523.     sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Recvd ZONE_UPDATE: %u", newZone);
  524.  
  525.     // use server size data
  526.     uint32 newzone, newarea;
  527.     GetPlayer()->GetZoneAndAreaId(newzone, newarea);
  528.     GetPlayer()->UpdateZone(newzone, newarea);
  529.     //GetPlayer()->SendInitWorldStates(true, newZone);
  530. }
  531.  
  532. void WorldSession::HandleSetSelectionOpcode(WorldPacket& recvData)
  533. {
  534.     uint64 guid;
  535.     recvData >> guid;
  536.  
  537.     _player->SetSelection(guid);
  538. }
  539.  
  540. void WorldSession::HandleStandStateChangeOpcode(WorldPacket& recvData)
  541. {
  542.     // sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_STANDSTATECHANGE"); -- too many spam in log at lags/debug stop
  543.     uint32 animstate;
  544.     recvData >> animstate;
  545.  
  546.     _player->SetStandState(animstate);
  547. }
  548.  
  549. void WorldSession::HandleContactListOpcode(WorldPacket& recvData)
  550. {
  551.     uint32 unk;
  552.     recvData >> unk;
  553.     sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_CONTACT_LIST - Unk: %d", unk);
  554.     _player->GetSocial()->SendSocialList(_player);
  555. }
  556.  
  557. void WorldSession::HandleAddFriendOpcode(WorldPacket& recvData)
  558. {
  559.     sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_ADD_FRIEND");
  560.  
  561.     std::string friendName = GetTrinityString(LANG_FRIEND_IGNORE_UNKNOWN);
  562.     std::string friendNote;
  563.  
  564.     recvData >> friendName;
  565.  
  566.     recvData >> friendNote;
  567.  
  568.     if (!normalizePlayerName(friendName))
  569.         return;
  570.  
  571.     sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: %s asked to add friend : '%s'",
  572.         GetPlayer()->GetName().c_str(), friendName.c_str());
  573.  
  574.     PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_GUID_RACE_ACC_BY_NAME);
  575.  
  576.     stmt->setString(0, friendName);
  577.  
  578.     _addFriendCallback.SetParam(friendNote);
  579.     _addFriendCallback.SetFutureResult(CharacterDatabase.AsyncQuery(stmt));
  580. }
  581.  
  582. void WorldSession::HandleAddFriendOpcodeCallBack(PreparedQueryResult result, std::string const& friendNote)
  583. {
  584.     if (!GetPlayer())
  585.         return;
  586.  
  587.     uint64 friendGuid;
  588.     uint32 friendAccountId;
  589.     uint32 team;
  590.     FriendsResult friendResult;
  591.  
  592.     friendResult = FRIEND_NOT_FOUND;
  593.     friendGuid = 0;
  594.  
  595.     if (result)
  596.     {
  597.         Field* fields = result->Fetch();
  598.  
  599.         friendGuid = MAKE_NEW_GUID(fields[0].GetUInt32(), 0, HIGHGUID_PLAYER);
  600.         team = Player::TeamForRace(fields[1].GetUInt8());
  601.         friendAccountId = fields[2].GetUInt32();
  602.  
  603.         if (!AccountMgr::IsPlayerAccount(GetSecurity()) || sWorld->getBoolConfig(CONFIG_ALLOW_GM_FRIEND) || AccountMgr::IsPlayerAccount(AccountMgr::GetSecurity(friendAccountId, realmID)))
  604.         {
  605.             if (friendGuid)
  606.             {
  607.                 if (friendGuid == GetPlayer()->GetGUID())
  608.                     friendResult = FRIEND_SELF;
  609.                 else if (GetPlayer()->GetTeam() != team && !sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_ADD_FRIEND) && AccountMgr::IsPlayerAccount(GetSecurity()))
  610.                     friendResult = FRIEND_ENEMY;
  611.                 else if (GetPlayer()->GetSocial()->HasFriend(GUID_LOPART(friendGuid)))
  612.                     friendResult = FRIEND_ALREADY;
  613.                 else
  614.                 {
  615.                     Player* pFriend = ObjectAccessor::FindPlayer(friendGuid);
  616.                     if (pFriend && pFriend->IsInWorld() && pFriend->IsVisibleGloballyFor(GetPlayer()))
  617.                         friendResult = FRIEND_ADDED_ONLINE;
  618.                     else
  619.                         friendResult = FRIEND_ADDED_OFFLINE;
  620.                     if (!GetPlayer()->GetSocial()->AddToSocialList(GUID_LOPART(friendGuid), false))
  621.                     {
  622.                         friendResult = FRIEND_LIST_FULL;
  623.                         sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: %s's friend list is full.", GetPlayer()->GetName().c_str());
  624.                     }
  625.                 }
  626.                 GetPlayer()->GetSocial()->SetFriendNote(GUID_LOPART(friendGuid), friendNote);
  627.             }
  628.         }
  629.     }
  630.  
  631.     sSocialMgr->SendFriendStatus(GetPlayer(), friendResult, GUID_LOPART(friendGuid), false);
  632.  
  633.     sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Sent (SMSG_FRIEND_STATUS)");
  634. }
  635.  
  636. void WorldSession::HandleDelFriendOpcode(WorldPacket& recvData)
  637. {
  638.     uint64 FriendGUID;
  639.  
  640.     sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_DEL_FRIEND");
  641.  
  642.     recvData >> FriendGUID;
  643.  
  644.     _player->GetSocial()->RemoveFromSocialList(GUID_LOPART(FriendGUID), false);
  645.  
  646.     sSocialMgr->SendFriendStatus(GetPlayer(), FRIEND_REMOVED, GUID_LOPART(FriendGUID), false);
  647.  
  648.     sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Sent motd (SMSG_FRIEND_STATUS)");
  649. }
  650.  
  651. void WorldSession::HandleAddIgnoreOpcode(WorldPacket& recvData)
  652. {
  653.     sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_ADD_IGNORE");
  654.  
  655.     std::string ignoreName = GetTrinityString(LANG_FRIEND_IGNORE_UNKNOWN);
  656.  
  657.     recvData >> ignoreName;
  658.  
  659.     if (!normalizePlayerName(ignoreName))
  660.         return;
  661.  
  662.     sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: %s asked to Ignore: '%s'",
  663.         GetPlayer()->GetName().c_str(), ignoreName.c_str());
  664.  
  665.     PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_GUID_BY_NAME);
  666.  
  667.     stmt->setString(0, ignoreName);
  668.  
  669.     _addIgnoreCallback = CharacterDatabase.AsyncQuery(stmt);
  670. }
  671.  
  672. void WorldSession::HandleAddIgnoreOpcodeCallBack(PreparedQueryResult result)
  673. {
  674.     if (!GetPlayer())
  675.         return;
  676.  
  677.     uint64 IgnoreGuid;
  678.     FriendsResult ignoreResult;
  679.  
  680.     ignoreResult = FRIEND_IGNORE_NOT_FOUND;
  681.     IgnoreGuid = 0;
  682.  
  683.     if (result)
  684.     {
  685.         IgnoreGuid = MAKE_NEW_GUID((*result)[0].GetUInt32(), 0, HIGHGUID_PLAYER);
  686.  
  687.         if (IgnoreGuid)
  688.         {
  689.             if (IgnoreGuid == GetPlayer()->GetGUID())              //not add yourself
  690.                 ignoreResult = FRIEND_IGNORE_SELF;
  691.             else if (GetPlayer()->GetSocial()->HasIgnore(GUID_LOPART(IgnoreGuid)))
  692.                 ignoreResult = FRIEND_IGNORE_ALREADY;
  693.             else
  694.             {
  695.                 ignoreResult = FRIEND_IGNORE_ADDED;
  696.  
  697.                 // ignore list full
  698.                 if (!GetPlayer()->GetSocial()->AddToSocialList(GUID_LOPART(IgnoreGuid), true))
  699.                     ignoreResult = FRIEND_IGNORE_FULL;
  700.             }
  701.         }
  702.     }
  703.  
  704.     sSocialMgr->SendFriendStatus(GetPlayer(), ignoreResult, GUID_LOPART(IgnoreGuid), false);
  705.  
  706.     sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Sent (SMSG_FRIEND_STATUS)");
  707. }
  708.  
  709. void WorldSession::HandleDelIgnoreOpcode(WorldPacket& recvData)
  710. {
  711.     uint64 IgnoreGUID;
  712.  
  713.     sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_DEL_IGNORE");
  714.  
  715.     recvData >> IgnoreGUID;
  716.  
  717.     _player->GetSocial()->RemoveFromSocialList(GUID_LOPART(IgnoreGUID), true);
  718.  
  719.     sSocialMgr->SendFriendStatus(GetPlayer(), FRIEND_IGNORE_REMOVED, GUID_LOPART(IgnoreGUID), false);
  720.  
  721.     sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Sent motd (SMSG_FRIEND_STATUS)");
  722. }
  723.  
  724. void WorldSession::HandleSetContactNotesOpcode(WorldPacket& recvData)
  725. {
  726.     sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_SET_CONTACT_NOTES");
  727.     uint64 guid;
  728.     std::string note;
  729.     recvData >> guid >> note;
  730.     _player->GetSocial()->SetFriendNote(GUID_LOPART(guid), note);
  731. }
  732.  
  733. void WorldSession::HandleBugOpcode(WorldPacket& recvData)
  734. {
  735.     uint32 suggestion, contentlen, typelen;
  736.     std::string content, type;
  737.  
  738.     recvData >> suggestion >> contentlen >> content;
  739.  
  740.     recvData >> typelen >> type;
  741.  
  742.     if (suggestion == 0)
  743.         sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_BUG [Bug Report]");
  744.     else
  745.         sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_BUG [Suggestion]");
  746.  
  747.     sLog->outDebug(LOG_FILTER_NETWORKIO, "%s", type.c_str());
  748.     sLog->outDebug(LOG_FILTER_NETWORKIO, "%s", content.c_str());
  749.  
  750.     PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_BUG_REPORT);
  751.  
  752.     stmt->setString(0, type);
  753.     stmt->setString(1, content);
  754.  
  755.     CharacterDatabase.Execute(stmt);
  756. }
  757.  
  758. void WorldSession::HandleReclaimCorpseOpcode(WorldPacket& recvData)
  759. {
  760.     sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_RECLAIM_CORPSE");
  761.  
  762.     uint64 guid;
  763.     recvData >> guid;
  764.  
  765.     if (GetPlayer()->isAlive())
  766.         return;
  767.  
  768.     // do not allow corpse reclaim in arena
  769.     if (GetPlayer()->InArena())
  770.         return;
  771.  
  772.     // body not released yet
  773.     if (!GetPlayer()->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_GHOST))
  774.         return;
  775.  
  776.     Corpse* corpse = GetPlayer()->GetCorpse();
  777.  
  778.     if (!corpse)
  779.         return;
  780.  
  781.     // prevent resurrect before 30-sec delay after body release not finished
  782.     if (time_t(corpse->GetGhostTime() + GetPlayer()->GetCorpseReclaimDelay(corpse->GetType() == CORPSE_RESURRECTABLE_PVP)) > time_t(time(NULL)))
  783.         return;
  784.  
  785.     if (!corpse->IsWithinDistInMap(GetPlayer(), CORPSE_RECLAIM_RADIUS, true))
  786.         return;
  787.  
  788.     // resurrect
  789.     GetPlayer()->ResurrectPlayer(GetPlayer()->InBattleground() ? 1.0f : 0.5f);
  790.  
  791.     // spawn bones
  792.     GetPlayer()->SpawnCorpseBones();
  793. }
  794.  
  795. void WorldSession::HandleResurrectResponseOpcode(WorldPacket& recvData)
  796. {
  797.     sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_RESURRECT_RESPONSE");
  798.  
  799.     uint64 guid;
  800.     uint8 status;
  801.     recvData >> guid;
  802.     recvData >> status;
  803.  
  804.     if (GetPlayer()->isAlive())
  805.         return;
  806.  
  807.     if (status == 0)
  808.     {
  809.         GetPlayer()->clearResurrectRequestData();           // reject
  810.         return;
  811.     }
  812.  
  813.     if (!GetPlayer()->isRessurectRequestedBy(guid))
  814.         return;
  815.  
  816.     GetPlayer()->ResurectUsingRequestData();
  817. }
  818.  
  819. void WorldSession::SendAreaTriggerMessage(const char* Text, ...)
  820. {
  821.     va_list ap;
  822.     char szStr [1024];
  823.     szStr[0] = '\0';
  824.  
  825.     va_start(ap, Text);
  826.     vsnprintf(szStr, 1024, Text, ap);
  827.     va_end(ap);
  828.  
  829.     uint32 length = strlen(szStr)+1;
  830.     WorldPacket data(SMSG_AREA_TRIGGER_MESSAGE, 4+length);
  831.     data << length;
  832.     data << szStr;
  833.     SendPacket(&data);
  834. }
  835.  
  836. void WorldSession::HandleAreaTriggerOpcode(WorldPacket& recvData)
  837. {
  838.     uint32 triggerId;
  839.     recvData >> triggerId;
  840.  
  841.     sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_AREATRIGGER. Trigger ID: %u", triggerId);
  842.  
  843.     Player* player = GetPlayer();
  844.     if (player->isInFlight())
  845.     {
  846.         sLog->outDebug(LOG_FILTER_NETWORKIO, "HandleAreaTriggerOpcode: Player '%s' (GUID: %u) in flight, ignore Area Trigger ID:%u",
  847.             player->GetName().c_str(), player->GetGUIDLow(), triggerId);
  848.         return;
  849.     }
  850.  
  851.     AreaTriggerEntry const* atEntry = sAreaTriggerStore.LookupEntry(triggerId);
  852.     if (!atEntry)
  853.     {
  854.         sLog->outDebug(LOG_FILTER_NETWORKIO, "HandleAreaTriggerOpcode: Player '%s' (GUID: %u) send unknown (by DBC) Area Trigger ID:%u",
  855.             player->GetName().c_str(), player->GetGUIDLow(), triggerId);
  856.         return;
  857.     }
  858.  
  859.     if (player->GetMapId() != atEntry->mapid)
  860.     {
  861.         sLog->outDebug(LOG_FILTER_NETWORKIO, "HandleAreaTriggerOpcode: Player '%s' (GUID: %u) too far (trigger map: %u player map: %u), ignore Area Trigger ID: %u",
  862.             player->GetName().c_str(), atEntry->mapid, player->GetMapId(), player->GetGUIDLow(), triggerId);
  863.         return;
  864.     }
  865.  
  866.     // delta is safe radius
  867.     const float delta = 5.0f;
  868.  
  869.     if (atEntry->radius > 0)
  870.     {
  871.         // if we have radius check it
  872.         float dist = player->GetDistance(atEntry->x, atEntry->y, atEntry->z);
  873.         if (dist > atEntry->radius + delta)
  874.         {
  875.             sLog->outDebug(LOG_FILTER_NETWORKIO, "HandleAreaTriggerOpcode: Player '%s' (GUID: %u) too far (radius: %f distance: %f), ignore Area Trigger ID: %u",
  876.                 player->GetName().c_str(), player->GetGUIDLow(), atEntry->radius, dist, triggerId);
  877.             return;
  878.         }
  879.     }
  880.     else
  881.     {
  882.         // we have only extent
  883.  
  884.         // rotate the players position instead of rotating the whole cube, that way we can make a simplified
  885.         // is-in-cube check and we have to calculate only one point instead of 4
  886.  
  887.         // 2PI = 360°, keep in mind that ingame orientation is counter-clockwise
  888.         double rotation = 2 * M_PI - atEntry->box_orientation;
  889.         double sinVal = std::sin(rotation);
  890.         double cosVal = std::cos(rotation);
  891.  
  892.         float playerBoxDistX = player->GetPositionX() - atEntry->x;
  893.         float playerBoxDistY = player->GetPositionY() - atEntry->y;
  894.  
  895.         float rotPlayerX = float(atEntry->x + playerBoxDistX * cosVal - playerBoxDistY*sinVal);
  896.         float rotPlayerY = float(atEntry->y + playerBoxDistY * cosVal + playerBoxDistX*sinVal);
  897.  
  898.         // box edges are parallel to coordiante axis, so we can treat every dimension independently :D
  899.         float dz = player->GetPositionZ() - atEntry->z;
  900.         float dx = rotPlayerX - atEntry->x;
  901.         float dy = rotPlayerY - atEntry->y;
  902.         if ((fabs(dx) > atEntry->box_x / 2 + delta) ||
  903.             (fabs(dy) > atEntry->box_y / 2 + delta) ||
  904.             (fabs(dz) > atEntry->box_z / 2 + delta))
  905.         {
  906.             sLog->outDebug(LOG_FILTER_NETWORKIO, "HandleAreaTriggerOpcode: Player '%s' (GUID: %u) too far (1/2 box X: %f 1/2 box Y: %f 1/2 box Z: %f rotatedPlayerX: %f rotatedPlayerY: %f dZ:%f), ignore Area Trigger ID: %u",
  907.                 player->GetName().c_str(), player->GetGUIDLow(), atEntry->box_x/2, atEntry->box_y/2, atEntry->box_z/2, rotPlayerX, rotPlayerY, dz, triggerId);
  908.             return;
  909.         }
  910.     }
  911.  
  912.     if (player->isDebugAreaTriggers)
  913.         ChatHandler(player->GetSession()).PSendSysMessage(LANG_DEBUG_AREATRIGGER_REACHED, triggerId);
  914.  
  915.     if (sScriptMgr->OnAreaTrigger(player, atEntry))
  916.         return;
  917.  
  918.     if (player->isAlive())
  919.         if (uint32 questId = sObjectMgr->GetQuestForAreaTrigger(triggerId))
  920.             if (player->GetQuestStatus(questId) == QUEST_STATUS_INCOMPLETE)
  921.                 player->AreaExploredOrEventHappens(questId);
  922.  
  923.     if (sObjectMgr->IsTavernAreaTrigger(triggerId))
  924.     {
  925.         // set resting flag we are in the inn
  926.         player->SetFlag(PLAYER_FLAGS, PLAYER_FLAGS_RESTING);
  927.         player->InnEnter(time(NULL), atEntry->mapid, atEntry->x, atEntry->y, atEntry->z);
  928.         player->SetRestType(REST_TYPE_IN_TAVERN);
  929.  
  930.         if (sWorld->IsFFAPvPRealm())
  931.             player->RemoveByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP);
  932.  
  933.         return;
  934.     }
  935.  
  936.     if (Battleground* bg = player->GetBattleground())
  937.         if (bg->GetStatus() == STATUS_IN_PROGRESS)
  938.         {
  939.             bg->HandleAreaTrigger(player, triggerId);
  940.             return;
  941.         }
  942.  
  943.     if (OutdoorPvP* pvp = player->GetOutdoorPvP())
  944.         if (pvp->HandleAreaTrigger(_player, triggerId))
  945.             return;
  946.  
  947.     AreaTrigger const* at = sObjectMgr->GetAreaTrigger(triggerId);
  948.     if (!at)
  949.         return;
  950.  
  951.     bool teleported = false;
  952.     if (player->GetMapId() != at->target_mapId)
  953.     {
  954.         if (!sMapMgr->CanPlayerEnter(at->target_mapId, player, false))
  955.             return;
  956.  
  957.         if (Group* group = player->GetGroup())
  958.             if (group->isLFGGroup() && player->GetMap()->IsDungeon())
  959.                 teleported = player->TeleportToBGEntryPoint();
  960.     }
  961.  
  962.     if (!teleported)
  963.         player->TeleportTo(at->target_mapId, at->target_X, at->target_Y, at->target_Z, at->target_Orientation, TELE_TO_NOT_LEAVE_TRANSPORT);
  964. }
  965.  
  966. void WorldSession::HandleUpdateAccountData(WorldPacket& recvData)
  967. {
  968.     sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_UPDATE_ACCOUNT_DATA");
  969.  
  970.     uint32 type, timestamp, decompressedSize;
  971.     recvData >> type >> timestamp >> decompressedSize;
  972.  
  973.     sLog->outDebug(LOG_FILTER_NETWORKIO, "UAD: type %u, time %u, decompressedSize %u", type, timestamp, decompressedSize);
  974.  
  975.     if (type > NUM_ACCOUNT_DATA_TYPES)
  976.         return;
  977.  
  978.     if (decompressedSize == 0)                               // erase
  979.     {
  980.         SetAccountData(AccountDataType(type), 0, "");
  981.  
  982.         WorldPacket data(SMSG_UPDATE_ACCOUNT_DATA_COMPLETE, 4+4);
  983.         data << uint32(type);
  984.         data << uint32(0);
  985.         SendPacket(&data);
  986.  
  987.         return;
  988.     }
  989.  
  990.     if (decompressedSize > 0xFFFF)
  991.     {
  992.         recvData.rfinish();                   // unnneded warning spam in this case
  993.         sLog->outError(LOG_FILTER_NETWORKIO, "UAD: Account data packet too big, size %u", decompressedSize);
  994.         return;
  995.     }
  996.  
  997.     ByteBuffer dest;
  998.     dest.resize(decompressedSize);
  999.  
  1000.     uLongf realSize = decompressedSize;
  1001.     if (uncompress(dest.contents(), &realSize, recvData.contents() + recvData.rpos(), recvData.size() - recvData.rpos()) != Z_OK)
  1002.     {
  1003.         recvData.rfinish();                   // unnneded warning spam in this case
  1004.         sLog->outError(LOG_FILTER_NETWORKIO, "UAD: Failed to decompress account data");
  1005.         return;
  1006.     }
  1007.  
  1008.     recvData.rfinish();                       // uncompress read (recvData.size() - recvData.rpos())
  1009.  
  1010.     std::string adata;
  1011.     dest >> adata;
  1012.  
  1013.     SetAccountData(AccountDataType(type), timestamp, adata);
  1014.  
  1015.     WorldPacket data(SMSG_UPDATE_ACCOUNT_DATA_COMPLETE, 4+4);
  1016.     data << uint32(type);
  1017.     data << uint32(0);
  1018.     SendPacket(&data);
  1019. }
  1020.  
  1021. void WorldSession::HandleRequestAccountData(WorldPacket& recvData)
  1022. {
  1023.     sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_REQUEST_ACCOUNT_DATA");
  1024.  
  1025.     uint32 type;
  1026.     recvData >> type;
  1027.  
  1028.     sLog->outDebug(LOG_FILTER_NETWORKIO, "RAD: type %u", type);
  1029.  
  1030.     if (type > NUM_ACCOUNT_DATA_TYPES)
  1031.         return;
  1032.  
  1033.     AccountData* adata = GetAccountData(AccountDataType(type));
  1034.  
  1035.     uint32 size = adata->Data.size();
  1036.  
  1037.     uLongf destSize = compressBound(size);
  1038.  
  1039.     ByteBuffer dest;
  1040.     dest.resize(destSize);
  1041.  
  1042.     if (size && compress(dest.contents(), &destSize, (uint8 const*)adata->Data.c_str(), size) != Z_OK)
  1043.     {
  1044.         sLog->outDebug(LOG_FILTER_NETWORKIO, "RAD: Failed to compress account data");
  1045.         return;
  1046.     }
  1047.  
  1048.     dest.resize(destSize);
  1049.  
  1050.     WorldPacket data(SMSG_UPDATE_ACCOUNT_DATA, 8+4+4+4+destSize);
  1051.     data << uint64(_player ? _player->GetGUID() : 0);       // player guid
  1052.     data << uint32(type);                                   // type (0-7)
  1053.     data << uint32(adata->Time);                            // unix time
  1054.     data << uint32(size);                                   // decompressed length
  1055.     data.append(dest);                                      // compressed data
  1056.     SendPacket(&data);
  1057. }
  1058.  
  1059. void WorldSession::HandleSetActionButtonOpcode(WorldPacket& recvData)
  1060. {
  1061.     uint8 button;
  1062.     uint32 packetData;
  1063.     recvData >> button >> packetData;
  1064.     sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_SET_ACTION_BUTTON Button: %u Data: %u", button, packetData);
  1065.  
  1066.     if (!packetData)
  1067.         GetPlayer()->removeActionButton(button);
  1068.     else
  1069.         GetPlayer()->addActionButton(button, ACTION_BUTTON_ACTION(packetData), ACTION_BUTTON_TYPE(packetData));
  1070. }
  1071.  
  1072. void WorldSession::HandleCompleteCinematic(WorldPacket& /*recvData*/)
  1073. {
  1074.     sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_COMPLETE_CINEMATIC");
  1075. }
  1076.  
  1077. void WorldSession::HandleNextCinematicCamera(WorldPacket& /*recvData*/)
  1078. {
  1079.     sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_NEXT_CINEMATIC_CAMERA");
  1080. }
  1081.  
  1082. void WorldSession::HandleMoveTimeSkippedOpcode(WorldPacket& recvData)
  1083. {
  1084.     /*  WorldSession::Update(getMSTime());*/
  1085.     sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_MOVE_TIME_SKIPPED");
  1086.  
  1087.     uint64 guid;
  1088.     recvData.readPackGUID(guid);
  1089.     recvData.read_skip<uint32>();
  1090.     /*
  1091.         uint64 guid;
  1092.         uint32 time_skipped;
  1093.         recvData >> guid;
  1094.         recvData >> time_skipped;
  1095.         sLog->outDebug(LOG_FILTER_PACKETIO, "WORLD: CMSG_MOVE_TIME_SKIPPED");
  1096.  
  1097.         /// TODO
  1098.         must be need use in Trinity
  1099.         We substract server Lags to move time (AntiLags)
  1100.         for exmaple
  1101.         GetPlayer()->ModifyLastMoveTime(-int32(time_skipped));
  1102.     */
  1103. }
  1104.  
  1105. void WorldSession::HandleFeatherFallAck(WorldPacket& recvData)
  1106. {
  1107.     sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: CMSG_MOVE_FEATHER_FALL_ACK");
  1108.  
  1109.     // no used
  1110.     recvData.rfinish();                       // prevent warnings spam
  1111. }
  1112.  
  1113. void WorldSession::HandleMoveUnRootAck(WorldPacket& recvData)
  1114. {
  1115.     // no used
  1116.     recvData.rfinish();                       // prevent warnings spam
  1117. /*
  1118.     uint64 guid;
  1119.     recvData >> guid;
  1120.  
  1121.     // now can skip not our packet
  1122.     if (_player->GetGUID() != guid)
  1123.     {
  1124.         recvData.rfinish();                   // prevent warnings spam
  1125.         return;
  1126.     }
  1127.  
  1128.     sLog->outDebug(LOG_FILTER_PACKETIO, "WORLD: CMSG_FORCE_MOVE_UNROOT_ACK");
  1129.  
  1130.     recvData.read_skip<uint32>();                          // unk
  1131.  
  1132.     MovementInfo movementInfo;
  1133.     movementInfo.guid = guid;
  1134.     ReadMovementInfo(recvData, &movementInfo);
  1135.     recvData.read_skip<float>();                           // unk2
  1136. */
  1137. }
  1138.  
  1139. void WorldSession::HandleMoveRootAck(WorldPacket& recvData)
  1140. {
  1141.     // no used
  1142.     recvData.rfinish();                       // prevent warnings spam
  1143. /*
  1144.     uint64 guid;
  1145.     recvData >> guid;
  1146.  
  1147.     // now can skip not our packet
  1148.     if (_player->GetGUID() != guid)
  1149.     {
  1150.         recvData.rfinish();                   // prevent warnings spam
  1151.         return;
  1152.     }
  1153.  
  1154.     sLog->outDebug(LOG_FILTER_PACKETIO, "WORLD: CMSG_FORCE_MOVE_ROOT_ACK");
  1155.  
  1156.     recvData.read_skip<uint32>();                          // unk
  1157.  
  1158.     MovementInfo movementInfo;
  1159.     ReadMovementInfo(recvData, &movementInfo);
  1160. */
  1161. }
  1162.  
  1163. void WorldSession::HandleSetActionBarToggles(WorldPacket& recvData)
  1164. {
  1165.     uint8 actionBar;
  1166.  
  1167.     recvData >> actionBar;
  1168.  
  1169.     if (!GetPlayer())                                        // ignore until not logged (check needed because STATUS_AUTHED)
  1170.     {
  1171.         if (actionBar != 0)
  1172.             sLog->outError(LOG_FILTER_NETWORKIO, "WorldSession::HandleSetActionBarToggles in not logged state with value: %u, ignored", uint32(actionBar));
  1173.         return;
  1174.     }
  1175.  
  1176.     GetPlayer()->SetByteValue(PLAYER_FIELD_BYTES, 2, actionBar);
  1177. }
  1178.  
  1179. void WorldSession::HandlePlayedTime(WorldPacket& recvData)
  1180. {
  1181.     uint8 unk1;
  1182.     recvData >> unk1;                                      // 0 or 1 expected
  1183.  
  1184.     WorldPacket data(SMSG_PLAYED_TIME, 4 + 4 + 1);
  1185.     data << uint32(_player->GetTotalPlayedTime());
  1186.     data << uint32(_player->GetLevelPlayedTime());
  1187.     data << uint8(unk1);                                    // 0 - will not show in chat frame
  1188.     SendPacket(&data);
  1189. }
  1190.  
  1191. void WorldSession::HandleInspectOpcode(WorldPacket& recvData)
  1192. {
  1193.     uint64 guid;
  1194.     recvData >> guid;
  1195.  
  1196.     sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_INSPECT");
  1197.  
  1198.     _player->SetSelection(guid);
  1199.  
  1200.     Player* player = ObjectAccessor::FindPlayer(guid);
  1201.     if (!player)
  1202.     {
  1203.         sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_INSPECT: No player found from GUID: " UI64FMTD, guid);
  1204.         return;
  1205.     }
  1206.  
  1207.     uint32 talent_points = 0x47;
  1208.     uint32 guid_size = player->GetPackGUID().wpos();
  1209.     WorldPacket data(SMSG_INSPECT_TALENT, guid_size+4+talent_points);
  1210.     data.append(player->GetPackGUID());
  1211.  
  1212.     if (sWorld->getBoolConfig(CONFIG_TALENTS_INSPECTING) || _player->isGameMaster())
  1213.         player->BuildPlayerTalentsInfoData(&data);
  1214.     else
  1215.     {
  1216.         data << uint32(0);                                  // unspentTalentPoints
  1217.         data << uint8(0);                                   // talentGroupCount
  1218.         data << uint8(0);                                   // talentGroupIndex
  1219.     }
  1220.  
  1221.     player->BuildEnchantmentsInfoData(&data);
  1222.     SendPacket(&data);
  1223. }
  1224.  
  1225. void WorldSession::HandleInspectHonorStatsOpcode(WorldPacket& recvData)
  1226. {
  1227.     uint64 guid;
  1228.     recvData >> guid;
  1229.  
  1230.     Player* player = ObjectAccessor::FindPlayer(guid);
  1231.  
  1232.     if (!player)
  1233.     {
  1234.         sLog->outDebug(LOG_FILTER_NETWORKIO, "MSG_INSPECT_HONOR_STATS: No player found from GUID: " UI64FMTD, guid);
  1235.         return;
  1236.     }
  1237.  
  1238.     WorldPacket data(MSG_INSPECT_HONOR_STATS, 8+1+4*4);
  1239.     data << uint64(player->GetGUID());
  1240.     data << uint8(player->GetHonorPoints());
  1241.     data << uint32(player->GetUInt32Value(PLAYER_FIELD_KILLS));
  1242.     data << uint32(player->GetUInt32Value(PLAYER_FIELD_TODAY_CONTRIBUTION));
  1243.     data << uint32(player->GetUInt32Value(PLAYER_FIELD_YESTERDAY_CONTRIBUTION));
  1244.     data << uint32(player->GetUInt32Value(PLAYER_FIELD_LIFETIME_HONORABLE_KILLS));
  1245.     SendPacket(&data);
  1246. }
  1247.  
  1248. void WorldSession::HandleWorldTeleportOpcode(WorldPacket& recvData)
  1249. {
  1250.     uint32 time;
  1251.     uint32 mapid;
  1252.     float PositionX;
  1253.     float PositionY;
  1254.     float PositionZ;
  1255.     float Orientation;
  1256.  
  1257.     recvData >> time;                                      // time in m.sec.
  1258.     recvData >> mapid;
  1259.     recvData >> PositionX;
  1260.     recvData >> PositionY;
  1261.     recvData >> PositionZ;
  1262.     recvData >> Orientation;                               // o (3.141593 = 180 degrees)
  1263.  
  1264.     sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_WORLD_TELEPORT");
  1265.  
  1266.     if (GetPlayer()->isInFlight())
  1267.     {
  1268.         sLog->outDebug(LOG_FILTER_NETWORKIO, "Player '%s' (GUID: %u) in flight, ignore worldport command.",
  1269.             GetPlayer()->GetName().c_str(), GetPlayer()->GetGUIDLow());
  1270.         return;
  1271.     }
  1272.  
  1273.     sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_WORLD_TELEPORT: Player = %s, Time = %u, map = %u, x = %f, y = %f, z = %f, o = %f",
  1274.         GetPlayer()->GetName().c_str(), time, mapid, PositionX, PositionY, PositionZ, Orientation);
  1275.  
  1276.     if (AccountMgr::IsAdminAccount(GetSecurity()))
  1277.         GetPlayer()->TeleportTo(mapid, PositionX, PositionY, PositionZ, Orientation);
  1278.     else
  1279.         SendNotification(LANG_YOU_NOT_HAVE_PERMISSION);
  1280. }
  1281.  
  1282. void WorldSession::HandleWhoisOpcode(WorldPacket& recvData)
  1283. {
  1284.     sLog->outDebug(LOG_FILTER_NETWORKIO, "Received opcode CMSG_WHOIS");
  1285.     std::string charname;
  1286.     recvData >> charname;
  1287.  
  1288.     if (!AccountMgr::IsAdminAccount(GetSecurity()))
  1289.     {
  1290.         SendNotification(LANG_YOU_NOT_HAVE_PERMISSION);
  1291.         return;
  1292.     }
  1293.  
  1294.     if (charname.empty() || !normalizePlayerName (charname))
  1295.     {
  1296.         SendNotification(LANG_NEED_CHARACTER_NAME);
  1297.         return;
  1298.     }
  1299.  
  1300.     Player* player = sObjectAccessor->FindPlayerByName(charname);
  1301.  
  1302.     if (!player)
  1303.     {
  1304.         SendNotification(LANG_PLAYER_NOT_EXIST_OR_OFFLINE, charname.c_str());
  1305.         return;
  1306.     }
  1307.  
  1308.     uint32 accid = player->GetSession()->GetAccountId();
  1309.  
  1310.     PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_ACCOUNT_WHOIS);
  1311.  
  1312.     stmt->setUInt32(0, accid);
  1313.  
  1314.     PreparedQueryResult result = LoginDatabase.Query(stmt);
  1315.  
  1316.     if (!result)
  1317.     {
  1318.         SendNotification(LANG_ACCOUNT_FOR_PLAYER_NOT_FOUND, charname.c_str());
  1319.         return;
  1320.     }
  1321.  
  1322.     Field* fields = result->Fetch();
  1323.     std::string acc = fields[0].GetString();
  1324.     if (acc.empty())
  1325.         acc = "Unknown";
  1326.     std::string email = fields[1].GetString();
  1327.     if (email.empty())
  1328.         email = "Unknown";
  1329.     std::string lastip = fields[2].GetString();
  1330.     if (lastip.empty())
  1331.         lastip = "Unknown";
  1332.  
  1333.     std::string msg = charname + "'s " + "account is " + acc + ", e-mail: " + email + ", last ip: " + lastip;
  1334.  
  1335.     WorldPacket data(SMSG_WHOIS, msg.size()+1);
  1336.     data << msg;
  1337.     SendPacket(&data);
  1338.  
  1339.     sLog->outDebug(LOG_FILTER_NETWORKIO, "Received whois command from player %s for character %s",
  1340.         GetPlayer()->GetName().c_str(), charname.c_str());
  1341. }
  1342.  
  1343. void WorldSession::HandleComplainOpcode(WorldPacket& recvData)
  1344. {
  1345.     sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: CMSG_COMPLAIN");
  1346.  
  1347.     uint8 spam_type;                                        // 0 - mail, 1 - chat
  1348.     uint64 spammer_guid;
  1349.     uint32 unk1 = 0;
  1350.     uint32 unk2 = 0;
  1351.     uint32 unk3 = 0;
  1352.     uint32 unk4 = 0;
  1353.     std::string description = "";
  1354.     recvData >> spam_type;                                 // unk 0x01 const, may be spam type (mail/chat)
  1355.     recvData >> spammer_guid;                              // player guid
  1356.     switch (spam_type)
  1357.     {
  1358.         case 0:
  1359.             recvData >> unk1;                              // const 0
  1360.             recvData >> unk2;                              // probably mail id
  1361.             recvData >> unk3;                              // const 0
  1362.             break;
  1363.         case 1:
  1364.             recvData >> unk1;                              // probably language
  1365.             recvData >> unk2;                              // message type?
  1366.             recvData >> unk3;                              // probably channel id
  1367.             recvData >> unk4;                              // time
  1368.             recvData >> description;                       // spam description string (messagetype, channel name, player name, message)
  1369.             break;
  1370.     }
  1371.  
  1372.     // NOTE: all chat messages from this spammer automatically ignored by spam reporter until logout in case chat spam.
  1373.     // if it's mail spam - ALL mails from this spammer automatically removed by client
  1374.  
  1375.     // Complaint Received message
  1376.     WorldPacket data(SMSG_COMPLAIN_RESULT, 1);
  1377.     data << uint8(0);
  1378.     SendPacket(&data);
  1379.  
  1380.     sLog->outDebug(LOG_FILTER_NETWORKIO, "REPORT SPAM: type %u, guid %u, unk1 %u, unk2 %u, unk3 %u, unk4 %u, message %s", spam_type, GUID_LOPART(spammer_guid), unk1, unk2, unk3, unk4, description.c_str());
  1381. }
  1382.  
  1383. void WorldSession::HandleRealmSplitOpcode(WorldPacket& recvData)
  1384. {
  1385.     sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_REALM_SPLIT");
  1386.  
  1387.     uint32 unk;
  1388.     std::string split_date = "01/01/01";
  1389.     recvData >> unk;
  1390.  
  1391.     WorldPacket data(SMSG_REALM_SPLIT, 4+4+split_date.size()+1);
  1392.     data << unk;
  1393.     data << uint32(0x00000000);                             // realm split state
  1394.     // split states:
  1395.     // 0x0 realm normal
  1396.     // 0x1 realm split
  1397.     // 0x2 realm split pending
  1398.     data << split_date;
  1399.     SendPacket(&data);
  1400.     //sLog->outDebug("response sent %u", unk);
  1401. }
  1402.  
  1403. void WorldSession::HandleFarSightOpcode(WorldPacket& recvData)
  1404. {
  1405.     sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: CMSG_FAR_SIGHT");
  1406.  
  1407.     bool apply;
  1408.     recvData >> apply;
  1409.  
  1410.     if (apply)
  1411.     {
  1412.         sLog->outDebug(LOG_FILTER_NETWORKIO, "Added FarSight " UI64FMTD " to player %u", _player->GetUInt64Value(PLAYER_FARSIGHT), _player->GetGUIDLow());
  1413.         if (WorldObject* target = _player->GetViewpoint())
  1414.             _player->SetSeer(target);
  1415.         else
  1416.             sLog->outError(LOG_FILTER_NETWORKIO, "Player %s requests non-existing seer " UI64FMTD, _player->GetName().c_str(), _player->GetUInt64Value(PLAYER_FARSIGHT));
  1417.     }
  1418.     else
  1419.     {
  1420.         sLog->outDebug(LOG_FILTER_NETWORKIO, "Player %u set vision to self", _player->GetGUIDLow());
  1421.         _player->SetSeer(_player);
  1422.     }
  1423.  
  1424.     GetPlayer()->UpdateVisibilityForPlayer();
  1425. }
  1426.  
  1427. void WorldSession::HandleSetTitleOpcode(WorldPacket& recvData)
  1428. {
  1429.     sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_SET_TITLE");
  1430.  
  1431.     int32 title;
  1432.     recvData >> title;
  1433.  
  1434.     // -1 at none
  1435.     if (title > 0 && title < MAX_TITLE_INDEX)
  1436.     {
  1437.        if (!GetPlayer()->HasTitle(title))
  1438.             return;
  1439.     }
  1440.     else
  1441.         title = 0;
  1442.  
  1443.     GetPlayer()->SetUInt32Value(PLAYER_CHOSEN_TITLE, title);
  1444. }
  1445.  
  1446. void WorldSession::HandleTimeSyncResp(WorldPacket& recvData)
  1447. {
  1448.     sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_TIME_SYNC_RESP");
  1449.  
  1450.     uint32 counter, clientTicks;
  1451.     recvData >> counter >> clientTicks;
  1452.  
  1453.     if (counter != _player->m_timeSyncCounter - 1)
  1454.         sLog->outDebug(LOG_FILTER_NETWORKIO, "Wrong time sync counter from player %s (cheater?)", _player->GetName().c_str());
  1455.  
  1456.     sLog->outDebug(LOG_FILTER_NETWORKIO, "Time sync received: counter %u, client ticks %u, time since last sync %u", counter, clientTicks, clientTicks - _player->m_timeSyncClient);
  1457.  
  1458.     uint32 ourTicks = clientTicks + (getMSTime() - _player->m_timeSyncServer);
  1459.  
  1460.     // diff should be small
  1461.     sLog->outDebug(LOG_FILTER_NETWORKIO, "Our ticks: %u, diff %u, latency %u", ourTicks, ourTicks - clientTicks, GetLatency());
  1462.  
  1463.     _player->m_timeSyncClient = clientTicks;
  1464. }
  1465.  
  1466. void WorldSession::HandleResetInstancesOpcode(WorldPacket& /*recvData*/)
  1467. {
  1468.     sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: CMSG_RESET_INSTANCES");
  1469.  
  1470.     if (Group* group = _player->GetGroup())
  1471.     {
  1472.         if (group->IsLeader(_player->GetGUID()))
  1473.             group->ResetInstances(INSTANCE_RESET_ALL, false, _player);
  1474.     }
  1475.     else
  1476.         _player->ResetInstances(INSTANCE_RESET_ALL, false);
  1477. }
  1478.  
  1479. void WorldSession::HandleSetDungeonDifficultyOpcode(WorldPacket& recvData)
  1480. {
  1481.     sLog->outDebug(LOG_FILTER_NETWORKIO, "MSG_SET_DUNGEON_DIFFICULTY");
  1482.  
  1483.     uint32 mode;
  1484.     recvData >> mode;
  1485.  
  1486.     if (mode >= MAX_DUNGEON_DIFFICULTY)
  1487.     {
  1488.         sLog->outDebug(LOG_FILTER_NETWORKIO, "WorldSession::HandleSetDungeonDifficultyOpcode: player %d sent an invalid instance mode %d!", _player->GetGUIDLow(), mode);
  1489.         return;
  1490.     }
  1491.  
  1492.     if (Difficulty(mode) == _player->GetDungeonDifficulty())
  1493.         return;
  1494.  
  1495.     // cannot reset while in an instance
  1496.     Map* map = _player->FindMap();
  1497.     if (map && map->IsDungeon())
  1498.     {
  1499.         sLog->outDebug(LOG_FILTER_NETWORKIO, "WorldSession::HandleSetDungeonDifficultyOpcode: player (Name: %s, GUID: %u) tried to reset the instance while player is inside!",
  1500.             _player->GetName().c_str(), _player->GetGUIDLow());
  1501.         return;
  1502.     }
  1503.  
  1504.     Group* group = _player->GetGroup();
  1505.     if (group)
  1506.     {
  1507.         if (group->IsLeader(_player->GetGUID()))
  1508.         {
  1509.             for (GroupReference* itr = group->GetFirstMember(); itr != NULL; itr = itr->next())
  1510.             {
  1511.                 Player* groupGuy = itr->getSource();
  1512.                 if (!groupGuy)
  1513.                     continue;
  1514.  
  1515.                 if (!groupGuy->IsInMap(groupGuy))
  1516.                     return;
  1517.  
  1518.                 if (groupGuy->GetMap()->IsNonRaidDungeon())
  1519.                 {
  1520.                     sLog->outDebug(LOG_FILTER_NETWORKIO, "WorldSession::HandleSetDungeonDifficultyOpcode: player %d tried to reset the instance while group member (Name: %s, GUID: %u) is inside!",
  1521.                         _player->GetGUIDLow(), groupGuy->GetName().c_str(), groupGuy->GetGUIDLow());
  1522.                     return;
  1523.                 }
  1524.             }
  1525.             // the difficulty is set even if the instances can't be reset
  1526.             //_player->SendDungeonDifficulty(true);
  1527.             group->ResetInstances(INSTANCE_RESET_CHANGE_DIFFICULTY, false, _player);
  1528.             group->SetDungeonDifficulty(Difficulty(mode));
  1529.         }
  1530.     }
  1531.     else
  1532.     {
  1533.         _player->ResetInstances(INSTANCE_RESET_CHANGE_DIFFICULTY, false);
  1534.         _player->SetDungeonDifficulty(Difficulty(mode));
  1535.     }
  1536. }
  1537.  
  1538. void WorldSession::HandleSetRaidDifficultyOpcode(WorldPacket& recvData)
  1539. {
  1540.     sLog->outDebug(LOG_FILTER_NETWORKIO, "MSG_SET_RAID_DIFFICULTY");
  1541.  
  1542.     uint32 mode;
  1543.     recvData >> mode;
  1544.  
  1545.     if (mode >= MAX_RAID_DIFFICULTY)
  1546.     {
  1547.         sLog->outError(LOG_FILTER_NETWORKIO, "WorldSession::HandleSetRaidDifficultyOpcode: player %d sent an invalid instance mode %d!", _player->GetGUIDLow(), mode);
  1548.         return;
  1549.     }
  1550.  
  1551.     // cannot reset while in an instance
  1552.     Map* map = _player->FindMap();
  1553.     if (map && map->IsDungeon())
  1554.     {
  1555.         sLog->outDebug(LOG_FILTER_NETWORKIO, "WorldSession::HandleSetRaidDifficultyOpcode: player %d tried to reset the instance while inside!", _player->GetGUIDLow());
  1556.         return;
  1557.     }
  1558.  
  1559.     if (Difficulty(mode) == _player->GetRaidDifficulty())
  1560.         return;
  1561.  
  1562.     Group* group = _player->GetGroup();
  1563.     if (group)
  1564.     {
  1565.         if (group->IsLeader(_player->GetGUID()))
  1566.         {
  1567.             for (GroupReference* itr = group->GetFirstMember(); itr != NULL; itr = itr->next())
  1568.             {
  1569.                 Player* groupGuy = itr->getSource();
  1570.                 if (!groupGuy)
  1571.                     continue;
  1572.  
  1573.                 if (!groupGuy->IsInMap(groupGuy))
  1574.                     return;
  1575.  
  1576.                 if (groupGuy->GetMap()->IsRaid())
  1577.                 {
  1578.                     sLog->outDebug(LOG_FILTER_NETWORKIO, "WorldSession::HandleSetRaidDifficultyOpcode: player %d tried to reset the instance while inside!", _player->GetGUIDLow());
  1579.                     return;
  1580.                 }
  1581.             }
  1582.             // the difficulty is set even if the instances can't be reset
  1583.             //_player->SendDungeonDifficulty(true);
  1584.             group->ResetInstances(INSTANCE_RESET_CHANGE_DIFFICULTY, true, _player);
  1585.             group->SetRaidDifficulty(Difficulty(mode));
  1586.         }
  1587.     }
  1588.     else
  1589.     {
  1590.         _player->ResetInstances(INSTANCE_RESET_CHANGE_DIFFICULTY, true);
  1591.         _player->SetRaidDifficulty(Difficulty(mode));
  1592.     }
  1593. }
  1594.  
  1595. void WorldSession::HandleCancelMountAuraOpcode(WorldPacket& /*recvData*/)
  1596. {
  1597.     sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: CMSG_CANCEL_MOUNT_AURA");
  1598.  
  1599.     //If player is not mounted, so go out :)
  1600.     if (!_player->IsMounted())                              // not blizz like; no any messages on blizz
  1601.     {
  1602.         ChatHandler(this).SendSysMessage(LANG_CHAR_NON_MOUNTED);
  1603.         return;
  1604.     }
  1605.  
  1606.     if (_player->isInFlight())                               // not blizz like; no any messages on blizz
  1607.     {
  1608.         ChatHandler(this).SendSysMessage(LANG_YOU_IN_FLIGHT);
  1609.         return;
  1610.     }
  1611.  
  1612.     _player->Dismount();
  1613.     _player->RemoveAurasByType(SPELL_AURA_MOUNTED);
  1614. }
  1615.  
  1616. void WorldSession::HandleMoveSetCanFlyAckOpcode(WorldPacket& recvData)
  1617. {
  1618.     // fly mode on/off
  1619.     sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: CMSG_MOVE_SET_CAN_FLY_ACK");
  1620.  
  1621.     uint64 guid;                                            // guid - unused
  1622.     recvData.readPackGUID(guid);
  1623.  
  1624.     recvData.read_skip<uint32>();                          // unk
  1625.  
  1626.     MovementInfo movementInfo;
  1627.     movementInfo.guid = guid;
  1628.     ReadMovementInfo(recvData, &movementInfo);
  1629.  
  1630.     recvData.read_skip<float>();                           // unk2
  1631.  
  1632.     _player->m_mover->m_movementInfo.flags = movementInfo.GetMovementFlags();
  1633. }
  1634.  
  1635. void WorldSession::HandleRequestPetInfoOpcode(WorldPacket& /*recvData */)
  1636. {
  1637.     /*
  1638.         sLog->outDebug(LOG_FILTER_PACKETIO, "WORLD: CMSG_REQUEST_PET_INFO");
  1639.         recvData.hexlike();
  1640.     */
  1641. }
  1642.  
  1643. void WorldSession::HandleSetTaxiBenchmarkOpcode(WorldPacket& recvData)
  1644. {
  1645.     uint8 mode;
  1646.     recvData >> mode;
  1647.  
  1648.     sLog->outDebug(LOG_FILTER_NETWORKIO, "Client used \"/timetest %d\" command", mode);
  1649. }
  1650.  
  1651. void WorldSession::HandleQueryInspectAchievements(WorldPacket& recvData)
  1652. {
  1653.     uint64 guid;
  1654.     recvData.readPackGUID(guid);
  1655.  
  1656.     sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_QUERY_INSPECT_ACHIEVEMENTS [" UI64FMTD "] Inspected Player [" UI64FMTD "]", _player->GetGUID(), guid);
  1657.     Player* player = ObjectAccessor::FindPlayer(guid);
  1658.     if (!player)
  1659.         return;
  1660.  
  1661.     player->SendRespondInspectAchievements(_player);
  1662. }
  1663.  
  1664. void WorldSession::HandleWorldStateUITimerUpdate(WorldPacket& /*recvData*/)
  1665. {
  1666.     // empty opcode
  1667.     sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: CMSG_WORLD_STATE_UI_TIMER_UPDATE");
  1668.  
  1669.     WorldPacket data(SMSG_WORLD_STATE_UI_TIMER_UPDATE, 4);
  1670.     data << uint32(time(NULL));
  1671.     SendPacket(&data);
  1672. }
  1673.  
  1674. void WorldSession::HandleReadyForAccountDataTimes(WorldPacket& /*recvData*/)
  1675. {
  1676.     // empty opcode
  1677.     sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: CMSG_READY_FOR_ACCOUNT_DATA_TIMES");
  1678.  
  1679.     SendAccountDataTimes(GLOBAL_CACHE_MASK);
  1680. }
  1681.  
  1682. void WorldSession::SendSetPhaseShift(uint32 PhaseShift)
  1683. {
  1684.     WorldPacket data(SMSG_SET_PHASE_SHIFT, 4);
  1685.     data << uint32(PhaseShift);
  1686.     SendPacket(&data);
  1687. }
  1688. // Battlefield and Battleground
  1689. void WorldSession::HandleAreaSpiritHealerQueryOpcode(WorldPacket& recvData)
  1690. {
  1691.     sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: CMSG_AREA_SPIRIT_HEALER_QUERY");
  1692.  
  1693.     Battleground* bg = _player->GetBattleground();
  1694.  
  1695.     uint64 guid;
  1696.     recvData >> guid;
  1697.  
  1698.     Creature* unit = GetPlayer()->GetMap()->GetCreature(guid);
  1699.     if (!unit)
  1700.         return;
  1701.  
  1702.     if (!unit->isSpiritService())                            // it's not spirit service
  1703.         return;
  1704.  
  1705.     if (bg)
  1706.         sBattlegroundMgr->SendAreaSpiritHealerQueryOpcode(_player, bg, guid);
  1707.  
  1708.     if (Battlefield* bf = sBattlefieldMgr->GetBattlefieldToZoneId(_player->GetZoneId()))
  1709.         bf->SendAreaSpiritHealerQueryOpcode(_player, guid);
  1710. }
  1711.  
  1712. void WorldSession::HandleAreaSpiritHealerQueueOpcode(WorldPacket& recvData)
  1713. {
  1714.     sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: CMSG_AREA_SPIRIT_HEALER_QUEUE");
  1715.  
  1716.     Battleground* bg = _player->GetBattleground();
  1717.  
  1718.     uint64 guid;
  1719.     recvData >> guid;
  1720.  
  1721.     Creature* unit = GetPlayer()->GetMap()->GetCreature(guid);
  1722.     if (!unit)
  1723.         return;
  1724.  
  1725.     if (!unit->isSpiritService())                            // it's not spirit service
  1726.         return;
  1727.  
  1728.     if (bg)
  1729.         bg->AddPlayerToResurrectQueue(guid, _player->GetGUID());
  1730.  
  1731.     if (Battlefield* bf = sBattlefieldMgr->GetBattlefieldToZoneId(_player->GetZoneId()))
  1732.         bf->AddPlayerToResurrectQueue(guid, _player->GetGUID());
  1733. }
  1734.  
  1735. void WorldSession::HandleHearthAndResurrect(WorldPacket& /*recvData*/)
  1736. {
  1737.     if (_player->isInFlight())
  1738.         return;
  1739.  
  1740.     if (/*Battlefield* bf = */sBattlefieldMgr->GetBattlefieldToZoneId(_player->GetZoneId()))
  1741.     {
  1742.         // bf->PlayerAskToLeave(_player); FIXME
  1743.         return;
  1744.     }
  1745.  
  1746.     AreaTableEntry const* atEntry = GetAreaEntryByAreaID(_player->GetAreaId());
  1747.     if (!atEntry || !(atEntry->flags & AREA_FLAG_WINTERGRASP_2))
  1748.         return;
  1749.  
  1750.     _player->BuildPlayerRepop();
  1751.     _player->ResurrectPlayer(100);
  1752.     _player->TeleportTo(_player->m_homebindMapId, _player->m_homebindX, _player->m_homebindY, _player->m_homebindZ, _player->GetOrientation());
  1753. }
  1754.  
  1755. void WorldSession::HandleInstanceLockResponse(WorldPacket& recvPacket)
  1756. {
  1757.     uint8 accept;
  1758.     recvPacket >> accept;
  1759.  
  1760.     if (!_player->HasPendingBind())
  1761.     {
  1762.         sLog->outInfo(LOG_FILTER_NETWORKIO, "InstanceLockResponse: Player %s (guid %u) tried to bind himself/teleport to graveyard without a pending bind!",
  1763.             _player->GetName().c_str(), _player->GetGUIDLow());
  1764.         return;
  1765.     }
  1766.  
  1767.     if (accept)
  1768.         _player->BindToInstance();
  1769.     else
  1770.         _player->RepopAtGraveyard();
  1771.  
  1772.     _player->SetPendingBind(0, 0);
  1773. }
  1774.  
  1775. void WorldSession::HandleUpdateMissileTrajectory(WorldPacket& recvPacket)
  1776. {
  1777.     sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: CMSG_UPDATE_MISSILE_TRAJECTORY");
  1778.  
  1779.     uint64 guid;
  1780.     uint32 spellId;
  1781.     float elevation, speed;
  1782.     float curX, curY, curZ;
  1783.     float targetX, targetY, targetZ;
  1784.     uint8 moveStop;
  1785.  
  1786.     recvPacket >> guid >> spellId >> elevation >> speed;
  1787.     recvPacket >> curX >> curY >> curZ;
  1788.     recvPacket >> targetX >> targetY >> targetZ;
  1789.     recvPacket >> moveStop;
  1790.  
  1791.     Unit* caster = ObjectAccessor::GetUnit(*_player, guid);
  1792.     Spell* spell = caster ? caster->GetCurrentSpell(CURRENT_GENERIC_SPELL) : NULL;
  1793.     if (!spell || spell->m_spellInfo->Id != spellId || !spell->m_targets.HasDst() || !spell->m_targets.HasSrc())
  1794.     {
  1795.         recvPacket.rfinish();
  1796.         return;
  1797.     }
  1798.  
  1799.     Position pos = *spell->m_targets.GetSrcPos();
  1800.     pos.Relocate(curX, curY, curZ);
  1801.     spell->m_targets.ModSrc(pos);
  1802.  
  1803.     pos = *spell->m_targets.GetDstPos();
  1804.     pos.Relocate(targetX, targetY, targetZ);
  1805.     spell->m_targets.ModDst(pos);
  1806.  
  1807.     spell->m_targets.SetElevation(elevation);
  1808.     spell->m_targets.SetSpeed(speed);
  1809.  
  1810.     if (moveStop)
  1811.     {
  1812.         uint32 opcode;
  1813.         recvPacket >> opcode;
  1814.         recvPacket.SetOpcode(opcode);
  1815.         HandleMovementOpcodes(recvPacket);
  1816.     }
  1817. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement