Advertisement
darksoke

MiscHandler.cpp

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