diff options
Diffstat (limited to 'src')
118 files changed, 1970 insertions, 1035 deletions
diff --git a/src/common/Collision/Management/MMapManager.cpp b/src/common/Collision/Management/MMapManager.cpp index 3f873b704d1..486219b9f32 100644 --- a/src/common/Collision/Management/MMapManager.cpp +++ b/src/common/Collision/Management/MMapManager.cpp @@ -179,7 +179,7 @@ namespace MMAP dtTileRef tileRef = 0; // memory allocated for data is now managed by detour, and will be deallocated when the tile is removed - if (dtStatusSucceed(mmap->navMesh->addTile(data, fileHeader.size, 0/*DT_TILE_FREE_DATA*/, 0, &tileRef))) + if (dtStatusSucceed(mmap->navMesh->addTile(data, fileHeader.size, DT_TILE_FREE_DATA, 0, &tileRef))) { mmap->loadedTileRefs.insert(std::pair<uint32, dtTileRef>(packedGridPos, tileRef)); ++loadedTiles; diff --git a/src/common/Threading/MPSCQueue.h b/src/common/Threading/MPSCQueue.h new file mode 100644 index 00000000000..09648b844be --- /dev/null +++ b/src/common/Threading/MPSCQueue.h @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef MPSCQueue_h__ +#define MPSCQueue_h__ + +#include <atomic> +#include <utility> + +// C++ implementation of Dmitry Vyukov's lock free MPSC queue +// http://www.1024cores.net/home/lock-free-algorithms/queues/non-intrusive-mpsc-node-based-queue +template<typename T> +class MPSCQueue +{ +public: + MPSCQueue() : _head(new Node()), _tail(_head.load(std::memory_order_relaxed)) + { + Node* front = _head.load(std::memory_order_relaxed); + front->Next.store(nullptr, std::memory_order_relaxed); + } + + ~MPSCQueue() + { + T* output; + while (this->Dequeue(output)) + ; + + Node* front = _head.load(std::memory_order_relaxed); + delete front; + } + + void Enqueue(T* input) + { + Node* node = new Node(input); + Node* prevHead = _head.exchange(node, std::memory_order_acq_rel); + prevHead->Next.store(node, std::memory_order_release); + } + + bool Dequeue(T*& result) + { + Node* tail = _tail.load(std::memory_order_relaxed); + Node* next = tail->Next.load(std::memory_order_acquire); + if (!next) + return false; + + result = next->Data; + _tail.store(next, std::memory_order_release); + delete tail; + return true; + } + +private: + struct Node + { + Node() = default; + explicit Node(T* data) : Data(data) { Next.store(nullptr, std::memory_order_relaxed); } + + T* Data; + std::atomic<Node*> Next; + }; + + std::atomic<Node*> _head; + std::atomic<Node*> _tail; + + MPSCQueue(MPSCQueue const&) = delete; + MPSCQueue& operator=(MPSCQueue const&) = delete; +}; + +#endif // MPSCQueue_h__ diff --git a/src/server/bnetserver/Main.cpp b/src/server/bnetserver/Main.cpp index 3d1481fae9e..740a0efa438 100644 --- a/src/server/bnetserver/Main.cpp +++ b/src/server/bnetserver/Main.cpp @@ -71,13 +71,16 @@ void ServiceStatusWatcher(boost::system::error_code const& error); bool StartDB(); void StopDB(); -void SignalHandler(const boost::system::error_code& error, int signalNumber); -void KeepDatabaseAliveHandler(const boost::system::error_code& error); +void SignalHandler(boost::system::error_code const& error, int signalNumber); +void KeepDatabaseAliveHandler(boost::system::error_code const& error); +void BanExpiryHandler(boost::system::error_code const& error); variables_map GetConsoleArguments(int argc, char** argv, std::string& configFile, std::string& configService); static boost::asio::io_service* _ioService; static boost::asio::deadline_timer* _dbPingTimer; static uint32 _dbPingInterval; +static boost::asio::deadline_timer* _banExpiryCheckTimer; +static uint32 _banExpiryCheckInterval; LoginDatabaseWorkerPool LoginDatabase; int main(int argc, char** argv) @@ -180,6 +183,11 @@ int main(int argc, char** argv) _dbPingTimer->expires_from_now(boost::posix_time::minutes(_dbPingInterval)); _dbPingTimer->async_wait(KeepDatabaseAliveHandler); + _banExpiryCheckInterval = sConfigMgr->GetIntDefault("BanExpiryCheckInterval", 60); + _banExpiryCheckTimer = new boost::asio::deadline_timer(*_ioService); + _banExpiryCheckTimer->expires_from_now(boost::posix_time::seconds(_banExpiryCheckInterval)); + _banExpiryCheckTimer->async_wait(BanExpiryHandler); + sComponentMgr->Load(); sModuleMgr->Load(); @@ -195,6 +203,7 @@ int main(int argc, char** argv) // Start the io service worker loop _ioService->run(); + _banExpiryCheckTimer->cancel(); _dbPingTimer->cancel(); sSessionMgr.StopNetwork(); @@ -210,6 +219,7 @@ int main(int argc, char** argv) signals.cancel(); + delete _banExpiryCheckTimer; delete _dbPingTimer; delete _ioService; return 0; @@ -240,13 +250,13 @@ void StopDB() MySQL::Library_End(); } -void SignalHandler(const boost::system::error_code& error, int /*signalNumber*/) +void SignalHandler(boost::system::error_code const& error, int /*signalNumber*/) { if (!error) _ioService->stop(); } -void KeepDatabaseAliveHandler(const boost::system::error_code& error) +void KeepDatabaseAliveHandler(boost::system::error_code const& error) { if (!error) { @@ -258,6 +268,18 @@ void KeepDatabaseAliveHandler(const boost::system::error_code& error) } } +void BanExpiryHandler(boost::system::error_code const& error) +{ + if (!error) + { + LoginDatabase.Execute(LoginDatabase.GetPreparedStatement(LOGIN_DEL_EXPIRED_IP_BANS)); + LoginDatabase.Execute(LoginDatabase.GetPreparedStatement(LOGIN_UPD_EXPIRED_ACCOUNT_BANS)); + + _banExpiryCheckTimer->expires_from_now(boost::posix_time::seconds(_banExpiryCheckInterval)); + _banExpiryCheckTimer->async_wait(BanExpiryHandler); + } +} + #if PLATFORM == PLATFORM_WINDOWS void ServiceStatusWatcher(boost::system::error_code const& error) { diff --git a/src/server/bnetserver/Server/Session.cpp b/src/server/bnetserver/Server/Session.cpp index 51a50b48a5b..4d54562501f 100644 --- a/src/server/bnetserver/Server/Session.cpp +++ b/src/server/bnetserver/Server/Session.cpp @@ -615,18 +615,6 @@ void Battlenet::Session::Start() std::string ip_address = GetRemoteIpAddress().to_string(); TC_LOG_TRACE("session", "Accepted connection from %s", ip_address.c_str()); - if (_queryCallback) - { - Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse(); - logonResponse->SetAuthResult(AUTH_LOGON_TOO_FAST); - AsyncWrite(logonResponse); - TC_LOG_DEBUG("session", "[Session::Start] %s attempted to log too quick after previous attempt!", GetClientInfo().c_str()); - return; - } - - // Verify that this IP is not in the ip_banned table - LoginDatabase.Execute(LoginDatabase.GetPreparedStatement(LOGIN_DEL_EXPIRED_IP_BANS)); - PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_IP_INFO); stmt->setString(0, ip_address); stmt->setUInt32(1, inet_addr(ip_address.c_str())); @@ -666,12 +654,37 @@ void Battlenet::Session::CheckIpCallback(PreparedQueryResult result) bool Battlenet::Session::Update() { + EncryptableBuffer* queued; + MessageBuffer buffer((std::size_t(BufferSizes::Read))); + while (_bufferQueue.Dequeue(queued)) + { + std::size_t packetSize = queued->Buffer.GetActiveSize(); + if (queued->Encrypt) + _crypt.EncryptSend(queued->Buffer.GetReadPointer(), packetSize); + + if (buffer.GetRemainingSpace() < packetSize) + { + QueuePacket(std::move(buffer)); + buffer.Resize(std::size_t(BufferSizes::Read)); + } + + if (buffer.GetRemainingSpace() >= packetSize) + buffer.Write(queued->Buffer.GetReadPointer(), packetSize); + else // single packet larger than 16384 bytes - client will reject. + QueuePacket(std::move(queued->Buffer)); + + delete queued; + } + + if (buffer.GetActiveSize() > 0) + QueuePacket(std::move(buffer)); + if (!BattlenetSocket::Update()) return false; if (_queryFuture.valid() && _queryFuture.wait_for(std::chrono::seconds(0)) == std::future_status::ready) { - auto callback = std::move(_queryCallback); + auto callback = _queryCallback; _queryCallback = nullptr; callback(_queryFuture.get()); } @@ -691,15 +704,12 @@ void Battlenet::Session::AsyncWrite(ServerPacket* packet) packet->Write(); - MessageBuffer buffer; - buffer.Write(packet->GetData(), packet->GetSize()); + EncryptableBuffer* buffer = new EncryptableBuffer(); + buffer->Buffer.Write(packet->GetData(), packet->GetSize()); + buffer->Encrypt = _crypt.IsInitialized(); delete packet; - std::unique_lock<std::mutex> guard(_writeLock); - - _crypt.EncryptSend(buffer.GetReadPointer(), buffer.GetActiveSize()); - - QueuePacket(std::move(buffer), guard); + _bufferQueue.Enqueue(buffer); } inline void ReplaceResponse(Battlenet::ServerPacket** oldResponse, Battlenet::ServerPacket* newResponse) @@ -827,9 +837,6 @@ bool Battlenet::Session::HandlePasswordModule(BitStream* dataStream, ServerPacke return false; } - //set expired game account bans to inactive - LoginDatabase.Execute(LoginDatabase.GetPreparedStatement(LOGIN_UPD_EXPIRED_ACCOUNT_BANS)); - BigNumber M; sha.Initialize(); sha.UpdateBigNumbers(&A, &M1, &K, NULL); diff --git a/src/server/bnetserver/Server/Session.h b/src/server/bnetserver/Server/Session.h index 75c30096417..2443d694a80 100644 --- a/src/server/bnetserver/Server/Session.h +++ b/src/server/bnetserver/Server/Session.h @@ -23,6 +23,7 @@ #include "Socket.h" #include "BigNumber.h" #include "Callback.h" +#include "MPSCQueue.h" #include <memory> #include <boost/asio/ip/tcp.hpp> @@ -174,6 +175,13 @@ namespace Battlenet std::queue<ModuleType> _modulesWaitingForData; + struct EncryptableBuffer + { + MessageBuffer Buffer; + bool Encrypt; + }; + + MPSCQueue<EncryptableBuffer> _bufferQueue; PacketCrypt _crypt; bool _authed; bool _subscribedToRealmListUpdates; diff --git a/src/server/bnetserver/Server/SessionManager.cpp b/src/server/bnetserver/Server/SessionManager.cpp index 8201f4869b4..c53214495d4 100644 --- a/src/server/bnetserver/Server/SessionManager.cpp +++ b/src/server/bnetserver/Server/SessionManager.cpp @@ -22,7 +22,8 @@ bool Battlenet::SessionManager::StartNetwork(boost::asio::io_service& service, s if (!BaseSocketMgr::StartNetwork(service, bindIp, port)) return false; - _acceptor->AsyncAcceptManaged(&OnSocketAccept); + _acceptor->SetSocketFactory(std::bind(&BaseSocketMgr::GetSocketForAccept, this)); + _acceptor->AsyncAcceptWithCallback<&OnSocketAccept>(); return true; } @@ -31,9 +32,9 @@ NetworkThread<Battlenet::Session>* Battlenet::SessionManager::CreateThreads() co return new NetworkThread<Session>[GetNetworkThreadCount()]; } -void Battlenet::SessionManager::OnSocketAccept(tcp::socket&& sock) +void Battlenet::SessionManager::OnSocketAccept(tcp::socket&& sock, uint32 threadIndex) { - sSessionMgr.OnSocketOpen(std::forward<tcp::socket>(sock)); + sSessionMgr.OnSocketOpen(std::forward<tcp::socket>(sock), threadIndex); } void Battlenet::SessionManager::AddSession(Session* session) diff --git a/src/server/bnetserver/Server/SessionManager.h b/src/server/bnetserver/Server/SessionManager.h index fe262b29f4e..5cf0b199f15 100644 --- a/src/server/bnetserver/Server/SessionManager.h +++ b/src/server/bnetserver/Server/SessionManager.h @@ -75,7 +75,7 @@ namespace Battlenet NetworkThread<Session>* CreateThreads() const override; private: - static void OnSocketAccept(tcp::socket&& sock); + static void OnSocketAccept(tcp::socket&& sock, uint32 threadIndex); SessionMap _sessions; SessionByAccountMap _sessionsByAccountId; diff --git a/src/server/database/Updater/UpdateFetcher.cpp b/src/server/database/Updater/UpdateFetcher.cpp index fd0dbdd4b5a..001fdf20610 100644 --- a/src/server/database/Updater/UpdateFetcher.cpp +++ b/src/server/database/Updater/UpdateFetcher.cpp @@ -142,14 +142,12 @@ UpdateFetcher::SQLUpdate UpdateFetcher::ReadSQLUpdate(boost::filesystem::path co std::ifstream in(file.c_str()); WPFatal(in.is_open(), "Could not read an update file."); - auto const start_pos = in.tellg(); - in.ignore(std::numeric_limits<std::streamsize>::max()); - auto const char_count = in.gcount(); - in.seekg(start_pos); + auto update = [&in] { + std::ostringstream ss; + ss << in.rdbuf(); + return Trinity::make_unique<std::string>(ss.str()); + }(); - SQLUpdate const update(new std::string(char_count, char{})); - - in.read(&(*update)[0], update->size()); in.close(); return update; } diff --git a/src/server/database/Updater/UpdateFetcher.h b/src/server/database/Updater/UpdateFetcher.h index 22a0d08c7f8..32f8516413d 100644 --- a/src/server/database/Updater/UpdateFetcher.h +++ b/src/server/database/Updater/UpdateFetcher.h @@ -103,7 +103,7 @@ private: typedef std::unordered_map<std::string, std::string> HashToFileNameStorage; typedef std::unordered_map<std::string, AppliedFileEntry> AppliedFileStorage; typedef std::vector<UpdateFetcher::DirectoryEntry> DirectoryStorage; - typedef std::shared_ptr<std::string> SQLUpdate; + typedef std::unique_ptr<std::string> SQLUpdate; LocaleFileStorage GetFileList() const; void FillFileListRecursively(Path const& path, LocaleFileStorage& storage, State const state, uint32 const depth) const; diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp index 9796464e821..b02906a7164 100644 --- a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp +++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp @@ -469,7 +469,7 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e) TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry " SI64FMTD " SourceType %u Event %u Action %u uses non-existent Map entry %u, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), e.event.respawn.map); return false; } - if (e.event.respawn.type == SMART_SCRIPT_RESPAWN_CONDITION_AREA && !GetAreaEntryByAreaID(e.event.respawn.area)) + if (e.event.respawn.type == SMART_SCRIPT_RESPAWN_CONDITION_AREA && !sAreaTableStore.LookupEntry(e.event.respawn.area)) { TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry " SI64FMTD " SourceType %u Event %u Action %u uses non-existent Area entry %u, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), e.event.respawn.area); return false; diff --git a/src/server/game/Achievements/AchievementMgr.cpp b/src/server/game/Achievements/AchievementMgr.cpp index 7c9739217d2..6462c89a694 100644 --- a/src/server/game/Achievements/AchievementMgr.cpp +++ b/src/server/game/Achievements/AchievementMgr.cpp @@ -2275,17 +2275,18 @@ bool AchievementMgr<T>::RequirementsSatisfied(AchievementCriteria const* achieve bool matchFound = false; for (int j = 0; j < MAX_WORLD_MAP_OVERLAY_AREA_IDX; ++j) { - uint32 area_id = worldOverlayEntry->AreaID[j]; - if (!area_id) // array have 0 only in empty tail + AreaTableEntry const* area = sAreaTableStore.LookupEntry(worldOverlayEntry->AreaID[j]); + if (!area) break; - int32 exploreFlag = GetAreaFlagByAreaID(area_id); - if (exploreFlag < 0) + if (area->AreaBit < 0) continue; - uint32 playerIndexOffset = uint32(exploreFlag) / 32; - uint32 mask = 1 << (uint32(exploreFlag) % 32); + uint32 playerIndexOffset = uint32(area->AreaBit) / 32; + if (playerIndexOffset >= PLAYER_EXPLORED_ZONES_SIZE) + continue; + uint32 mask = 1 << (uint32(area->AreaBit) % 32); if (referencePlayer->GetUInt32Value(PLAYER_EXPLORED_ZONES_1 + playerIndexOffset) & mask) { matchFound = true; diff --git a/src/server/game/Battlefield/Battlefield.cpp b/src/server/game/Battlefield/Battlefield.cpp index 72c03f7fbce..2f4d101b4f1 100644 --- a/src/server/game/Battlefield/Battlefield.cpp +++ b/src/server/game/Battlefield/Battlefield.cpp @@ -624,13 +624,12 @@ void Battlefield::RemovePlayerFromResurrectQueue(ObjectGuid playerGuid) } } -void Battlefield::SendAreaSpiritHealerQueryOpcode(Player* player, ObjectGuid guid) +void Battlefield::SendAreaSpiritHealerQueryOpcode(Player* player, ObjectGuid const& guid) { - WorldPacket data(SMSG_AREA_SPIRIT_HEALER_TIME, 12); - uint32 time = m_LastResurrectTimer; // resurrect every 30 seconds - - data << guid << time; - player->SendDirectMessage(&data); + WorldPackets::Battleground::AreaSpiritHealerTime areaSpiritHealerTime; + areaSpiritHealerTime.HealerGuid = guid; + areaSpiritHealerTime.TimeLeft = m_LastResurrectTimer; + player->SendDirectMessage(areaSpiritHealerTime.Write()); } // ---------------------- diff --git a/src/server/game/Battlefield/Battlefield.h b/src/server/game/Battlefield/Battlefield.h index 1b28dd82ed1..0159ba95eeb 100644 --- a/src/server/game/Battlefield/Battlefield.h +++ b/src/server/game/Battlefield/Battlefield.h @@ -334,7 +334,7 @@ class Battlefield : public ZoneScript /// Return if we can use mount in battlefield bool CanFlyIn() { return !m_isActive; } - void SendAreaSpiritHealerQueryOpcode(Player* player, ObjectGuid guid); + void SendAreaSpiritHealerQueryOpcode(Player* player, ObjectGuid const& guid); void StartBattle(); void EndBattle(bool endByTimer); diff --git a/src/server/game/Battlegrounds/BattlegroundMgr.cpp b/src/server/game/Battlegrounds/BattlegroundMgr.cpp index f39babba46e..57f61c0e195 100644 --- a/src/server/game/Battlegrounds/BattlegroundMgr.cpp +++ b/src/server/game/Battlegrounds/BattlegroundMgr.cpp @@ -592,14 +592,16 @@ void BattlegroundMgr::SendToBattleground(Player* player, uint32 instanceId, Batt TC_LOG_ERROR("bg.battleground", "BattlegroundMgr::SendToBattleground: Instance %u (bgType %u) not found while trying to teleport player %s", instanceId, bgTypeId, player->GetName().c_str()); } -void BattlegroundMgr::SendAreaSpiritHealerQueryOpcode(Player* player, Battleground* bg, ObjectGuid guid) +void BattlegroundMgr::SendAreaSpiritHealerQueryOpcode(Player* player, Battleground* bg, ObjectGuid const& guid) { - WorldPacket data(SMSG_AREA_SPIRIT_HEALER_TIME, 12); uint32 time_ = 30000 - bg->GetLastResurrectTime(); // resurrect every 30 seconds if (time_ == uint32(-1)) time_ = 0; - data << guid << time_; - player->GetSession()->SendPacket(&data); + + WorldPackets::Battleground::AreaSpiritHealerTime areaSpiritHealerTime; + areaSpiritHealerTime.HealerGuid = guid; + areaSpiritHealerTime.TimeLeft = time_; + player->GetSession()->SendPacket(areaSpiritHealerTime.Write()); } bool BattlegroundMgr::IsArenaType(BattlegroundTypeId bgTypeId) diff --git a/src/server/game/Battlegrounds/BattlegroundMgr.h b/src/server/game/Battlegrounds/BattlegroundMgr.h index 9f776e3c62b..354f37b8cd8 100644 --- a/src/server/game/Battlegrounds/BattlegroundMgr.h +++ b/src/server/game/Battlegrounds/BattlegroundMgr.h @@ -90,7 +90,7 @@ class BattlegroundMgr void BuildBattlegroundStatusActive(WorldPackets::Battleground::BattlefieldStatusActive* battlefieldStatus, Battleground* bg, Player* player, uint32 ticketId, uint32 joinTime, uint32 arenaType); void BuildBattlegroundStatusQueued(WorldPackets::Battleground::BattlefieldStatusQueued* battlefieldStatus, Battleground* bg, Player* player, uint32 ticketId, uint32 joinTime, uint32 avgWaitTime, uint32 arenaType, bool asGroup); void BuildBattlegroundStatusFailed(WorldPackets::Battleground::BattlefieldStatusFailed* battlefieldStatus, Battleground* bg, Player* pPlayer, uint32 ticketId, uint32 arenaType, GroupJoinBattlegroundResult result, ObjectGuid const* errorGuid = nullptr); - void SendAreaSpiritHealerQueryOpcode(Player* player, Battleground* bg, ObjectGuid guid); + void SendAreaSpiritHealerQueryOpcode(Player* player, Battleground* bg, ObjectGuid const& guid); /* Battlegrounds */ Battleground* GetBattleground(uint32 InstanceID, BattlegroundTypeId bgTypeId); diff --git a/src/server/game/Chat/Chat.cpp b/src/server/game/Chat/Chat.cpp index 89d871137f2..07e77a4e6a3 100644 --- a/src/server/game/Chat/Chat.cpp +++ b/src/server/game/Chat/Chat.cpp @@ -297,10 +297,10 @@ bool ChatHandler::ExecuteCommandInTable(std::vector<ChatCommand> const& table, c uint32 areaId = player->GetAreaId(); std::string areaName = "Unknown"; std::string zoneName = "Unknown"; - if (AreaTableEntry const* area = GetAreaEntryByAreaID(areaId)) + if (AreaTableEntry const* area = sAreaTableStore.LookupEntry(areaId)) { areaName = area->AreaName_lang; - if (AreaTableEntry const* zone = GetAreaEntryByAreaID(area->ParentAreaID)) + if (AreaTableEntry const* zone = sAreaTableStore.LookupEntry(area->ParentAreaID)) zoneName = zone->AreaName_lang; } diff --git a/src/server/game/Conditions/ConditionMgr.cpp b/src/server/game/Conditions/ConditionMgr.cpp index ff08b5ea7e8..ed3ae7cb8e5 100644 --- a/src/server/game/Conditions/ConditionMgr.cpp +++ b/src/server/game/Conditions/ConditionMgr.cpp @@ -1768,7 +1768,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond) const } case CONDITION_SOURCE_TYPE_PHASE: { - if (cond->SourceEntry && !GetAreaEntryByAreaID(cond->SourceEntry)) + if (cond->SourceEntry && !sAreaTableStore.LookupEntry(cond->SourceEntry)) { TC_LOG_ERROR("sql.sql", "%s SourceEntry in `condition` table, does not exist in AreaTable.dbc, ignoring.", cond->ToString().c_str()); return false; @@ -1845,7 +1845,7 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond) const } case CONDITION_ZONEID: { - AreaTableEntry const* areaEntry = GetAreaEntryByAreaID(cond->ConditionValue1); + AreaTableEntry const* areaEntry = sAreaTableStore.LookupEntry(cond->ConditionValue1); if (!areaEntry) { TC_LOG_ERROR("sql.sql", "%s Area (%u) does not exist, skipped.", cond->ToString(true).c_str(), cond->ConditionValue1); @@ -2592,12 +2592,9 @@ bool ConditionMgr::IsPlayerMeetingCondition(Player* player, PlayerConditionEntry for (std::size_t i = 0; i < ExploredCount::value; ++i) { - if (condition->Explored[i]) - { - int32 exploreFlag = GetAreaFlagByAreaID(condition->Explored[i]); - if (exploreFlag != -1 && !(player->GetUInt32Value(PLAYER_EXPLORED_ZONES_1 + exploreFlag / 32) & (1 << (uint32(exploreFlag) % 32)))) + if (AreaTableEntry const* area = sAreaTableStore.LookupEntry(condition->Explored[i])) + if (area->AreaBit != -1 && !(player->GetUInt32Value(PLAYER_EXPLORED_ZONES_1 + area->AreaBit / 32) & (1 << (uint32(area->AreaBit) % 32)))) return false; - } } } diff --git a/src/server/game/DataStores/DBCStores.cpp b/src/server/game/DataStores/DBCStores.cpp index 2bf38bdc769..b1a8a1179c6 100644 --- a/src/server/game/DataStores/DBCStores.cpp +++ b/src/server/game/DataStores/DBCStores.cpp @@ -44,16 +44,12 @@ struct WMOAreaTableTripple int32 adtId; }; -typedef std::map<uint16, uint32> AreaFlagByAreaID; -typedef std::map<uint32, uint32> AreaFlagByMapID; typedef std::multimap<uint32, CharSectionsEntry const*> CharSectionsMap; typedef std::map<uint32, std::vector<uint32>> FactionTeamMap; typedef std::map<WMOAreaTableTripple, WMOAreaTableEntry const*> WMOAreaInfoByTripple; DBCStorage<AnimKitEntry> sAnimKitStore(AnimKitfmt); -DBCStorage<AreaTableEntry> sAreaStore(AreaTablefmt); -static AreaFlagByAreaID sAreaFlagByAreaID; -static AreaFlagByMapID sAreaFlagByMapID; // for instances without generated *.map files +DBCStorage<AreaTableEntry> sAreaTableStore(AreaTablefmt); DBCStorage<AreaTriggerEntry> sAreaTriggerStore(AreaTriggerfmt); DBCStorage<ArmorLocationEntry> sArmorLocationStore(ArmorLocationfmt); @@ -298,7 +294,7 @@ void LoadDBCStores(const std::string& dataPath, uint32 defaultLocale) #define LOAD_DBC(store, file) LoadDBC(availableDbcLocales, bad_dbc_files, store, dbcPath, file, defaultLocale) LOAD_DBC(sAnimKitStore, "AnimKit.dbc");//20444 - LOAD_DBC(sAreaStore, "AreaTable.dbc");//20444 + LOAD_DBC(sAreaTableStore, "AreaTable.dbc");//20444 LOAD_DBC(sAreaTriggerStore, "AreaTrigger.dbc");//20444 LOAD_DBC(sArmorLocationStore, "ArmorLocation.dbc");//20444 LOAD_DBC(sBankBagSlotPricesStore, "BankBagSlotPrices.dbc");//20444 @@ -382,20 +378,6 @@ void LoadDBCStores(const std::string& dataPath, uint32 defaultLocale) #undef LOAD_DBC - // must be after sAreaStore loading - for (uint32 i = 0; i < sAreaStore.GetNumRows(); ++i) // areaflag numbered from 0 - { - if (AreaTableEntry const* area = sAreaStore.LookupEntry(i)) - { - // fill AreaId->DBC records - sAreaFlagByAreaID.insert(AreaFlagByAreaID::value_type(uint16(area->ID), area->AreaBit)); - - // fill MapId->DBC records (skip sub zones and continents) - if (area->ParentAreaID == 0) - sAreaFlagByMapID.insert(AreaFlagByMapID::value_type(area->MapID, area->AreaBit)); - } - } - for (uint32 i = 0; i < sCharSectionsStore.GetNumRows(); ++i) if (CharSectionsEntry const* entry = sCharSectionsStore.LookupEntry(i)) if (entry->Race && ((1 << (entry->Race - 1)) & RACEMASK_ALL_PLAYABLE) != 0) //ignore Nonplayable races @@ -494,7 +476,7 @@ void LoadDBCStores(const std::string& dataPath, uint32 defaultLocale) } // Check loaded DBC files proper version - if (!sAreaStore.LookupEntry(6565) || // last area (areaflag) added in 6.2.2 (20444) + if (!sAreaTableStore.LookupEntry(7941) || // last area added in 6.2.2 (20444) !sCharTitlesStore.LookupEntry(457) || // last char title added in 6.2.2 (20444) !sGemPropertiesStore.LookupEntry(2544) || // last gem property added in 6.2.2 (20444) !sMapStore.LookupEntry(1497) || // last map added in 6.2.2 (20444) @@ -580,41 +562,12 @@ char const* GetCreatureFamilyPetName(uint32 petfamily, uint32 /*locale*/) return pet_family->Name_lang ? pet_family->Name_lang : NULL; } -int32 GetAreaFlagByAreaID(uint32 area_id) -{ - AreaFlagByAreaID::iterator i = sAreaFlagByAreaID.find(area_id); - if (i == sAreaFlagByAreaID.end()) - return -1; - - return i->second; -} - WMOAreaTableEntry const* GetWMOAreaTableEntryByTripple(int32 rootid, int32 adtid, int32 groupid) { WMOAreaInfoByTripple::iterator i = sWMOAreaInfoByTripple.find(WMOAreaTableTripple(rootid, adtid, groupid)); - if (i == sWMOAreaInfoByTripple.end()) - return NULL; - return i->second; -} - -AreaTableEntry const* GetAreaEntryByAreaID(uint32 area_id) -{ - int32 areaflag = GetAreaFlagByAreaID(area_id); - if (areaflag < 0) + if (i == sWMOAreaInfoByTripple.end()) return NULL; - - return sAreaStore.LookupEntry(areaflag); -} - -AreaTableEntry const* GetAreaEntryByAreaFlagAndMap(uint32 area_flag, uint32 map_id) -{ - if (area_flag) - return sAreaStore.LookupEntry(area_flag); - - if (MapEntry const* mapEntry = sMapStore.LookupEntry(map_id)) - return GetAreaEntryByAreaID(mapEntry->AreaTableID); - - return NULL; + return i->second; } char const* GetRaceName(uint8 race, uint8 /*locale*/) @@ -629,15 +582,6 @@ char const* GetClassName(uint8 class_, uint8 /*locale*/) return classEntry ? classEntry->Name_lang : NULL; } -uint32 GetAreaFlagByMapId(uint32 mapid) -{ - AreaFlagByMapID::iterator i = sAreaFlagByMapID.find(mapid); - if (i == sAreaFlagByMapID.end()) - return 0; - else - return i->second; -} - uint32 GetVirtualMapForMapAndZone(uint32 mapid, uint32 zoneId) { if (mapid != 530 && mapid != 571 && mapid != 732) // speed for most cases diff --git a/src/server/game/DataStores/DBCStores.h b/src/server/game/DataStores/DBCStores.h index 017f641fb18..d8af7418be4 100644 --- a/src/server/game/DataStores/DBCStores.h +++ b/src/server/game/DataStores/DBCStores.h @@ -24,12 +24,6 @@ #include "DB2Structure.h" #include "SharedDefines.h" -// AreaTable -int32 GetAreaFlagByAreaID(uint32 area_id); // -1 if not found -AreaTableEntry const* GetAreaEntryByAreaID(uint32 area_id); -AreaTableEntry const* GetAreaEntryByAreaFlagAndMap(uint32 area_flag, uint32 map_id); -uint32 GetAreaFlagByMapId(uint32 mapid); - // CharSections CharSectionsEntry const* GetCharSectionEntry(uint8 race, CharSectionType genType, uint8 gender, uint8 type, uint8 color); @@ -128,7 +122,7 @@ private: }; extern DBCStorage<AnimKitEntry> sAnimKitStore; -extern DBCStorage<AreaTableEntry> sAreaStore;// recommend access using functions +extern DBCStorage<AreaTableEntry> sAreaTableStore; extern DBCStorage<AreaTriggerEntry> sAreaTriggerStore; extern DBCStorage<ArmorLocationEntry> sArmorLocationStore; extern DBCStorage<BankBagSlotPricesEntry> sBankBagSlotPricesStore; diff --git a/src/server/game/DataStores/DBCStructure.h b/src/server/game/DataStores/DBCStructure.h index 418c238b52d..ec334fb3b8f 100644 --- a/src/server/game/DataStores/DBCStructure.h +++ b/src/server/game/DataStores/DBCStructure.h @@ -34,15 +34,12 @@ struct AnimKitEntry //uint32 LowDefAnimKitID; // 3 }; -// Temporary define until max depth is found somewhere (adt?) -#define MAX_MAP_DEPTH -5000 - struct AreaTableEntry { uint32 ID; // 0 uint32 MapID; // 1 uint32 ParentAreaID; // 2 if 0 then it's zone, else it's zone id of this area - uint32 AreaBit; // 3, main index + int32 AreaBit; // 3 uint32 Flags[2]; // 4-5, //uint32 SoundProviderPref; // 6, //uint32 SoundProviderPrefUnderwater; // 7, diff --git a/src/server/game/DataStores/DBCfmt.h b/src/server/game/DataStores/DBCfmt.h index ce378ea5d43..d52891576da 100644 --- a/src/server/game/DataStores/DBCfmt.h +++ b/src/server/game/DataStores/DBCfmt.h @@ -23,7 +23,7 @@ // n - index (included), l - uint64, p - field present in sql dbc, a - field absent in sql dbc char const AnimKitfmt[] = "nxxx"; -char const AreaTablefmt[] = "iiiniixxxxxxisiiiiixxxxxxxxxx"; +char const AreaTablefmt[] = "niiiiixxxxxxisiiiiixxxxxxxxxx"; char const AreaTriggerfmt[] = "nifffxxxfffffxxxx"; char const ArmorLocationfmt[] = "nfffff"; char const BankBagSlotPricesfmt[] = "ni"; diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp index 02176cca13c..050217996ee 100644 --- a/src/server/game/Entities/GameObject/GameObject.cpp +++ b/src/server/game/Entities/GameObject/GameObject.cpp @@ -463,9 +463,7 @@ void GameObject::Update(uint32 diff) if (caster && caster->GetTypeId() == TYPEID_PLAYER) { caster->ToPlayer()->RemoveGameObject(this, false); - - WorldPacket data(SMSG_FISH_ESCAPED, 0); - caster->ToPlayer()->SendDirectMessage(&data); + caster->ToPlayer()->SendDirectMessage(WorldPackets::GameObject::FishEscaped().Write()); } // can be delete m_lootState = GO_JUST_DEACTIVATED; @@ -1442,7 +1440,10 @@ void GameObject::Use(Unit* user) player->SendCinematicStart(info->camera.camera); if (info->camera.eventID) + { GetMap()->ScriptsStart(sEventScripts, info->camera.eventID, player, this); + EventInform(info->camera.eventID, user); + } return; } @@ -1517,9 +1518,7 @@ void GameObject::Use(Unit* user) default: { SetLootState(GO_JUST_DEACTIVATED); - - WorldPacket data(SMSG_FISH_NOT_HOOKED, 0); - player->SendDirectMessage(&data); + player->SendDirectMessage(WorldPackets::GameObject::FishNotHooked().Write()); break; } } diff --git a/src/server/game/Entities/Object/Position.h b/src/server/game/Entities/Object/Position.h index ce4fd7dcfbc..cc528b973f8 100644 --- a/src/server/game/Entities/Object/Position.h +++ b/src/server/game/Entities/Object/Position.h @@ -20,6 +20,8 @@ #include "Common.h" +#include <G3D/Vector3.h> + class ByteBuffer; struct Position @@ -87,6 +89,11 @@ public: m_positionX = pos->m_positionX; m_positionY = pos->m_positionY; m_positionZ = pos->m_positionZ; SetOrientation(pos->m_orientation); } + void Relocate(G3D::Vector3 const& pos) + { + m_positionX = pos.x; m_positionY = pos.y; m_positionZ = pos.z; + } + void RelocateOffset(Position const &offset); void SetOrientation(float orientation) diff --git a/src/server/game/Entities/Pet/Pet.cpp b/src/server/game/Entities/Pet/Pet.cpp index b5fb841333c..d4db53634c2 100644 --- a/src/server/game/Entities/Pet/Pet.cpp +++ b/src/server/game/Entities/Pet/Pet.cpp @@ -1726,25 +1726,22 @@ uint8 Pet::GetMaxTalentPointsForLevel(uint8 level) const void Pet::ToggleAutocast(SpellInfo const* spellInfo, bool apply) { + ASSERT(spellInfo); + if (!spellInfo->IsAutocastable()) return; - uint32 spellid = spellInfo->Id; - - PetSpellMap::iterator itr = m_spells.find(spellid); + PetSpellMap::iterator itr = m_spells.find(spellInfo->Id); if (itr == m_spells.end()) return; - uint32 i; + auto autospellItr = std::find(m_autospells.begin(), m_autospells.end(), spellInfo->Id); if (apply) { - for (i = 0; i < m_autospells.size() && m_autospells[i] != spellid; ++i) - ; // just search - - if (i == m_autospells.size()) + if (autospellItr == m_autospells.end()) { - m_autospells.push_back(spellid); + m_autospells.push_back(spellInfo->Id); if (itr->second.active != ACT_ENABLED) { @@ -1756,13 +1753,10 @@ void Pet::ToggleAutocast(SpellInfo const* spellInfo, bool apply) } else { - AutoSpellList::iterator itr2 = m_autospells.begin(); - for (i = 0; i < m_autospells.size() && m_autospells[i] != spellid; ++i, ++itr2) - ; // just search - - if (i < m_autospells.size()) + if (autospellItr != m_autospells.end()) { - m_autospells.erase(itr2); + m_autospells.erase(autospellItr); + if (itr->second.active != ACT_DISABLED) { itr->second.active = ACT_DISABLED; diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index a26c1f3c841..7e30a125827 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -2124,7 +2124,7 @@ bool Player::CanInteractWithQuestGiver(Object* questGiver) const return false; } -Creature* Player::GetNPCIfCanInteractWith(ObjectGuid guid, uint64 npcflagmask) const +Creature* Player::GetNPCIfCanInteractWith(ObjectGuid const& guid, uint64 npcflagmask) const { // unit checks if (!guid) @@ -2168,7 +2168,21 @@ Creature* Player::GetNPCIfCanInteractWith(ObjectGuid guid, uint64 npcflagmask) c return creature; } -GameObject* Player::GetGameObjectIfCanInteractWith(ObjectGuid guid, GameobjectTypes type) const +GameObject* Player::GetGameObjectIfCanInteractWith(ObjectGuid const& guid) const +{ + if (GameObject* go = GetMap()->GetGameObject(guid)) + { + if (go->IsWithinDistInMap(this, go->GetInteractionDistance())) + return go; + + TC_LOG_DEBUG("maps", "Player::GetGameObjectIfCanInteractWith: GameObject '%s' (%s) is too far away from player '%s' (%s) to be used by him (Distance: %f, maximal %f is allowed)", + go->GetGOInfo()->name.c_str(), go->GetGUID().ToString().c_str(), GetName().c_str(), GetGUID().ToString().c_str(), go->GetDistance(this), go->GetInteractionDistance()); + } + + return nullptr; +} + +GameObject* Player::GetGameObjectIfCanInteractWith(ObjectGuid const& guid, GameobjectTypes type) const { if (GameObject* go = GetMap()->GetGameObject(guid)) { @@ -2177,8 +2191,8 @@ GameObject* Player::GetGameObjectIfCanInteractWith(ObjectGuid guid, GameobjectTy if (go->IsWithinDistInMap(this, go->GetInteractionDistance())) return go; - TC_LOG_DEBUG("maps", "Player::GetGameObjectIfCanInteractWith: GameObject '%s' (%s) is too far away from player '%s' (%s) to be used by him (Distance: %f, maximal 10 is allowed)", - go->GetGOInfo()->name.c_str(), go->GetGUID().ToString().c_str(), GetName().c_str(), GetGUID().ToString().c_str(), go->GetDistance(this)); + TC_LOG_DEBUG("maps", "Player::GetGameObjectIfCanInteractWith: GameObject '%s' (%s) is too far away from player '%s' (%s) to be used by him (Distance: %f, maximal %f is allowed)", + go->GetGOInfo()->name.c_str(), go->GetGUID().ToString().c_str(), GetName().c_str(), GetGUID().ToString().c_str(), go->GetDistance(this), go->GetInteractionDistance()); } } @@ -4221,6 +4235,7 @@ void Player::ResurrectPlayer(float restore_percent, bool applySickness) // remove death flag + set aura SetByteValue(UNIT_FIELD_BYTES_1, 3, 0x00); + RemoveFlag(PLAYER_FLAGS, PLAYER_FLAGS_IS_OUT_OF_BOUNDS); // This must be called always even on Players with race != RACE_NIGHTELF in case of faction change RemoveAurasDueToSpell(20584); // RACE_NIGHTELF speed bonuses @@ -4618,10 +4633,10 @@ void Player::RepopAtGraveyard() // note: this can be called also when the player is alive // for example from WorldSession::HandleMovementOpcodes - AreaTableEntry const* zone = GetAreaEntryByAreaID(GetAreaId()); + AreaTableEntry const* zone = sAreaTableStore.LookupEntry(GetAreaId()); // Such zones are considered unreachable as a ghost and the player must be automatically revived - if ((!IsAlive() && zone && zone->Flags[0] & AREA_FLAG_NEED_FLY) || GetTransport() || GetPositionZ() < MAX_MAP_DEPTH) + if ((!IsAlive() && zone && zone->Flags[0] & AREA_FLAG_NEED_FLY) || GetTransport() || GetPositionZ() < GetMap()->GetMinHeight(GetPositionX(), GetPositionY())) { ResurrectPlayer(0.5f); SpawnCorpseBones(); @@ -4656,8 +4671,10 @@ void Player::RepopAtGraveyard() GetSession()->SendPacket(packet.Write()); } } - else if (GetPositionZ() < MAX_MAP_DEPTH) + else if (GetPositionZ() < GetMap()->GetMinHeight(GetPositionX(), GetPositionY())) TeleportTo(m_homebindMapId, m_homebindX, m_homebindY, m_homebindZ, GetOrientation()); + + RemoveFlag(PLAYER_FLAGS, PLAYER_FLAGS_IS_OUT_OF_BOUNDS); } bool Player::CanJoinConstantChannelInZone(ChatChannelsEntry const* channel, AreaTableEntry const* zone) const @@ -4702,7 +4719,7 @@ void Player::UpdateLocalChannels(uint32 newZone) if (GetSession()->PlayerLoading() && !IsBeingTeleportedFar()) return; // The client handles it automatically after loading, but not after teleporting - AreaTableEntry const* current_zone = GetAreaEntryByAreaID(newZone); + AreaTableEntry const* current_zone = sAreaTableStore.LookupEntry(newZone); if (!current_zone) return; @@ -5900,23 +5917,32 @@ void Player::CheckAreaExploreAndOutdoor() return; bool isOutdoor; - uint16 areaFlag = GetBaseMap()->GetAreaFlag(GetPositionX(), GetPositionY(), GetPositionZ(), &isOutdoor); + uint32 areaId = GetBaseMap()->GetAreaId(GetPositionX(), GetPositionY(), GetPositionZ(), &isOutdoor); + AreaTableEntry const* areaEntry = sAreaTableStore.LookupEntry(areaId); if (sWorld->getBoolConfig(CONFIG_VMAP_INDOOR_CHECK) && !isOutdoor) RemoveAurasWithAttribute(SPELL_ATTR0_OUTDOORS_ONLY); - if (areaFlag == 0xffff) + if (!areaId) return; - int offset = areaFlag / 32; + + if (!areaEntry) + { + TC_LOG_ERROR("entities.player", "Player '%s' (%s) discovered unknown area (x: %f y: %f z: %f map: %u)", + GetName().c_str(), GetGUID().ToString().c_str(), GetPositionX(), GetPositionY(), GetPositionZ(), GetMapId()); + return; + } + + uint32 offset = areaEntry->AreaBit / 32; if (offset >= PLAYER_EXPLORED_ZONES_SIZE) { TC_LOG_ERROR("entities.player", "Player::CheckAreaExploreAndOutdoor: Wrong area flag %u in map data for (X: %f Y: %f) point to field PLAYER_EXPLORED_ZONES_1 + %u ( %u must be < %u ).", - areaFlag, GetPositionX(), GetPositionY(), offset, offset, PLAYER_EXPLORED_ZONES_SIZE); + areaId, GetPositionX(), GetPositionY(), offset, offset, PLAYER_EXPLORED_ZONES_SIZE); return; } - uint32 val = (uint32)(1 << (areaFlag % 32)); + uint32 val = (uint32)(1 << (areaEntry->AreaBit % 32)); uint32 currFields = GetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset); if (!(currFields & val)) @@ -5925,20 +5951,11 @@ void Player::CheckAreaExploreAndOutdoor() UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_EXPLORE_AREA); - AreaTableEntry const* areaEntry = GetAreaEntryByAreaFlagAndMap(areaFlag, GetMapId()); - if (!areaEntry) - { - TC_LOG_ERROR("entities.player", "Player '%s' (%s) discovered unknown area (x: %f y: %f z: %f map: %u)", - GetName().c_str(), GetGUID().ToString().c_str(), GetPositionX(), GetPositionY(), GetPositionZ(), GetMapId()); - return; - } - if (areaEntry->ExplorationLevel > 0) { - uint32 area = areaEntry->ID; if (getLevel() >= sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL)) { - SendExplorationExperience(area, 0); + SendExplorationExperience(areaId, 0); } else { @@ -5962,9 +5979,9 @@ void Player::CheckAreaExploreAndOutdoor() } GiveXP(XP, nullptr); - SendExplorationExperience(area, XP); + SendExplorationExperience(areaId, XP); } - TC_LOG_DEBUG("entities.player", "Player '%s' (%s) discovered a new area: %u", GetName().c_str(),GetGUID().ToString().c_str(), area); + TC_LOG_DEBUG("entities.player", "Player '%s' (%s) discovered a new area: %u", GetName().c_str(),GetGUID().ToString().c_str(), areaId); } } } @@ -6871,7 +6888,7 @@ void Player::UpdateArea(uint32 newArea) // so apply them accordingly m_areaUpdateId = newArea; - AreaTableEntry const* area = GetAreaEntryByAreaID(newArea); + AreaTableEntry const* area = sAreaTableStore.LookupEntry(newArea); pvpInfo.IsInFFAPvPArea = area && (area->Flags[0] & AREA_FLAG_ARENA); UpdatePvPState(true); @@ -6923,7 +6940,7 @@ void Player::UpdateZone(uint32 newZone, uint32 newArea) // zone changed, so area changed as well, update it UpdateArea(newArea); - AreaTableEntry const* zone = GetAreaEntryByAreaID(newZone); + AreaTableEntry const* zone = sAreaTableStore.LookupEntry(newZone); if (!zone) return; @@ -9045,10 +9062,11 @@ void Player::SetBindPoint(ObjectGuid guid) const void Player::SendRespecWipeConfirm(ObjectGuid const& guid, uint32 cost) const { - WorldPacket data(SMSG_RESPEC_WIPE_CONFIRM, 8 + 4); - data << guid; - data << cost; - GetSession()->SendPacket(&data); + WorldPackets::Talent::RespecWipeConfirm respecWipeConfirm; + respecWipeConfirm.RespecMaster = guid; + respecWipeConfirm.Cost = cost; + respecWipeConfirm.RespecType = SPEC_RESET_TALENTS; + GetSession()->SendPacket(respecWipeConfirm.Write()); } void Player::ResetPetTalents() @@ -25825,10 +25843,10 @@ std::string Player::GetMapAreaAndZoneString() const uint32 areaId = GetAreaId(); std::string areaName = "Unknown"; std::string zoneName = "Unknown"; - if (AreaTableEntry const* area = GetAreaEntryByAreaID(areaId)) + if (AreaTableEntry const* area = sAreaTableStore.LookupEntry(areaId)) { areaName = area->AreaName_lang; - if (AreaTableEntry const* zone = GetAreaEntryByAreaID(area->ParentAreaID)) + if (AreaTableEntry const* zone = sAreaTableStore.LookupEntry(area->ParentAreaID)) zoneName = zone->AreaName_lang; } diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index 6b235a3d0e0..b5221a8cbc5 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -155,6 +155,14 @@ enum TalentSpecialization // talent tabs TALENT_SPEC_MONK_MISTWEAVER = 270 }; +enum SpecResetType +{ + SPEC_RESET_TALENTS = 0, + SPEC_RESET_SPECIALIZATION = 1, + SPEC_RESET_GLYPHS = 2, + SPEC_RESET_PET_TALENTS = 3 +}; + // Spell modifier (used for modify other spells) struct SpellModifier { @@ -1221,8 +1229,9 @@ class Player : public Unit, public GridObject<Player> void SendInstanceResetWarning(uint32 mapid, Difficulty difficulty, uint32 time, bool welcome) const; bool CanInteractWithQuestGiver(Object* questGiver) const; - Creature* GetNPCIfCanInteractWith(ObjectGuid guid, uint64 npcflagmask) const; - GameObject* GetGameObjectIfCanInteractWith(ObjectGuid guid, GameobjectTypes type) const; + Creature* GetNPCIfCanInteractWith(ObjectGuid const& guid, uint64 npcflagmask) const; + GameObject* GetGameObjectIfCanInteractWith(ObjectGuid const& guid) const; + GameObject* GetGameObjectIfCanInteractWith(ObjectGuid const& guid, GameobjectTypes type) const; void ToggleAFK(); void ToggleDND(); diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h index 4c945365640..9902b2a2af9 100644 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -668,7 +668,7 @@ enum DamageEffectType }; // Value masks for UNIT_FIELD_FLAGS -enum UnitFlags +enum UnitFlags : uint32 { UNIT_FLAG_SERVER_CONTROLLED = 0x00000001, // set only when unit movement is controlled by server - by SPLINE/MONSTER_MOVE packets, together with UNIT_FLAG_STUNNED; only set to units controlled by client; client function CGUnit_C::IsClientControlled returns false when set for owner UNIT_FLAG_NON_ATTACKABLE = 0x00000002, // not attackable diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp index e15a4e59d9b..d818ab0edb5 100644 --- a/src/server/game/Globals/ObjectMgr.cpp +++ b/src/server/game/Globals/ObjectMgr.cpp @@ -3929,7 +3929,7 @@ void ObjectMgr::LoadQuests() // client quest log visual (area case) if (qinfo->QuestSortID > 0) { - if (!GetAreaEntryByAreaID(qinfo->QuestSortID)) + if (!sAreaTableStore.LookupEntry(qinfo->QuestSortID)) { TC_LOG_ERROR("sql.sql", "Quest %u has `QuestSortID` = %u (zone case) but zone with this id does not exist.", qinfo->GetQuestId(), qinfo->QuestSortID); @@ -5868,7 +5868,7 @@ void ObjectMgr::LoadGraveyardZones() continue; } - AreaTableEntry const* areaEntry = GetAreaEntryByAreaID(zoneId); + AreaTableEntry const* areaEntry = sAreaTableStore.LookupEntry(zoneId); if (!areaEntry) { TC_LOG_ERROR("sql.sql", "Table `graveyard_zone` has a record for non-existing Zone (ID: %u), skipped.", zoneId); @@ -7764,7 +7764,7 @@ void ObjectMgr::LoadFishingBaseSkillLevel() uint32 entry = fields[0].GetUInt32(); int32 skill = fields[1].GetInt16(); - AreaTableEntry const* fArea = GetAreaEntryByAreaID(entry); + AreaTableEntry const* fArea = sAreaTableStore.LookupEntry(entry); if (!fArea) { TC_LOG_ERROR("sql.sql", "AreaId %u defined in `skill_fishing_base_level` does not exist", entry); diff --git a/src/server/game/Grids/GridDefines.h b/src/server/game/Grids/GridDefines.h index 09bcbfb5e64..1e304fcaca3 100644 --- a/src/server/game/Grids/GridDefines.h +++ b/src/server/game/Grids/GridDefines.h @@ -227,7 +227,7 @@ namespace Trinity inline bool IsValidMapCoord(float x, float y, float z) { - return IsValidMapCoord(x, y) && std::isfinite(z); + return IsValidMapCoord(x, y) && IsValidMapCoord(z); } inline bool IsValidMapCoord(float x, float y, float z, float o) diff --git a/src/server/game/Handlers/BattleGroundHandler.cpp b/src/server/game/Handlers/BattleGroundHandler.cpp index c37928d32ad..e8fdb384d89 100644 --- a/src/server/game/Handlers/BattleGroundHandler.cpp +++ b/src/server/game/Handlers/BattleGroundHandler.cpp @@ -595,13 +595,8 @@ void WorldSession::HandleReportPvPAFK(WorldPackets::Battleground::ReportPvPPlaye reportedPlayer->ReportedAfkBy(_player); } -void WorldSession::HandleRequestRatedBattlefieldInfo(WorldPacket& recvData) +void WorldSession::HandleRequestRatedBattlefieldInfo(WorldPackets::Battleground::RequestRatedBattlefieldInfo& /*packet*/) { - uint8 unk; - recvData >> unk; - - TC_LOG_DEBUG("bg.battleground", "WorldSession::HandleRequestRatedBattlefieldInfo: unk = %u", unk); - /// @Todo: perfome research in this case /// The unk fields are related to arenas WorldPacket data(SMSG_RATED_BATTLEFIELD_INFO, 72); @@ -640,7 +635,7 @@ void WorldSession::HandleGetPVPOptionsEnabled(WorldPackets::Battleground::GetPVP SendPacket(pvpOptionsEnabled.Write()); } -void WorldSession::HandleRequestPvpReward(WorldPacket& /*recvData*/) +void WorldSession::HandleRequestPvpReward(WorldPackets::Battleground::RequestPVPRewards& /*packet*/) { _player->SendPvpRewards(); } @@ -688,7 +683,7 @@ void WorldSession::HandleHearthAndResurrect(WorldPackets::Battleground::HearthAn return; } - AreaTableEntry const* atEntry = GetAreaEntryByAreaID(_player->GetAreaId()); + AreaTableEntry const* atEntry = sAreaTableStore.LookupEntry(_player->GetAreaId()); if (!atEntry || !(atEntry->Flags[0] & AREA_FLAG_CAN_HEARTH_AND_RESURRECT)) return; diff --git a/src/server/game/Handlers/ChannelHandler.cpp b/src/server/game/Handlers/ChannelHandler.cpp index 09569e833d1..344592580cf 100644 --- a/src/server/game/Handlers/ChannelHandler.cpp +++ b/src/server/game/Handlers/ChannelHandler.cpp @@ -35,7 +35,7 @@ void WorldSession::HandleJoinChannel(WorldPackets::Channel::JoinChannel& packet) if (!channel) return; - AreaTableEntry const* zone = GetAreaEntryByAreaID(GetPlayer()->GetZoneId()); + AreaTableEntry const* zone = sAreaTableStore.LookupEntry(GetPlayer()->GetZoneId()); if (!zone || !GetPlayer()->CanJoinConstantChannelInZone(channel, zone)) return; } diff --git a/src/server/game/Handlers/CharacterHandler.cpp b/src/server/game/Handlers/CharacterHandler.cpp index 8c89f19357f..ef197cbe541 100644 --- a/src/server/game/Handlers/CharacterHandler.cpp +++ b/src/server/game/Handlers/CharacterHandler.cpp @@ -1350,80 +1350,64 @@ void WorldSession::HandleCharRenameCallBack(PreparedQueryResult result, WorldPac sWorld->UpdateCharacterInfo(renameInfo->Guid, renameInfo->NewName); } -void WorldSession::HandleSetPlayerDeclinedNames(WorldPacket& recvData) +void WorldSession::HandleSetPlayerDeclinedNames(WorldPackets::Character::SetPlayerDeclinedNames& packet) { - ObjectGuid guid; - - recvData >> guid; - // not accept declined names for unsupported languages std::string name; - if (!ObjectMgr::GetPlayerNameByGUID(guid, name)) + if (!ObjectMgr::GetPlayerNameByGUID(packet.Player, name)) { - SendSetPlayerDeclinedNamesResult(DECLINED_NAMES_RESULT_ERROR, guid); + SendSetPlayerDeclinedNamesResult(DECLINED_NAMES_RESULT_ERROR, packet.Player); return; } std::wstring wname; if (!Utf8toWStr(name, wname)) { - SendSetPlayerDeclinedNamesResult(DECLINED_NAMES_RESULT_ERROR, guid); + SendSetPlayerDeclinedNamesResult(DECLINED_NAMES_RESULT_ERROR, packet.Player); return; } if (!isCyrillicCharacter(wname[0])) // name already stored as only single alphabet using { - SendSetPlayerDeclinedNamesResult(DECLINED_NAMES_RESULT_ERROR, guid); - return; - } - - std::string name2; - DeclinedName declinedname; - - recvData >> name2; - - if (name2 != name) // character have different name - { - SendSetPlayerDeclinedNamesResult(DECLINED_NAMES_RESULT_ERROR, guid); + SendSetPlayerDeclinedNamesResult(DECLINED_NAMES_RESULT_ERROR, packet.Player); return; } for (int i = 0; i < MAX_DECLINED_NAME_CASES; ++i) { - recvData >> declinedname.name[i]; - if (!normalizePlayerName(declinedname.name[i])) + if (!normalizePlayerName(packet.DeclinedNames.name[i])) { - SendSetPlayerDeclinedNamesResult(DECLINED_NAMES_RESULT_ERROR, guid); + SendSetPlayerDeclinedNamesResult(DECLINED_NAMES_RESULT_ERROR, packet.Player); return; } } - if (!ObjectMgr::CheckDeclinedNames(wname, declinedname)) + if (!ObjectMgr::CheckDeclinedNames(wname, packet.DeclinedNames)) { - SendSetPlayerDeclinedNamesResult(DECLINED_NAMES_RESULT_ERROR, guid); + SendSetPlayerDeclinedNamesResult(DECLINED_NAMES_RESULT_ERROR, packet.Player); return; } for (int i = 0; i < MAX_DECLINED_NAME_CASES; ++i) - CharacterDatabase.EscapeString(declinedname.name[i]); + CharacterDatabase.EscapeString(packet.DeclinedNames.name[i]); SQLTransaction trans = CharacterDatabase.BeginTransaction(); PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_DECLINED_NAME); - stmt->setUInt64(0, guid.GetCounter()); + stmt->setUInt64(0, packet.Player.GetCounter()); trans->Append(stmt); stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_CHAR_DECLINED_NAME); - stmt->setUInt64(0, guid.GetCounter()); + stmt->setUInt64(0, packet.Player.GetCounter()); - for (uint8 i = 0; i < 5; i++) - stmt->setString(i+1, declinedname.name[i]); + for (uint8 i = 0; i < MAX_DECLINED_NAME_CASES; i++) + stmt->setString(i + 1, packet.DeclinedNames.name[i]); trans->Append(stmt); CharacterDatabase.CommitTransaction(trans); - SendSetPlayerDeclinedNamesResult(DECLINED_NAMES_RESULT_SUCCESS, guid); + SendSetPlayerDeclinedNamesResult(DECLINED_NAMES_RESULT_SUCCESS, packet.Player); } void WorldSession::HandleAlterAppearance(WorldPackets::Character::AlterApperance& packet) @@ -2564,11 +2548,11 @@ void WorldSession::SendCharFactionChange(ResponseCodes result, WorldPackets::Cha void WorldSession::SendSetPlayerDeclinedNamesResult(DeclinedNameResult result, ObjectGuid guid) { - WorldPacket data(SMSG_SET_PLAYER_DECLINED_NAMES_RESULT, 4 + 8); - data << uint32(result); - if (result == DECLINED_NAMES_RESULT_SUCCESS) - data << guid; - SendPacket(&data); + WorldPackets::Character::SetPlayerDeclinedNamesResult packet; + packet.ResultCode = result; + packet.Player = guid; + + SendPacket(packet.Write()); } void WorldSession::SendBarberShopResult(BarberShopResult result) diff --git a/src/server/game/Handlers/ChatHandler.cpp b/src/server/game/Handlers/ChatHandler.cpp index 462ed8051be..2c77d8df04d 100644 --- a/src/server/game/Handlers/ChatHandler.cpp +++ b/src/server/game/Handlers/ChatHandler.cpp @@ -653,14 +653,12 @@ void WorldSession::SendChatPlayerNotfoundNotice(std::string const& name) void WorldSession::SendPlayerAmbiguousNotice(std::string const& name) { - WorldPacket data(SMSG_CHAT_PLAYER_AMBIGUOUS, name.size()+1); - data << name; - SendPacket(&data); + SendPacket(WorldPackets::Chat::ChatPlayerAmbiguous(name).Write()); } -void WorldSession::SendChatRestrictedNotice(ChatRestrictionType restriction) +void WorldSession::SendChatRestricted(ChatRestrictionType restriction) { - WorldPacket data(SMSG_CHAT_RESTRICTED, 1); - data << uint8(restriction); - SendPacket(&data); + WorldPackets::Chat::ChatRestricted packet; + packet.Reason = restriction; + SendPacket(packet.Write()); } diff --git a/src/server/game/Handlers/GroupHandler.cpp b/src/server/game/Handlers/GroupHandler.cpp index 49a10b61ed5..297cd9c3124 100644 --- a/src/server/game/Handlers/GroupHandler.cpp +++ b/src/server/game/Handlers/GroupHandler.cpp @@ -524,10 +524,8 @@ void WorldSession::HandleSetAssistantLeaderOpcode(WorldPackets::Party::SetAssist group->SetGroupMemberFlag(packet.Target, packet.Apply, MEMBER_FLAG_ASSISTANT); } -void WorldSession::HandlePartyAssignmentOpcode(WorldPacket& recvData) +void WorldSession::HandleSetPartyAssignment(WorldPackets::Party::SetPartyAssignment& packet) { - TC_LOG_DEBUG("network", "WORLD: Received MSG_PARTY_ASSIGNMENT"); - Group* group = GetPlayer()->GetGroup(); if (!group) return; @@ -536,21 +534,15 @@ void WorldSession::HandlePartyAssignmentOpcode(WorldPacket& recvData) if (!group->IsLeader(senderGuid) && !group->IsAssistant(senderGuid)) return; - uint8 assignment; - bool apply; - ObjectGuid guid; - recvData >> assignment >> apply; - recvData >> guid; - - switch (assignment) + switch (packet.Assignment) { case GROUP_ASSIGN_MAINASSIST: group->RemoveUniqueGroupMemberFlag(MEMBER_FLAG_MAINASSIST); - group->SetGroupMemberFlag(guid, apply, MEMBER_FLAG_MAINASSIST); + group->SetGroupMemberFlag(packet.Target, packet.Set, MEMBER_FLAG_MAINASSIST); break; case GROUP_ASSIGN_MAINTANK: group->RemoveUniqueGroupMemberFlag(MEMBER_FLAG_MAINTANK); // Remove main assist flag from current if any. - group->SetGroupMemberFlag(guid, apply, MEMBER_FLAG_MAINTANK); + group->SetGroupMemberFlag(packet.Target, packet.Set, MEMBER_FLAG_MAINTANK); default: break; } diff --git a/src/server/game/Handlers/ItemHandler.cpp b/src/server/game/Handlers/ItemHandler.cpp index 7a88c3a1315..c43c996614a 100644 --- a/src/server/game/Handlers/ItemHandler.cpp +++ b/src/server/game/Handlers/ItemHandler.cpp @@ -1083,20 +1083,17 @@ void WorldSession::HandleGetItemPurchaseData(WorldPackets::Item::GetItemPurchase GetPlayer()->SendRefundInfo(item); } -void WorldSession::HandleItemRefund(WorldPacket &recvData) +void WorldSession::HandleItemRefund(WorldPackets::Item::ItemPurchaseRefund& packet) { - ObjectGuid guid; - recvData >> guid; // item guid - - Item* item = _player->GetItemByGuid(guid); + Item* item = _player->GetItemByGuid(packet.ItemGUID); if (!item) { - TC_LOG_DEBUG("network", "Item refund: item not found!"); + TC_LOG_DEBUG("network", "WorldSession::HandleItemRefund: Item (%s) not found!", packet.ItemGUID.ToString().c_str()); return; } // Don't try to refund item currently being disenchanted - if (_player->GetLootGUID() == guid) + if (_player->GetLootGUID() == packet.ItemGUID) return; GetPlayer()->RefundItem(item); diff --git a/src/server/game/Handlers/MiscHandler.cpp b/src/server/game/Handlers/MiscHandler.cpp index a51b61050ee..b94b4ce838e 100644 --- a/src/server/game/Handlers/MiscHandler.cpp +++ b/src/server/game/Handlers/MiscHandler.cpp @@ -197,7 +197,7 @@ void WorldSession::HandleWhoOpcode(WorldPackets::Who::WhoRequestPkt& whoRequest) if (!wWords.empty()) { std::string aName; - if (AreaTableEntry const* areaEntry = GetAreaEntryByAreaID(target->GetZoneId())) + if (AreaTableEntry const* areaEntry = sAreaTableStore.LookupEntry(target->GetZoneId())) aName = areaEntry->AreaName_lang; bool show = false; @@ -724,46 +724,6 @@ void WorldSession::HandleWhoIsOpcode(WorldPackets::Who::WhoIsRequest& packet) SendPacket(response.Write()); } -void WorldSession::HandleComplainOpcode(WorldPacket& recvData) -{ - uint8 spam_type; // 0 - mail, 1 - chat - ObjectGuid spammer_guid; - uint32 unk1 = 0; - uint32 unk2 = 0; - uint32 unk3 = 0; - uint32 unk4 = 0; - std::string description = ""; - recvData >> spam_type; // unk 0x01 const, may be spam type (mail/chat) - recvData >> spammer_guid; // player guid - switch (spam_type) - { - case 0: - recvData >> unk1; // const 0 - recvData >> unk2; // probably mail id - recvData >> unk3; // const 0 - break; - case 1: - recvData >> unk1; // probably language - recvData >> unk2; // message type? - recvData >> unk3; // probably channel id - recvData >> unk4; // time - recvData >> description; // spam description string (messagetype, channel name, player name, message) - break; - } - - // NOTE: all chat messages from this spammer automatically ignored by spam reporter until logout in case chat spam. - // if it's mail spam - ALL mails from this spammer automatically removed by client - - // Complaint Received message - WorldPacket data(SMSG_COMPLAINT_RESULT, 2); - data << uint8(0); // value 1 resets CGChat::m_complaintsSystemStatus in client. (unused?) - data << uint8(0); // value 0xC generates a "CalendarError" in client. - SendPacket(&data); - - TC_LOG_DEBUG("network", "REPORT SPAM: type %u, %s, unk1 %u, unk2 %u, unk3 %u, unk4 %u, message %s", - spam_type, spammer_guid.ToString().c_str(), unk1, unk2, unk3, unk4, description.c_str()); -} - void WorldSession::HandleFarSightOpcode(WorldPackets::Misc::FarSight& packet) { if (packet.Enable) @@ -988,21 +948,9 @@ void WorldSession::HandleSetRaidDifficultyOpcode(WorldPackets::Misc::SetRaidDiff } } -void WorldSession::HandleRequestPetInfoOpcode(WorldPacket& /*recvData */) +void WorldSession::HandleSetTaxiBenchmark(WorldPackets::Misc::SetTaxiBenchmarkMode& packet) { - /* - recvData.hexlike(); - */ -} - -void WorldSession::HandleSetTaxiBenchmarkOpcode(WorldPacket& recvData) -{ - uint8 mode; - recvData >> mode; - - mode ? _player->SetFlag(PLAYER_FLAGS, PLAYER_FLAGS_TAXI_BENCHMARK) : _player->RemoveFlag(PLAYER_FLAGS, PLAYER_FLAGS_TAXI_BENCHMARK); - - TC_LOG_DEBUG("network", "Client used \"/timetest %d\" command", mode); + _player->ApplyModFlag(PLAYER_FLAGS, PLAYER_FLAGS_TAXI_BENCHMARK, packet.Enable); } void WorldSession::HandleGuildSetFocusedAchievement(WorldPackets::Achievement::GuildSetFocusedAchievement& setFocusedAchievement) @@ -1046,48 +994,6 @@ void WorldSession::HandleInstanceLockResponse(WorldPackets::Instance::InstanceLo _player->SetPendingBind(0, 0); } -void WorldSession::HandleUpdateMissileTrajectory(WorldPacket& recvPacket) -{ - ObjectGuid guid; - uint32 spellId; - float pitch, speed; - float curX, curY, curZ; - float targetX, targetY, targetZ; - uint8 moveStop; - - recvPacket >> guid >> spellId >> pitch >> speed; - recvPacket >> curX >> curY >> curZ; - recvPacket >> targetX >> targetY >> targetZ; - recvPacket >> moveStop; - - Unit* caster = ObjectAccessor::GetUnit(*_player, guid); - Spell* spell = caster ? caster->GetCurrentSpell(CURRENT_GENERIC_SPELL) : NULL; - if (!spell || spell->m_spellInfo->Id != spellId || !spell->m_targets.HasDst() || !spell->m_targets.HasSrc()) - { - recvPacket.rfinish(); - return; - } - - Position pos = *spell->m_targets.GetSrcPos(); - pos.Relocate(curX, curY, curZ); - spell->m_targets.ModSrc(pos); - - pos = *spell->m_targets.GetDstPos(); - pos.Relocate(targetX, targetY, targetZ); - spell->m_targets.ModDst(pos); - - spell->m_targets.SetPitch(pitch); - spell->m_targets.SetSpeed(speed); - - if (moveStop) - { - uint32 opcode; - recvPacket >> opcode; - recvPacket.SetOpcode(CMSG_MOVE_STOP); // always set to CMSG_MOVE_STOP in client SetOpcode - //HandleMovementOpcodes(recvPacket); - } -} - void WorldSession::HandleViolenceLevel(WorldPackets::Misc::ViolenceLevel& /*violenceLevel*/) { // do something? diff --git a/src/server/game/Handlers/MovementHandler.cpp b/src/server/game/Handlers/MovementHandler.cpp index fb391229340..3ab9f683dea 100644 --- a/src/server/game/Handlers/MovementHandler.cpp +++ b/src/server/game/Handlers/MovementHandler.cpp @@ -382,7 +382,7 @@ void WorldSession::HandleMovementOpcodes(WorldPackets::Movement::ClientPlayerMov plrMover->UpdateFallInformationIfNeed(movementInfo, opcode); - if (movementInfo.pos.GetPositionZ() < MAX_MAP_DEPTH) + if (movementInfo.pos.GetPositionZ() < plrMover->GetMap()->GetMinHeight(movementInfo.pos.GetPositionX(), movementInfo.pos.GetPositionY())) { if (!(plrMover->GetBattleground() && plrMover->GetBattleground()->HandlePlayerUnderMap(_player))) { @@ -391,6 +391,7 @@ void WorldSession::HandleMovementOpcodes(WorldPackets::Movement::ClientPlayerMov /// @todo discard movement packets after the player is rooted if (plrMover->IsAlive()) { + plrMover->SetFlag(PLAYER_FLAGS, PLAYER_FLAGS_IS_OUT_OF_BOUNDS); plrMover->EnvironmentalDamage(DAMAGE_FALL_TO_VOID, GetPlayer()->GetMaxHealth()); // player can be alive if GM/etc // change the death state to CORPSE to prevent the death timer from diff --git a/src/server/game/Handlers/NPCHandler.cpp b/src/server/game/Handlers/NPCHandler.cpp index e514a1c2767..7590ef2b120 100644 --- a/src/server/game/Handlers/NPCHandler.cpp +++ b/src/server/game/Handlers/NPCHandler.cpp @@ -256,7 +256,7 @@ void WorldSession::SendTrainerBuyFailed(ObjectGuid trainerGUID, uint32 spellID, void WorldSession::HandleGossipHelloOpcode(WorldPackets::NPC::Hello& packet) { - Creature* unit = GetPlayer()->GetNPCIfCanInteractWith(packet.Unit, UNIT_NPC_FLAG_NONE); + Creature* unit = GetPlayer()->GetNPCIfCanInteractWith(packet.Unit, UNIT_NPC_FLAG_GOSSIP); if (!unit) { TC_LOG_DEBUG("network", "WORLD: HandleGossipHelloOpcode - %s not found or you can not interact with him.", packet.Unit.ToString().c_str()); @@ -296,7 +296,6 @@ void WorldSession::HandleGossipHelloOpcode(WorldPackets::NPC::Hello& packet) unit->AI()->sGossipHello(_player); } - void WorldSession::HandleGossipSelectOptionOpcode(WorldPackets::NPC::GossipSelectOption& packet) { if (!_player->PlayerTalkClass->GetGossipMenu().GetItem(packet.GossipIndex)) @@ -310,20 +309,19 @@ void WorldSession::HandleGossipSelectOptionOpcode(WorldPackets::NPC::GossipSelec GameObject* go = nullptr; if (packet.GossipUnit.IsCreatureOrVehicle()) { - unit = GetPlayer()->GetNPCIfCanInteractWith(packet.GossipUnit, UNIT_NPC_FLAG_NONE); + unit = GetPlayer()->GetNPCIfCanInteractWith(packet.GossipUnit, UNIT_NPC_FLAG_GOSSIP); if (!unit) { - TC_LOG_DEBUG("network", "WORLD: HandleGossipSelectOptionOpcode - %s not found or you can't interact with him.", packet.GossipUnit.ToString().c_str()); return; } } else if (packet.GossipUnit.IsGameObject()) { - go = _player->GetMap()->GetGameObject(packet.GossipUnit); + go = _player->GetGameObjectIfCanInteractWith(packet.GossipUnit); if (!go) { - TC_LOG_DEBUG("network", "WORLD: HandleGossipSelectOptionOpcode - %s not found.", packet.GossipUnit.ToString().c_str()); + TC_LOG_DEBUG("network", "WORLD: HandleGossipSelectOptionOpcode - %s not found or you can't interact with it.", packet.GossipUnit.ToString().c_str()); return; } } @@ -465,14 +463,9 @@ void WorldSession::SendBindPoint(Creature* npc) _player->PlayerTalkClass->SendCloseGossip(); } -void WorldSession::HandleListStabledPetsOpcode(WorldPacket& recvData) +void WorldSession::HandleRequestStabledPets(WorldPackets::NPC::RequestStabledPets& packet) { - TC_LOG_DEBUG("network", "WORLD: Recv MSG_LIST_STABLED_PETS"); - ObjectGuid npcGUID; - - recvData >> npcGUID; - - if (!CheckStableMaster(npcGUID)) + if (!CheckStableMaster(packet.StableMaster)) return; // remove fake death @@ -483,7 +476,7 @@ void WorldSession::HandleListStabledPetsOpcode(WorldPacket& recvData) if (GetPlayer()->IsMounted()) GetPlayer()->RemoveAurasByType(SPELL_AURA_MOUNTED); - SendStablePet(npcGUID); + SendStablePet(packet.StableMaster); } void WorldSession::SendStablePet(ObjectGuid guid) diff --git a/src/server/game/Handlers/PetHandler.cpp b/src/server/game/Handlers/PetHandler.cpp index 83792e6fc05..6f62fc7cd5a 100644 --- a/src/server/game/Handlers/PetHandler.cpp +++ b/src/server/game/Handlers/PetHandler.cpp @@ -33,22 +33,18 @@ #include "SpellHistory.h" #include "SpellInfo.h" #include "Player.h" +#include "PetPackets.h" #include "SpellPackets.h" #include "QueryPackets.h" -void WorldSession::HandleDismissCritter(WorldPacket& recvData) +void WorldSession::HandleDismissCritter(WorldPackets::Pet::DismissCritter& packet) { - ObjectGuid guid; - recvData >> guid; - - TC_LOG_DEBUG("network", "WORLD: Received CMSG_DISMISS_CRITTER for %s", guid.ToString().c_str()); - - Unit* pet = ObjectAccessor::GetCreatureOrPetOrVehicle(*_player, guid); + Unit* pet = ObjectAccessor::GetCreatureOrPetOrVehicle(*_player, packet.CritterGUID); if (!pet) { TC_LOG_DEBUG("network", "Vanitypet (%s) does not exist - player '%s' (%s / account: %u) attempted to dismiss it (possibly lagged out)", - guid.ToString().c_str(), GetPlayer()->GetName().c_str(), GetPlayer()->GetGUID().ToString().c_str(), GetAccountId()); + packet.CritterGUID.ToString().c_str(), GetPlayer()->GetName().c_str(), GetPlayer()->GetGUID().ToString().c_str(), GetAccountId()); return; } @@ -59,6 +55,10 @@ void WorldSession::HandleDismissCritter(WorldPacket& recvData) } } +void WorldSession::HandleRequestPetInfo(WorldPackets::Pet::RequestPetInfo& /*packet */) +{ +} + void WorldSession::HandlePetAction(WorldPacket& recvData) { ObjectGuid guid1; @@ -119,25 +119,20 @@ void WorldSession::HandlePetAction(WorldPacket& recvData) } } -void WorldSession::HandlePetStopAttack(WorldPacket &recvData) +void WorldSession::HandlePetStopAttack(WorldPackets::Pet::PetStopAttack& packet) { - ObjectGuid guid; - recvData >> guid; - - TC_LOG_DEBUG("network", "WORLD: Received CMSG_PET_STOP_ATTACK for %s", guid.ToString().c_str()); - - Unit* pet = ObjectAccessor::GetCreatureOrPetOrVehicle(*_player, guid); + Unit* pet = ObjectAccessor::GetCreatureOrPetOrVehicle(*_player, packet.PetGUID); if (!pet) { - TC_LOG_ERROR("network", "HandlePetStopAttack: %s does not exist", guid.ToString().c_str()); + TC_LOG_ERROR("network", "HandlePetStopAttack: %s does not exist", packet.PetGUID.ToString().c_str()); return; } if (pet != GetPlayer()->GetPet() && pet != GetPlayer()->GetCharm()) { TC_LOG_ERROR("network", "HandlePetStopAttack: %s isn't a pet or charmed creature of player %s", - guid.ToString().c_str(), GetPlayer()->GetName().c_str()); + packet.PetGUID.ToString().c_str(), GetPlayer()->GetName().c_str()); return; } @@ -666,71 +661,61 @@ void WorldSession::HandlePetRename(WorldPacket& recvData) pet->SetUInt32Value(UNIT_FIELD_PET_NAME_TIMESTAMP, uint32(time(NULL))); // cast can't be helped } -void WorldSession::HandlePetAbandon(WorldPacket& recvData) +void WorldSession::HandlePetAbandon(WorldPackets::Pet::PetAbandon& packet) { - ObjectGuid guid; - recvData >> guid; //pet guid - TC_LOG_DEBUG("network", "WORLD: Received CMSG_PET_ABANDON %s", guid.ToString().c_str()); - if (!_player->IsInWorld()) return; - // pet/charmed - Creature* pet = ObjectAccessor::GetCreatureOrPetOrVehicle(*_player, guid); + Creature* pet = ObjectAccessor::GetCreatureOrPetOrVehicle(*_player, packet.Pet); if (pet) { if (pet->IsPet()) - _player->RemovePet((Pet*)pet, PET_SAVE_AS_DELETED); + _player->RemovePet(pet->ToPet(), PET_SAVE_AS_DELETED); else if (pet->GetGUID() == _player->GetCharmGUID()) _player->StopCastingCharm(); } } -void WorldSession::HandlePetSpellAutocastOpcode(WorldPacket& recvPacket) +void WorldSession::HandlePetSpellAutocastOpcode(WorldPackets::Pet::PetSpellAutocast& packet) { - ObjectGuid guid; - uint32 spellid; - uint8 state; //1 for on, 0 for off - recvPacket >> guid >> spellid >> state; - - if (!_player->GetGuardianPet() && !_player->GetCharm()) - return; - - if (ObjectAccessor::FindPlayer(guid)) + Creature* pet = ObjectAccessor::GetCreatureOrPetOrVehicle(*_player, packet.PetGUID); + if (!pet) + { + TC_LOG_ERROR("network", "WorldSession::HandlePetSpellAutocastOpcode: Pet %s not found.", packet.PetGUID.ToString().c_str()); return; + } - Creature* pet=ObjectAccessor::GetCreatureOrPetOrVehicle(*_player, guid); - - if (!pet || (pet != _player->GetGuardianPet() && pet != _player->GetCharm())) + if (pet != _player->GetGuardianPet() && pet != _player->GetCharm()) { - TC_LOG_ERROR("network", "HandlePetSpellAutocastOpcode. %s isn't pet of player %s (%s).", guid.ToString().c_str(), GetPlayer()->GetName().c_str(), GetPlayer()->GetGUID().ToString().c_str()); + TC_LOG_ERROR("network", "WorldSession::HandlePetSpellAutocastOpcode: %s isn't pet of player %s (%s).", + packet.PetGUID.ToString().c_str(), GetPlayer()->GetName().c_str(), GetPlayer()->GetGUID().ToString().c_str()); return; } - SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellid); + SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(packet.SpellID); if (!spellInfo) { - TC_LOG_ERROR("network", "WORLD: unknown PET spell id %u", spellid); + TC_LOG_ERROR("network", "WorldSession::HandlePetSpellAutocastOpcode: Unknown spell id %u used by %s.", packet.SpellID, packet.PetGUID.ToString().c_str()); return; } // do not add not learned spells/ passive spells - if (!pet->HasSpell(spellid) || !spellInfo->IsAutocastable()) + if (!pet->HasSpell(packet.SpellID) || !spellInfo->IsAutocastable()) return; CharmInfo* charmInfo = pet->GetCharmInfo(); if (!charmInfo) { - TC_LOG_ERROR("network", "WorldSession::HandlePetSpellAutocastOpcod: object (%s) is considered pet-like but doesn't have a charminfo!", pet->GetGUID().ToString().c_str()); + TC_LOG_ERROR("network", "WorldSession::HandlePetSpellAutocastOpcode: object (%s) is considered pet-like but doesn't have a charminfo!", pet->GetGUID().ToString().c_str()); return; } if (pet->IsPet()) - ((Pet*)pet)->ToggleAutocast(spellInfo, state != 0); + pet->ToPet()->ToggleAutocast(spellInfo, packet.AutocastEnabled); else - pet->GetCharmInfo()->ToggleCreatureAutocast(spellInfo, state != 0); + charmInfo->ToggleCreatureAutocast(spellInfo, packet.AutocastEnabled); - charmInfo->SetSpellAutocast(spellInfo, state != 0); + charmInfo->SetSpellAutocast(spellInfo, packet.AutocastEnabled); } void WorldSession::HandlePetCastSpellOpcode(WorldPackets::Spells::PetCastSpell& petCastSpell) @@ -738,19 +723,22 @@ void WorldSession::HandlePetCastSpellOpcode(WorldPackets::Spells::PetCastSpell& SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(petCastSpell.Cast.SpellID); if (!spellInfo) { - TC_LOG_ERROR("network", "WORLD: unknown PET spell id %i", petCastSpell.Cast.SpellID); + TC_LOG_ERROR("network", "WorldSession::HandlePetCastSpellOpcode: unknown spell id %i tried to cast by %s", + petCastSpell.Cast.SpellID, petCastSpell.PetGUID.ToString().c_str()); return; } - // This opcode is also sent from charmed and possessed units (players and creatures) - if (!_player->GetGuardianPet() && !_player->GetCharm()) - return; - Unit* caster = ObjectAccessor::GetUnit(*_player, petCastSpell.PetGUID); + if (!caster) + { + TC_LOG_ERROR("network", "WorldSession::HandlePetCastSpellOpcode: Caster %s not found.", petCastSpell.PetGUID.ToString().c_str()); + return; + } - if (!caster || (caster != _player->GetGuardianPet() && caster != _player->GetCharm())) + // This opcode is also sent from charmed and possessed units (players and creatures) + if (caster != _player->GetGuardianPet() && caster != _player->GetCharm()) { - TC_LOG_ERROR("network", "HandlePetCastSpellOpcode: %s isn't pet of player %s (%s).", petCastSpell.PetGUID.ToString().c_str(), GetPlayer()->GetName().c_str(), GetPlayer()->GetGUID().ToString().c_str()); + TC_LOG_ERROR("network", "WorldSession::HandlePetCastSpellOpcode: %s isn't pet of player %s (%s).", petCastSpell.PetGUID.ToString().c_str(), GetPlayer()->GetName().c_str(), GetPlayer()->GetGUID().ToString().c_str()); return; } diff --git a/src/server/game/Handlers/QuestHandler.cpp b/src/server/game/Handlers/QuestHandler.cpp index 83369002096..0b496100346 100644 --- a/src/server/game/Handlers/QuestHandler.cpp +++ b/src/server/game/Handlers/QuestHandler.cpp @@ -71,7 +71,7 @@ void WorldSession::HandleQuestgiverHelloOpcode(WorldPackets::Quest::QuestGiverHe { TC_LOG_DEBUG("network", "WORLD: Received CMSG_QUESTGIVER_HELLO %s", packet.QuestGiverGUID.ToString().c_str()); - Creature* creature = GetPlayer()->GetNPCIfCanInteractWith(packet.QuestGiverGUID, UNIT_NPC_FLAG_NONE); + Creature* creature = GetPlayer()->GetNPCIfCanInteractWith(packet.QuestGiverGUID, UNIT_NPC_FLAG_QUESTGIVER); if (!creature) { TC_LOG_DEBUG("network", "WORLD: HandleQuestgiverHelloOpcode - %s not found or you can't interact with him.", @@ -543,17 +543,12 @@ void WorldSession::HandleQuestgiverQuestAutoLaunch(WorldPacket& /*recvPacket*/) { } -void WorldSession::HandlePushQuestToParty(WorldPacket& recvPacket) +void WorldSession::HandlePushQuestToParty(WorldPackets::Quest::PushQuestToParty& packet) { - uint32 questId; - recvPacket >> questId; - - if (!_player->CanShareQuest(questId)) + if (!_player->CanShareQuest(packet.QuestID)) return; - TC_LOG_DEBUG("network", "WORLD: Received CMSG_PUSHQUESTTOPARTY questId = %u", questId); - - Quest const* quest = sObjectMgr->GetQuestTemplate(questId); + Quest const* quest = sObjectMgr->GetQuestTemplate(packet.QuestID); if (!quest) return; @@ -576,7 +571,7 @@ void WorldSession::HandlePushQuestToParty(WorldPacket& recvPacket) continue; } - if (receiver->GetQuestStatus(questId) == QUEST_STATUS_COMPLETE) + if (receiver->GetQuestStatus(packet.QuestID) == QUEST_STATUS_COMPLETE) { sender->SendPushToPartyResponse(receiver, QUEST_PUSH_ALREADY_DONE); continue; diff --git a/src/server/game/Handlers/SkillHandler.cpp b/src/server/game/Handlers/SkillHandler.cpp index 59ffde0d6b4..2060468a41a 100644 --- a/src/server/game/Handlers/SkillHandler.cpp +++ b/src/server/game/Handlers/SkillHandler.cpp @@ -37,16 +37,18 @@ void WorldSession::HandleLearnTalentsOpcode(WorldPackets::Talent::LearnTalents& _player->SendTalentsInfoData(); } -void WorldSession::HandleConfirmRespecWipeOpcode(WorldPacket& recvData) +void WorldSession::HandleConfirmRespecWipeOpcode(WorldPackets::Talent::ConfirmRespecWipe& confirmRespecWipe) { - TC_LOG_DEBUG("network", "MSG_TALENT_WIPE_CONFIRM"); - ObjectGuid guid; - recvData >> guid; - - Creature* unit = GetPlayer()->GetNPCIfCanInteractWith(guid, UNIT_NPC_FLAG_TRAINER); + Creature* unit = GetPlayer()->GetNPCIfCanInteractWith(confirmRespecWipe.RespecMaster, UNIT_NPC_FLAG_TRAINER); if (!unit) { - TC_LOG_DEBUG("network", "WORLD: HandleConfirmRespecWipeOpcode - %s not found or you can't interact with him.", guid.ToString().c_str()); + TC_LOG_DEBUG("network", "WORLD: HandleConfirmRespecWipeOpcode - %s not found or you can't interact with him.", confirmRespecWipe.RespecMaster.ToString().c_str()); + return; + } + + if (confirmRespecWipe.RespecType != SPEC_RESET_TALENTS) + { + TC_LOG_DEBUG("network", "WORLD: HandleConfirmRespecWipeOpcode - reset type %d is not implemented.", confirmRespecWipe.RespecType); return; } diff --git a/src/server/game/Handlers/SpellHandler.cpp b/src/server/game/Handlers/SpellHandler.cpp index b58e2fca69e..4a28c076ce6 100644 --- a/src/server/game/Handlers/SpellHandler.cpp +++ b/src/server/game/Handlers/SpellHandler.cpp @@ -216,11 +216,8 @@ void WorldSession::HandleOpenItemOpcode(WorldPackets::Spells::OpenItem& packet) void WorldSession::HandleGameObjectUseOpcode(WorldPackets::GameObject::GameObjUse& packet) { - if (GameObject* obj = GetPlayer()->GetMap()->GetGameObject(packet.Guid)) + if (GameObject* obj = GetPlayer()->GetGameObjectIfCanInteractWith(packet.Guid)) { - if (!obj->IsWithinDistInMap(GetPlayer(), obj->GetInteractionDistance())) - return; - // ignore for remote control state if (GetPlayer()->m_mover != GetPlayer()) if (!(GetPlayer()->IsOnVehicle(GetPlayer()->m_mover) || GetPlayer()->IsMounted()) && !obj->GetGOInfo()->IsUsableMounted()) @@ -236,17 +233,13 @@ void WorldSession::HandleGameobjectReportUse(WorldPackets::GameObject::GameObjRe if (_player->m_mover != _player) return; - GameObject* go = GetPlayer()->GetMap()->GetGameObject(packet.Guid); - if (!go) - return; - - if (!go->IsWithinDistInMap(_player, INTERACTION_DISTANCE)) - return; - - if (go->AI()->GossipHello(_player)) - return; + if (GameObject* go = GetPlayer()->GetGameObjectIfCanInteractWith(packet.Guid)) + { + if (go->AI()->GossipHello(_player)) + return; - _player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_USE_GAMEOBJECT, go->GetEntry()); + _player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_USE_GAMEOBJECT, go->GetEntry()); + } } void WorldSession::HandleCastSpellOpcode(WorldPackets::Spells::CastSpell& cast) @@ -367,32 +360,26 @@ void WorldSession::HandleCancelAuraOpcode(WorldPackets::Spells::CancelAura& canc } } -void WorldSession::HandlePetCancelAuraOpcode(WorldPacket& recvPacket) +void WorldSession::HandlePetCancelAuraOpcode(WorldPackets::Spells::PetCancelAura& packet) { - ObjectGuid guid; - uint32 spellId; - - recvPacket >> guid; - recvPacket >> spellId; - - SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId); + SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(packet.SpellID); if (!spellInfo) { - TC_LOG_ERROR("network", "WORLD: unknown PET spell id %u", spellId); + TC_LOG_ERROR("network", "WORLD: unknown PET spell id %u", packet.SpellID); return; } - Creature* pet=ObjectAccessor::GetCreatureOrPetOrVehicle(*_player, guid); + Creature* pet = ObjectAccessor::GetCreatureOrPetOrVehicle(*_player, packet.PetGUID); if (!pet) { - TC_LOG_ERROR("network", "HandlePetCancelAura: Attempt to cancel an aura for non-existant %s by player '%s'", guid.ToString().c_str(), GetPlayer()->GetName().c_str()); + TC_LOG_ERROR("network", "HandlePetCancelAura: Attempt to cancel an aura for non-existant %s by player '%s'", packet.PetGUID.ToString().c_str(), GetPlayer()->GetName().c_str()); return; } if (pet != GetPlayer()->GetGuardianPet() && pet != GetPlayer()->GetCharm()) { - TC_LOG_ERROR("network", "HandlePetCancelAura: %s is not a pet of player '%s'", guid.ToString().c_str(), GetPlayer()->GetName().c_str()); + TC_LOG_ERROR("network", "HandlePetCancelAura: %s is not a pet of player '%s'", packet.PetGUID.ToString().c_str(), GetPlayer()->GetName().c_str()); return; } @@ -402,7 +389,7 @@ void WorldSession::HandlePetCancelAuraOpcode(WorldPacket& recvPacket) return; } - pet->RemoveOwnedAura(spellId, ObjectGuid::Empty, 0, AURA_REMOVE_BY_CANCEL); + pet->RemoveOwnedAura(packet.SpellID, ObjectGuid::Empty, 0, AURA_REMOVE_BY_CANCEL); } void WorldSession::HandleCancelGrowthAuraOpcode(WorldPackets::Spells::CancelGrowthAura& /*cancelGrowthAura*/) @@ -568,39 +555,53 @@ void WorldSession::HandleMirrorImageDataRequest(WorldPackets::Spells::GetMirrorI } } -void WorldSession::HandleUpdateProjectilePosition(WorldPacket& recvPacket) +void WorldSession::HandleMissileTrajectoryCollision(WorldPackets::Spells::MissileTrajectoryCollision& packet) { - ObjectGuid casterGuid; - uint32 spellId; - uint8 castCount; - float x, y, z; // Position of missile hit - - recvPacket >> casterGuid; - recvPacket >> spellId; - recvPacket >> castCount; - recvPacket >> x; - recvPacket >> y; - recvPacket >> z; - - Unit* caster = ObjectAccessor::GetUnit(*_player, casterGuid); + Unit* caster = ObjectAccessor::GetUnit(*_player, packet.Target); if (!caster) return; - Spell* spell = caster->FindCurrentSpellBySpellId(spellId); + Spell* spell = caster->FindCurrentSpellBySpellId(packet.SpellID); if (!spell || !spell->m_targets.HasDst()) return; Position pos = *spell->m_targets.GetDstPos(); - pos.Relocate(x, y, z); + pos.Relocate(packet.CollisionPos); spell->m_targets.ModDst(pos); - WorldPacket data(SMSG_NOTIFY_MISSILE_TRAJECTORY_COLLISION, 21); - data << casterGuid; - data << uint8(castCount); - data << float(x); - data << float(y); - data << float(z); - caster->SendMessageToSet(&data, true); + WorldPackets::Spells::NotifyMissileTrajectoryCollision notify; + notify.Caster = packet.Target; + notify.CastID = packet.CastID; + notify.CollisionPos = packet.CollisionPos; + caster->SendMessageToSet(notify.Write(), true); +} + +void WorldSession::HandleUpdateMissileTrajectory(WorldPackets::Spells::UpdateMissileTrajectory& packet) +{ + Unit* caster = ObjectAccessor::GetUnit(*_player, packet.Guid); + Spell* spell = caster ? caster->GetCurrentSpell(CURRENT_GENERIC_SPELL) : NULL; + if (!spell || spell->m_spellInfo->Id != uint32(packet.SpellID) || !spell->m_targets.HasDst() || !spell->m_targets.HasSrc()) + return; + + Position pos = *spell->m_targets.GetSrcPos(); + pos.Relocate(packet.FirePos); + spell->m_targets.ModSrc(pos); + + pos = *spell->m_targets.GetDstPos(); + pos.Relocate(packet.ImpactPos); + spell->m_targets.ModDst(pos); + + spell->m_targets.SetPitch(packet.Pitch); + spell->m_targets.SetSpeed(packet.Speed); + + if (packet.Status.is_initialized()) + { + GetPlayer()->ValidateMovementInfo(packet.Status.get_ptr()); + /*uint32 opcode; + recvPacket >> opcode; + recvPacket.SetOpcode(CMSG_MOVE_STOP); // always set to CMSG_MOVE_STOP in client SetOpcode + //HandleMovementOpcodes(recvPacket);*/ + } } void WorldSession::HandleRequestCategoryCooldowns(WorldPackets::Spells::RequestCategoryCooldowns& /*requestCategoryCooldowns*/) diff --git a/src/server/game/Handlers/TicketHandler.cpp b/src/server/game/Handlers/TicketHandler.cpp index 907cd9cd6f4..6f7a6acaa10 100644 --- a/src/server/game/Handlers/TicketHandler.cpp +++ b/src/server/game/Handlers/TicketHandler.cpp @@ -95,3 +95,13 @@ void WorldSession::HandleBugReportOpcode(WorldPackets::Ticket::BugReport& bugRep stmt->setString(1, bugReport.DiagInfo); CharacterDatabase.Execute(stmt); } + +void WorldSession::HandleComplaint(WorldPackets::Ticket::Complaint& packet) +{ // NOTE: all chat messages from this spammer are automatically ignored by the spam reporter until logout in case of chat spam. + // if it's mail spam - ALL mails from this spammer are automatically removed by client + + WorldPackets::Ticket::ComplaintResult result; + result.ComplaintType = packet.ComplaintType; + result.Result = 0; + SendPacket(result.Write()); +} diff --git a/src/server/game/Handlers/VoiceChatHandler.cpp b/src/server/game/Handlers/VoiceChatHandler.cpp index 4c96e6bdebb..37d23c120e7 100644 --- a/src/server/game/Handlers/VoiceChatHandler.cpp +++ b/src/server/game/Handlers/VoiceChatHandler.cpp @@ -16,20 +16,14 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include "Common.h" -#include "WorldPacket.h" #include "WorldSession.h" +#include "VoicePackets.h" -void WorldSession::HandleVoiceSessionEnableOpcode(WorldPacket& recvData) +void WorldSession::HandleVoiceSessionEnable(WorldPackets::Voice::VoiceSessionEnable& /*packet*/) { - // uint8 isVoiceEnabled, uint8 isMicrophoneEnabled - recvData.read_skip<uint8>(); - recvData.read_skip<uint8>(); } -void WorldSession::HandleSetActiveVoiceChannel(WorldPacket& recvData) +void WorldSession::HandleSetActiveVoiceChannel(WorldPackets::Voice::SetActiveVoiceChannel& /*packet*/) { - recvData.read_skip<uint32>(); - recvData.read_skip<char*>(); } diff --git a/src/server/game/Loot/LootMgr.cpp b/src/server/game/Loot/LootMgr.cpp index bbeb2ce3040..e57bf681b8a 100644 --- a/src/server/game/Loot/LootMgr.cpp +++ b/src/server/game/Loot/LootMgr.cpp @@ -1586,8 +1586,8 @@ void LoadLootTemplates_Fishing() uint32 count = LootTemplates_Fishing.LoadAndCollectLootIds(lootIdSet); // remove real entries and check existence loot - for (uint32 i = 1; i < sAreaStore.GetNumRows(); ++i) - if (AreaTableEntry const* areaEntry = sAreaStore.LookupEntry(i)) + for (uint32 i = 1; i < sAreaTableStore.GetNumRows(); ++i) + if (AreaTableEntry const* areaEntry = sAreaTableStore.LookupEntry(i)) if (lootIdSet.find(areaEntry->ID) != lootIdSet.end()) lootIdSet.erase(areaEntry->ID); diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp index d1bc8a278c4..9335539bc6e 100644 --- a/src/server/game/Maps/Map.cpp +++ b/src/server/game/Maps/Map.cpp @@ -40,7 +40,7 @@ #include "Weather.h" u_map_magic MapMagic = { {'M','A','P','S'} }; -u_map_magic MapVersionMagic = { {'v','1','.','5'} }; +u_map_magic MapVersionMagic = { {'v','1','.','8'} }; u_map_magic MapAreaMagic = { {'A','R','E','A'} }; u_map_magic MapHeightMagic = { {'M','H','G','T'} }; u_map_magic MapLiquidMagic = { {'M','L','I','Q'} }; @@ -1655,13 +1655,15 @@ GridMap::GridMap() _flags = 0; // Area data _gridArea = 0; - _areaMap = NULL; + _areaMap = nullptr; // Height level data _gridHeight = INVALID_HEIGHT; _gridGetHeight = &GridMap::getHeightFromFlat; _gridIntHeightMultiplier = 0; - m_V9 = NULL; - m_V8 = NULL; + m_V9 = nullptr; + m_V8 = nullptr; + _maxHeight = nullptr; + _minHeight = nullptr; // Liquid data _liquidType = 0; _liquidOffX = 0; @@ -1669,9 +1671,9 @@ GridMap::GridMap() _liquidWidth = 0; _liquidHeight = 0; _liquidLevel = INVALID_HEIGHT; - _liquidEntry = NULL; - _liquidFlags = NULL; - _liquidMap = NULL; + _liquidEntry = nullptr; + _liquidFlags = nullptr; + _liquidMap = nullptr; } GridMap::~GridMap() @@ -1734,15 +1736,19 @@ void GridMap::unloadData() delete[] _areaMap; delete[] m_V9; delete[] m_V8; + delete[] _maxHeight; + delete[] _minHeight; delete[] _liquidEntry; delete[] _liquidFlags; delete[] _liquidMap; - _areaMap = NULL; - m_V9 = NULL; - m_V8 = NULL; - _liquidEntry = NULL; - _liquidFlags = NULL; - _liquidMap = NULL; + _areaMap = nullptr; + m_V9 = nullptr; + m_V8 = nullptr; + _maxHeight = nullptr; + _minHeight = nullptr; + _liquidEntry = nullptr; + _liquidFlags = nullptr; + _liquidMap = nullptr; _gridGetHeight = &GridMap::getHeightFromFlat; } @@ -1757,7 +1763,7 @@ bool GridMap::loadAreaData(FILE* in, uint32 offset, uint32 /*size*/) _gridArea = header.gridArea; if (!(header.flags & MAP_AREA_NO_AREA)) { - _areaMap = new uint16 [16*16]; + _areaMap = new uint16[16 * 16]; if (fread(_areaMap, sizeof(uint16), 16*16, in) != 16*16) return false; } @@ -1807,6 +1813,16 @@ bool GridMap::loadHeightData(FILE* in, uint32 offset, uint32 /*size*/) } else _gridGetHeight = &GridMap::getHeightFromFlat; + + if (header.flags & MAP_HEIGHT_HAS_FLIGHT_BOUNDS) + { + _maxHeight = new int16[3 * 3]; + _minHeight = new int16[3 * 3]; + if (fread(_maxHeight, sizeof(int16), 3 * 3, in) != 3 * 3 || + fread(_minHeight, sizeof(int16), 3 * 3, in) != 3 * 3) + return false; + } + return true; } @@ -2077,6 +2093,66 @@ float GridMap::getHeightFromUint16(float x, float y) const return (float)((a * x) + (b * y) + c)*_gridIntHeightMultiplier + _gridHeight; } +float GridMap::getMinHeight(float x, float y) const +{ + if (!_minHeight) + return -500.0f; + + static uint32 const indices[] = + { + 3, 0, 4, + 0, 1, 4, + 1, 2, 4, + 2, 5, 4, + 5, 8, 4, + 8, 7, 4, + 7, 6, 4, + 6, 3, 4 + }; + + static float const boundGridCoords[] = + { + 0.0f, 0.0f, + 0.0f, -266.66666f, + 0.0f, -533.33331f, + -266.66666f, 0.0f, + -266.66666f, -266.66666f, + -266.66666f, -533.33331f, + -533.33331f, 0.0f, + -533.33331f, -266.66666f, + -533.33331f, -533.33331f + }; + + Cell cell(x, y); + float gx = x - (int32(cell.GridX()) - CENTER_GRID_ID + 1) * SIZE_OF_GRIDS; + float gy = y - (int32(cell.GridY()) - CENTER_GRID_ID + 1) * SIZE_OF_GRIDS; + + uint32 quarterIndex = 0; + if (cell.CellY() < MAX_NUMBER_OF_CELLS / 2) + { + if (cell.CellX() < MAX_NUMBER_OF_CELLS / 2) + { + quarterIndex = 4 + (gy > gx); + } + else + quarterIndex = 2 + ((-SIZE_OF_GRIDS - gx) > gy); + } + else if (cell.CellX() < MAX_NUMBER_OF_CELLS / 2) + { + quarterIndex = 6 + ((-SIZE_OF_GRIDS - gx) <= gy); + } + else + quarterIndex = gx > gy; + + quarterIndex *= 3; + + return G3D::Plane( + G3D::Vector3(boundGridCoords[indices[quarterIndex + 0] * 2 + 0], boundGridCoords[indices[quarterIndex + 0] * 2 + 1], _minHeight[indices[quarterIndex + 0]]), + G3D::Vector3(boundGridCoords[indices[quarterIndex + 1] * 2 + 0], boundGridCoords[indices[quarterIndex + 1] * 2 + 1], _minHeight[indices[quarterIndex + 1]]), + G3D::Vector3(boundGridCoords[indices[quarterIndex + 2] * 2 + 0], boundGridCoords[indices[quarterIndex + 2] * 2 + 1], _minHeight[indices[quarterIndex + 2]]) + ).distance(G3D::Vector3(gx, gy, 0.0f)); +} + float GridMap::getLiquidLevel(float x, float y) const { if (!_liquidMap) @@ -2136,12 +2212,12 @@ inline ZLiquidStatus GridMap::getLiquidStatus(float x, float y, float z, uint8 R uint32 liqTypeIdx = liquidEntry->Type; if (entry < 21) { - if (AreaTableEntry const* area = GetAreaEntryByAreaFlagAndMap(getArea(x, y), MAPID_INVALID)) + if (AreaTableEntry const* area = sAreaTableStore.LookupEntry(getArea(x, y))) { uint32 overrideLiquid = area->LiquidTypeID[liquidEntry->Type]; if (!overrideLiquid && area->ParentAreaID) { - area = GetAreaEntryByAreaID(area->ParentAreaID); + area = sAreaTableStore.LookupEntry(area->ParentAreaID); if (area) overrideLiquid = area->LiquidTypeID[liquidEntry->Type]; } @@ -2277,6 +2353,14 @@ float Map::GetHeight(float x, float y, float z, bool checkVMap /*= true*/, float return mapHeight; // explicitly use map data } +float Map::GetMinHeight(float x, float y) const +{ + if (GridMap const* grid = const_cast<Map*>(this)->GetGrid(x, y)) + return grid->getMinHeight(x, y); + + return -500.0f; +} + inline bool IsOutdoorWMO(uint32 mogpFlags, int32 /*adtId*/, int32 /*rootId*/, int32 /*groupId*/, WMOAreaTableEntry const* wmoEntry, AreaTableEntry const* atEntry) { bool outdoor = true; @@ -2315,7 +2399,7 @@ bool Map::IsOutdoors(float x, float y, float z) const if (wmoEntry) { TC_LOG_DEBUG("maps", "Got WMOAreaTableEntry! flag %u, areaid %u", wmoEntry->Flags, wmoEntry->AreaTableID); - atEntry = GetAreaEntryByAreaID(wmoEntry->AreaTableID); + atEntry = sAreaTableStore.LookupEntry(wmoEntry->AreaTableID); } return IsOutdoorWMO(mogpFlags, adtId, rootId, groupId, wmoEntry, atEntry); } @@ -2339,7 +2423,7 @@ bool Map::GetAreaInfo(float x, float y, float z, uint32 &flags, int32 &adtId, in return false; } -uint16 Map::GetAreaFlag(float x, float y, float z, bool *isOutdoors) const +uint32 Map::GetAreaId(float x, float y, float z, bool *isOutdoors) const { uint32 mogpFlags; int32 adtId, rootId, groupId; @@ -2352,20 +2436,21 @@ uint16 Map::GetAreaFlag(float x, float y, float z, bool *isOutdoors) const haveAreaInfo = true; wmoEntry = GetWMOAreaTableEntryByTripple(rootId, adtId, groupId); if (wmoEntry) - atEntry = GetAreaEntryByAreaID(wmoEntry->AreaTableID); + atEntry = sAreaTableStore.LookupEntry(wmoEntry->AreaTableID); } - uint16 areaflag; + uint32 areaId = 0; if (atEntry) - areaflag = atEntry->AreaBit; + areaId = atEntry->ID; else { if (GridMap* gmap = const_cast<Map*>(this)->GetGrid(x, y)) - areaflag = gmap->getArea(x, y); + areaId = gmap->getArea(x, y); + // this used while not all *.map files generated (instances) - else - areaflag = GetAreaFlagByMapId(i_mapEntry->ID); + if (!areaId) + areaId = i_mapEntry->AreaTableID; } if (isOutdoors) @@ -2375,8 +2460,31 @@ uint16 Map::GetAreaFlag(float x, float y, float z, bool *isOutdoors) const else *isOutdoors = true; } - return areaflag; - } + return areaId; +} + +uint32 Map::GetAreaId(float x, float y, float z) const +{ + return GetAreaId(x, y, z, nullptr); +} + +uint32 Map::GetZoneId(float x, float y, float z) const +{ + uint32 areaId = GetAreaId(x, y, z); + if (AreaTableEntry const* area = sAreaTableStore.LookupEntry(areaId)) + if (area->ParentAreaID) + return area->ParentAreaID; + + return areaId; +} + +void Map::GetZoneAndAreaId(uint32& zoneid, uint32& areaid, float x, float y, float z) const +{ + areaid = zoneid = GetAreaId(x, y, z); + if (AreaTableEntry const* area = sAreaTableStore.LookupEntry(areaid)) + if (area->ParentAreaID) + zoneid = area->ParentAreaID; +} uint8 Map::GetTerrainType(float x, float y) const { @@ -2412,12 +2520,12 @@ ZLiquidStatus Map::getLiquidStatus(float x, float y, float z, uint8 ReqLiquidTyp if (liquid_type && liquid_type < 21) { - if (AreaTableEntry const* area = GetAreaEntryByAreaFlagAndMap(GetAreaFlag(x, y, z), GetId())) + if (AreaTableEntry const* area = sAreaTableStore.LookupEntry(GetAreaId(x, y, z))) { uint32 overrideLiquid = area->LiquidTypeID[liquidFlagType]; if (!overrideLiquid && area->ParentAreaID) { - area = GetAreaEntryByAreaID(area->ParentAreaID); + area = sAreaTableStore.LookupEntry(area->ParentAreaID); if (area) overrideLiquid = area->LiquidTypeID[liquidFlagType]; } @@ -2479,34 +2587,6 @@ float Map::GetWaterLevel(float x, float y) const return 0; } -uint32 Map::GetAreaIdByAreaFlag(uint16 areaflag, uint32 map_id) -{ - AreaTableEntry const* entry = GetAreaEntryByAreaFlagAndMap(areaflag, map_id); - - if (entry) - return entry->ID; - else - return 0; -} - -uint32 Map::GetZoneIdByAreaFlag(uint16 areaflag, uint32 map_id) -{ - AreaTableEntry const* entry = GetAreaEntryByAreaFlagAndMap(areaflag, map_id); - - if (entry) - return (entry->ParentAreaID != 0) ? entry->ParentAreaID : entry->ID; - else - return 0; -} - -void Map::GetZoneAndAreaIdByAreaFlag(uint32& zoneid, uint32& areaid, uint16 areaflag, uint32 map_id) -{ - AreaTableEntry const* entry = GetAreaEntryByAreaFlagAndMap(areaflag, map_id); - - areaid = entry ? entry->ID : 0; - zoneid = entry ? ((entry->ParentAreaID != 0) ? entry->ParentAreaID : entry->ID) : 0; -} - bool Map::isInLineOfSight(float x1, float y1, float z1, float x2, float y2, float z2, uint32 phasemask) const { return VMAP::VMapFactory::createOrGetVMapManager()->isInLineOfSight(GetId(), x1, y1, z1, x2, y2, z2) diff --git a/src/server/game/Maps/Map.h b/src/server/game/Maps/Map.h index 3ee28f69f12..34aa00e4bf9 100644 --- a/src/server/game/Maps/Map.h +++ b/src/server/game/Maps/Map.h @@ -100,9 +100,10 @@ struct map_areaHeader uint16 gridArea; }; -#define MAP_HEIGHT_NO_HEIGHT 0x0001 -#define MAP_HEIGHT_AS_INT16 0x0002 -#define MAP_HEIGHT_AS_INT8 0x0004 +#define MAP_HEIGHT_NO_HEIGHT 0x0001 +#define MAP_HEIGHT_AS_INT16 0x0002 +#define MAP_HEIGHT_AS_INT8 0x0004 +#define MAP_HEIGHT_HAS_FLIGHT_BOUNDS 0x0008 struct map_heightHeader { @@ -168,6 +169,8 @@ class GridMap uint16* m_uint16_V8; uint8* m_uint8_V8; }; + int16* _maxHeight; + int16* _minHeight; // Height level data float _gridHeight; float _gridIntHeightMultiplier; @@ -208,6 +211,7 @@ public: uint16 getArea(float x, float y) const; inline float getHeight(float x, float y) const {return (this->*_gridGetHeight)(x, y);} + float getMinHeight(float x, float y) const; float getLiquidLevel(float x, float y) const; uint8 getTerrainType(float x, float y) const; ZLiquidStatus getLiquidStatus(float x, float y, float z, uint8 ReqLiquidType, LiquidData* data = 0); @@ -329,11 +333,15 @@ class Map : public GridRefManager<NGridType> // some calls like isInWater should not use vmaps due to processor power // can return INVALID_HEIGHT if under z+2 z coord not found height float GetHeight(float x, float y, float z, bool checkVMap = true, float maxSearchDist = DEFAULT_HEIGHT_SEARCH) const; + float GetMinHeight(float x, float y) const; ZLiquidStatus getLiquidStatus(float x, float y, float z, uint8 ReqLiquidType, LiquidData* data = nullptr) const; - uint16 GetAreaFlag(float x, float y, float z, bool *isOutdoors=nullptr) const; - bool GetAreaInfo(float x, float y, float z, uint32 &mogpflags, int32 &adtId, int32 &rootId, int32 &groupId) const; + uint32 GetAreaId(float x, float y, float z, bool *isOutdoors) const; + bool GetAreaInfo(float x, float y, float z, uint32& mogpflags, int32& adtId, int32& rootId, int32& groupId) const; + uint32 GetAreaId(float x, float y, float z) const; + uint32 GetZoneId(float x, float y, float z) const; + void GetZoneAndAreaId(uint32& zoneid, uint32& areaid, float x, float y, float z) const; bool IsOutdoors(float x, float y, float z) const; @@ -342,25 +350,6 @@ class Map : public GridRefManager<NGridType> bool IsInWater(float x, float y, float z, LiquidData* data = nullptr) const; bool IsUnderWater(float x, float y, float z) const; - static uint32 GetAreaIdByAreaFlag(uint16 areaflag, uint32 map_id); - static uint32 GetZoneIdByAreaFlag(uint16 areaflag, uint32 map_id); - static void GetZoneAndAreaIdByAreaFlag(uint32& zoneid, uint32& areaid, uint16 areaflag, uint32 map_id); - - uint32 GetAreaId(float x, float y, float z) const - { - return GetAreaIdByAreaFlag(GetAreaFlag(x, y, z), GetId()); - } - - uint32 GetZoneId(float x, float y, float z) const - { - return GetZoneIdByAreaFlag(GetAreaFlag(x, y, z), GetId()); - } - - void GetZoneAndAreaId(uint32& zoneid, uint32& areaid, float x, float y, float z) const - { - GetZoneAndAreaIdByAreaFlag(zoneid, areaid, GetAreaFlag(x, y, z), GetId()); - } - void MoveAllCreaturesInMoveList(); void MoveAllGameObjectsInMoveList(); void MoveAllDynamicObjectsInMoveList(); diff --git a/src/server/game/Maps/MapManager.h b/src/server/game/Maps/MapManager.h index 086277448a8..c0811e7fecc 100644 --- a/src/server/game/Maps/MapManager.h +++ b/src/server/game/Maps/MapManager.h @@ -42,22 +42,20 @@ class MapManager Map* CreateMap(uint32 mapId, Player* player); Map* FindMap(uint32 mapId, uint32 instanceId) const; - uint16 GetAreaFlag(uint32 mapid, float x, float y, float z) const - { - Map const* m = const_cast<MapManager*>(this)->CreateBaseMap(mapid); - return m->GetAreaFlag(x, y, z); - } uint32 GetAreaId(uint32 mapid, float x, float y, float z) const { - return Map::GetAreaIdByAreaFlag(GetAreaFlag(mapid, x, y, z), mapid); + Map const* m = const_cast<MapManager*>(this)->CreateBaseMap(mapid); + return m->GetAreaId(x, y, z); } uint32 GetZoneId(uint32 mapid, float x, float y, float z) const { - return Map::GetZoneIdByAreaFlag(GetAreaFlag(mapid, x, y, z), mapid); + Map const* m = const_cast<MapManager*>(this)->CreateBaseMap(mapid); + return m->GetZoneId(x, y, z); } void GetZoneAndAreaId(uint32& zoneid, uint32& areaid, uint32 mapid, float x, float y, float z) { - Map::GetZoneAndAreaIdByAreaFlag(zoneid, areaid, GetAreaFlag(mapid, x, y, z), mapid); + Map const* m = const_cast<MapManager*>(this)->CreateBaseMap(mapid); + m->GetZoneAndAreaId(zoneid, areaid, x, y, z); } void Initialize(void); diff --git a/src/server/game/Miscellaneous/SharedDefines.h b/src/server/game/Miscellaneous/SharedDefines.h index 88b9190af6f..238c39ed2c9 100644 --- a/src/server/game/Miscellaneous/SharedDefines.h +++ b/src/server/game/Miscellaneous/SharedDefines.h @@ -85,7 +85,7 @@ enum Expansions MAX_EXPANSIONS = 6 }; -#define CURRENT_EXPANSION EXPANSION_WARLORDS_OF_DRAENOR; +#define CURRENT_EXPANSION EXPANSION_WARLORDS_OF_DRAENOR enum Gender { diff --git a/src/server/game/OutdoorPvP/OutdoorPvP.cpp b/src/server/game/OutdoorPvP/OutdoorPvP.cpp index d10b196f08d..4f05c1871aa 100644 --- a/src/server/game/OutdoorPvP/OutdoorPvP.cpp +++ b/src/server/game/OutdoorPvP/OutdoorPvP.cpp @@ -650,7 +650,7 @@ void OutdoorPvP::BroadcastWorker(Worker& _worker, uint32 zoneId) void OutdoorPvP::SetMapFromZone(uint32 zone) { - AreaTableEntry const* areaTable = GetAreaEntryByAreaID(zone); + AreaTableEntry const* areaTable = sAreaTableStore.LookupEntry(zone); ASSERT(areaTable); Map* map = sMapMgr->CreateBaseMap(areaTable->MapID); ASSERT(!map->Instanceable()); diff --git a/src/server/game/Scripting/ScriptMgr.cpp b/src/server/game/Scripting/ScriptMgr.cpp index 774c4e279d0..38ca4911a21 100644 --- a/src/server/game/Scripting/ScriptMgr.cpp +++ b/src/server/game/Scripting/ScriptMgr.cpp @@ -37,7 +37,6 @@ // namespace // { - UnusedScriptContainer UnusedScripts; UnusedScriptNamesContainer UnusedScriptNames; // } @@ -107,8 +106,9 @@ class ScriptRegistry // The actual list of scripts. This will be accessed concurrently, so it must not be modified // after server startup. static ScriptMap ScriptPointerList; + static std::vector<TScript*> Scripts; - static void AddScript(TScript* const script) + static void AddScript(TScript* const script, bool addToDeleteContainer = true) { ASSERT(script); @@ -126,6 +126,8 @@ class ScriptRegistry } AddScript(is_script_database_bound<TScript>{}, script); + if (addToDeleteContainer) + Scripts.push_back(script); } // Gets a script by its ID (assigned by ObjectMgr). @@ -186,11 +188,6 @@ class ScriptRegistry { // The script uses a script name from database, but isn't assigned to anything. TC_LOG_ERROR("sql.sql", "Script named '%s' does not have a script name assigned in database.", script->GetName().c_str()); - - // Avoid calling "delete script;" because we are currently in the script constructor - // In a valid scenario this will not happen because every script has a name assigned in the database - UnusedScripts.push_back(script); - return; } } @@ -210,6 +207,7 @@ class ScriptRegistry #define SCR_REG_MAP(T) ScriptRegistry<T>::ScriptMap #define SCR_REG_ITR(T) ScriptRegistry<T>::ScriptMapIterator #define SCR_REG_LST(T) ScriptRegistry<T>::ScriptPointerList +#define SCR_REG_VEC(T) ScriptRegistry<T>::Scripts // Utility macros for looping over scripts. #define FOR_SCRIPTS(T, C, E) \ @@ -266,17 +264,15 @@ void ScriptMgr::Initialize() } #endif - UnloadUnusedScripts(); - TC_LOG_INFO("server.loading", ">> Loaded %u C++ scripts in %u ms", GetScriptCount(), GetMSTimeDiffToNow(oldMSTime)); } void ScriptMgr::Unload() { #define SCR_CLEAR(T) \ - for (SCR_REG_ITR(T) itr = SCR_REG_LST(T).begin(); itr != SCR_REG_LST(T).end(); ++itr) \ - delete itr->second; \ - SCR_REG_LST(T).clear(); + for (T* scr : SCR_REG_VEC(T)) \ + delete scr; \ + SCR_REG_VEC(T).clear(); // Clear scripts for every script type. SCR_CLEAR(SpellScriptLoader); @@ -308,19 +304,10 @@ void ScriptMgr::Unload() #undef SCR_CLEAR - UnloadUnusedScripts(); - delete[] SpellSummary; delete[] UnitAI::AISpellInfo; } -void ScriptMgr::UnloadUnusedScripts() -{ - for (size_t i = 0; i < UnusedScripts.size(); ++i) - delete UnusedScripts[i]; - UnusedScripts.clear(); -} - void ScriptMgr::LoadDatabase() { sScriptSystemMgr->LoadScriptWaypoints(); @@ -1558,8 +1545,7 @@ FormulaScript::FormulaScript(const char* name) UnitScript::UnitScript(const char* name, bool addToScripts) : ScriptObject(name) { - if (addToScripts) - ScriptRegistry<UnitScript>::AddScript(this); + ScriptRegistry<UnitScript>::AddScript(this, addToScripts); } WorldMapScript::WorldMapScript(const char* name, uint32 mapId) @@ -1699,6 +1685,7 @@ GroupScript::GroupScript(const char* name) // Instantiate static members of ScriptRegistry. template<class TScript> std::map<uint32, TScript*> ScriptRegistry<TScript>::ScriptPointerList; +template<class TScript> std::vector<TScript*> ScriptRegistry<TScript>::Scripts; template<class TScript> uint32 ScriptRegistry<TScript>::_scriptIdCounter = 0; // Specialize for each script type class like so: diff --git a/src/server/game/Scripting/ScriptMgr.h b/src/server/game/Scripting/ScriptMgr.h index 49d561f8885..aac2cdeabfa 100644 --- a/src/server/game/Scripting/ScriptMgr.h +++ b/src/server/game/Scripting/ScriptMgr.h @@ -842,10 +842,7 @@ class GroupScript : public ScriptObject // namespace // { - typedef std::vector<ScriptObject*> UnusedScriptContainer; typedef std::list<std::string> UnusedScriptNamesContainer; - - extern UnusedScriptContainer UnusedScripts; extern UnusedScriptNamesContainer UnusedScriptNames; // } @@ -877,7 +874,6 @@ class ScriptMgr public: /* Unloading */ void Unload(); - void UnloadUnusedScripts(); public: /* SpellScriptLoader */ diff --git a/src/server/game/Server/Packets/AllPackets.h b/src/server/game/Server/Packets/AllPackets.h index 186d702cc8b..caf895abe03 100644 --- a/src/server/game/Server/Packets/AllPackets.h +++ b/src/server/game/Server/Packets/AllPackets.h @@ -50,6 +50,7 @@ #include "NPCPackets.h" #include "PacketUtilities.h" #include "PartyPackets.h" +#include "PetPackets.h" #include "PetitionPackets.h" #include "QueryPackets.h" #include "QuestPackets.h" @@ -67,7 +68,9 @@ #include "ToyPackets.h" #include "TradePackets.h" #include "VehiclePackets.h" +#include "VoicePackets.h" #include "VoidStoragePackets.h" +#include "WardenPackets.h" #include "WhoPackets.h" #include "WorldStatePackets.h" diff --git a/src/server/game/Server/Packets/BattlegroundPackets.cpp b/src/server/game/Server/Packets/BattlegroundPackets.cpp index cc1eee44c2c..52b99035141 100644 --- a/src/server/game/Server/Packets/BattlegroundPackets.cpp +++ b/src/server/game/Server/Packets/BattlegroundPackets.cpp @@ -35,6 +35,14 @@ void WorldPackets::Battleground::AreaSpiritHealerQueue::Read() _worldPacket >> HealerGuid; } +WorldPacket const* WorldPackets::Battleground::AreaSpiritHealerTime::Write() +{ + _worldPacket << HealerGuid; + _worldPacket << int32(TimeLeft); + + return &_worldPacket; +} + ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Battleground::PVPLogData::RatingData const& ratingData) { data.append(ratingData.Prematch, 2); diff --git a/src/server/game/Server/Packets/BattlegroundPackets.h b/src/server/game/Server/Packets/BattlegroundPackets.h index 7d9c6017db8..e67860e6727 100644 --- a/src/server/game/Server/Packets/BattlegroundPackets.h +++ b/src/server/game/Server/Packets/BattlegroundPackets.h @@ -59,6 +59,17 @@ namespace WorldPackets ObjectGuid HealerGuid; }; + class AreaSpiritHealerTime final : public ServerPacket + { + public: + AreaSpiritHealerTime() : ServerPacket(SMSG_AREA_SPIRIT_HEALER_TIME, 14 + 4) { } + + WorldPacket const* Write() override; + + ObjectGuid HealerGuid; + int32 TimeLeft = 0; + }; + class HearthAndResurrect final : public ClientPacket { public: @@ -378,6 +389,22 @@ namespace WorldPackets ObjectGuid Guid; }; + + class RequestPVPRewards final : public ClientPacket + { + public: + RequestPVPRewards(WorldPacket&& packet) : ClientPacket(CMSG_REQUEST_PVP_REWARDS, std::move(packet)) { } + + void Read() override { } + }; + + class RequestRatedBattlefieldInfo final : public ClientPacket + { + public: + RequestRatedBattlefieldInfo(WorldPacket&& packet) : ClientPacket(CMSG_REQUEST_RATED_BATTLEFIELD_INFO, std::move(packet)) { } + + void Read() override { } + }; } } diff --git a/src/server/game/Server/Packets/CharacterPackets.cpp b/src/server/game/Server/Packets/CharacterPackets.cpp index ef41d16c2b2..d54402d40c7 100644 --- a/src/server/game/Server/Packets/CharacterPackets.cpp +++ b/src/server/game/Server/Packets/CharacterPackets.cpp @@ -545,3 +545,24 @@ WorldPacket const* WorldPackets::Character::CharCustomizeFailed::Write() return &_worldPacket; } + +void WorldPackets::Character::SetPlayerDeclinedNames::Read() +{ + _worldPacket >> Player; + + uint8 stringLengths[MAX_DECLINED_NAME_CASES]; + + for (uint8 i = 0; i < MAX_DECLINED_NAME_CASES; ++i) + stringLengths[i] = _worldPacket.ReadBits(7); + + for (uint8 i = 0; i < MAX_DECLINED_NAME_CASES; ++i) + DeclinedNames.name[i] = _worldPacket.ReadString(stringLengths[i]); +} + +WorldPacket const * WorldPackets::Character::SetPlayerDeclinedNamesResult::Write() +{ + _worldPacket << int32(ResultCode); + _worldPacket << Player; + + return &_worldPacket; +} diff --git a/src/server/game/Server/Packets/CharacterPackets.h b/src/server/game/Server/Packets/CharacterPackets.h index cbf4f55906c..bb163b075cc 100644 --- a/src/server/game/Server/Packets/CharacterPackets.h +++ b/src/server/game/Server/Packets/CharacterPackets.h @@ -716,6 +716,28 @@ namespace WorldPackets uint8 Result = 0; ObjectGuid CharGUID; }; + + class SetPlayerDeclinedNames final : public ClientPacket + { + public: + SetPlayerDeclinedNames(WorldPacket&& packet) : ClientPacket(CMSG_SET_PLAYER_DECLINED_NAMES, std::move(packet)) { } + + void Read() override; + + ObjectGuid Player; + DeclinedName DeclinedNames; + }; + + class SetPlayerDeclinedNamesResult final : public ServerPacket + { + public: + SetPlayerDeclinedNamesResult() : ServerPacket(SMSG_SET_PLAYER_DECLINED_NAMES_RESULT, 8 + 4) { } + + WorldPacket const* Write() override; + + ObjectGuid Player; + int32 ResultCode = 0; + }; } } diff --git a/src/server/game/Server/Packets/ChatPackets.cpp b/src/server/game/Server/Packets/ChatPackets.cpp index be923c1b847..612b46ca919 100644 --- a/src/server/game/Server/Packets/ChatPackets.cpp +++ b/src/server/game/Server/Packets/ChatPackets.cpp @@ -271,3 +271,18 @@ void WorldPackets::Chat::ChatReportIgnored::Read() _worldPacket >> IgnoredGUID; _worldPacket >> Reason; } + +WorldPacket const* WorldPackets::Chat::ChatPlayerAmbiguous::Write() +{ + _worldPacket.WriteBits(Name.length(), 9); + _worldPacket.WriteString(Name); + + return &_worldPacket; +} + +WorldPacket const* WorldPackets::Chat::ChatRestricted::Write() +{ + _worldPacket << uint8(Reason); + + return &_worldPacket; +} diff --git a/src/server/game/Server/Packets/ChatPackets.h b/src/server/game/Server/Packets/ChatPackets.h index 6f13419666e..faa060b3c0f 100644 --- a/src/server/game/Server/Packets/ChatPackets.h +++ b/src/server/game/Server/Packets/ChatPackets.h @@ -300,6 +300,26 @@ namespace WorldPackets ObjectGuid IgnoredGUID; uint8 Reason = 0; }; + + class ChatPlayerAmbiguous final : public ServerPacket + { + public: + ChatPlayerAmbiguous(std::string const& name) : ServerPacket(SMSG_CHAT_PLAYER_AMBIGUOUS, 2 + name.length()), Name(name) { } + + WorldPacket const* Write() override; + + std::string Name; + }; + + class ChatRestricted final : public ServerPacket + { + public: + ChatRestricted() : ServerPacket(SMSG_CHAT_RESTRICTED, 1) { } + + WorldPacket const* Write() override; + + uint8 Reason = 0; + }; } } diff --git a/src/server/game/Server/Packets/GameObjectPackets.h b/src/server/game/Server/Packets/GameObjectPackets.h index 65eb2c7bed8..5261beede13 100644 --- a/src/server/game/Server/Packets/GameObjectPackets.h +++ b/src/server/game/Server/Packets/GameObjectPackets.h @@ -92,6 +92,22 @@ namespace WorldPackets int32 Damage = 0; int32 SpellID = 0; }; + + class FishNotHooked final : public ServerPacket + { + public: + FishNotHooked() : ServerPacket(SMSG_FISH_NOT_HOOKED, 0) { } + + WorldPacket const* Write() override { return &_worldPacket; } + }; + + class FishEscaped final : public ServerPacket + { + public: + FishEscaped() : ServerPacket(SMSG_FISH_ESCAPED, 0) { } + + WorldPacket const* Write() override { return &_worldPacket; } + }; } } #endif // GOPackets_h__ diff --git a/src/server/game/Server/Packets/ItemPackets.cpp b/src/server/game/Server/Packets/ItemPackets.cpp index ab25edcecf0..e627d80fdea 100644 --- a/src/server/game/Server/Packets/ItemPackets.cpp +++ b/src/server/game/Server/Packets/ItemPackets.cpp @@ -109,6 +109,11 @@ WorldPacket const* WorldPackets::Item::SetItemPurchaseData::Write() return &_worldPacket; } +void WorldPackets::Item::ItemPurchaseRefund::Read() +{ + _worldPacket >> ItemGUID; +} + WorldPacket const* WorldPackets::Item::ItemPurchaseRefundResult::Write() { _worldPacket << ItemGUID; diff --git a/src/server/game/Server/Packets/ItemPackets.h b/src/server/game/Server/Packets/ItemPackets.h index ecf264b1fde..833d1bd9261 100644 --- a/src/server/game/Server/Packets/ItemPackets.h +++ b/src/server/game/Server/Packets/ItemPackets.h @@ -147,6 +147,16 @@ namespace WorldPackets ObjectGuid ItemGUID; }; + class ItemPurchaseRefund final : public ClientPacket + { + public: + ItemPurchaseRefund(WorldPacket&& packet) : ClientPacket(CMSG_ITEM_PURCHASE_REFUND, std::move(packet)) { } + + void Read() override; + + ObjectGuid ItemGUID; + }; + class ItemPurchaseRefundResult final : public ServerPacket { public: diff --git a/src/server/game/Server/Packets/MiscPackets.cpp b/src/server/game/Server/Packets/MiscPackets.cpp index 4b5fbf40a2d..74a098df47f 100644 --- a/src/server/game/Server/Packets/MiscPackets.cpp +++ b/src/server/game/Server/Packets/MiscPackets.cpp @@ -612,3 +612,8 @@ WorldPacket const* WorldPackets::Misc::CrossedInebriationThreshold::Write() return &_worldPacket; } + +void WorldPackets::Misc::SetTaxiBenchmarkMode::Read() +{ + Enable = _worldPacket.ReadBit(); +} diff --git a/src/server/game/Server/Packets/MiscPackets.h b/src/server/game/Server/Packets/MiscPackets.h index bb090525b9d..7125fd629d7 100644 --- a/src/server/game/Server/Packets/MiscPackets.h +++ b/src/server/game/Server/Packets/MiscPackets.h @@ -801,6 +801,16 @@ namespace WorldPackets int32 ItemID = 0; int32 Threshold = 0; }; + + class SetTaxiBenchmarkMode final : public ClientPacket + { + public: + SetTaxiBenchmarkMode(WorldPacket&& packet) : ClientPacket(CMSG_SET_TAXI_BENCHMARK_MODE, std::move(packet)) { } + + void Read() override; + + bool Enable = false; + }; } } diff --git a/src/server/game/Server/Packets/NPCPackets.cpp b/src/server/game/Server/Packets/NPCPackets.cpp index 710a6df42d2..9e8090b03b2 100644 --- a/src/server/game/Server/Packets/NPCPackets.cpp +++ b/src/server/game/Server/Packets/NPCPackets.cpp @@ -191,3 +191,8 @@ WorldPacket const* WorldPackets::NPC::TrainerBuyFailed::Write() return &_worldPacket; } + +void WorldPackets::NPC::RequestStabledPets::Read() +{ + _worldPacket >> StableMaster; +} diff --git a/src/server/game/Server/Packets/NPCPackets.h b/src/server/game/Server/Packets/NPCPackets.h index d20f78f3bf2..28444e87e75 100644 --- a/src/server/game/Server/Packets/NPCPackets.h +++ b/src/server/game/Server/Packets/NPCPackets.h @@ -240,6 +240,16 @@ namespace WorldPackets int32 SpellID = 0; int32 TrainerFailedReason = 0; }; + + class RequestStabledPets final : public ClientPacket + { + public: + RequestStabledPets(WorldPacket&& packet) : ClientPacket(CMSG_REQUEST_STABLED_PETS, std::move(packet)) { } + + void Read() override; + + ObjectGuid StableMaster; + }; } } diff --git a/src/server/game/Server/Packets/PartyPackets.cpp b/src/server/game/Server/Packets/PartyPackets.cpp index e93c0030cd5..2d5a85d4fd0 100644 --- a/src/server/game/Server/Packets/PartyPackets.cpp +++ b/src/server/game/Server/Packets/PartyPackets.cpp @@ -163,6 +163,15 @@ void WorldPackets::Party::SetPartyLeader::Read() _worldPacket >> TargetGUID; } +void WorldPackets::Party::SetPartyAssignment::Read() +{ + _worldPacket >> PartyIndex; + _worldPacket >> Assignment; + _worldPacket >> Target; + Set = _worldPacket.ReadBit(); +} + + void WorldPackets::Party::SetRole::Read() { _worldPacket >> PartyIndex; @@ -503,7 +512,7 @@ void WorldPackets::Party::PartyMemberStats::Initialize(Player const* player) // Pet if (player->GetPet()) { - Pet* pet = player->GetPet(); + ::Pet* pet = player->GetPet(); MemberStats.PetStats = boost::in_place(); diff --git a/src/server/game/Server/Packets/PartyPackets.h b/src/server/game/Server/Packets/PartyPackets.h index 85742d09f7e..1c31ba25879 100644 --- a/src/server/game/Server/Packets/PartyPackets.h +++ b/src/server/game/Server/Packets/PartyPackets.h @@ -362,6 +362,18 @@ namespace WorldPackets bool Apply = false; }; + class SetPartyAssignment final : public ClientPacket + { + public: + SetPartyAssignment(WorldPacket&& packet) : ClientPacket(CMSG_SET_PARTY_ASSIGNMENT, std::move(packet)) { } + + void Read() override; + uint8 Assignment = 0; + uint8 PartyIndex = 0; + ObjectGuid Target; + bool Set = false; + }; + class DoReadyCheck final : public ClientPacket { public: diff --git a/src/server/game/Server/Packets/PetPackets.cpp b/src/server/game/Server/Packets/PetPackets.cpp new file mode 100644 index 00000000000..803b956b4ee --- /dev/null +++ b/src/server/game/Server/Packets/PetPackets.cpp @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "PetPackets.h" + +void WorldPackets::Pet::DismissCritter::Read() +{ + _worldPacket >> CritterGUID; +} + +void WorldPackets::Pet::PetAbandon::Read() +{ + _worldPacket >> Pet; +} + +void WorldPackets::Pet::PetStopAttack::Read() +{ + _worldPacket >> PetGUID; +} + +void WorldPackets::Pet::PetSpellAutocast::Read() +{ + _worldPacket >> PetGUID; + _worldPacket >> SpellID; + AutocastEnabled = _worldPacket.ReadBit(); +} diff --git a/src/server/game/Server/Packets/PetPackets.h b/src/server/game/Server/Packets/PetPackets.h new file mode 100644 index 00000000000..04af0d2bdd3 --- /dev/null +++ b/src/server/game/Server/Packets/PetPackets.h @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef PetPackets_h__ +#define PetPackets_h__ + +#include "Packet.h" +#include "ObjectGuid.h" + +namespace WorldPackets +{ + namespace Pet + { + class DismissCritter final : public ClientPacket + { + public: + DismissCritter(WorldPacket&& packet) : ClientPacket(CMSG_DISMISS_CRITTER, std::move(packet)) { } + + void Read() override; + + ObjectGuid CritterGUID; + }; + + class RequestPetInfo final : public ClientPacket + { + public: + RequestPetInfo(WorldPacket&& packet) : ClientPacket(CMSG_REQUEST_PET_INFO, std::move(packet)) { } + + void Read() override { } + }; + + class PetAbandon final : public ClientPacket + { + public: + PetAbandon(WorldPacket&& packet) : ClientPacket(CMSG_PET_ABANDON, std::move(packet)) { } + + void Read() override; + + ObjectGuid Pet; + }; + + class PetStopAttack final : public ClientPacket + { + public: + PetStopAttack(WorldPacket&& packet) : ClientPacket(CMSG_PET_STOP_ATTACK, std::move(packet)) { } + + void Read() override; + + ObjectGuid PetGUID; + }; + + class PetSpellAutocast final : public ClientPacket + { + public: + PetSpellAutocast(WorldPacket&& packet) : ClientPacket(CMSG_PET_SPELL_AUTOCAST, std::move(packet)) { } + + void Read() override; + + ObjectGuid PetGUID; + uint32 SpellID = 0; + bool AutocastEnabled = false; + }; + } +} + +#endif // PetPackets_h__ diff --git a/src/server/game/Server/Packets/QuestPackets.cpp b/src/server/game/Server/Packets/QuestPackets.cpp index 371da76570c..f7604e864d3 100644 --- a/src/server/game/Server/Packets/QuestPackets.cpp +++ b/src/server/game/Server/Packets/QuestPackets.cpp @@ -538,3 +538,8 @@ WorldPacket const* WorldPackets::Quest::QuestGiverQuestFailed::Write() return &_worldPacket; } + +void WorldPackets::Quest::PushQuestToParty::Read() +{ + _worldPacket >> QuestID; +} diff --git a/src/server/game/Server/Packets/QuestPackets.h b/src/server/game/Server/Packets/QuestPackets.h index b509bcc94af..ff5835047b5 100644 --- a/src/server/game/Server/Packets/QuestPackets.h +++ b/src/server/game/Server/Packets/QuestPackets.h @@ -548,6 +548,16 @@ namespace WorldPackets uint32 QuestID = 0; uint32 Reason = 0; }; + + class PushQuestToParty final : public ClientPacket + { + public: + PushQuestToParty(WorldPacket&& packet) : ClientPacket(CMSG_PUSH_QUEST_TO_PARTY, std::move(packet)) { } + + void Read() override; + + uint32 QuestID = 0; + }; } } diff --git a/src/server/game/Server/Packets/SpellPackets.cpp b/src/server/game/Server/Packets/SpellPackets.cpp index 0d0be9eae94..3eea414f024 100644 --- a/src/server/game/Server/Packets/SpellPackets.cpp +++ b/src/server/game/Server/Packets/SpellPackets.cpp @@ -24,6 +24,12 @@ void WorldPackets::Spells::CancelAura::Read() _worldPacket >> CasterGUID; } +void WorldPackets::Spells::PetCancelAura::Read() +{ + _worldPacket >> PetGUID; + _worldPacket >> SpellID; +} + void WorldPackets::Spells::CancelChannelling::Read() { _worldPacket >> ChannelSpell; @@ -793,3 +799,40 @@ WorldPacket const* WorldPackets::Spells::ResyncRunes::Write() return &_worldPacket; } + +void WorldPackets::Spells::MissileTrajectoryCollision::Read() +{ + _worldPacket >> Target; + _worldPacket >> SpellID; + _worldPacket >> CastID; + _worldPacket >> CollisionPos; +} + +WorldPacket const* WorldPackets::Spells::NotifyMissileTrajectoryCollision::Write() +{ + _worldPacket << Caster; + _worldPacket << uint8(CastID); + _worldPacket << CollisionPos; + + return &_worldPacket; +} + +void WorldPackets::Spells::UpdateMissileTrajectory::Read() +{ + _worldPacket >> Guid; + _worldPacket >> MoveMsgID; + _worldPacket >> SpellID; + _worldPacket >> Pitch; + _worldPacket >> Speed; + _worldPacket >> FirePos; + _worldPacket >> ImpactPos; + bool hasStatus = _worldPacket.ReadBit(); + + _worldPacket.ResetBitPos(); + if (hasStatus) + { + MovementInfo info; + _worldPacket >> info; + Status = info; + } +} diff --git a/src/server/game/Server/Packets/SpellPackets.h b/src/server/game/Server/Packets/SpellPackets.h index 3fc1d6cca56..15a2ac34fc2 100644 --- a/src/server/game/Server/Packets/SpellPackets.h +++ b/src/server/game/Server/Packets/SpellPackets.h @@ -19,6 +19,7 @@ #define SpellPackets_h__ #include "Packet.h" +#include "PacketUtilities.h" #include "Player.h" #include "SpellAuras.h" #include "Spell.h" @@ -72,6 +73,17 @@ namespace WorldPackets void Read() override { } }; + class PetCancelAura final : public ClientPacket + { + public: + PetCancelAura(WorldPacket&& packet) : ClientPacket(CMSG_PET_CANCEL_AURA, std::move(packet)) { } + + void Read() override; + + ObjectGuid PetGUID; + uint32 SpellID = 0; + }; + class RequestCategoryCooldowns final : public ClientPacket { public: @@ -813,6 +825,48 @@ namespace WorldPackets std::vector<ResyncRune> Runes; }; + + class MissileTrajectoryCollision final : public ClientPacket + { + public: + MissileTrajectoryCollision(WorldPacket&& packet) : ClientPacket(CMSG_MISSILE_TRAJECTORY_COLLISION, std::move(packet)) { } + + void Read() override; + + ObjectGuid Target; + int32 SpellID = 0; + uint8 CastID = 0; + G3D::Vector3 CollisionPos; + }; + + class NotifyMissileTrajectoryCollision : public ServerPacket + { + public: + NotifyMissileTrajectoryCollision() : ServerPacket(SMSG_NOTIFY_MISSILE_TRAJECTORY_COLLISION, 8 + 1 + 12) { } + + WorldPacket const* Write() override; + + ObjectGuid Caster; + uint8 CastID = 0; + G3D::Vector3 CollisionPos; + }; + + class UpdateMissileTrajectory final : public ClientPacket + { + public: + UpdateMissileTrajectory(WorldPacket&& packet) : ClientPacket(CMSG_UPDATE_MISSILE_TRAJECTORY, std::move(packet)) { } + + void Read() override; + + ObjectGuid Guid; + uint16 MoveMsgID = 0; + int32 SpellID = 0; + float Pitch = 0.0f; + float Speed = 0.0f; + G3D::Vector3 FirePos; + G3D::Vector3 ImpactPos; + Optional<MovementInfo> Status; + }; } } diff --git a/src/server/game/Server/Packets/TalentPackets.cpp b/src/server/game/Server/Packets/TalentPackets.cpp index 932392e0cb4..7dc2daaa706 100644 --- a/src/server/game/Server/Packets/TalentPackets.cpp +++ b/src/server/game/Server/Packets/TalentPackets.cpp @@ -54,4 +54,18 @@ void WorldPackets::Talent::LearnTalents::Read() _worldPacket >> talent; Talents.push_back(talent); } -}
\ No newline at end of file +} + +WorldPacket const* WorldPackets::Talent::RespecWipeConfirm::Write() +{ + _worldPacket << int8(RespecType); + _worldPacket << uint32(Cost); + _worldPacket << RespecMaster; + return &_worldPacket; +} + +void WorldPackets::Talent::ConfirmRespecWipe::Read() +{ + _worldPacket >> RespecMaster; + _worldPacket >> RespecType; +} diff --git a/src/server/game/Server/Packets/TalentPackets.h b/src/server/game/Server/Packets/TalentPackets.h index 47519ba4e3b..ca6b0217a28 100644 --- a/src/server/game/Server/Packets/TalentPackets.h +++ b/src/server/game/Server/Packets/TalentPackets.h @@ -68,8 +68,31 @@ namespace WorldPackets void Read() override; std::vector<uint16> Talents; + }; + + class RespecWipeConfirm final : public ServerPacket + { + public: + RespecWipeConfirm() : ServerPacket(SMSG_RESPEC_WIPE_CONFIRM, 16 + 4 +1) { } + + WorldPacket const* Write() override; + + ObjectGuid RespecMaster; + uint32 Cost = 0; + int8 RespecType = 0; + }; + + class ConfirmRespecWipe final : public ClientPacket + { + public: + ConfirmRespecWipe(WorldPacket&& packet) : ClientPacket(CMSG_CONFIRM_RESPEC_WIPE, std::move(packet)) { } + void Read() override; + + ObjectGuid RespecMaster; + uint8 RespecType = 0; }; + } } diff --git a/src/server/game/Server/Packets/TicketPackets.cpp b/src/server/game/Server/Packets/TicketPackets.cpp index 97c23b47191..1e9eb14e3ea 100644 --- a/src/server/game/Server/Packets/TicketPackets.cpp +++ b/src/server/game/Server/Packets/TicketPackets.cpp @@ -18,6 +18,7 @@ #include "LFGPackets.h" #include "TicketPackets.h" #include "PacketUtilities.h" +#include "SupportMgr.h" using namespace WorldPackets; @@ -223,6 +224,46 @@ void WorldPackets::Ticket::SupportTicketSubmitComplaint::Read() _worldPacket >> LFGListApplicant; } +ByteBuffer& operator>>(ByteBuffer& data, WorldPackets::Ticket::Complaint::ComplaintOffender& complaintOffender) +{ + data >> complaintOffender.PlayerGuid; + data >> complaintOffender.RealmAddress; + data >> complaintOffender.TimeSinceOffence; + + return data; +} + +ByteBuffer& operator>>(ByteBuffer& data, WorldPackets::Ticket::Complaint::ComplaintChat& chat) +{ + data >> chat.Command; + data >> chat.ChannelID; + chat.MessageLog = data.ReadString(data.ReadBits(12)); + + return data; +} + +void WorldPackets::Ticket::Complaint::Read() +{ + _worldPacket >> ComplaintType; + _worldPacket >> Offender; + + switch (ComplaintType) + { + case SUPPORT_SPAM_TYPE_MAIL: + _worldPacket >> MailID; + break; + case SUPPORT_SPAM_TYPE_CHAT: + _worldPacket >> Chat; + break; + case SUPPORT_SPAM_TYPE_CALENDAR: + _worldPacket >> EventGuid; + _worldPacket >> InviteGuid; + break; + default: + break; + } +} + WorldPacket const* WorldPackets::Ticket::ComplaintResult::Write() { _worldPacket << uint32(ComplaintType); diff --git a/src/server/game/Server/Packets/TicketPackets.h b/src/server/game/Server/Packets/TicketPackets.h index 9b126d681b0..691a7b27bb8 100644 --- a/src/server/game/Server/Packets/TicketPackets.h +++ b/src/server/game/Server/Packets/TicketPackets.h @@ -193,6 +193,36 @@ namespace WorldPackets }; + class Complaint final : public ClientPacket + { + public: + struct ComplaintOffender + { + ObjectGuid PlayerGuid; + uint32 RealmAddress = 0; + uint32 TimeSinceOffence = 0; + }; + + struct ComplaintChat + { + uint32 Command = 0; + uint32 ChannelID = 0; + std::string MessageLog; + }; + + Complaint(WorldPacket&& packet) : ClientPacket(CMSG_COMPLAINT, std::move(packet)) { } + + void Read() override; + + uint8 ComplaintType = 0; + ComplaintOffender Offender; + uint32 MailID = 0; + ComplaintChat Chat; + ObjectGuid EventGuid; + ObjectGuid InviteGuid; + + }; + class ComplaintResult final : public ServerPacket { public: diff --git a/src/server/game/Server/Packets/VoicePackets.cpp b/src/server/game/Server/Packets/VoicePackets.cpp new file mode 100644 index 00000000000..3e2269a0905 --- /dev/null +++ b/src/server/game/Server/Packets/VoicePackets.cpp @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "VoicePackets.h" + +void WorldPackets::Voice::VoiceSessionEnable::Read() +{ + EnableVoiceChat = _worldPacket.ReadBit(); + EnableMicrophone = _worldPacket.ReadBit(); +} + +void WorldPackets::Voice::SetActiveVoiceChannel::Read() +{ + _worldPacket >> ChannelType; + ChannelName = _worldPacket.ReadString(_worldPacket.ReadBits(7)); +} diff --git a/src/server/game/Server/Packets/VoicePackets.h b/src/server/game/Server/Packets/VoicePackets.h new file mode 100644 index 00000000000..0ae2645c498 --- /dev/null +++ b/src/server/game/Server/Packets/VoicePackets.h @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef VoicePackets_h__ +#define VoicePackets_h__ + +#include "Packet.h" + +namespace WorldPackets +{ + namespace Voice + { + class VoiceSessionEnable final : public ClientPacket + { + public: + VoiceSessionEnable(WorldPacket&& packet) : ClientPacket(CMSG_VOICE_SESSION_ENABLE, std::move(packet)) { } + + void Read() override; + + bool EnableVoiceChat = false; + bool EnableMicrophone = false; + }; + + class SetActiveVoiceChannel final : public ClientPacket + { + public: + SetActiveVoiceChannel(WorldPacket&& packet) : ClientPacket(CMSG_SET_ACTIVE_VOICE_CHANNEL, std::move(packet)) { } + + void Read() override; + + uint8 ChannelType = 0; + std::string ChannelName; + }; + } +} + +#endif // VoicePackets_h__ diff --git a/src/server/game/Server/Packets/WardenPackets.cpp b/src/server/game/Server/Packets/WardenPackets.cpp new file mode 100644 index 00000000000..89ff90dc175 --- /dev/null +++ b/src/server/game/Server/Packets/WardenPackets.cpp @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "WardenPackets.h" + +void WorldPackets::Warden::WardenData::Read() +{ + uint32 size = _worldPacket.read<uint32>(); + + if (size) + { + Data.resize(size); + _worldPacket.read(Data.contents(), size); + } +} diff --git a/src/server/game/Server/Packets/WardenPackets.h b/src/server/game/Server/Packets/WardenPackets.h new file mode 100644 index 00000000000..a23046235ff --- /dev/null +++ b/src/server/game/Server/Packets/WardenPackets.h @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef WardenPackets_h__ +#define WardenPackets_h__ + +#include "Packet.h" + +namespace WorldPackets +{ + namespace Warden + { + class WardenData final : public ClientPacket + { + public: + WardenData(WorldPacket&& packet) : ClientPacket(CMSG_WARDEN_DATA, std::move(packet)) { } + + void Read() override; + + ByteBuffer Data; + }; + } +} + +#endif // WardenPackets_h__ diff --git a/src/server/game/Server/Protocol/Opcodes.cpp b/src/server/game/Server/Protocol/Opcodes.cpp index 337afae1c05..b7693d89b4b 100644 --- a/src/server/game/Server/Protocol/Opcodes.cpp +++ b/src/server/game/Server/Protocol/Opcodes.cpp @@ -291,10 +291,10 @@ void OpcodeTable::Initialize() DEFINE_HANDLER(CMSG_COMMENTATOR_GET_MAP_INFO, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL); DEFINE_HANDLER(CMSG_COMMENTATOR_GET_PLAYER_INFO, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL); DEFINE_HANDLER(CMSG_COMMENTATOR_START_WARGAME, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL); - DEFINE_OPCODE_HANDLER_OLD(CMSG_COMPLAINT, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleComplainOpcode ); + DEFINE_HANDLER(CMSG_COMPLAINT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Ticket::Complaint, &WorldSession::HandleComplaint); DEFINE_HANDLER(CMSG_COMPLETE_CINEMATIC, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Misc::CompleteCinematic, &WorldSession::HandleCompleteCinematic); DEFINE_HANDLER(CMSG_COMPLETE_MOVIE, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL); - DEFINE_OPCODE_HANDLER_OLD(CMSG_CONFIRM_RESPEC_WIPE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleConfirmRespecWipeOpcode ); + DEFINE_HANDLER(CMSG_CONFIRM_RESPEC_WIPE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Talent::ConfirmRespecWipe, &WorldSession::HandleConfirmRespecWipeOpcode); DEFINE_HANDLER(CMSG_CONNECT_TO_FAILED, STATUS_NEVER, PROCESS_INPLACE, WorldPacket, &WorldSession::Handle_EarlyProccess); DEFINE_HANDLER(CMSG_CONVERT_RAID, STATUS_LOGGEDIN, PROCESS_INPLACE, WorldPackets::Party::ConvertRaid, &WorldSession::HandleConvertRaidOpcode); DEFINE_HANDLER(CMSG_CREATE_CHARACTER, STATUS_AUTHED, PROCESS_THREADUNSAFE, WorldPackets::Character::CreateCharacter, &WorldSession::HandleCharCreateOpcode); @@ -320,7 +320,7 @@ void OpcodeTable::Initialize() DEFINE_OPCODE_HANDLER_OLD(CMSG_DF_SET_ROLES, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleLfgSetRolesOpcode ); DEFINE_OPCODE_HANDLER_OLD(CMSG_DF_TELEPORT, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleLfgTeleportOpcode ); DEFINE_HANDLER(CMSG_DISCARDED_TIME_SYNC_ACKS, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL); - DEFINE_OPCODE_HANDLER_OLD(CMSG_DISMISS_CRITTER, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleDismissCritter ); + DEFINE_HANDLER(CMSG_DISMISS_CRITTER, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Pet::DismissCritter, &WorldSession::HandleDismissCritter); DEFINE_HANDLER(CMSG_DO_MASTER_LOOT_ROLL, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL); DEFINE_HANDLER(CMSG_DO_READY_CHECK, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Party::DoReadyCheck, &WorldSession::HandleDoReadyCheckOpcode); DEFINE_HANDLER(CMSG_DUEL_RESPONSE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Duel::DuelResponse, &WorldSession::HandleDuelResponseOpcode); @@ -422,7 +422,7 @@ void OpcodeTable::Initialize() DEFINE_HANDLER(CMSG_INSPECT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Inspect::Inspect, &WorldSession::HandleInspectOpcode); DEFINE_HANDLER(CMSG_INSPECT_PVP, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Inspect::InspectPVPRequest, &WorldSession::HandleInspectPVP); DEFINE_HANDLER(CMSG_INSTANCE_LOCK_RESPONSE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Instance::InstanceLockResponse, &WorldSession::HandleInstanceLockResponse); - DEFINE_OPCODE_HANDLER_OLD(CMSG_ITEM_PURCHASE_REFUND, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleItemRefund ); + DEFINE_HANDLER(CMSG_ITEM_PURCHASE_REFUND, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Item::ItemPurchaseRefund, &WorldSession::HandleItemRefund); DEFINE_HANDLER(CMSG_ITEM_TEXT_QUERY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Query::ItemTextQuery, &WorldSession::HandleItemTextQuery); DEFINE_HANDLER(CMSG_JOIN_PET_BATTLE_QUEUE, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL); DEFINE_HANDLER(CMSG_JOIN_RATED_BATTLEGROUND, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL); @@ -474,7 +474,7 @@ void OpcodeTable::Initialize() DEFINE_HANDLER(CMSG_MAIL_TAKE_MONEY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Mail::MailTakeMoney, &WorldSession::HandleMailTakeMoney); DEFINE_OPCODE_HANDLER_OLD(CMSG_MASTER_LOOT_ITEM, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleLootMasterGiveOpcode ); DEFINE_HANDLER(CMSG_MINIMAP_PING, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Party::MinimapPingClient, &WorldSession::HandleMinimapPingOpcode); - DEFINE_OPCODE_HANDLER_OLD(CMSG_MISSILE_TRAJECTORY_COLLISION, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleUpdateProjectilePosition ); + DEFINE_HANDLER(CMSG_MISSILE_TRAJECTORY_COLLISION, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Spells::MissileTrajectoryCollision, &WorldSession::HandleMissileTrajectoryCollision); DEFINE_HANDLER(CMSG_MOUNT_SET_FAVORITE, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL); DEFINE_HANDLER(CMSG_MOUNT_SPECIAL_ANIM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Misc::MountSpecial, &WorldSession::HandleMountSpecialAnimOpcode); DEFINE_HANDLER(CMSG_MOVE_APPLY_MOVEMENT_FORCE_ACK, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL); @@ -557,7 +557,7 @@ void OpcodeTable::Initialize() DEFINE_HANDLER(CMSG_PETITION_RENAME_GUILD, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Petition::PetitionRenameGuild, &WorldSession::HandlePetitionRenameGuild); DEFINE_HANDLER(CMSG_PETITION_SHOW_LIST, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Petition::PetitionShowList, &WorldSession::HandlePetitionShowList); DEFINE_HANDLER(CMSG_PETITION_SHOW_SIGNATURES, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Petition::PetitionShowSignatures, &WorldSession::HandlePetitionShowSignatures); - DEFINE_OPCODE_HANDLER_OLD(CMSG_PET_ABANDON, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandlePetAbandon ); + DEFINE_HANDLER(CMSG_PET_ABANDON, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Pet::PetAbandon ,&WorldSession::HandlePetAbandon); DEFINE_OPCODE_HANDLER_OLD(CMSG_PET_ACTION, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandlePetAction ); DEFINE_HANDLER(CMSG_PET_BATTLE_FINAL_NOTIFY, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL); DEFINE_HANDLER(CMSG_PET_BATTLE_INPUT, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL); @@ -568,16 +568,16 @@ void OpcodeTable::Initialize() DEFINE_HANDLER(CMSG_PET_BATTLE_REQUEST_UPDATE, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL); DEFINE_HANDLER(CMSG_PET_BATTLE_REQUEST_WILD, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL); DEFINE_HANDLER(CMSG_PET_BATTLE_SCRIPT_ERROR_NOTIFY, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL); - DEFINE_OPCODE_HANDLER_OLD(CMSG_PET_CANCEL_AURA, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandlePetCancelAuraOpcode ); + DEFINE_HANDLER(CMSG_PET_CANCEL_AURA, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Spells::PetCancelAura, &WorldSession::HandlePetCancelAuraOpcode); DEFINE_HANDLER(CMSG_PET_CAST_SPELL, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Spells::PetCastSpell, &WorldSession::HandlePetCastSpellOpcode); DEFINE_OPCODE_HANDLER_OLD(CMSG_PET_RENAME, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandlePetRename ); DEFINE_OPCODE_HANDLER_OLD(CMSG_PET_SET_ACTION, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandlePetSetAction ); - DEFINE_OPCODE_HANDLER_OLD(CMSG_PET_SPELL_AUTOCAST, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandlePetSpellAutocastOpcode ); - DEFINE_OPCODE_HANDLER_OLD(CMSG_PET_STOP_ATTACK, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandlePetStopAttack ); + DEFINE_HANDLER(CMSG_PET_SPELL_AUTOCAST, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Pet::PetSpellAutocast, &WorldSession::HandlePetSpellAutocastOpcode); + DEFINE_HANDLER(CMSG_PET_STOP_ATTACK, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Pet::PetStopAttack, &WorldSession::HandlePetStopAttack); DEFINE_HANDLER(CMSG_PING, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPacket, &WorldSession::Handle_EarlyProccess); DEFINE_HANDLER(CMSG_PLAYER_LOGIN, STATUS_AUTHED, PROCESS_THREADUNSAFE, WorldPackets::Character::PlayerLogin, &WorldSession::HandlePlayerLoginOpcode); DEFINE_HANDLER(CMSG_PROTOCOL_MISMATCH, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL); - DEFINE_OPCODE_HANDLER_OLD(CMSG_PUSH_QUEST_TO_PARTY, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandlePushQuestToParty ); + DEFINE_HANDLER(CMSG_PUSH_QUEST_TO_PARTY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Quest::PushQuestToParty, &WorldSession::HandlePushQuestToParty); DEFINE_HANDLER(CMSG_PVP_LOG_DATA, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Battleground::PVPLogDataRequest, &WorldSession::HandlePVPLogDataOpcode); DEFINE_HANDLER(CMSG_QUERY_BATTLE_PET_NAME, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL); DEFINE_HANDLER(CMSG_QUERY_CORPSE_LOCATION_FROM_CLIENT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Query::QueryCorpseLocationFromClient, &WorldSession::HandleQueryCorpseLocation); @@ -637,13 +637,13 @@ void OpcodeTable::Initialize() DEFINE_HANDLER(CMSG_REQUEST_LFG_LIST_BLACKLIST, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL); DEFINE_HANDLER(CMSG_REQUEST_PARTY_JOIN_UPDATES, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Party::RequestPartyJoinUpdates, &WorldSession::HandleRequestPartyJoinUpdates); DEFINE_HANDLER(CMSG_REQUEST_PARTY_MEMBER_STATS, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Party::RequestPartyMemberStats, &WorldSession::HandleRequestPartyMemberStatsOpcode); - DEFINE_OPCODE_HANDLER_OLD(CMSG_REQUEST_PET_INFO, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleRequestPetInfoOpcode ); + DEFINE_HANDLER(CMSG_REQUEST_PET_INFO, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, WorldPackets::Pet::RequestPetInfo, &WorldSession::HandleRequestPetInfo); DEFINE_HANDLER(CMSG_REQUEST_PLAYED_TIME, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Character::RequestPlayedTime, &WorldSession::HandlePlayedTime); - DEFINE_OPCODE_HANDLER_OLD(CMSG_REQUEST_PVP_REWARDS, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::HandleRequestPvpReward ); + DEFINE_HANDLER(CMSG_REQUEST_PVP_REWARDS, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Battleground::RequestPVPRewards, &WorldSession::HandleRequestPvpReward); DEFINE_HANDLER(CMSG_REQUEST_RAID_INFO, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Party::RequestRaidInfo, &WorldSession::HandleRequestRaidInfoOpcode); - DEFINE_OPCODE_HANDLER_OLD(CMSG_REQUEST_RATED_BATTLEFIELD_INFO, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleRequestRatedBattlefieldInfo); + DEFINE_HANDLER(CMSG_REQUEST_RATED_BATTLEFIELD_INFO, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Battleground::RequestRatedBattlefieldInfo, &WorldSession::HandleRequestRatedBattlefieldInfo); DEFINE_HANDLER(CMSG_REQUEST_RESEARCH_HISTORY, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL); - DEFINE_OPCODE_HANDLER_OLD(CMSG_REQUEST_STABLED_PETS, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleListStabledPetsOpcode ); + DEFINE_HANDLER(CMSG_REQUEST_STABLED_PETS, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::NPC::RequestStabledPets, &WorldSession::HandleRequestStabledPets); DEFINE_HANDLER(CMSG_REQUEST_VEHICLE_EXIT, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, WorldPackets::Vehicle::RequestVehicleExit, &WorldSession::HandleRequestVehicleExit); DEFINE_HANDLER(CMSG_REQUEST_VEHICLE_NEXT_SEAT, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, WorldPackets::Vehicle::RequestVehicleNextSeat, &WorldSession::HandleRequestVehicleNextSeat); DEFINE_HANDLER(CMSG_REQUEST_VEHICLE_PREV_SEAT, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, WorldPackets::Vehicle::RequestVehiclePrevSeat, &WorldSession::HandleRequestVehiclePrevSeat); @@ -673,7 +673,7 @@ void OpcodeTable::Initialize() DEFINE_HANDLER(CMSG_SET_ACTION_BAR_TOGGLES, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Character::SetActionBarToggles, &WorldSession::HandleSetActionBarToggles); DEFINE_HANDLER(CMSG_SET_ACTION_BUTTON, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Spells::SetActionButton, &WorldSession::HandleSetActionButtonOpcode); DEFINE_HANDLER(CMSG_SET_ACTIVE_MOVER, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Movement::SetActiveMover, &WorldSession::HandleSetActiveMoverOpcode); - DEFINE_OPCODE_HANDLER_OLD(CMSG_SET_ACTIVE_VOICE_CHANNEL, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleSetActiveVoiceChannel ); + DEFINE_HANDLER(CMSG_SET_ACTIVE_VOICE_CHANNEL, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, WorldPackets::Voice::SetActiveVoiceChannel, &WorldSession::HandleSetActiveVoiceChannel); DEFINE_HANDLER(CMSG_SET_ADVANCED_COMBAT_LOGGING, STATUS_LOGGEDIN, PROCESS_INPLACE, WorldPackets::ClientConfig::SetAdvancedCombatLogging, &WorldSession::HandleSetAdvancedCombatLogging); DEFINE_HANDLER(CMSG_SET_ASSISTANT_LEADER, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Party::SetAssistantLeader, &WorldSession::HandleSetAssistantLeaderOpcode); DEFINE_HANDLER(CMSG_SET_BACKPACK_AUTOSORT_DISABLED, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL); @@ -691,10 +691,10 @@ void OpcodeTable::Initialize() DEFINE_HANDLER(CMSG_SET_LFG_BONUS_FACTION_ID, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL); DEFINE_HANDLER(CMSG_SET_LOOT_METHOD, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Party::SetLootMethod, &WorldSession::HandleSetLootMethodOpcode); DEFINE_HANDLER(CMSG_SET_LOOT_SPECIALIZATION, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Loot::SetLootSpecialization, &WorldSession::HandleSetLootSpecialization); - DEFINE_OPCODE_HANDLER_OLD(CMSG_SET_PARTY_ASSIGNMENT, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandlePartyAssignmentOpcode ); + DEFINE_HANDLER(CMSG_SET_PARTY_ASSIGNMENT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Party::SetPartyAssignment, &WorldSession::HandleSetPartyAssignment); DEFINE_HANDLER(CMSG_SET_PARTY_LEADER, STATUS_LOGGEDIN, PROCESS_INPLACE, WorldPackets::Party::SetPartyLeader, &WorldSession::HandleSetPartyLeaderOpcode); DEFINE_HANDLER(CMSG_SET_PET_SLOT, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL); - DEFINE_OPCODE_HANDLER_OLD(CMSG_SET_PLAYER_DECLINED_NAMES, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleSetPlayerDeclinedNames ); + DEFINE_HANDLER(CMSG_SET_PLAYER_DECLINED_NAMES, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Character::SetPlayerDeclinedNames, &WorldSession::HandleSetPlayerDeclinedNames); DEFINE_HANDLER(CMSG_SET_PREFERRED_CEMETERY, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL); DEFINE_HANDLER(CMSG_SET_PVP, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Misc::SetPvP, &WorldSession::HandleSetPvP); DEFINE_HANDLER(CMSG_SET_RAID_DIFFICULTY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Misc::SetRaidDifficulty, &WorldSession::HandleSetRaidDifficultyOpcode); @@ -704,7 +704,7 @@ void OpcodeTable::Initialize() DEFINE_HANDLER(CMSG_SET_SHEATHED, STATUS_LOGGEDIN, PROCESS_INPLACE, WorldPackets::Combat::SetSheathed, &WorldSession::HandleSetSheathedOpcode); DEFINE_HANDLER(CMSG_SET_SORT_BAGS_RIGHT_TO_LEFT, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL); DEFINE_HANDLER(CMSG_SET_SPECIALIZATION, STATUS_LOGGEDIN, PROCESS_INPLACE, WorldPackets::Talent::SetSpecialization, &WorldSession::HandleSetSpecializationOpcode); - DEFINE_OPCODE_HANDLER_OLD(CMSG_SET_TAXI_BENCHMARK_MODE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleSetTaxiBenchmarkOpcode ); + DEFINE_HANDLER(CMSG_SET_TAXI_BENCHMARK_MODE, STATUS_LOGGEDIN, PROCESS_INPLACE, WorldPackets::Misc::SetTaxiBenchmarkMode, &WorldSession::HandleSetTaxiBenchmark); DEFINE_HANDLER(CMSG_SET_TITLE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Character::SetTitle, &WorldSession::HandleSetTitleOpcode); DEFINE_HANDLER(CMSG_SET_TRADE_CURRENCY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Trade::SetTradeCurrency, &WorldSession::HandleSetTradeCurrencyOpcode); DEFINE_HANDLER(CMSG_SET_TRADE_GOLD, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Trade::SetTradeGold, &WorldSession::HandleSetTradeGoldOpcode); @@ -767,7 +767,7 @@ void OpcodeTable::Initialize() DEFINE_HANDLER(CMSG_UNLOCK_VOID_STORAGE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::VoidStorage::UnlockVoidStorage, &WorldSession::HandleVoidStorageUnlock); DEFINE_HANDLER(CMSG_UPDATE_ACCOUNT_DATA, STATUS_AUTHED, PROCESS_THREADUNSAFE, WorldPackets::ClientConfig::UserClientUpdateAccountData, &WorldSession::HandleUpdateAccountData); DEFINE_HANDLER(CMSG_UPDATE_CLIENT_SETTINGS, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL); - DEFINE_OPCODE_HANDLER_OLD(CMSG_UPDATE_MISSILE_TRAJECTORY, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleUpdateMissileTrajectory ); + DEFINE_HANDLER(CMSG_UPDATE_MISSILE_TRAJECTORY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Spells::UpdateMissileTrajectory, &WorldSession::HandleUpdateMissileTrajectory); DEFINE_HANDLER(CMSG_UPDATE_RAID_TARGET, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Party::UpdateRaidTarget, &WorldSession::HandleUpdateRaidTargetOpcode); DEFINE_HANDLER(CMSG_UPDATE_VAS_PURCHASE_STATES, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL); DEFINE_HANDLER(CMSG_UPDATE_WOW_TOKEN_AUCTIONABLE_LIST, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, WorldPackets::Token::UpdateListedAuctionableTokens, &WorldSession::HandleUpdateListedAuctionableTokens); @@ -782,9 +782,9 @@ void OpcodeTable::Initialize() DEFINE_HANDLER(CMSG_VIOLENCE_LEVEL, STATUS_AUTHED, PROCESS_INPLACE, WorldPackets::Misc::ViolenceLevel, &WorldSession::HandleViolenceLevel); DEFINE_HANDLER(CMSG_VOICE_ADD_IGNORE, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL); DEFINE_HANDLER(CMSG_VOICE_DEL_IGNORE, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL); - DEFINE_OPCODE_HANDLER_OLD(CMSG_VOICE_SESSION_ENABLE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleVoiceSessionEnableOpcode ); + DEFINE_HANDLER(CMSG_VOICE_SESSION_ENABLE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, WorldPackets::Voice::VoiceSessionEnable, &WorldSession::HandleVoiceSessionEnable); DEFINE_HANDLER(CMSG_VOID_STORAGE_TRANSFER, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::VoidStorage::VoidStorageTransfer, &WorldSession::HandleVoidStorageTransfer); - DEFINE_OPCODE_HANDLER_OLD(CMSG_WARDEN_DATA, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleWardenDataOpcode ); + DEFINE_HANDLER(CMSG_WARDEN_DATA, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, WorldPackets::Warden::WardenData, &WorldSession::HandleWardenData); DEFINE_HANDLER(CMSG_WHO, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Who::WhoRequestPkt, &WorldSession::HandleWhoOpcode); DEFINE_HANDLER(CMSG_WHO_IS, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Who::WhoIsRequest, &WorldSession::HandleWhoIsOpcode); DEFINE_HANDLER(CMSG_WORLD_PORT_RESPONSE, STATUS_TRANSFER, PROCESS_THREADUNSAFE, WorldPackets::Movement::WorldPortResponse, &WorldSession::HandleMoveWorldportAckOpcode); @@ -820,9 +820,9 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_ALL_ACHIEVEMENT_DATA, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); DEFINE_SERVER_OPCODE_HANDLER(SMSG_ALL_GUILD_ACHIEVEMENTS, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_ARCHAEOLOGY_SURVERY_CAST, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_AREA_SPIRIT_HEALER_TIME, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_AREA_SPIRIT_HEALER_TIME, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_AREA_TRIGGER_DENIED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_AREA_TRIGGER_NO_CORPSE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_AREA_TRIGGER_NO_CORPSE, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_AREA_TRIGGER_RE_PATH, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_AREA_TRIGGER_RE_SHAPE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_ARENA_ERROR, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); @@ -970,10 +970,10 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_CHAT_IGNORED_ACCOUNT_MUTED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_CHAT_IS_DOWN, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_CHAT_NOT_IN_PARTY, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_CHAT_PLAYER_AMBIGUOUS, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_CHAT_PLAYER_AMBIGUOUS, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_CHAT_PLAYER_NOTFOUND, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_CHAT_RECONNECT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_CHAT_RESTRICTED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_CHAT_RESTRICTED, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_CHAT_SERVER_MESSAGE, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_CHEAT_IGNORE_DIMISHING_RETURNS, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_CHECK_WARGAME_ENTRY, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); @@ -990,9 +990,9 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_COMMENTATOR_MAP_INFO, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_COMMENTATOR_PLAYER_INFO, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_COMMENTATOR_STATE_CHANGED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_COMPLAINT_RESULT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_COMPLAINT_RESULT, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_COMPLETE_SHIPMENT_RESPONSE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_COMPRESSED_PACKET, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_COMPRESSED_PACKET, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_CONNECT_TO, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_CONQUEST_FORMULA_CONSTANTS, STATUS_UNHANDLED, CONNECTION_TYPE_INSTANCE); DEFINE_SERVER_OPCODE_HANDLER(SMSG_CONSOLE_WRITE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); @@ -1003,7 +1003,7 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_COOLDOWN_EVENT, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); DEFINE_SERVER_OPCODE_HANDLER(SMSG_CORPSE_LOCATION, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_CORPSE_RECLAIM_DELAY, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_CORPSE_TRANSPORT_QUERY, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_CORPSE_TRANSPORT_QUERY, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_CREATE_CHAR, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_CREATE_SHIPMENT_RESPONSE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_CRITERIA_DELETED, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); @@ -1054,8 +1054,8 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_FEATURE_SYSTEM_STATUS_GLUE_SCREEN, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_FEIGN_DEATH_RESISTED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_FINAL_CHUNK, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_FISH_ESCAPED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_FISH_NOT_HOOKED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_FISH_ESCAPED, STATUS_NEVER, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_FISH_NOT_HOOKED, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_FLIGHT_SPLINE_SYNC, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_FORCED_DEATH_UPDATE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_FORCE_ANIM, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); @@ -1124,7 +1124,7 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_GM_PLAYER_INFO, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_GM_REQUEST_PLAYER_INFO, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_GM_TICKET_CASE_STATUS, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_GM_TICKET_SYSTEM_STATUS, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_GM_TICKET_SYSTEM_STATUS, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_GOD_MODE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_GOSSIP_COMPLETE, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_GOSSIP_MESSAGE, STATUS_NEVER, CONNECTION_TYPE_REALM); @@ -1380,11 +1380,11 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_NEW_TAXI_PATH, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_NEW_WORLD, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_NOTIFY_DEST_LOC_SPELL_CAST, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_NOTIFY_MISSILE_TRAJECTORY_COLLISION, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_NOTIFY_MISSILE_TRAJECTORY_COLLISION, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_NOTIFY_MONEY, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_NOTIFY_RECEIVED_MAIL, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_OFFER_PETITION_ERROR, STATUS_NEVER, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_ON_CANCEL_EXPECTED_RIDE_VEHICLE_AURA, STATUS_UNHANDLED, CONNECTION_TYPE_INSTANCE); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_ON_CANCEL_EXPECTED_RIDE_VEHICLE_AURA, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); DEFINE_SERVER_OPCODE_HANDLER(SMSG_ON_MONSTER_MOVE, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); DEFINE_SERVER_OPCODE_HANDLER(SMSG_OPEN_CONTAINER, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_OPEN_LFG_DUNGEON_FINDER, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); @@ -1446,7 +1446,7 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_PLAY_OBJECT_SOUND, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_PLAY_ONE_SHOT_ANIM_KIT, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_PLAY_ORPHAN_SPELL_VISUAL, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_PLAY_SCENE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_PLAY_SCENE, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_PLAY_SOUND, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_PLAY_SPEAKERBOT_SOUND, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_PLAY_SPELL_VISUAL, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); @@ -1458,7 +1458,7 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_PRINT_NOTIFICATION, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_PROC_RESIST, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_PROPOSE_LEVEL_GRANT, STATUS_NEVER, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_PVP_CREDIT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_PVP_CREDIT, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_PVP_LOG_DATA, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); DEFINE_SERVER_OPCODE_HANDLER(SMSG_PVP_OPTIONS_ENABLED, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_PVP_SEASON, STATUS_NEVER, CONNECTION_TYPE_REALM); @@ -1467,7 +1467,7 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUERY_GAME_OBJECT_RESPONSE, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUERY_GARRISON_CREATURE_NAME_RESPONSE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUERY_GUILD_INFO_RESPONSE, STATUS_NEVER, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUERY_ITEM_TEXT_RESPONSE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUERY_ITEM_TEXT_RESPONSE, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUERY_NPC_TEXT_RESPONSE, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUERY_PAGE_TEXT_RESPONSE, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUERY_PETITION_RESPONSE, STATUS_NEVER, CONNECTION_TYPE_REALM); @@ -1527,7 +1527,7 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_RESET_FAILED_NOTIFY, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_RESET_RANGED_COMBAT_TIMER, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_RESET_WEEKLY_CURRENCY, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_RESPEC_WIPE_CONFIRM, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_RESPEC_WIPE_CONFIRM, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); DEFINE_SERVER_OPCODE_HANDLER(SMSG_RESPOND_INSPECT_ACHIEVEMENTS, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); DEFINE_SERVER_OPCODE_HANDLER(SMSG_RESUME_CAST_BAR, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_RESUME_COMMS, STATUS_NEVER, CONNECTION_TYPE_REALM); @@ -1584,7 +1584,7 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_MOVEMENT_ANIM_KIT, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_PCT_SPELL_MODIFIER, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_PET_SPECIALIZATION, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_PLAYER_DECLINED_NAMES_RESULT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_PLAYER_DECLINED_NAMES_RESULT, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_PLAY_HOVER_ANIM, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_PROFICIENCY, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_SPELL_CHARGES, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); @@ -1614,7 +1614,7 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPELL_HEAL_LOG, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPELL_INSTAKILL_LOG, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPELL_INTERRUPT_LOG, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPELL_MISS_LOG, STATUS_UNHANDLED, CONNECTION_TYPE_INSTANCE); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPELL_MISS_LOG, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPELL_MULTISTRIKE_EFFECT, STATUS_UNHANDLED, CONNECTION_TYPE_INSTANCE); DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPELL_NON_MELEE_DAMAGE_LOG, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPELL_OR_DAMAGE_IMMUNE, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); @@ -1672,7 +1672,7 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_UPDATE_DUNGEON_ENCOUNTER_FOR_LOOT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_UPDATE_EXPANSION_LEVEL, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_UPDATE_INSTANCE_OWNERSHIP, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_UPDATE_LAST_INSTANCE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_UPDATE_LAST_INSTANCE, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_UPDATE_OBJECT, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); DEFINE_SERVER_OPCODE_HANDLER(SMSG_UPDATE_TALENT_DATA, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); DEFINE_SERVER_OPCODE_HANDLER(SMSG_UPDATE_TASK_PROGRESS, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h index dc4f3b32417..857988313d0 100644 --- a/src/server/game/Server/WorldSession.h +++ b/src/server/game/Server/WorldSession.h @@ -125,6 +125,8 @@ namespace WorldPackets class GetPVPOptionsEnabled; class RequestBattlefieldStatus; class ReportPvPPlayerAFK; + class RequestPVPRewards; + class RequestRatedBattlefieldInfo; } namespace BattlePet @@ -195,6 +197,7 @@ namespace WorldPackets class SetFactionNotAtWar; class SetFactionInactive; class SetWatchedFaction; + class SetPlayerDeclinedNames; enum class LoginFailureReason : uint8; } @@ -346,6 +349,7 @@ namespace WorldPackets class BuyBackItem; class DestroyItem; class GetItemPurchaseData; + class ItemPurchaseRefund; class RepairItem; class ReadItem; class SellItem; @@ -411,6 +415,7 @@ namespace WorldPackets class SetPvP; class WorldTeleport; class MountSpecial; + class SetTaxiBenchmarkMode; } namespace Movement @@ -433,6 +438,7 @@ namespace WorldPackets class GossipSelectOption; class SpiritHealerActivate; class TrainerBuySpell; + class RequestStabledPets; } namespace Party @@ -446,6 +452,7 @@ namespace WorldPackets class RequestPartyMemberStats; class PartyMemberStats; class SetPartyLeader; + class SetPartyAssignment; class SetRole; class RoleChangedInform; class SetLootMethod; @@ -476,6 +483,15 @@ namespace WorldPackets class ClearRaidMarker; } + namespace Pet + { + class DismissCritter; + class RequestPetInfo; + class PetAbandon; + class PetStopAttack; + class PetSpellAutocast; + } + namespace Petition { class DeclinePetition; @@ -520,6 +536,7 @@ namespace WorldPackets class QuestGiverAcceptQuest; class QuestLogRemoveQuest; class QuestPushResult; + class PushQuestToParty; } namespace RaF @@ -565,6 +582,7 @@ namespace WorldPackets class CancelChannelling; class CancelGrowthAura; class CancelMountAura; + class PetCancelAura; class RequestCategoryCooldowns; class CancelCast; class CastSpell; @@ -576,12 +594,15 @@ namespace WorldPackets class SelfRes; class GetMirrorImageData; class SpellClick; + class MissileTrajectoryCollision; + class UpdateMissileTrajectory; } namespace Talent { class SetSpecialization; class LearnTalents; + class ConfirmRespecWipe; } namespace Taxi @@ -602,6 +623,7 @@ namespace WorldPackets class SupportTicketSubmitSuggestion; class SupportTicketSubmitComplaint; class BugReport; + class Complaint; } namespace Token @@ -644,6 +666,12 @@ namespace WorldPackets class MoveSetVehicleRecIdAck; } + namespace Voice + { + class VoiceSessionEnable; + class SetActiveVoiceChannel; + } + namespace VoidStorage { class UnlockVoidStorage; @@ -652,6 +680,11 @@ namespace WorldPackets class SwapVoidItem; } + namespace Warden + { + class WardenData; + } + namespace Who { class WhoIsRequest; @@ -754,10 +787,11 @@ enum BFLeaveReason enum ChatRestrictionType { - ERR_CHAT_RESTRICTED = 0, - ERR_CHAT_THROTTLED = 1, - ERR_USER_SQUELCHED = 2, - ERR_YELL_RESTRICTED = 3 + ERR_CHAT_RESTRICTED = 0, + ERR_CHAT_THROTTLED = 1, + ERR_USER_SQUELCHED = 2, + ERR_YELL_RESTRICTED = 3, + ERR_CHAT_RAID_RESTRICTED = 4 }; enum CharterTypes @@ -1054,7 +1088,7 @@ class WorldSession void HandlePlayerLogin(LoginQueryHolder * holder); void HandleCharRenameOpcode(WorldPackets::Character::CharacterRenameRequest& request); void HandleCharRenameCallBack(PreparedQueryResult result, WorldPackets::Character::CharacterRenameInfo* renameInfo); - void HandleSetPlayerDeclinedNames(WorldPacket& recvData); + void HandleSetPlayerDeclinedNames(WorldPackets::Character::SetPlayerDeclinedNames& packet); void HandleAlterAppearance(WorldPackets::Character::AlterApperance& packet); void HandleCharCustomizeOpcode(WorldPackets::Character::CharCustomize& packet); void HandleCharCustomizeCallback(PreparedQueryResult result, WorldPackets::Character::CharCustomizeInfo* customizeInfo); @@ -1130,6 +1164,7 @@ class WorldSession void HandleSupportTicketSubmitSuggestion(WorldPackets::Ticket::SupportTicketSubmitSuggestion& packet); void HandleSupportTicketSubmitComplaint(WorldPackets::Ticket::SupportTicketSubmitComplaint& packet); void HandleBugReportOpcode(WorldPackets::Ticket::BugReport& bugReport); + void HandleComplaint(WorldPackets::Ticket::Complaint& packet); void HandleTogglePvP(WorldPackets::Misc::TogglePvP& packet); void HandleSetPvP(WorldPackets::Misc::SetPvP& packet); @@ -1211,7 +1246,7 @@ class WorldSession void HandleChangeSubGroupOpcode(WorldPackets::Party::ChangeSubGroup& packet); void HandleSwapSubGroupsOpcode(WorldPackets::Party::SwapSubGroups& packet); void HandleSetAssistantLeaderOpcode(WorldPackets::Party::SetAssistantLeader& packet); - void HandlePartyAssignmentOpcode(WorldPacket& recvData); + void HandleSetPartyAssignment(WorldPackets::Party::SetPartyAssignment& packet); void HandleInitiateRolePoll(WorldPackets::Party::InitiateRolePoll& packet); void HandleSetEveryoneIsAssistant(WorldPackets::Party::SetEveryoneIsAssistant& packet); void HandleClearRaidMarker(WorldPackets::Party::ClearRaidMarker& packet); @@ -1281,7 +1316,7 @@ class WorldSession void HandleSpiritHealerActivate(WorldPackets::NPC::SpiritHealerActivate& packet); void HandleNpcTextQueryOpcode(WorldPackets::Query::QueryNPCText& packet); void HandleBinderActivateOpcode(WorldPackets::NPC::Hello& packet); - void HandleListStabledPetsOpcode(WorldPacket& recvPacket); + void HandleRequestStabledPets(WorldPackets::NPC::RequestStabledPets& packet); void HandleStablePet(WorldPacket& recvPacket); void HandleStablePetCallback(PreparedQueryResult result); void HandleUnstablePet(WorldPacket& recvPacket); @@ -1367,9 +1402,11 @@ class WorldSession void HandleCancelGrowthAuraOpcode(WorldPackets::Spells::CancelGrowthAura& cancelGrowthAura); void HandleCancelMountAuraOpcode(WorldPackets::Spells::CancelMountAura& cancelMountAura); void HandleCancelAutoRepeatSpellOpcode(WorldPackets::Spells::CancelAutoRepeatSpell& cancelAutoRepeatSpell); + void HandleMissileTrajectoryCollision(WorldPackets::Spells::MissileTrajectoryCollision& packet); + void HandleUpdateMissileTrajectory(WorldPackets::Spells::UpdateMissileTrajectory& packet); void HandleLearnTalentsOpcode(WorldPackets::Talent::LearnTalents& packet); - void HandleConfirmRespecWipeOpcode(WorldPacket& recvPacket); + void HandleConfirmRespecWipeOpcode(WorldPackets::Talent::ConfirmRespecWipe& confirmRespecWipe); void HandleUnlearnSkillOpcode(WorldPackets::Spells::UnlearnSkill& packet); void HandleSetSpecializationOpcode(WorldPackets::Talent::SetSpecialization& packet); @@ -1386,7 +1423,7 @@ class WorldSession void HandleQuestConfirmAccept(WorldPackets::Quest::QuestConfirmAccept& packet); void HandleQuestgiverCompleteQuest(WorldPackets::Quest::QuestGiverCompleteQuest& packet); void HandleQuestgiverQuestAutoLaunch(WorldPacket& recvPacket); - void HandlePushQuestToParty(WorldPacket& recvPacket); + void HandlePushQuestToParty(WorldPackets::Quest::PushQuestToParty& packet); void HandleQuestPushResult(WorldPackets::Quest::QuestPushResult& packet); void HandleChatMessageOpcode(WorldPackets::Chat::ChatMessage& chatMessage); @@ -1402,7 +1439,7 @@ class WorldSession void HandleChatMessageEmoteOpcode(WorldPackets::Chat::ChatMessageEmote& chatMessageEmote); void SendChatPlayerNotfoundNotice(std::string const& name); void SendPlayerAmbiguousNotice(std::string const& name); - void SendChatRestrictedNotice(ChatRestrictionType restriction); + void SendChatRestricted(ChatRestrictionType restriction); void HandleTextEmoteOpcode(WorldPackets::Chat::CTextEmote& packet); void HandleChatIgnoredOpcode(WorldPackets::Chat::ChatReportIgnored& chatReportIgnored); @@ -1424,8 +1461,8 @@ class WorldSession template<void(Channel::*CommandFunction)(Player const*, std::string const&)> void HandleChannelPlayerCommand(WorldPackets::Channel::ChannelPlayerCommand& packet); - void HandleVoiceSessionEnableOpcode(WorldPacket& recvData); - void HandleSetActiveVoiceChannel(WorldPacket& recvData); + void HandleVoiceSessionEnable(WorldPackets::Voice::VoiceSessionEnable& packet); + void HandleSetActiveVoiceChannel(WorldPackets::Voice::SetActiveVoiceChannel& packet); void HandleCompleteCinematic(WorldPackets::Misc::CompleteCinematic& packet); void HandleNextCinematicCamera(WorldPackets::Misc::NextCinematicCamera& packet); @@ -1436,20 +1473,20 @@ class WorldSession //Pet void HandlePetAction(WorldPacket& recvData); - void HandlePetStopAttack(WorldPacket& recvData); + void HandlePetStopAttack(WorldPackets::Pet::PetStopAttack& packet); void HandlePetActionHelper(Unit* pet, ObjectGuid guid1, uint32 spellid, uint16 flag, ObjectGuid guid2, float x, float y, float z); void HandleQueryPetName(WorldPackets::Query::QueryPetName& packet); void HandlePetSetAction(WorldPacket& recvData); - void HandlePetAbandon(WorldPacket& recvData); + void HandlePetAbandon(WorldPackets::Pet::PetAbandon& packet); void HandlePetRename(WorldPacket& recvData); - void HandlePetCancelAuraOpcode(WorldPacket& recvPacket); - void HandlePetSpellAutocastOpcode(WorldPacket& recvPacket); + void HandlePetCancelAuraOpcode(WorldPackets::Spells::PetCancelAura& packet); + void HandlePetSpellAutocastOpcode(WorldPackets::Pet::PetSpellAutocast& packet); void HandlePetCastSpellOpcode(WorldPackets::Spells::PetCastSpell& petCastSpell); void HandleSetActionBarToggles(WorldPackets::Character::SetActionBarToggles& packet); void HandleTotemDestroyed(WorldPackets::Totem::TotemDestroyed& totemDestroyed); - void HandleDismissCritter(WorldPacket& recvData); + void HandleDismissCritter(WorldPackets::Pet::DismissCritter& dismissCritter); //Battleground void HandleBattlemasterHelloOpcode(WorldPackets::NPC::Hello& hello); @@ -1460,9 +1497,9 @@ class WorldSession void HandleBattlefieldLeaveOpcode(WorldPackets::Battleground::BattlefieldLeave& battlefieldLeave); void HandleBattlemasterJoinArena(WorldPackets::Battleground::BattlemasterJoinArena& packet); void HandleReportPvPAFK(WorldPackets::Battleground::ReportPvPPlayerAFK& reportPvPPlayerAFK); - void HandleRequestRatedBattlefieldInfo(WorldPacket& recvData); + void HandleRequestRatedBattlefieldInfo(WorldPackets::Battleground::RequestRatedBattlefieldInfo& packet); void HandleGetPVPOptionsEnabled(WorldPackets::Battleground::GetPVPOptionsEnabled& getPvPOptionsEnabled); - void HandleRequestPvpReward(WorldPacket& recvData); + void HandleRequestPvpReward(WorldPackets::Battleground::RequestPVPRewards& packet); void HandleAreaSpiritHealerQueryOpcode(WorldPackets::Battleground::AreaSpiritHealerQuery& areaSpiritHealerQuery); void HandleAreaSpiritHealerQueueOpcode(WorldPackets::Battleground::AreaSpiritHealerQueue& areaSpiritHealerQueue); void HandleHearthAndResurrect(WorldPackets::Battleground::HearthAndResurrect& hearthAndResurrect); @@ -1478,7 +1515,7 @@ class WorldSession void HandleBfQueueInviteResponse(WorldPackets::Battlefield::BFMgrQueueInviteResponse& bfMgrQueueInviteResponse); void HandleBfQueueExitRequest(WorldPackets::Battlefield::BFMgrQueueExitRequest& bfMgrQueueExitRequest); - void HandleWardenDataOpcode(WorldPacket& recvData); + void HandleWorldTeleportOpcode(WorldPackets::Misc::WorldTeleport& worldTeleport); void HandleMinimapPingOpcode(WorldPackets::Party::MinimapPingClient& packet); void HandleRandomRollOpcode(WorldPackets::Misc::RandomRollClient& packet); @@ -1520,8 +1557,7 @@ class WorldSession void SendLfgTeleportError(uint8 err); void HandleSelfResOpcode(WorldPackets::Spells::SelfRes& packet); - void HandleComplainOpcode(WorldPacket& recvData); - void HandleRequestPetInfoOpcode(WorldPacket& recvData); + void HandleRequestPetInfo(WorldPackets::Pet::RequestPetInfo& packet); // Socket gem void HandleSocketGems(WorldPackets::Item::SocketGems& socketGems); @@ -1529,9 +1565,9 @@ class WorldSession void HandleCancelTempEnchantmentOpcode(WorldPackets::Item::CancelTempEnchantment& cancelTempEnchantment); void HandleGetItemPurchaseData(WorldPackets::Item::GetItemPurchaseData& packet); - void HandleItemRefund(WorldPacket& recvData); + void HandleItemRefund(WorldPackets::Item::ItemPurchaseRefund& packet); - void HandleSetTaxiBenchmarkOpcode(WorldPacket& recvData); + void HandleSetTaxiBenchmark(WorldPackets::Misc::SetTaxiBenchmarkMode& packet); // Guild Bank void HandleGuildPermissionsQuery(WorldPackets::Guild::GuildPermissionsQuery& packet); @@ -1594,8 +1630,6 @@ class WorldSession void HandleUITimeRequest(WorldPackets::Misc::UITimeRequest& /*request*/); void HandleQueryQuestCompletionNPCs(WorldPackets::Query::QueryQuestCompletionNPCs& queryQuestCompletionNPCs); void HandleQuestPOIQuery(WorldPackets::Query::QuestPOIQuery& questPoiQuery); - void HandleUpdateProjectilePosition(WorldPacket& recvPacket); - void HandleUpdateMissileTrajectory(WorldPacket& recvPacket); void HandleViolenceLevel(WorldPackets::Misc::ViolenceLevel& violenceLevel); void HandleObjectUpdateFailedOpcode(WorldPackets::Misc::ObjectUpdateFailed& objectUpdateFailed); void HandleObjectUpdateRescuedOpcode(WorldPackets::Misc::ObjectUpdateRescued& objectUpdateRescued); @@ -1635,6 +1669,9 @@ class WorldSession void HandleBattlePetSummon(WorldPackets::BattlePet::BattlePetSummon& battlePetSummon); void HandleCageBattlePet(WorldPackets::BattlePet::CageBattlePet& cageBattlePet); + // Warden + void HandleWardenData(WorldPackets::Warden::WardenData& packet); + union ConnectToKey { struct diff --git a/src/server/game/Server/WorldSocket.cpp b/src/server/game/Server/WorldSocket.cpp index 8f8c9d89502..acec25a7363 100644 --- a/src/server/game/Server/WorldSocket.cpp +++ b/src/server/game/Server/WorldSocket.cpp @@ -38,6 +38,17 @@ struct CompressedWorldPacket uint32 CompressedAdler; }; +class EncryptablePacket : public WorldPacket +{ +public: + EncryptablePacket(WorldPacket const& packet, bool encrypt) : WorldPacket(packet), _encrypt(encrypt) { } + + bool NeedsEncryption() const { return _encrypt; } + +private: + bool _encrypt; +}; + #pragma pack(pop) using boost::asio::ip::tcp; @@ -76,11 +87,8 @@ void WorldSocket::Start() stmt->setString(0, ip_address); stmt->setUInt32(1, inet_addr(ip_address.c_str())); - { - std::lock_guard<std::mutex> guard(_queryLock); - _queryCallback = io_service().wrap(std::bind(&WorldSocket::CheckIpCallback, this, std::placeholders::_1)); - _queryFuture = LoginDatabase.AsyncQuery(stmt); - } + _queryCallback = std::bind(&WorldSocket::CheckIpCallback, this, std::placeholders::_1); + _queryFuture = LoginDatabase.AsyncQuery(stmt); } void WorldSocket::CheckIpCallback(PreparedQueryResult result) @@ -116,23 +124,50 @@ void WorldSocket::CheckIpCallback(PreparedQueryResult result) initializer.Write(&header, sizeof(header.Setup.Size)); initializer.Write(ServerConnectionInitialize.c_str(), ServerConnectionInitialize.length()); - std::unique_lock<std::mutex> guard(_writeLock); - QueuePacket(std::move(initializer), guard); + // - io_service.run thread, safe. + QueuePacket(std::move(initializer)); } bool WorldSocket::Update() { + EncryptablePacket* queued; + MessageBuffer buffer; + while (_bufferQueue.Dequeue(queued)) + { + uint32 sizeOfHeader = SizeOfServerHeader[queued->NeedsEncryption()]; + uint32 packetSize = queued->size(); + if (packetSize > MinSizeForCompression && queued->NeedsEncryption()) + packetSize = compressBound(packetSize) + sizeof(CompressedWorldPacket); + + if (buffer.GetRemainingSpace() < packetSize + sizeOfHeader) + { + QueuePacket(std::move(buffer)); + buffer.Resize(4096); + } + + if (buffer.GetRemainingSpace() >= packetSize + sizeOfHeader) + WritePacketToBuffer(*queued, buffer); + else // single packet larger than 4096 bytes + { + MessageBuffer packetBuffer(packetSize + sizeOfHeader); + WritePacketToBuffer(*queued, packetBuffer); + QueuePacket(std::move(packetBuffer)); + } + + delete queued; + } + + if (buffer.GetActiveSize() > 0) + QueuePacket(std::move(buffer)); + if (!BaseSocket::Update()) return false; + if (_queryFuture.valid() && _queryFuture.wait_for(std::chrono::seconds(0)) == std::future_status::ready) { - std::lock_guard<std::mutex> guard(_queryLock); - if (_queryFuture.valid() && _queryFuture.wait_for(std::chrono::seconds(0)) == std::future_status::ready) - { - auto callback = std::move(_queryCallback); - _queryCallback = nullptr; - callback(_queryFuture.get()); - } + auto callback = _queryCallback; + _queryCallback = nullptr; + callback(_queryFuture.get()); } return true; @@ -428,29 +463,13 @@ void WorldSocket::SendPacket(WorldPacket const& packet) if (sPacketLog->CanLogPacket()) sPacketLog->LogPacket(packet, SERVER_TO_CLIENT, GetRemoteIpAddress(), GetRemotePort(), GetConnectionType()); - uint32 packetSize = packet.size(); - uint32 sizeOfHeader = SizeOfServerHeader[_authCrypt.IsInitialized()]; - if (packetSize > MinSizeForCompression && _authCrypt.IsInitialized()) - packetSize = compressBound(packetSize) + sizeof(CompressedWorldPacket); - - std::unique_lock<std::mutex> guard(_writeLock); - -#ifndef TC_SOCKET_USE_IOCP - if (_writeQueue.empty() && _writeBuffer.GetRemainingSpace() >= sizeOfHeader + packetSize) - WritePacketToBuffer(packet, _writeBuffer); - else -#endif - { - MessageBuffer buffer(sizeOfHeader + packetSize); - WritePacketToBuffer(packet, buffer); - QueuePacket(std::move(buffer), guard); - } + _bufferQueue.Enqueue(new EncryptablePacket(packet, _authCrypt.IsInitialized())); } -void WorldSocket::WritePacketToBuffer(WorldPacket const& packet, MessageBuffer& buffer) +void WorldSocket::WritePacketToBuffer(EncryptablePacket const& packet, MessageBuffer& buffer) { ServerPktHeader header; - uint32 sizeOfHeader = SizeOfServerHeader[_authCrypt.IsInitialized()]; + uint32 sizeOfHeader = SizeOfServerHeader[packet.NeedsEncryption()]; uint32 opcode = packet.GetOpcode(); uint32 packetSize = packet.size(); @@ -458,7 +477,7 @@ void WorldSocket::WritePacketToBuffer(WorldPacket const& packet, MessageBuffer& uint8* headerPos = buffer.GetWritePointer(); buffer.WriteCompleted(sizeOfHeader); - if (packetSize > MinSizeForCompression && _authCrypt.IsInitialized()) + if (packetSize > MinSizeForCompression && packet.NeedsEncryption()) { CompressedWorldPacket cmp; cmp.UncompressedSize = packetSize + 4; @@ -481,7 +500,7 @@ void WorldSocket::WritePacketToBuffer(WorldPacket const& packet, MessageBuffer& else if (!packet.empty()) buffer.Write(packet.contents(), packet.size()); - if (_authCrypt.IsInitialized()) + if (packet.NeedsEncryption()) { header.Normal.Size = packetSize; header.Normal.Command = opcode; @@ -598,11 +617,8 @@ void WorldSocket::HandleAuthSession(std::shared_ptr<WorldPackets::Auth::AuthSess stmt->setInt32(0, int32(realm.Id.Realm)); stmt->setString(1, authSession->Account); - { - std::lock_guard<std::mutex> guard(_queryLock); - _queryCallback = io_service().wrap(std::bind(&WorldSocket::HandleAuthSessionCallback, this, authSession, std::placeholders::_1)); - _queryFuture = LoginDatabase.AsyncQuery(stmt); - } + _queryCallback = std::bind(&WorldSocket::HandleAuthSessionCallback, this, authSession, std::placeholders::_1); + _queryFuture = LoginDatabase.AsyncQuery(stmt); } void WorldSocket::HandleAuthSessionCallback(std::shared_ptr<WorldPackets::Auth::AuthSession> authSession, PreparedQueryResult result) @@ -768,7 +784,7 @@ void WorldSocket::HandleAuthSessionCallback(std::shared_ptr<WorldPackets::Auth:: if (wardenActive) _worldSession->InitWarden(&account.Game.SessionKey, account.BattleNet.OS); - _queryCallback = io_service().wrap(std::bind(&WorldSocket::LoadSessionPermissionsCallback, this, std::placeholders::_1)); + _queryCallback = std::bind(&WorldSocket::LoadSessionPermissionsCallback, this, std::placeholders::_1); _queryFuture = _worldSession->LoadPermissionsAsync(); AsyncRead(); } @@ -801,11 +817,8 @@ void WorldSocket::HandleAuthContinuedSession(std::shared_ptr<WorldPackets::Auth: PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_ACCOUNT_INFO_CONTINUED_SESSION); stmt->setUInt32(0, accountId); - { - std::lock_guard<std::mutex> guard(_queryLock); - _queryCallback = io_service().wrap(std::bind(&WorldSocket::HandleAuthContinuedSessionCallback, this, authSession, std::placeholders::_1)); - _queryFuture = LoginDatabase.AsyncQuery(stmt); - } + _queryCallback = std::bind(&WorldSocket::HandleAuthContinuedSessionCallback, this, authSession, std::placeholders::_1); + _queryFuture = LoginDatabase.AsyncQuery(stmt); } void WorldSocket::HandleAuthContinuedSessionCallback(std::shared_ptr<WorldPackets::Auth::AuthContinuedSession> authSession, PreparedQueryResult result) diff --git a/src/server/game/Server/WorldSocket.h b/src/server/game/Server/WorldSocket.h index 59975c12f13..205494ca4ea 100644 --- a/src/server/game/Server/WorldSocket.h +++ b/src/server/game/Server/WorldSocket.h @@ -26,12 +26,13 @@ #include "Util.h" #include "WorldPacket.h" #include "WorldSession.h" +#include "MPSCQueue.h" #include <chrono> #include <boost/asio/ip/tcp.hpp> -#include <boost/asio/buffer.hpp> using boost::asio::ip::tcp; struct z_stream_s; +class EncryptablePacket; namespace WorldPackets { @@ -112,7 +113,7 @@ private: void LogOpcodeText(OpcodeClient opcode, std::unique_lock<std::mutex> const& guard) const; /// sends and logs network.opcode without accessing WorldSession void SendPacketAndLogOpcode(WorldPacket const& packet); - void WritePacketToBuffer(WorldPacket const& packet, MessageBuffer& buffer); + void WritePacketToBuffer(EncryptablePacket const& packet, MessageBuffer& buffer); uint32 CompressPacket(uint8* buffer, WorldPacket const& packet); void HandleSendAuthSession(); @@ -143,12 +144,12 @@ private: MessageBuffer _headerBuffer; MessageBuffer _packetBuffer; + MPSCQueue<EncryptablePacket> _bufferQueue; z_stream_s* _compressionStream; bool _initialized; - std::mutex _queryLock; PreparedQueryResultFuture _queryFuture; std::function<void(PreparedQueryResult&&)> _queryCallback; std::string _ipCountry; diff --git a/src/server/game/Server/WorldSocketMgr.cpp b/src/server/game/Server/WorldSocketMgr.cpp index 937483e1179..4f42e943245 100644 --- a/src/server/game/Server/WorldSocketMgr.cpp +++ b/src/server/game/Server/WorldSocketMgr.cpp @@ -24,9 +24,9 @@ #include <boost/system/error_code.hpp> -static void OnSocketAccept(tcp::socket&& sock) +static void OnSocketAccept(tcp::socket&& sock, uint32 threadIndex) { - sWorldSocketMgr.OnSocketOpen(std::forward<tcp::socket>(sock)); + sWorldSocketMgr.OnSocketOpen(std::forward<tcp::socket>(sock), threadIndex); } class WorldSocketThread : public NetworkThread<WorldSocket> @@ -49,7 +49,7 @@ WorldSocketMgr::WorldSocketMgr() : BaseSocketMgr(), _instanceAcceptor(nullptr), WorldSocketMgr::~WorldSocketMgr() { - delete _instanceAcceptor; + ASSERT(!_instanceAcceptor, "StopNetwork must be called prior to WorldSocketMgr destruction"); } bool WorldSocketMgr::StartNetwork(boost::asio::io_service& service, std::string const& bindIp, uint16 port) @@ -73,8 +73,11 @@ bool WorldSocketMgr::StartNetwork(boost::asio::io_service& service, std::string BaseSocketMgr::StartNetwork(service, bindIp, port); _instanceAcceptor = new AsyncAcceptor(service, bindIp, uint16(sWorld->getIntConfig(CONFIG_PORT_INSTANCE))); - _acceptor->AsyncAcceptManaged(&OnSocketAccept); - _instanceAcceptor->AsyncAcceptManaged(&OnSocketAccept); + _acceptor->SetSocketFactory(std::bind(&BaseSocketMgr::GetSocketForAccept, this)); + _instanceAcceptor->SetSocketFactory(std::bind(&BaseSocketMgr::GetSocketForAccept, this)); + + _acceptor->AsyncAcceptWithCallback<&OnSocketAccept>(); + _instanceAcceptor->AsyncAcceptWithCallback<&OnSocketAccept>(); sScriptMgr->OnNetworkStart(); return true; @@ -82,12 +85,16 @@ bool WorldSocketMgr::StartNetwork(boost::asio::io_service& service, std::string void WorldSocketMgr::StopNetwork() { + _instanceAcceptor->Close(); BaseSocketMgr::StopNetwork(); + delete _instanceAcceptor; + _instanceAcceptor = nullptr; + sScriptMgr->OnNetworkStop(); } -void WorldSocketMgr::OnSocketOpen(tcp::socket&& sock) +void WorldSocketMgr::OnSocketOpen(tcp::socket&& sock, uint32 threadIndex) { // set some options here if (_socketSendBufferSize >= 0) @@ -115,7 +122,7 @@ void WorldSocketMgr::OnSocketOpen(tcp::socket&& sock) //sock->m_OutBufferSize = static_cast<size_t> (m_SockOutUBuff); - BaseSocketMgr::OnSocketOpen(std::forward<tcp::socket>(sock)); + BaseSocketMgr::OnSocketOpen(std::forward<tcp::socket>(sock), threadIndex); } NetworkThread<WorldSocket>* WorldSocketMgr::CreateThreads() const diff --git a/src/server/game/Server/WorldSocketMgr.h b/src/server/game/Server/WorldSocketMgr.h index d4bf4115deb..2079b62d14f 100644 --- a/src/server/game/Server/WorldSocketMgr.h +++ b/src/server/game/Server/WorldSocketMgr.h @@ -49,7 +49,7 @@ public: /// Stops all network threads, It will wait for all running threads . void StopNetwork() override; - void OnSocketOpen(tcp::socket&& sock) override; + void OnSocketOpen(tcp::socket&& sock, uint32 threadIndex) override; protected: WorldSocketMgr(); diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index 0be2fed3424..1cef132fcda 100644 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -5501,7 +5501,7 @@ SpellCastResult Spell::CheckCast(bool strict) if (m_originalCaster && m_originalCaster->GetTypeId() == TYPEID_PLAYER && m_originalCaster->IsAlive()) { Battlefield* Bf = sBattlefieldMgr->GetBattlefieldToZoneId(m_originalCaster->GetZoneId()); - if (AreaTableEntry const* area = GetAreaEntryByAreaID(m_originalCaster->GetAreaId())) + if (AreaTableEntry const* area = sAreaTableStore.LookupEntry(m_originalCaster->GetAreaId())) if (area->Flags[0] & AREA_FLAG_NO_FLY_ZONE || (Bf && !Bf->CanFlyIn())) return (_triggeredCastFlags & TRIGGERED_DONT_REPORT_CAST_ERROR) ? SPELL_FAILED_DONT_REPORT : SPELL_FAILED_NOT_HERE; } diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp index d014119f00c..a43c30917b4 100644 --- a/src/server/game/Spells/SpellEffects.cpp +++ b/src/server/game/Spells/SpellEffects.cpp @@ -3866,14 +3866,14 @@ void Spell::EffectDuel(SpellEffIndex effIndex) return; // Players can only fight a duel in zones with this flag - AreaTableEntry const* casterAreaEntry = GetAreaEntryByAreaID(caster->GetAreaId()); + AreaTableEntry const* casterAreaEntry = sAreaTableStore.LookupEntry(caster->GetAreaId()); if (casterAreaEntry && !(casterAreaEntry->Flags[0] & AREA_FLAG_ALLOW_DUELS)) { SendCastResult(SPELL_FAILED_NO_DUELING); // Dueling isn't allowed here return; } - AreaTableEntry const* targetAreaEntry = GetAreaEntryByAreaID(target->GetAreaId()); + AreaTableEntry const* targetAreaEntry = sAreaTableStore.LookupEntry(target->GetAreaId()); if (targetAreaEntry && !(targetAreaEntry->Flags[0] & AREA_FLAG_ALLOW_DUELS)) { SendCastResult(SPELL_FAILED_NO_DUELING); // Dueling isn't allowed here diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp index dd73c261853..a628e934465 100644 --- a/src/server/game/Spells/SpellMgr.cpp +++ b/src/server/game/Spells/SpellMgr.cpp @@ -2625,7 +2625,7 @@ void SpellMgr::LoadSpellAreas() } } - if (spellArea.areaId && !GetAreaEntryByAreaID(spellArea.areaId)) + if (spellArea.areaId && !sAreaTableStore.LookupEntry(spellArea.areaId)) { TC_LOG_ERROR("sql.sql", "Spell %u listed in `spell_area` have wrong area (%u) requirement", spell, spellArea.areaId); continue; diff --git a/src/server/game/Support/SupportMgr.h b/src/server/game/Support/SupportMgr.h index c312651d789..f79f71e7b2f 100644 --- a/src/server/game/Support/SupportMgr.h +++ b/src/server/game/Support/SupportMgr.h @@ -41,6 +41,13 @@ enum GMSupportComplaintType GMTICKET_SUPPORT_COMPLAINT_TYPE_SPAMMING = 24 }; +enum SupportSpamType +{ + SUPPORT_SPAM_TYPE_MAIL = 0, + SUPPORT_SPAM_TYPE_CHAT = 1, + SUPPORT_SPAM_TYPE_CALENDAR = 2 +}; + using ChatLog = WorldPackets::Ticket::SupportTicketSubmitComplaint::SupportTicketChatLog; class Ticket diff --git a/src/server/game/Warden/Warden.cpp b/src/server/game/Warden/Warden.cpp index 5f5147c739b..906e0cade08 100644 --- a/src/server/game/Warden/Warden.cpp +++ b/src/server/game/Warden/Warden.cpp @@ -26,6 +26,7 @@ #include "Util.h" #include "Warden.h" #include "AccountMgr.h" +#include "WardenPackets.h" #include <openssl/sha.h> @@ -220,16 +221,16 @@ std::string Warden::Penalty(WardenCheck* check /*= NULL*/) return "Undefined"; } -void WorldSession::HandleWardenDataOpcode(WorldPacket& recvData) +void WorldSession::HandleWardenData(WorldPackets::Warden::WardenData& packet) { - if (!_warden || recvData.empty()) + if (!_warden || packet.Data.empty()) return; - _warden->DecryptData(recvData.contents(), recvData.size()); + _warden->DecryptData(packet.Data.contents(), packet.Data.size()); uint8 opcode; - recvData >> opcode; - TC_LOG_DEBUG("warden", "Got packet, opcode %02X, size %u", opcode, uint32(recvData.size())); - recvData.hexlike(); + packet.Data >> opcode; + TC_LOG_DEBUG("warden", "Got packet, opcode %02X, size %u", opcode, uint32(packet.Data.size())); + packet.Data.hexlike(); switch (opcode) { @@ -240,20 +241,20 @@ void WorldSession::HandleWardenDataOpcode(WorldPacket& recvData) _warden->RequestHash(); break; case WARDEN_CMSG_CHEAT_CHECKS_RESULT: - _warden->HandleData(recvData); + _warden->HandleData(packet.Data); break; case WARDEN_CMSG_MEM_CHECKS_RESULT: TC_LOG_DEBUG("warden", "NYI WARDEN_CMSG_MEM_CHECKS_RESULT received!"); break; case WARDEN_CMSG_HASH_RESULT: - _warden->HandleHashResult(recvData); + _warden->HandleHashResult(packet.Data); _warden->InitializeModule(); break; case WARDEN_CMSG_MODULE_FAILED: TC_LOG_DEBUG("warden", "NYI WARDEN_CMSG_MODULE_FAILED received!"); break; default: - TC_LOG_DEBUG("warden", "Got unknown warden opcode %02X of size %u.", opcode, uint32(recvData.size() - 1)); + TC_LOG_DEBUG("warden", "Got unknown warden opcode %02X of size %u.", opcode, uint32(packet.Data.size() - 1)); break; } } diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index 972860f790f..d2ccb025165 100644 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -227,7 +227,7 @@ void World::AddSession(WorldSession* s) addSessQueue.add(s); } -void World::AddInstanceSocket(std::shared_ptr<WorldSocket> sock, uint64 connectToKey) +void World::AddInstanceSocket(std::weak_ptr<WorldSocket> sock, uint64 connectToKey) { _linkSocketQueue.add(std::make_pair(sock, connectToKey)); } @@ -298,25 +298,28 @@ void World::AddSession_(WorldSession* s) } } -void World::ProcessLinkInstanceSocket(std::pair<std::shared_ptr<WorldSocket>, uint64> linkInfo) +void World::ProcessLinkInstanceSocket(std::pair<std::weak_ptr<WorldSocket>, uint64> linkInfo) { - if (!linkInfo.first->IsOpen()) - return; + if (std::shared_ptr<WorldSocket> sock = linkInfo.first.lock()) + { + if (!sock->IsOpen()) + return; - WorldSession::ConnectToKey key; - key.Raw = linkInfo.second; + WorldSession::ConnectToKey key; + key.Raw = linkInfo.second; - WorldSession* session = FindSession(uint32(key.Fields.AccountId)); - if (!session || session->GetConnectToInstanceKey() != linkInfo.second) - { - linkInfo.first->SendAuthResponseError(AUTH_SESSION_EXPIRED); - linkInfo.first->DelayedCloseSocket(); - return; - } + WorldSession* session = FindSession(uint32(key.Fields.AccountId)); + if (!session || session->GetConnectToInstanceKey() != linkInfo.second) + { + sock->SendAuthResponseError(AUTH_SESSION_EXPIRED); + sock->DelayedCloseSocket(); + return; + } - linkInfo.first->SetWorldSession(session); - session->AddInstanceConnection(linkInfo.first); - session->HandleContinuePlayerLogin(); + sock->SetWorldSession(session); + session->AddInstanceConnection(sock); + session->HandleContinuePlayerLogin(); + } } bool World::HasRecentlyDisconnected(WorldSession* session) @@ -427,9 +430,9 @@ void World::LoadConfigSettings(bool reload) m_defaultDbcLocale = LocaleConstant(sConfigMgr->GetIntDefault("DBC.Locale", 0)); - if (m_defaultDbcLocale >= TOTAL_LOCALES || m_defaultDbcLocale < LOCALE_enUS) + if (m_defaultDbcLocale >= TOTAL_LOCALES || m_defaultDbcLocale < LOCALE_enUS || m_defaultDbcLocale == LOCALE_none) { - TC_LOG_ERROR("server.loading", "Incorrect DBC.Locale! Must be >= 0 and < %d (set to 0)", TOTAL_LOCALES); + TC_LOG_ERROR("server.loading", "Incorrect DBC.Locale! Must be >= 0 and < %d and not %d (set to 0)", TOTAL_LOCALES, LOCALE_none); m_defaultDbcLocale = LOCALE_enUS; } @@ -1044,12 +1047,12 @@ void World::LoadConfigSettings(bool reload) if (reload) { - uint32 val = sConfigMgr->GetIntDefault("Expansion", 2); + uint32 val = sConfigMgr->GetIntDefault("Expansion", CURRENT_EXPANSION); if (val != m_int_configs[CONFIG_EXPANSION]) TC_LOG_ERROR("server.loading", "Expansion option can't be changed at worldserver.conf reload, using current value (%u).", m_int_configs[CONFIG_EXPANSION]); } else - m_int_configs[CONFIG_EXPANSION] = sConfigMgr->GetIntDefault("Expansion", 2); + m_int_configs[CONFIG_EXPANSION] = sConfigMgr->GetIntDefault("Expansion", CURRENT_EXPANSION); m_int_configs[CONFIG_CHATFLOOD_MESSAGE_COUNT] = sConfigMgr->GetIntDefault("ChatFlood.MessageCount", 10); m_int_configs[CONFIG_CHATFLOOD_MESSAGE_DELAY] = sConfigMgr->GetIntDefault("ChatFlood.MessageDelay", 1); @@ -2821,7 +2824,7 @@ void World::SendServerMessage(ServerMessageType messageID, std::string stringPar void World::UpdateSessions(uint32 diff) { - std::pair<std::shared_ptr<WorldSocket>, uint64> linkInfo; + std::pair<std::weak_ptr<WorldSocket>, uint64> linkInfo; while (_linkSocketQueue.next(linkInfo)) ProcessLinkInstanceSocket(std::move(linkInfo)); diff --git a/src/server/game/World/World.h b/src/server/game/World/World.h index d28738ffc8c..0f9a27c733f 100644 --- a/src/server/game/World/World.h +++ b/src/server/game/World/World.h @@ -568,7 +568,7 @@ class World WorldSession* FindSession(uint32 id) const; void AddSession(WorldSession* s); - void AddInstanceSocket(std::shared_ptr<WorldSocket> sock, uint64 connectToKey); + void AddInstanceSocket(std::weak_ptr<WorldSocket> sock, uint64 connectToKey); void SendAutoBroadcast(); bool RemoveSession(uint32 id); /// Get the number of current active sessions @@ -878,8 +878,8 @@ class World void AddSession_(WorldSession* s); LockedQueue<WorldSession*> addSessQueue; - void ProcessLinkInstanceSocket(std::pair<std::shared_ptr<WorldSocket>, uint64> linkInfo); - LockedQueue<std::pair<std::shared_ptr<WorldSocket>, uint64>> _linkSocketQueue; + void ProcessLinkInstanceSocket(std::pair<std::weak_ptr<WorldSocket>, uint64> linkInfo); + LockedQueue<std::pair<std::weak_ptr<WorldSocket>, uint64>> _linkSocketQueue; // used versions std::string m_DBVersion; diff --git a/src/server/scripts/Commands/cs_go.cpp b/src/server/scripts/Commands/cs_go.cpp index 0995746b4b0..081280532fb 100644 --- a/src/server/scripts/Commands/cs_go.cpp +++ b/src/server/scripts/Commands/cs_go.cpp @@ -487,7 +487,7 @@ public: uint32 areaId = id ? (uint32)atoi(id) : player->GetZoneId(); - AreaTableEntry const* areaEntry = GetAreaEntryByAreaID(areaId); + AreaTableEntry const* areaEntry = sAreaTableStore.LookupEntry(areaId); if (x < 0 || x > 100 || y < 0 || y > 100 || !areaEntry) { @@ -497,7 +497,7 @@ public: } // update to parent zone if exist (client map show only zones without parents) - AreaTableEntry const* zoneEntry = areaEntry->ParentAreaID ? GetAreaEntryByAreaID(areaEntry->ParentAreaID) : areaEntry; + AreaTableEntry const* zoneEntry = areaEntry->ParentAreaID ? sAreaTableStore.LookupEntry(areaEntry->ParentAreaID) : areaEntry; ASSERT(zoneEntry); Map const* map = sMapMgr->CreateBaseMap(zoneEntry->MapID); diff --git a/src/server/scripts/Commands/cs_group.cpp b/src/server/scripts/Commands/cs_group.cpp index 77a157443b8..33356409f17 100644 --- a/src/server/scripts/Commands/cs_group.cpp +++ b/src/server/scripts/Commands/cs_group.cpp @@ -347,10 +347,10 @@ public: onlineState = "online"; phase = (!p->IsGameMaster() ? p->GetPhaseMask() : -1); - AreaTableEntry const* area = GetAreaEntryByAreaID(p->GetAreaId()); + AreaTableEntry const* area = sAreaTableStore.LookupEntry(p->GetAreaId()); if (area) { - AreaTableEntry const* zone = GetAreaEntryByAreaID(area->ParentAreaID); + AreaTableEntry const* zone = sAreaTableStore.LookupEntry(area->ParentAreaID); if (zone) zoneName = zone->AreaName_lang; } diff --git a/src/server/scripts/Commands/cs_lookup.cpp b/src/server/scripts/Commands/cs_lookup.cpp index 847634637b0..57bf557771b 100644 --- a/src/server/scripts/Commands/cs_lookup.cpp +++ b/src/server/scripts/Commands/cs_lookup.cpp @@ -97,9 +97,9 @@ public: wstrToLower(wNamePart); // Search in AreaTable.dbc - for (uint32 areaflag = 0; areaflag < sAreaStore.GetNumRows(); ++areaflag) + for (uint32 i = 0; i < sAreaTableStore.GetNumRows(); ++i) { - AreaTableEntry const* areaEntry = sAreaStore.LookupEntry(areaflag); + AreaTableEntry const* areaEntry = sAreaTableStore.LookupEntry(i); if (areaEntry) { std::string name = areaEntry->AreaName_lang; @@ -118,9 +118,9 @@ public: // send area in "id - [name]" format std::ostringstream ss; if (handler->GetSession()) - ss << areaEntry->ID << " - |cffffffff|Harea:" << areaEntry->ID << "|h[" << name<< "]|h|r"; + ss << i << " - |cffffffff|Harea:" << i << "|h[" << name<< "]|h|r"; else - ss << areaEntry->ID << " - " << name; + ss << i << " - " << name; handler->SendSysMessage(ss.str().c_str()); diff --git a/src/server/scripts/Commands/cs_misc.cpp b/src/server/scripts/Commands/cs_misc.cpp index 778eaaf44f1..0e9e8aecfec 100644 --- a/src/server/scripts/Commands/cs_misc.cpp +++ b/src/server/scripts/Commands/cs_misc.cpp @@ -201,8 +201,8 @@ public: uint32 mapId = object->GetMapId(); MapEntry const* mapEntry = sMapStore.LookupEntry(mapId); - AreaTableEntry const* zoneEntry = GetAreaEntryByAreaID(zoneId); - AreaTableEntry const* areaEntry = GetAreaEntryByAreaID(areaId); + AreaTableEntry const* zoneEntry = sAreaTableStore.LookupEntry(zoneId); + AreaTableEntry const* areaEntry = sAreaTableStore.LookupEntry(areaId); float zoneX = object->GetPositionX(); float zoneY = object->GetPositionY(); @@ -988,7 +988,7 @@ public: uint32 zoneId = player->GetZoneId(); - AreaTableEntry const* areaEntry = GetAreaEntryByAreaID(zoneId); + AreaTableEntry const* areaEntry = sAreaTableStore.LookupEntry(zoneId); if (!areaEntry || areaEntry->ParentAreaID !=0) { handler->PSendSysMessage(LANG_COMMAND_GRAVEYARDWRONGZONE, graveyardId, zoneId); @@ -1079,17 +1079,30 @@ public: return false; } - int32 area = GetAreaFlagByAreaID(atoi((char*)args)); - int32 offset = area / 32; + AreaTableEntry const* area = sAreaTableStore.LookupEntry(atoi(args)); + if (!area) + { + handler->SendSysMessage(LANG_BAD_VALUE); + handler->SetSentErrorMessage(true); + return false; + } + + if (area->AreaBit < 0) + { + handler->SendSysMessage(LANG_BAD_VALUE); + handler->SetSentErrorMessage(true); + return false; + } - if (area<0 || offset >= PLAYER_EXPLORED_ZONES_SIZE) + int32 offset = area->AreaBit / 32; + if (offset >= PLAYER_EXPLORED_ZONES_SIZE) { handler->SendSysMessage(LANG_BAD_VALUE); handler->SetSentErrorMessage(true); return false; } - uint32 val = uint32((1 << (area % 32))); + uint32 val = uint32((1 << (area->AreaBit % 32))); uint32 currFields = playerTarget->GetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset); playerTarget->SetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset, uint32((currFields | val))); @@ -1110,17 +1123,30 @@ public: return false; } - int32 area = GetAreaFlagByAreaID(atoi((char*)args)); - int32 offset = area / 32; + AreaTableEntry const* area = sAreaTableStore.LookupEntry(atoi(args)); + if (!area) + { + handler->SendSysMessage(LANG_BAD_VALUE); + handler->SetSentErrorMessage(true); + return false; + } + + if (area->AreaBit < 0) + { + handler->SendSysMessage(LANG_BAD_VALUE); + handler->SetSentErrorMessage(true); + return false; + } - if (area < 0 || offset >= PLAYER_EXPLORED_ZONES_SIZE) + int32 offset = area->AreaBit / 32; + if (offset >= PLAYER_EXPLORED_ZONES_SIZE) { handler->SendSysMessage(LANG_BAD_VALUE); handler->SetSentErrorMessage(true); return false; } - uint32 val = uint32((1 << (area % 32))); + uint32 val = uint32((1 << (area->AreaBit % 32))); uint32 currFields = playerTarget->GetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset); playerTarget->SetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset, uint32((currFields ^ val))); @@ -1787,12 +1813,12 @@ public: // Position data MapEntry const* map = sMapStore.LookupEntry(mapId); - AreaTableEntry const* area = GetAreaEntryByAreaID(areaId); + AreaTableEntry const* area = sAreaTableStore.LookupEntry(areaId); if (area) { areaName = area->AreaName_lang; - AreaTableEntry const* zone = GetAreaEntryByAreaID(area->ParentAreaID); + AreaTableEntry const* zone = sAreaTableStore.LookupEntry(area->ParentAreaID); if (zone) zoneName = zone->AreaName_lang; } diff --git a/src/server/scripts/EasternKingdoms/MagistersTerrace/instance_magisters_terrace.cpp b/src/server/scripts/EasternKingdoms/MagistersTerrace/instance_magisters_terrace.cpp index c726461044b..0a88ba17877 100644 --- a/src/server/scripts/EasternKingdoms/MagistersTerrace/instance_magisters_terrace.cpp +++ b/src/server/scripts/EasternKingdoms/MagistersTerrace/instance_magisters_terrace.cpp @@ -16,8 +16,10 @@ */ #include "ScriptMgr.h" +#include "ScriptedCreature.h" #include "InstanceScript.h" #include "magisters_terrace.h" +#include "EventMap.h" /* 0 - Selin Fireheart @@ -36,6 +38,8 @@ DoorData const doorData[] = { 0, 0, DOOR_TYPE_ROOM, BOUNDARY_NONE } // END }; +Position const KalecgosSpawnPos = { 164.3747f, -397.1197f, 2.151798f, 1.66219f }; + class instance_magisters_terrace : public InstanceMapScript { public: @@ -93,6 +97,10 @@ class instance_magisters_terrace : public InstanceMapScript case NPC_DELRISSA: DelrissaGUID = creature->GetGUID(); break; + case NPC_KALECGOS: + case NPC_HUMAN_KALECGOS: + KalecgosGUID = creature->GetGUID(); + break; default: break; } @@ -139,6 +147,25 @@ class instance_magisters_terrace : public InstanceMapScript } } + void ProcessEvent(WorldObject* obj, uint32 eventId) override + { + if (eventId == EVENT_SPAWN_KALECGOS) + if (!ObjectAccessor::GetCreature(*obj, KalecgosGUID) && Events.Empty()) + Events.ScheduleEvent(EVENT_SPAWN_KALECGOS, Minutes(1)); + } + + void Update(uint32 diff) override + { + Events.Update(diff); + + if (Events.ExecuteEvent() == EVENT_SPAWN_KALECGOS) + if (Creature* kalecgos = instance->SummonCreature(NPC_KALECGOS, KalecgosSpawnPos)) + { + kalecgos->GetMotionMaster()->MovePath(PATH_KALECGOS_FLIGHT, false); + kalecgos->AI()->Talk(SAY_KALECGOS_SPAWN); + } + } + bool SetBossState(uint32 type, EncounterState state) override { if (!InstanceScript::SetBossState(type, state)) @@ -177,10 +204,12 @@ class instance_magisters_terrace : public InstanceMapScript } protected: + EventMap Events; ObjectGuid SelinGUID; ObjectGuid DelrissaGUID; ObjectGuid KaelStatue[2]; ObjectGuid EscapeOrbGUID; + ObjectGuid KalecgosGUID; uint32 DelrissaDeathCount; }; diff --git a/src/server/scripts/EasternKingdoms/MagistersTerrace/magisters_terrace.cpp b/src/server/scripts/EasternKingdoms/MagistersTerrace/magisters_terrace.cpp index e216a024468..5b90ac8ccf4 100644 --- a/src/server/scripts/EasternKingdoms/MagistersTerrace/magisters_terrace.cpp +++ b/src/server/scripts/EasternKingdoms/MagistersTerrace/magisters_terrace.cpp @@ -31,7 +31,8 @@ EndContentData */ #include "ScriptedCreature.h" #include "ScriptedGossip.h" #include "Player.h" -#include "SpellInfo.h" +#include "magisters_terrace.h" +#include "EventMap.h" /*###### ## npc_kalecgos @@ -39,30 +40,29 @@ EndContentData */ enum Spells { - SPELL_TRANSFORM_TO_KAEL = 44670, + SPELL_KALECGOS_TRANSFORM = 44670, + SPELL_TRANSFORM_VISUAL = 24085, + SPELL_CAMERA_SHAKE = 44762, SPELL_ORB_KILL_CREDIT = 46307 }; -enum Creatures +enum MovementPoints { - NPC_KAEL = 24848 //human form entry + POINT_ID_PREPARE_LANDING = 6 }; -enum Misc +enum EventIds { - POINT_ID_LAND = 1 + EVENT_KALECGOS_TRANSFORM = 1, + EVENT_KALECGOS_LANDING = 2 }; -const float afKaelLandPoint[] = {225.045f, -276.236f, -5.434f}; - #define GOSSIP_ITEM_KAEL_1 "Who are you?" #define GOSSIP_ITEM_KAEL_2 "What can we do to assist you?" #define GOSSIP_ITEM_KAEL_3 "What brings you to the Sunwell?" #define GOSSIP_ITEM_KAEL_4 "You're not alone here?" #define GOSSIP_ITEM_KAEL_5 "What would Kil'jaeden want with a mortal woman?" -// This is friendly keal that appear after used Orb. -// If we assume DB handle summon, summon appear somewhere outside the platform where Orb is class npc_kalecgos : public CreatureScript { public: @@ -115,52 +115,46 @@ public: struct npc_kalecgosAI : public ScriptedAI { - npc_kalecgosAI(Creature* creature) : ScriptedAI(creature) - { - Initialize(); - } + npc_kalecgosAI(Creature* creature) : ScriptedAI(creature) { } - void Initialize() + void MovementInform(uint32 type, uint32 pointId) override { - m_uiTransformTimer = 0; - } - - uint32 m_uiTransformTimer; - - void Reset() override - { - Initialize(); - - // we must assume he appear as dragon somewhere outside the platform of orb, and then move directly to here - if (me->GetEntry() != NPC_KAEL) - me->GetMotionMaster()->MovePoint(POINT_ID_LAND, afKaelLandPoint[0], afKaelLandPoint[1], afKaelLandPoint[2]); - } - - void MovementInform(uint32 uiType, uint32 uiPointId) override - { - if (uiType != POINT_MOTION_TYPE) + if (type != WAYPOINT_MOTION_TYPE) return; - if (uiPointId == POINT_ID_LAND) - m_uiTransformTimer = MINUTE*IN_MILLISECONDS; + if (pointId == POINT_ID_PREPARE_LANDING) + { + me->HandleEmoteCommand(EMOTE_ONESHOT_LAND); + me->SetDisableGravity(false); + me->SetHover(false); + events.ScheduleEvent(EVENT_KALECGOS_LANDING, Seconds(2)); + } } - void UpdateAI(uint32 uiDiff) override + void UpdateAI(uint32 diff) override { - if (m_uiTransformTimer) + events.Update(diff); + + switch (events.ExecuteEvent()) { - if (m_uiTransformTimer <= uiDiff) - { + case EVENT_KALECGOS_LANDING: + DoCastAOE(SPELL_CAMERA_SHAKE); + me->SetObjectScale(0.6f); + events.ScheduleEvent(EVENT_KALECGOS_TRANSFORM, Seconds(1)); + break; + case EVENT_KALECGOS_TRANSFORM: DoCast(me, SPELL_ORB_KILL_CREDIT, true); - - // Transform and update entry, now ready for quest/read gossip - DoCast(me, SPELL_TRANSFORM_TO_KAEL, false); - me->UpdateEntry(NPC_KAEL); - - m_uiTransformTimer = 0; - } else m_uiTransformTimer -= uiDiff; + DoCast(me, SPELL_TRANSFORM_VISUAL, false); + DoCast(me, SPELL_KALECGOS_TRANSFORM, false); + me->UpdateEntry(NPC_HUMAN_KALECGOS); + break; + default: + break; } } + + private: + EventMap events; }; }; diff --git a/src/server/scripts/EasternKingdoms/MagistersTerrace/magisters_terrace.h b/src/server/scripts/EasternKingdoms/MagistersTerrace/magisters_terrace.h index 917ad0eb50b..05718dfc1dd 100644 --- a/src/server/scripts/EasternKingdoms/MagistersTerrace/magisters_terrace.h +++ b/src/server/scripts/EasternKingdoms/MagistersTerrace/magisters_terrace.h @@ -42,7 +42,9 @@ enum CreatureIds { NPC_SELIN = 24723, NPC_DELRISSA = 24560, - NPC_FEL_CRYSTAL = 24722 + NPC_FEL_CRYSTAL = 24722, + NPC_KALECGOS = 24844, + NPC_HUMAN_KALECGOS = 24848 }; enum GameObjectIds @@ -57,4 +59,19 @@ enum GameObjectIds GO_ESCAPE_ORB = 188173 }; +enum InstanceEventIds +{ + EVENT_SPAWN_KALECGOS = 16547 +}; + +enum InstanceText +{ + SAY_KALECGOS_SPAWN = 0 +}; + +enum MovementData +{ + PATH_KALECGOS_FLIGHT = 248440 +}; + #endif diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_algalon_the_observer.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_algalon_the_observer.cpp index 44686e80115..77657870320 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_algalon_the_observer.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_algalon_the_observer.cpp @@ -979,6 +979,9 @@ class go_celestial_planetarium_access : public GameObjectScript bool GossipHello(Player* player) override { + if (go->HasFlag(GAMEOBJECT_FLAGS, GO_FLAG_IN_USE)) + return true; + bool hasKey = true; if (LockEntry const* lock = sLockStore.LookupEntry(go->GetGOInfo()->GetLockId())) { diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_flame_leviathan.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_flame_leviathan.cpp index 2907fb09186..e1c02e7ad99 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_flame_leviathan.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_flame_leviathan.cpp @@ -1186,6 +1186,7 @@ class npc_brann_bronzebeard_ulduar_intro : public CreatureScript { if (menuId == GOSSIP_MENU_BRANN_BRONZEBEARD && gossipListId == GOSSIP_OPTION_BRANN_BRONZEBEARD) { + me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); player->PlayerTalkClass->SendCloseGossip(); if (Creature* loreKeeper = _instance->GetCreature(DATA_LORE_KEEPER_OF_NORGANNON)) loreKeeper->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); @@ -1238,6 +1239,7 @@ class npc_lorekeeper : public CreatureScript { if (menuId == GOSSIP_MENU_LORE_KEEPER && gossipListId == GOSSIP_OPTION_LORE_KEEPER) { + me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); player->PlayerTalkClass->SendCloseGossip(); _instance->instance->LoadGrid(364, -16); // make sure leviathan is loaded @@ -1250,6 +1252,7 @@ class npc_lorekeeper : public CreatureScript { if (Creature* brann = _instance->GetCreature(DATA_BRANN_BRONZEBEARD_INTRO)) { + brann->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); delorah->GetMotionMaster()->MovePoint(0, brann->GetPositionX() - 4, brann->GetPositionY(), brann->GetPositionZ()); /// @todo delorah->AI()->Talk(xxxx, brann->GetGUID()); when reached at branz } diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_mimiron.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_mimiron.cpp index 059ec7de4e8..3378185c2a8 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_mimiron.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_mimiron.cpp @@ -1636,6 +1636,9 @@ class go_mimiron_hardmode_button : public GameObjectScript bool OnGossipHello(Player* /*player*/, GameObject* go) override { + if (go->HasFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE)) + return true; + InstanceScript* instance = go->GetInstanceScript(); if (!instance) return false; diff --git a/src/server/scripts/Outland/TempestKeep/Eye/boss_kaelthas.cpp b/src/server/scripts/Outland/TempestKeep/Eye/boss_kaelthas.cpp index 66cd00489f8..fceeb108ebf 100644 --- a/src/server/scripts/Outland/TempestKeep/Eye/boss_kaelthas.cpp +++ b/src/server/scripts/Outland/TempestKeep/Eye/boss_kaelthas.cpp @@ -144,6 +144,7 @@ enum Spells // Thaladred the Darkener spells SPELL_PSYCHIC_BLOW = 10689, SPELL_SILENCE = 30225, + SPELL_REND = 36965, // Lord Sanguinar spells SPELL_BELLOWING_ROAR = 40636, // Grand Astromancer Capernian spells @@ -880,11 +881,13 @@ class boss_thaladred_the_darkener : public CreatureScript { Gaze_Timer = 100; Silence_Timer = 20000; + Rend_Timer = 4000; PsychicBlow_Timer = 10000; } uint32 Gaze_Timer; uint32 Silence_Timer; + uint32 Rend_Timer; uint32 PsychicBlow_Timer; void Reset() override @@ -938,6 +941,15 @@ class boss_thaladred_the_darkener : public CreatureScript else Silence_Timer -= diff; + //Rend_Timer + if (Rend_Timer <= diff) + { + DoCastVictim(SPELL_REND); + Rend_Timer = 4000; + } + else + Rend_Timer -= diff; + //PsychicBlow_Timer if (PsychicBlow_Timer <= diff) { diff --git a/src/server/scripts/Spells/spell_paladin.cpp b/src/server/scripts/Spells/spell_paladin.cpp index 5e8b5ab8885..5887aded51c 100644 --- a/src/server/scripts/Spells/spell_paladin.cpp +++ b/src/server/scripts/Spells/spell_paladin.cpp @@ -912,6 +912,8 @@ class spell_pal_light_s_beacon : public SpellScriptLoader bool CheckProc(ProcEventInfo& eventInfo) { + if (!eventInfo.GetActionTarget()) + return false; if (eventInfo.GetActionTarget()->HasAura(SPELL_PALADIN_BEACON_OF_LIGHT, eventInfo.GetActor()->GetGUID())) return false; return true; diff --git a/src/server/scripts/Spells/spell_warrior.cpp b/src/server/scripts/Spells/spell_warrior.cpp index 2619a5af065..5d686f6aa38 100644 --- a/src/server/scripts/Spells/spell_warrior.cpp +++ b/src/server/scripts/Spells/spell_warrior.cpp @@ -62,7 +62,11 @@ enum WarriorSpells SPELL_WARRIOR_UNRELENTING_ASSAULT_TRIGGER_1 = 64849, SPELL_WARRIOR_UNRELENTING_ASSAULT_TRIGGER_2 = 64850, SPELL_WARRIOR_VIGILANCE_PROC = 50725, - SPELL_WARRIOR_VENGEANCE = 76691 + SPELL_WARRIOR_VENGEANCE = 76691, + SPELL_WARRIOR_HEROIC_LEAP_JUMP = 178368, + SPELL_WARRIOR_GLYPH_OF_HEROIC_LEAP = 159708, + SPELL_WARRIOR_GLYPH_OF_HEROIC_LEAP_BUFF = 133278, + SPELL_WARRIOR_IMPROVED_HEROIC_LEAP = 157449, }; enum WarriorSpellIcons @@ -948,6 +952,117 @@ class spell_warr_vigilance_trigger : public SpellScriptLoader } }; +// Heroic leap - 6544 +class spell_warr_heroic_leap : public SpellScriptLoader +{ +public: + spell_warr_heroic_leap() : SpellScriptLoader("spell_warr_heroic_leap") { } + + class spell_warr_heroic_leap_SpellScript : public SpellScript + { + PrepareSpellScript(spell_warr_heroic_leap_SpellScript); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + if (!sSpellMgr->GetSpellInfo(SPELL_WARRIOR_HEROIC_LEAP_JUMP)) + return false; + return true; + } + + SpellCastResult CheckElevation() + { + if (WorldLocation const* dest = GetExplTargetDest()) + { + if (GetCaster()->HasUnitMovementFlag(MOVEMENTFLAG_ROOT)) + return SPELL_FAILED_ROOTED; + + if (GetCaster()->GetMap()->Instanceable()) + { + float range = GetSpellInfo()->GetMaxRange(true, GetCaster()) * 1.5f; + + PathGenerator generatedPath(GetCaster()); + generatedPath.SetPathLengthLimit(range); + + bool result = generatedPath.CalculatePath(dest->GetPositionX(), dest->GetPositionY(), dest->GetPositionZ(), false, true); + if (generatedPath.GetPathType() & PATHFIND_SHORT) + return SPELL_FAILED_OUT_OF_RANGE; + else if (!result || generatedPath.GetPathType() & PATHFIND_NOPATH) + { + result = generatedPath.CalculatePath(dest->GetPositionX(), dest->GetPositionY(), dest->GetPositionZ(), false, false); + if (generatedPath.GetPathType() & PATHFIND_SHORT) + return SPELL_FAILED_OUT_OF_RANGE; + else if (!result || generatedPath.GetPathType() & PATHFIND_NOPATH) + return SPELL_FAILED_NOPATH; + } + } + else if (dest->GetPositionZ() > GetCaster()->GetPositionZ() + 4.0f) + return SPELL_FAILED_NOPATH; + + return SPELL_CAST_OK; + } + + return SPELL_FAILED_NO_VALID_TARGETS; + } + + void HandleDummy(SpellEffIndex /*effIndex*/) + { + if (WorldLocation* dest = GetHitDest()) + GetCaster()->CastSpell(dest->GetPositionX(), dest->GetPositionY(), dest->GetPositionZ(), SPELL_WARRIOR_HEROIC_LEAP_JUMP, true); + } + + void Register() override + { + OnCheckCast += SpellCheckCastFn(spell_warr_heroic_leap_SpellScript::CheckElevation); + OnEffectHit += SpellEffectFn(spell_warr_heroic_leap_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + } + }; + + SpellScript* GetSpellScript() const override + { + return new spell_warr_heroic_leap_SpellScript(); + } +}; + +// Heroic Leap (triggered by Heroic Leap (6544)) - 178368 +class spell_warr_heroic_leap_jump : public SpellScriptLoader +{ +public: + spell_warr_heroic_leap_jump() : SpellScriptLoader("spell_warr_heroic_leap_jump") { } + + class spell_warr_heroic_leap_jump_SpellScript : public SpellScript + { + PrepareSpellScript(spell_warr_heroic_leap_jump_SpellScript); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + if (!sSpellMgr->GetSpellInfo(SPELL_WARRIOR_GLYPH_OF_HEROIC_LEAP) || + !sSpellMgr->GetSpellInfo(SPELL_WARRIOR_GLYPH_OF_HEROIC_LEAP_BUFF) || + !sSpellMgr->GetSpellInfo(SPELL_WARRIOR_IMPROVED_HEROIC_LEAP) || + !sSpellMgr->GetSpellInfo(SPELL_WARRIOR_TAUNT)) + return false; + return true; + } + + void AfterJump(SpellEffIndex /*effIndex*/) + { + if (GetCaster()->HasAura(SPELL_WARRIOR_GLYPH_OF_HEROIC_LEAP)) + GetCaster()->CastSpell(GetCaster(), SPELL_WARRIOR_GLYPH_OF_HEROIC_LEAP_BUFF, true); + if (GetCaster()->HasAura(SPELL_WARRIOR_IMPROVED_HEROIC_LEAP)) + GetCaster()->GetSpellHistory()->ResetCooldown(SPELL_WARRIOR_TAUNT, true); + } + + void Register() override + { + OnEffectHit += SpellEffectFn(spell_warr_heroic_leap_jump_SpellScript::AfterJump, EFFECT_1, SPELL_EFFECT_JUMP_DEST); + } + }; + + SpellScript* GetSpellScript() const override + { + return new spell_warr_heroic_leap_jump_SpellScript(); + } +}; + void AddSC_warrior_spell_scripts() { new spell_warr_bloodthirst(); @@ -972,4 +1087,6 @@ void AddSC_warrior_spell_scripts() new spell_warr_victorious(); new spell_warr_vigilance(); new spell_warr_vigilance_trigger(); + new spell_warr_heroic_leap(); + new spell_warr_heroic_leap_jump(); } diff --git a/src/server/shared/Networking/AsyncAcceptor.h b/src/server/shared/Networking/AsyncAcceptor.h index 2fa1e448ff8..d21801a64ac 100644 --- a/src/server/shared/Networking/AsyncAcceptor.h +++ b/src/server/shared/Networking/AsyncAcceptor.h @@ -20,34 +20,39 @@ #include "Log.h" #include <boost/asio.hpp> +#include <functional> using boost::asio::ip::tcp; class AsyncAcceptor { public: - typedef void(*ManagerAcceptHandler)(tcp::socket&& newSocket); + typedef void(*AcceptCallback)(tcp::socket&& newSocket, uint32 threadIndex); AsyncAcceptor(boost::asio::io_service& ioService, std::string const& bindIp, uint16 port) : _acceptor(ioService, tcp::endpoint(boost::asio::ip::address::from_string(bindIp), port)), - _socket(ioService), _closed(false) + _socket(ioService), _closed(false), _socketFactory(std::bind(&AsyncAcceptor::DefeaultSocketFactory, this)) { } - template <class T> + template<class T> void AsyncAccept(); - void AsyncAcceptManaged(ManagerAcceptHandler mgrHandler) + template<AcceptCallback acceptCallback> + void AsyncAcceptWithCallback() { - _acceptor.async_accept(_socket, [this, mgrHandler](boost::system::error_code error) + tcp::socket* socket; + uint32 threadIndex; + std::tie(socket, threadIndex) = _socketFactory(); + _acceptor.async_accept(*socket, [this, socket, threadIndex](boost::system::error_code error) { if (!error) { try { - _socket.non_blocking(true); + socket->non_blocking(true); - mgrHandler(std::move(_socket)); + acceptCallback(std::move(*socket), threadIndex); } catch (boost::system::system_error const& err) { @@ -56,7 +61,7 @@ public: } if (!_closed) - AsyncAcceptManaged(mgrHandler); + this->AsyncAcceptWithCallback<acceptCallback>(); }); } @@ -69,10 +74,15 @@ public: _acceptor.close(err); } + void SetSocketFactory(std::function<std::pair<tcp::socket*, uint32>()> func) { _socketFactory = func; } + private: + std::pair<tcp::socket*, uint32> DefeaultSocketFactory() { return std::make_pair(&_socket, 0); } + tcp::acceptor _acceptor; tcp::socket _socket; std::atomic<bool> _closed; + std::function<std::pair<tcp::socket*, uint32>()> _socketFactory; }; template<class T> diff --git a/src/server/shared/Networking/MessageBuffer.h b/src/server/shared/Networking/MessageBuffer.h index a6ed9b31e8f..42b65be8398 100644 --- a/src/server/shared/Networking/MessageBuffer.h +++ b/src/server/shared/Networking/MessageBuffer.h @@ -105,7 +105,7 @@ public: return std::move(_storage); } - MessageBuffer& operator=(MessageBuffer& right) + MessageBuffer& operator=(MessageBuffer const& right) { if (this != &right) { diff --git a/src/server/shared/Networking/NetworkThread.h b/src/server/shared/Networking/NetworkThread.h index e183209e989..5eb2fcb2f6a 100644 --- a/src/server/shared/Networking/NetworkThread.h +++ b/src/server/shared/Networking/NetworkThread.h @@ -22,6 +22,8 @@ #include "Errors.h" #include "Log.h" #include "Timer.h" +#include <boost/asio/ip/tcp.hpp> +#include <boost/asio/deadline_timer.hpp> #include <atomic> #include <chrono> #include <memory> @@ -29,11 +31,14 @@ #include <set> #include <thread> +using boost::asio::ip::tcp; + template<class SocketType> class NetworkThread { public: - NetworkThread() : _connections(0), _stopped(false), _thread(nullptr) + NetworkThread() : _connections(0), _stopped(false), _thread(nullptr), + _acceptSocket(_io_service), _updateTimer(_io_service) { } @@ -50,6 +55,7 @@ public: void Stop() { _stopped = true; + _io_service.stop(); } bool Start() @@ -80,10 +86,12 @@ public: std::lock_guard<std::mutex> lock(_newSocketsLock); ++_connections; - _newSockets.insert(sock); + _newSockets.push_back(sock); SocketAdded(sock); } + tcp::socket* GetSocketForAccept() { return &_acceptSocket; } + protected: virtual void SocketAdded(std::shared_ptr<SocketType> /*sock*/) { } virtual void SocketRemoved(std::shared_ptr<SocketType> /*sock*/) { } @@ -95,16 +103,15 @@ protected: if (_newSockets.empty()) return; - for (typename SocketSet::const_iterator i = _newSockets.begin(); i != _newSockets.end(); ++i) + for (std::shared_ptr<SocketType> sock : _newSockets) { - if (!(*i)->IsOpen()) + if (!sock->IsOpen()) { - SocketRemoved(*i); - + SocketRemoved(sock); --_connections; } else - _Sockets.insert(*i); + _sockets.push_back(sock); } _newSockets.clear(); @@ -114,55 +121,58 @@ protected: { TC_LOG_DEBUG("misc", "Network Thread Starting"); - typename SocketSet::iterator i, t; + _updateTimer.expires_from_now(boost::posix_time::milliseconds(10)); + _updateTimer.async_wait(std::bind(&NetworkThread<SocketType>::Update, this)); + _io_service.run(); - uint32 sleepTime = 10; - uint32 tickStart = 0, diff = 0; - while (!_stopped) - { - std::this_thread::sleep_for(std::chrono::milliseconds(sleepTime)); + TC_LOG_DEBUG("misc", "Network Thread exits"); + _newSockets.clear(); + _sockets.clear(); + } + + void Update() + { + if (_stopped) + return; - tickStart = getMSTime(); + _updateTimer.expires_from_now(boost::posix_time::milliseconds(10)); + _updateTimer.async_wait(std::bind(&NetworkThread<SocketType>::Update, this)); - AddNewSockets(); + AddNewSockets(); - for (i = _Sockets.begin(); i != _Sockets.end();) + _sockets.erase(std::remove_if(_sockets.begin(), _sockets.end(), [this](std::shared_ptr<SocketType> sock) + { + if (!sock->Update()) { - if (!(*i)->Update()) - { - if ((*i)->IsOpen()) - (*i)->CloseSocket(); - - SocketRemoved(*i); - - --_connections; - _Sockets.erase(i++); - } - else - ++i; - } + if (sock->IsOpen()) + sock->CloseSocket(); - diff = GetMSTimeDiffToNow(tickStart); - sleepTime = diff > 10 ? 0 : 10 - diff; - } + SocketRemoved(sock); - TC_LOG_DEBUG("misc", "Network Thread exits"); - _newSockets.clear(); - _Sockets.clear(); + --_connections; + return true; + } + + return false; + }), _sockets.end()); } private: - typedef std::set<std::shared_ptr<SocketType> > SocketSet; + typedef std::vector<std::shared_ptr<SocketType>> SocketContainer; std::atomic<int32> _connections; std::atomic<bool> _stopped; std::thread* _thread; - SocketSet _Sockets; + SocketContainer _sockets; std::mutex _newSocketsLock; - SocketSet _newSockets; + SocketContainer _newSockets; + + boost::asio::io_service _io_service; + tcp::socket _acceptSocket; + boost::asio::deadline_timer _updateTimer; }; #endif // NetworkThread_h__ diff --git a/src/server/shared/Networking/Socket.h b/src/server/shared/Networking/Socket.h index 34ee50eb84e..07f427652aa 100644 --- a/src/server/shared/Networking/Socket.h +++ b/src/server/shared/Networking/Socket.h @@ -21,15 +21,11 @@ #include "MessageBuffer.h" #include "Log.h" #include <atomic> -#include <vector> -#include <mutex> #include <queue> #include <memory> #include <functional> #include <type_traits> #include <boost/asio/ip/tcp.hpp> -#include <boost/asio/write.hpp> -#include <boost/asio/read.hpp> using boost::asio::ip::tcp; @@ -63,14 +59,10 @@ public: return false; #ifndef TC_SOCKET_USE_IOCP - std::unique_lock<std::mutex> guard(_writeLock); - if (!guard) + if (_isWritingAsync || _writeQueue.empty()) return true; - if (_isWritingAsync || (!_writeBuffer.GetActiveSize() && _writeQueue.empty())) - return true; - - for (; WriteHandler(guard);) + for (; HandleQueue();) ; #endif @@ -98,14 +90,12 @@ public: std::bind(&Socket<T>::ReadHandlerInternal, this->shared_from_this(), std::placeholders::_1, std::placeholders::_2)); } - void QueuePacket(MessageBuffer&& buffer, std::unique_lock<std::mutex>& guard) + void QueuePacket(MessageBuffer&& buffer) { _writeQueue.push(std::move(buffer)); #ifdef TC_SOCKET_USE_IOCP - AsyncProcessQueue(guard); -#else - (void)guard; + AsyncProcessQueue(); #endif } @@ -135,7 +125,7 @@ protected: virtual void ReadHandler() = 0; - bool AsyncProcessQueue(std::unique_lock<std::mutex>&) + bool AsyncProcessQueue() { if (_isWritingAsync) return false; @@ -157,19 +147,12 @@ protected: void SetNoDelay(bool enable) { boost::system::error_code err; - _socket.set_option(boost::asio::ip::tcp::no_delay(enable), err); + _socket.set_option(tcp::no_delay(enable), err); if (err) TC_LOG_DEBUG("network", "Socket::SetNoDelay: failed to set_option(boost::asio::ip::tcp::no_delay) for %s - %d (%s)", GetRemoteIpAddress().to_string().c_str(), err.value(), err.message().c_str()); } - std::mutex _writeLock; - std::queue<MessageBuffer> _writeQueue; -#ifndef TC_SOCKET_USE_IOCP - MessageBuffer _writeBuffer; -#endif - - boost::asio::io_service& io_service() { return _socket.get_io_service(); } private: void ReadHandlerInternal(boost::system::error_code error, size_t transferredBytes) @@ -190,15 +173,13 @@ private: { if (!error) { - std::unique_lock<std::mutex> deleteGuard(_writeLock); - _isWritingAsync = false; _writeQueue.front().ReadCompleted(transferedBytes); if (!_writeQueue.front().GetActiveSize()) _writeQueue.pop(); if (!_writeQueue.empty()) - AsyncProcessQueue(deleteGuard); + AsyncProcessQueue(); else if (_closing) CloseSocket(); } @@ -210,48 +191,15 @@ private: void WriteHandlerWrapper(boost::system::error_code /*error*/, std::size_t /*transferedBytes*/) { - std::unique_lock<std::mutex> guard(_writeLock); _isWritingAsync = false; - WriteHandler(guard); + HandleQueue(); } - bool WriteHandler(std::unique_lock<std::mutex>& guard) + bool HandleQueue() { if (!IsOpen()) return false; - std::size_t bytesToSend = _writeBuffer.GetActiveSize(); - - if (bytesToSend == 0) - return HandleQueue(guard); - - boost::system::error_code error; - std::size_t bytesWritten = _socket.write_some(boost::asio::buffer(_writeBuffer.GetReadPointer(), bytesToSend), error); - - if (error) - { - if (error == boost::asio::error::would_block || error == boost::asio::error::try_again) - return AsyncProcessQueue(guard); - - return false; - } - else if (bytesWritten == 0) - return false; - else if (bytesWritten < bytesToSend) - { - _writeBuffer.ReadCompleted(bytesWritten); - _writeBuffer.Normalize(); - return AsyncProcessQueue(guard); - } - - // now bytesWritten == bytesToSend - _writeBuffer.Reset(); - - return HandleQueue(guard); - } - - bool HandleQueue(std::unique_lock<std::mutex>& guard) - { if (_writeQueue.empty()) return false; @@ -265,7 +213,7 @@ private: if (error) { if (error == boost::asio::error::would_block || error == boost::asio::error::try_again) - return AsyncProcessQueue(guard); + return AsyncProcessQueue(); _writeQueue.pop(); return false; @@ -278,7 +226,7 @@ private: else if (bytesSent < bytesToSend) // now n > 0 { queuedMessage.ReadCompleted(bytesSent); - return AsyncProcessQueue(guard); + return AsyncProcessQueue(); } _writeQueue.pop(); @@ -293,6 +241,7 @@ private: uint16 _remotePort; MessageBuffer _readBuffer; + std::queue<MessageBuffer> _writeQueue; std::atomic<bool> _closed; std::atomic<bool> _closing; diff --git a/src/server/shared/Networking/SocketMgr.h b/src/server/shared/Networking/SocketMgr.h index 4037c85baa1..b14aac4ca47 100644 --- a/src/server/shared/Networking/SocketMgr.h +++ b/src/server/shared/Networking/SocketMgr.h @@ -90,20 +90,14 @@ public: _threads[i].Wait(); } - virtual void OnSocketOpen(tcp::socket&& sock) + virtual void OnSocketOpen(tcp::socket&& sock, uint32 threadIndex) { - size_t min = 0; - - for (int32 i = 1; i < _threadCount; ++i) - if (_threads[i].GetConnectionCount() < _threads[min].GetConnectionCount()) - min = i; - try { std::shared_ptr<SocketType> newSocket = std::make_shared<SocketType>(std::move(sock)); newSocket->Start(); - _threads[min].AddSocket(newSocket); + _threads[threadIndex].AddSocket(newSocket); } catch (boost::system::system_error const& err) { @@ -113,6 +107,23 @@ public: int32 GetNetworkThreadCount() const { return _threadCount; } + uint32 SelectThreadWithMinConnections() const + { + uint32 min = 0; + + for (int32 i = 1; i < _threadCount; ++i) + if (_threads[i].GetConnectionCount() < _threads[min].GetConnectionCount()) + min = i; + + return min; + } + + std::pair<tcp::socket*, uint32> GetSocketForAccept() + { + uint32 threadIndex = SelectThreadWithMinConnections(); + return std::make_pair(_threads[threadIndex].GetSocketForAccept(), threadIndex); + } + protected: SocketMgr() : _acceptor(nullptr), _threads(nullptr), _threadCount(1) { diff --git a/src/server/shared/Packets/ByteBuffer.h b/src/server/shared/Packets/ByteBuffer.h index 1f9fcacb772..b8c6ee1c36e 100644 --- a/src/server/shared/Packets/ByteBuffer.h +++ b/src/server/shared/Packets/ByteBuffer.h @@ -33,7 +33,6 @@ #include <time.h> #include <cmath> #include <type_traits> -#include <boost/asio/buffer.hpp> class MessageBuffer; diff --git a/src/tools/map_extractor/System.cpp b/src/tools/map_extractor/System.cpp index 8de3f95f68a..22a8cc72c3c 100644 --- a/src/tools/map_extractor/System.cpp +++ b/src/tools/map_extractor/System.cpp @@ -75,12 +75,10 @@ typedef struct } map_id; map_id *map_ids; -uint16 *areas; uint16 *LiqType; #define MAX_PATH_LENGTH 128 char output_path[MAX_PATH_LENGTH]; char input_path[MAX_PATH_LENGTH]; -uint32 maxAreaId = 0; // ************************************************** // Extractor options @@ -318,35 +316,6 @@ uint32 ReadMapDBC() return map_count; } -void ReadAreaTableDBC() -{ - printf("Read AreaTable.dbc file..."); - HANDLE dbcFile; - if (!CascOpenFile(CascStorage, "DBFilesClient\\AreaTable.dbc", CASC_LOCALE_NONE, 0, &dbcFile)) - { - printf("Fatal error: Cannot find AreaTable.dbc in archive! %s\n", HumanReadableCASCError(GetLastError())); - exit(1); - } - - DBCFile dbc(dbcFile); - if(!dbc.open()) - { - printf("Fatal error: Invalid AreaTable.dbc file format!\n"); - exit(1); - } - - size_t area_count = dbc.getRecordCount(); - maxAreaId = dbc.getMaxId(); - areas = new uint16[maxAreaId + 1]; - memset(areas, 0xFF, sizeof(uint16) * (maxAreaId + 1)); - - for (uint32 x = 0; x < area_count; ++x) - areas[dbc.getRecord(x).getUInt(0)] = dbc.getRecord(x).getUInt(3); - - CascCloseFile(dbcFile); - printf("Done! (" SZFMTD " areas loaded)\n", area_count); -} - void ReadLiquidTypeTableDBC() { printf("Read LiquidType.dbc file..."); @@ -382,7 +351,7 @@ void ReadLiquidTypeTableDBC() // Map file format data static char const* MAP_MAGIC = "MAPS"; -static char const* MAP_VERSION_MAGIC = "v1.5"; +static char const* MAP_VERSION_MAGIC = "v1.8"; static char const* MAP_AREA_MAGIC = "AREA"; static char const* MAP_HEIGHT_MAGIC = "MHGT"; static char const* MAP_LIQUID_MAGIC = "MLIQ"; @@ -411,9 +380,10 @@ struct map_areaHeader uint16 gridArea; }; -#define MAP_HEIGHT_NO_HEIGHT 0x0001 -#define MAP_HEIGHT_AS_INT16 0x0002 -#define MAP_HEIGHT_AS_INT8 0x0004 +#define MAP_HEIGHT_NO_HEIGHT 0x0001 +#define MAP_HEIGHT_AS_INT16 0x0002 +#define MAP_HEIGHT_AS_INT8 0x0004 +#define MAP_HEIGHT_HAS_FLIGHT_BOUNDS 0x0008 struct map_heightHeader { @@ -458,7 +428,7 @@ float selectUInt16StepStore(float maxDiff) return 65535 / maxDiff; } // Temporary grid data store -uint16 area_flags[ADT_CELLS_PER_GRID][ADT_CELLS_PER_GRID]; +uint16 area_ids[ADT_CELLS_PER_GRID][ADT_CELLS_PER_GRID]; float V8[ADT_GRID_SIZE][ADT_GRID_SIZE]; float V9[ADT_GRID_SIZE+1][ADT_GRID_SIZE+1]; @@ -473,14 +443,17 @@ bool liquid_show[ADT_GRID_SIZE][ADT_GRID_SIZE]; float liquid_height[ADT_GRID_SIZE+1][ADT_GRID_SIZE+1]; uint8 holes[ADT_CELLS_PER_GRID][ADT_CELLS_PER_GRID][8]; -bool TransformToHighRes(uint16 holes, uint8 hiResHoles[8]) +int16 flight_box_max[3][3]; +int16 flight_box_min[3][3]; + +bool TransformToHighRes(uint16 lowResHoles, uint8 hiResHoles[8]) { for (uint8 i = 0; i < 8; i++) { for (uint8 j = 0; j < 8; j++) { int32 holeIdxL = (i / 2) * 4 + (j / 2); - if (((holes >> holeIdxL) & 1) == 1) + if (((lowResHoles >> holeIdxL) & 1) == 1) hiResHoles[i] |= (1 << j); } } @@ -502,7 +475,7 @@ bool ConvertADT(std::string const& inputPath, std::string const& outputPath, int map.buildMagic = build; // Get area flags data - memset(area_flags, 0xFF, sizeof(area_flags)); + memset(area_ids, 0, sizeof(area_ids)); memset(V9, 0, sizeof(V9)); memset(V8, 0, sizeof(V8)); @@ -513,14 +486,14 @@ bool ConvertADT(std::string const& inputPath, std::string const& outputPath, int memset(holes, 0, sizeof(holes)); bool hasHoles = false; + bool hasFlightBox = false; for (std::multimap<std::string, FileChunk*>::const_iterator itr = adt.chunks.lower_bound("MCNK"); itr != adt.chunks.upper_bound("MCNK"); ++itr) { adt_MCNK* mcnk = itr->second->As<adt_MCNK>(); // Area data - if (mcnk->areaid <= maxAreaId && areas[mcnk->areaid] != 0xFFFF) - area_flags[mcnk->iy][mcnk->ix] = areas[mcnk->areaid]; + area_ids[mcnk->iy][mcnk->ix] = mcnk->areaid; // Height // Height values for triangles stored in order: @@ -728,16 +701,24 @@ bool ConvertADT(std::string const& inputPath, std::string const& outputPath, int } } + if (FileChunk* chunk = adt.GetChunk("MFBO")) + { + adt_MFBO* mfbo = chunk->As<adt_MFBO>(); + memcpy(flight_box_max, &mfbo->max, sizeof(flight_box_max)); + memcpy(flight_box_min, &mfbo->min, sizeof(flight_box_min)); + hasFlightBox = true; + } + //============================================ // Try pack area data //============================================ bool fullAreaData = false; - uint32 areaflag = area_flags[0][0]; - for (int y=0;y<ADT_CELLS_PER_GRID;y++) + uint32 areaId = area_ids[0][0]; + for (int y = 0; y < ADT_CELLS_PER_GRID; ++y) { - for(int x=0;x<ADT_CELLS_PER_GRID;x++) + for (int x = 0; x < ADT_CELLS_PER_GRID; ++x) { - if(area_flags[y][x]!=areaflag) + if (area_ids[y][x] != areaId) { fullAreaData = true; break; @@ -754,12 +735,12 @@ bool ConvertADT(std::string const& inputPath, std::string const& outputPath, int if (fullAreaData) { areaHeader.gridArea = 0; - map.areaMapSize+=sizeof(area_flags); + map.areaMapSize += sizeof(area_ids); } else { areaHeader.flags |= MAP_AREA_NO_AREA; - areaHeader.gridArea = static_cast<uint16>(areaflag); + areaHeader.gridArea = static_cast<uint16>(areaId); } //============================================ @@ -819,6 +800,12 @@ bool ConvertADT(std::string const& inputPath, std::string const& outputPath, int if (CONF_allow_float_to_int && (maxHeight - minHeight) < CONF_flat_height_delta_limit) heightHeader.flags |= MAP_HEIGHT_NO_HEIGHT; + if (hasFlightBox) + { + heightHeader.flags |= MAP_HEIGHT_HAS_FLIGHT_BOUNDS; + map.heightMapSize += sizeof(flight_box_max) + sizeof(flight_box_min); + } + // Try store as packed in uint16 or uint8 values if (!(heightHeader.flags & MAP_HEIGHT_NO_HEIGHT)) { @@ -966,8 +953,8 @@ bool ConvertADT(std::string const& inputPath, std::string const& outputPath, int outFile.write(reinterpret_cast<const char*>(&map), sizeof(map)); // Store area data outFile.write(reinterpret_cast<const char*>(&areaHeader), sizeof(areaHeader)); - if (!(areaHeader.flags&MAP_AREA_NO_AREA)) - outFile.write(reinterpret_cast<const char*>(area_flags), sizeof(area_flags)); + if (!(areaHeader.flags & MAP_AREA_NO_AREA)) + outFile.write(reinterpret_cast<const char*>(area_ids), sizeof(area_ids)); // Store height data outFile.write(reinterpret_cast<const char*>(&heightHeader), sizeof(heightHeader)); @@ -990,6 +977,12 @@ bool ConvertADT(std::string const& inputPath, std::string const& outputPath, int } } + if (heightHeader.flags & MAP_HEIGHT_HAS_FLIGHT_BOUNDS) + { + outFile.write(reinterpret_cast<char*>(flight_box_max), sizeof(flight_box_max)); + outFile.write(reinterpret_cast<char*>(flight_box_min), sizeof(flight_box_min)); + } + // Store liquid data if need if (map.liquidMapOffset) { @@ -1042,7 +1035,6 @@ void ExtractMaps(uint32 build) uint32 map_count = ReadMapDBC(); - ReadAreaTableDBC(); ReadLiquidTypeTableDBC(); std::string path = output_path; @@ -1098,7 +1090,6 @@ void ExtractMaps(uint32 build) } printf("\n"); - delete[] areas; delete[] map_ids; } diff --git a/src/tools/map_extractor/adt.h b/src/tools/map_extractor/adt.h index 0c3b3780c16..bb6980507b7 100644 --- a/src/tools/map_extractor/adt.h +++ b/src/tools/map_extractor/adt.h @@ -219,6 +219,22 @@ struct adt_MH2O }; +struct adt_MFBO +{ + union + { + uint32 fcc; + char fcc_txt[4]; + }; + uint32 size; + struct plane + { + int16 coords[9]; + }; + plane max; + plane min; +}; + #pragma pack(pop) #endif diff --git a/src/tools/map_extractor/loadlib.cpp b/src/tools/map_extractor/loadlib.cpp index 39bbe5b1412..067683577f4 100644 --- a/src/tools/map_extractor/loadlib.cpp +++ b/src/tools/map_extractor/loadlib.cpp @@ -96,7 +96,8 @@ u_map_fcc InterestingChunks[] = { { 'K', 'N', 'C', 'M' } }, { { 'T', 'V', 'C', 'M' } }, { { 'O', 'M', 'W', 'M' } }, - { { 'Q', 'L', 'C', 'M' } } + { { 'Q', 'L', 'C', 'M' } }, + { { 'O', 'B', 'F', 'M' } } }; bool IsInterestingChunk(u_map_fcc const& fcc) diff --git a/src/tools/mmaps_generator/TerrainBuilder.cpp b/src/tools/mmaps_generator/TerrainBuilder.cpp index 209c047a5fe..5dd6bed30b0 100644 --- a/src/tools/mmaps_generator/TerrainBuilder.cpp +++ b/src/tools/mmaps_generator/TerrainBuilder.cpp @@ -80,7 +80,7 @@ struct map_liquidHeader namespace MMAP { - char const* MAP_VERSION_MAGIC = "v1.5"; + char const* MAP_VERSION_MAGIC = "v1.8"; TerrainBuilder::TerrainBuilder(bool skipLiquid) : m_skipLiquid (skipLiquid){ } TerrainBuilder::~TerrainBuilder() { } |