diff options
author | Rat <gmstreetrat@gmail.com> | 2015-03-24 20:01:02 +0100 |
---|---|---|
committer | Rat <gmstreetrat@gmail.com> | 2015-03-24 20:01:02 +0100 |
commit | eebc468e628acc801a6426e03815150c8cfd9172 (patch) | |
tree | 2f269f7b97bd7fe83b8bfeb3240820521110f9aa /src | |
parent | bc5ebe3d0599a08e93fd6d0a8c63c7e7cc43c35f (diff) | |
parent | 3ad7776d5061308d3e2b4ff9e3cbf67d48bffdd6 (diff) |
Merge branch '6.x' of https://github.com/TrinityCore/TrinityCore into 6.x
Conflicts:
src/server/collision/Management/MMapManager.cpp
src/server/game/Conditions/ConditionMgr.cpp
src/server/game/Conditions/ConditionMgr.h
Diffstat (limited to 'src')
141 files changed, 3066 insertions, 1671 deletions
diff --git a/src/server/bnetserver/CMakeLists.txt b/src/server/bnetserver/CMakeLists.txt index 53d25846cc5..4ea4f697cf7 100644 --- a/src/server/bnetserver/CMakeLists.txt +++ b/src/server/bnetserver/CMakeLists.txt @@ -45,7 +45,9 @@ endif() include_directories( ${CMAKE_BINARY_DIR} + ${CMAKE_SOURCE_DIR}/dep/cppformat ${CMAKE_SOURCE_DIR}/dep/zmqpp + ${CMAKE_SOURCE_DIR}/dep/process ${CMAKE_SOURCE_DIR}/src/server/shared ${CMAKE_SOURCE_DIR}/src/server/shared/Configuration ${CMAKE_SOURCE_DIR}/src/server/shared/Database @@ -57,6 +59,7 @@ include_directories( ${CMAKE_SOURCE_DIR}/src/server/shared/Networking ${CMAKE_SOURCE_DIR}/src/server/shared/Realm ${CMAKE_SOURCE_DIR}/src/server/shared/Threading + ${CMAKE_SOURCE_DIR}/src/server/shared/Updater ${CMAKE_SOURCE_DIR}/src/server/shared/Utilities ${CMAKE_SOURCE_DIR}/src/server/ipc ${CMAKE_CURRENT_SOURCE_DIR} @@ -87,6 +90,7 @@ target_link_libraries(bnetserver ipc shared zmqpp + format ${MYSQL_LIBRARY} ${OPENSSL_LIBRARIES} ${ZMQ_LIBRARY} diff --git a/src/server/bnetserver/Main.cpp b/src/server/bnetserver/Main.cpp index 5f4f63287e5..678e24c4682 100644 --- a/src/server/bnetserver/Main.cpp +++ b/src/server/bnetserver/Main.cpp @@ -36,6 +36,7 @@ #include "SystemConfig.h" #include "Util.h" #include "ZmqContext.h" +#include "DatabaseLoader.h" #include <cstdlib> #include <iostream> #include <boost/date_time/posix_time/posix_time.hpp> @@ -162,32 +163,13 @@ bool StartDB() { MySQL::Library_Init(); - std::string dbstring = sConfigMgr->GetStringDefault("LoginDatabaseInfo", ""); - if (dbstring.empty()) - { - TC_LOG_ERROR("server.bnetserver", "Database not specified"); - return false; - } - - int32 worker_threads = sConfigMgr->GetIntDefault("LoginDatabase.WorkerThreads", 1); - if (worker_threads < 1 || worker_threads > 32) - { - TC_LOG_ERROR("server.bnetserver", "Improper value specified for LoginDatabase.WorkerThreads, defaulting to 1."); - worker_threads = 1; - } + // Load databases + DatabaseLoader loader("server.bnetserver", DatabaseLoader::DATABASE_NONE); + loader + .AddDatabase(LoginDatabase, "Login"); - int32 synch_threads = sConfigMgr->GetIntDefault("LoginDatabase.SynchThreads", 1); - if (synch_threads < 1 || synch_threads > 32) - { - TC_LOG_ERROR("server.bnetserver", "Improper value specified for LoginDatabase.SynchThreads, defaulting to 1."); - synch_threads = 1; - } - - if (!LoginDatabase.Open(dbstring, uint8(worker_threads), uint8(synch_threads))) - { - TC_LOG_ERROR("server.bnetserver", "Cannot connect to database"); + if (!loader.Load()) return false; - } TC_LOG_INFO("server.bnetserver", "Started auth database connection pool."); sLog->SetRealmId(0); // Enables DB appenders when realm is set. diff --git a/src/server/bnetserver/Server/ModuleManager.h b/src/server/bnetserver/Server/ModuleManager.h index 05a7298e27c..68d5b2a1e78 100644 --- a/src/server/bnetserver/Server/ModuleManager.h +++ b/src/server/bnetserver/Server/ModuleManager.h @@ -54,9 +54,10 @@ namespace Battlenet memcpy(Data, right.Data, DataSize); } } + ~ModuleInfo() { - delete Data; + delete[] Data; } std::string Type; diff --git a/src/server/bnetserver/bnetserver.conf.dist b/src/server/bnetserver/bnetserver.conf.dist index 462bb0cd075..9b133d36e4f 100644 --- a/src/server/bnetserver/bnetserver.conf.dist +++ b/src/server/bnetserver/bnetserver.conf.dist @@ -9,6 +9,7 @@ # EXAMPLE CONFIG # AUTH SERVER SETTINGS # MYSQL SETTINGS +# UPDATE SETTINGS # LOGGING SYSTEM SETTINGS # ################################################################################################### @@ -165,6 +166,89 @@ Wrong.Password.Login.Logging = 0 ################################################################################################### ################################################################################################### +# UPDATE SETTINGS +# +# Updates.EnableDatabases +# Description: A mask that describes which databases shall be updated. +# +# Following flags are available +# DATABASE_LOGIN = 1, // Auth database +# +# Default: 0 - (All Disabled) +# 1 - (All Enabled) + +Updates.EnableDatabases = 0 + +# +# Updates.SourcePath +# Description: The path to your TrinityCore source directory. +# If the path is left empty, built-in CMAKE_SOURCE_DIR is used. +# Example: "../TrinityCore" +# Default: "" + +Updates.SourcePath = "" + +# +# Updates.SourcePath +# Description: The path to your mysql cli binary. +# If the path is left empty, built-in path from cmake is used. +# Example: "C:/Program Files/MySQL/MySQL Server 5.6/bin/mysql.exe" +# "mysql.exe" +# "/usr/bin/mysql" +# Default: "" + +Updates.MySqlCLIPath = "" + +# +# Updates.AutoSetup +# Description: Auto populate empty databases. +# Default: 1 - (Enabled) +# 0 - (Disabled) + +Updates.AutoSetup = 1 + +# +# Updates.Redundancy +# Description: Perform data redundancy checks through hashing +# to detect changes on sql updates and reapply it. +# Default: 1 - (Enabled) +# 0 - (Disabled) + +Updates.Redundancy = 1 + +# +# Updates.ArchivedRedundancy +# Description: Check hashes of archived updates (slows down startup). +# Default: 0 - (Disabled) +# 1 - (Enabled) + +Updates.ArchivedRedundancy = 0 + +# +# Updates.AllowRehash +# Description: Inserts the current file hash in the database if it is left empty. +# Useful if you want to mark a file as applied but you don't know its hash. +# Default: 1 - (Enabled) +# 0 - (Disabled) + +Updates.AllowRehash = 1 + +# +# Updates.CleanDeadRefMaxCount +# Description: Cleans dead/ orphaned references that occur if an update was removed or renamed and edited in one step. +# It only starts the clean up if the count of the missing updates is below or equal the Updates.CleanDeadRefMaxCount value. +# This way prevents erasing of the update history due to wrong source directory state (maybe wrong branch or bad revision). +# Disable this if you want to know if the database is in a possible "dirty state". +# Default: 3 - (Enabled) +# 0 - (Disabled) +# -1 - (Enabled - unlimited) + +Updates.CleanDeadRefMaxCount = 3 + +# +################################################################################################### + +################################################################################################### # # LOGGING SYSTEM SETTINGS # @@ -255,6 +339,7 @@ Logger.root=3,Console Bnet Logger.realmlist=3,Console Bnet Logger.session=3,Console Bnet Logger.session.packets=3,Console Bnet +Logger.sql.updates=3,Console Bnet # ################################################################################################### diff --git a/src/server/collision/CMakeLists.txt b/src/server/collision/CMakeLists.txt index 293f05d1988..84f7de76543 100644 --- a/src/server/collision/CMakeLists.txt +++ b/src/server/collision/CMakeLists.txt @@ -35,6 +35,7 @@ include_directories( ${CMAKE_SOURCE_DIR}/dep/g3dlite/include ${CMAKE_SOURCE_DIR}/dep/recastnavigation/Detour ${CMAKE_SOURCE_DIR}/dep/recastnavigation/Detour/Include + ${CMAKE_SOURCE_DIR}/dep/cppformat ${CMAKE_SOURCE_DIR}/src/server/shared ${CMAKE_SOURCE_DIR}/src/server/shared/Configuration ${CMAKE_SOURCE_DIR}/src/server/shared/Debugging diff --git a/src/server/collision/Management/MMapManager.cpp b/src/server/collision/Management/MMapManager.cpp index 77fa36a3c45..914f919bf73 100644 --- a/src/server/collision/Management/MMapManager.cpp +++ b/src/server/collision/Management/MMapManager.cpp @@ -75,7 +75,7 @@ namespace MMAP delete [] fileName; - TC_LOG_INFO("maps", "MMAP:loadMapData: Loaded %03i.mmap", mapId); + TC_LOG_DEBUG("maps", "MMAP:loadMapData: Loaded %03i.mmap", mapId); // store inside our map list MMapData* mmap_data = new MMapData(mesh, mapId); @@ -157,7 +157,7 @@ namespace MMAP { mmap->loadedTileRefs.insert(std::pair<uint32, dtTileRef>(packedGridPos, tileRef)); ++loadedTiles; - TC_LOG_INFO("maps", "MMAP:loadMap: Loaded mmtile %03i[%02i, %02i] into %03i[%02i, %02i]", mapId, x, y, mapId, header->x, header->y); + TC_LOG_DEBUG("maps", "MMAP:loadMap: Loaded mmtile %03i[%02i, %02i] into %03i[%02i, %02i]", mapId, x, y, mapId, header->x, header->y); LoadPhaseTiles(mapId, x, y); @@ -303,7 +303,7 @@ namespace MMAP { mmap->loadedTileRefs.erase(packedGridPos); --loadedTiles; - TC_LOG_INFO("maps", "MMAP:unloadMap: Unloaded mmtile %03i[%02i, %02i] from %03i", mapId, x, y, mapId); + TC_LOG_DEBUG("maps", "MMAP:unloadMap: Unloaded mmtile %03i[%02i, %02i] from %03i", mapId, x, y, mapId); UnloadPhaseTile(mapId, x, y); return true; @@ -333,13 +333,13 @@ namespace MMAP { UnloadPhaseTile(mapId, x, y); --loadedTiles; - TC_LOG_INFO("maps", "MMAP:unloadMap: Unloaded mmtile %03i[%02i, %02i] from %03i", mapId, x, y, mapId); + TC_LOG_DEBUG("maps", "MMAP:unloadMap: Unloaded mmtile %03i[%02i, %02i] from %03i", mapId, x, y, mapId); } } delete mmap; loadedMMaps.erase(mapId); - TC_LOG_INFO("maps", "MMAP:unloadMap: Unloaded %03i.mmap", mapId); + TC_LOG_DEBUG("maps", "MMAP:unloadMap: Unloaded %03i.mmap", mapId); return true; } @@ -365,7 +365,7 @@ namespace MMAP dtFreeNavMeshQuery(query); mmap->navMeshQueries.erase(instanceId); - TC_LOG_INFO("maps", "MMAP:unloadMapInstance: Unloaded mapId %03u instanceId %u", mapId, instanceId); + TC_LOG_DEBUG("maps", "MMAP:unloadMapInstance: Unloaded mapId %03u instanceId %u", mapId, instanceId); return true; } @@ -396,7 +396,7 @@ namespace MMAP return NULL; } - TC_LOG_INFO("maps", "MMAP:GetNavMeshQuery: created dtNavMeshQuery for mapId %03u instanceId %u", mapId, instanceId); + TC_LOG_DEBUG("maps", "MMAP:GetNavMeshQuery: created dtNavMeshQuery for mapId %03u instanceId %u", mapId, instanceId); mmap->navMeshQueries.insert(std::pair<uint32, dtNavMeshQuery*>(instanceId, query)); } diff --git a/src/server/collision/Maps/MapTree.cpp b/src/server/collision/Maps/MapTree.cpp index 72435594ad0..b493ec18f5f 100644 --- a/src/server/collision/Maps/MapTree.cpp +++ b/src/server/collision/Maps/MapTree.cpp @@ -386,13 +386,12 @@ namespace VMAP { if (!iLoadedSpawns.count(referencedVal)) { -#ifdef VMAP_DEBUG if (referencedVal > iNTreeValues) { - TC_LOG_DEBUG("maps", "StaticMapTree::LoadMapTile() : invalid tree element (%u/%u)", referencedVal, iNTreeValues); + VMAP_ERROR_LOG("maps", "StaticMapTree::LoadMapTile() : invalid tree element (%u/%u) referenced in tile %s", referencedVal, iNTreeValues, tilefile.c_str()); continue; } -#endif + iTreeValues[referencedVal] = ModelInstance(spawn, model); iLoadedSpawns[referencedVal] = 1; } diff --git a/src/server/game/AI/SmartScripts/SmartScript.cpp b/src/server/game/AI/SmartScripts/SmartScript.cpp index b80e861c4df..08025fd1de1 100644 --- a/src/server/game/AI/SmartScripts/SmartScript.cpp +++ b/src/server/game/AI/SmartScripts/SmartScript.cpp @@ -497,7 +497,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u { if (cost.Power == POWER_HEALTH) { - if (me->GetHealth() <= cost.Amount) + if (me->GetHealth() <= uint32(cost.Amount)) { hasPower = false; break; diff --git a/src/server/game/Achievements/AchievementMgr.cpp b/src/server/game/Achievements/AchievementMgr.cpp index 4932a83d665..40401b2ba31 100644 --- a/src/server/game/Achievements/AchievementMgr.cpp +++ b/src/server/game/Achievements/AchievementMgr.cpp @@ -1738,7 +1738,7 @@ void AchievementMgr<Player>::CompletedAchievement(AchievementEntry const* achiev if (!GetOwner()->GetSession()->PlayerLoading()) SendAchievementEarned(achievement); - TC_LOG_INFO("achievement", "AchievementMgr::CompletedAchievement(%u). %s %s", + TC_LOG_DEBUG("achievement", "AchievementMgr::CompletedAchievement(%u). %s %s", achievement->ID, GetOwner()->GetGUID().ToString().c_str(), GetOwner()->GetName().c_str()); CompletedAchievementData& ca = m_completedAchievements[achievement->ID]; diff --git a/src/server/game/AuctionHouse/AuctionHouseMgr.cpp b/src/server/game/AuctionHouse/AuctionHouseMgr.cpp index b587e82013f..6ea09711667 100644 --- a/src/server/game/AuctionHouse/AuctionHouseMgr.cpp +++ b/src/server/game/AuctionHouse/AuctionHouseMgr.cpp @@ -440,8 +440,6 @@ bool AuctionHouseObject::RemoveAuction(AuctionEntry* auction) // we need to delete the entry, it is not referenced any more delete auction; - auction = NULL; - return wasInMap; } @@ -552,7 +550,7 @@ void AuctionHouseObject::BuildListAuctionItems(WorldPacket& data, Player* player if (itemSubClass != 0xffffffff && proto->GetSubClass() != itemSubClass) continue; - if (inventoryType != 0xffffffff && proto->GetInventoryType() != inventoryType) + if (inventoryType != 0xffffffff && proto->GetInventoryType() != InventoryType(inventoryType)) continue; if (quality != 0xffffffff && proto->GetQuality() != quality) diff --git a/src/server/game/AuctionHouseBot/AuctionHouseBotBuyer.cpp b/src/server/game/AuctionHouseBot/AuctionHouseBotBuyer.cpp index c1f195d0b94..993494c8b80 100644 --- a/src/server/game/AuctionHouseBot/AuctionHouseBotBuyer.cpp +++ b/src/server/game/AuctionHouseBot/AuctionHouseBotBuyer.cpp @@ -64,7 +64,7 @@ void AuctionBotBuyer::LoadConfig() } } -void AuctionBotBuyer::LoadBuyerValues(BuyerConfiguration& config) +void AuctionBotBuyer::LoadBuyerValues(BuyerConfiguration& /* config */) { } diff --git a/src/server/game/Battlegrounds/ArenaTeam.cpp b/src/server/game/Battlegrounds/ArenaTeam.cpp index 77aa29536e4..e2a572b6dc7 100644 --- a/src/server/game/Battlegrounds/ArenaTeam.cpp +++ b/src/server/game/Battlegrounds/ArenaTeam.cpp @@ -172,7 +172,7 @@ bool ArenaTeam::AddMember(ObjectGuid playerGuid) player->SetArenaTeamInfoField(GetSlot(), ARENA_TEAM_MEMBER, 1); } - TC_LOG_INFO("bg.arena", "Player: %s [%s] joined arena team type: %u [Id: %u, Name: %s].", playerName.c_str(), playerGuid.ToString().c_str(), GetType(), GetId(), GetName().c_str()); + TC_LOG_DEBUG("bg.arena", "Player: %s [%s] joined arena team type: %u [Id: %u, Name: %s].", playerName.c_str(), playerGuid.ToString().c_str(), GetType(), GetId(), GetName().c_str()); return true; } diff --git a/src/server/game/CMakeLists.txt b/src/server/game/CMakeLists.txt index 18c710c2a20..55792856eb4 100644 --- a/src/server/game/CMakeLists.txt +++ b/src/server/game/CMakeLists.txt @@ -110,6 +110,7 @@ include_directories( ${CMAKE_SOURCE_DIR}/dep/recastnavigation/Recast/Include ${CMAKE_SOURCE_DIR}/dep/g3dlite/include ${CMAKE_SOURCE_DIR}/dep/SFMT + ${CMAKE_SOURCE_DIR}/dep/cppformat ${CMAKE_SOURCE_DIR}/dep/zlib ${CMAKE_SOURCE_DIR}/dep/zmqpp ${CMAKE_SOURCE_DIR}/src/server/collision @@ -130,6 +131,7 @@ include_directories( ${CMAKE_SOURCE_DIR}/src/server/shared/Packets ${CMAKE_SOURCE_DIR}/src/server/shared/Realm ${CMAKE_SOURCE_DIR}/src/server/shared/Threading + ${CMAKE_SOURCE_DIR}/src/server/shared/Updater ${CMAKE_SOURCE_DIR}/src/server/shared/Utilities ${CMAKE_SOURCE_DIR}/src/server/ipc ${CMAKE_CURRENT_SOURCE_DIR} diff --git a/src/server/game/Chat/Chat.cpp b/src/server/game/Chat/Chat.cpp index d4559b0acef..837ff0be60f 100644 --- a/src/server/game/Chat/Chat.cpp +++ b/src/server/game/Chat/Chat.cpp @@ -106,17 +106,6 @@ ChatCommand* ChatHandler::getCommandTable() return commandTableCache; } -std::string ChatHandler::PGetParseString(uint32 entry, ...) const -{ - const char *format = GetTrinityString(entry); - char str[1024]; - va_list ap; - va_start(ap, entry); - vsnprintf(str, 1024, format, ap); - va_end(ap); - return std::string(str); -} - char const* ChatHandler::GetTrinityString(uint32 entry) const { return m_session->GetTrinityString(entry); @@ -260,27 +249,6 @@ void ChatHandler::SendSysMessage(uint32 entry) SendSysMessage(GetTrinityString(entry)); } -void ChatHandler::PSendSysMessage(uint32 entry, ...) -{ - const char *format = GetTrinityString(entry); - va_list ap; - char str [2048]; - va_start(ap, entry); - vsnprintf(str, 2048, format, ap); - va_end(ap); - SendSysMessage(str); -} - -void ChatHandler::PSendSysMessage(const char *format, ...) -{ - va_list ap; - char str [2048]; - va_start(ap, format); - vsnprintf(str, 2048, format, ap); - va_end(ap); - SendSysMessage(str); -} - bool ChatHandler::ExecuteCommandInTable(ChatCommand* table, const char* text, std::string const& fullcmd) { char const* oldtext = text; diff --git a/src/server/game/Chat/Chat.h b/src/server/game/Chat/Chat.h index 93b22739ccb..000d93683c5 100644 --- a/src/server/game/Chat/Chat.h +++ b/src/server/game/Chat/Chat.h @@ -20,6 +20,7 @@ #define TRINITYCORE_CHAT_H #include "SharedDefines.h" +#include "StringFormat.h" #include "WorldSession.h" #include "RBAC.h" #include "Packets/ChatPackets.h" @@ -61,9 +62,24 @@ class ChatHandler virtual void SendSysMessage(char const* str); void SendSysMessage(uint32 entry); - void PSendSysMessage(char const* format, ...) ATTR_PRINTF(2, 3); - void PSendSysMessage(uint32 entry, ...); - std::string PGetParseString(uint32 entry, ...) const; + + template<typename... Args> + void PSendSysMessage(const char* fmt, Args const&... args) + { + SendSysMessage(Trinity::StringFormat(fmt, args...).c_str()); + } + + template<typename... Args> + void PSendSysMessage(uint32 entry, Args const&... args) + { + SendSysMessage(PGetParseString(entry, args...).c_str()); + } + + template<typename... Args> + std::string PGetParseString(uint32 entry, Args const&... args) const + { + return Trinity::StringFormat(GetTrinityString(entry), args...); + } bool ParseCommands(const char* text); diff --git a/src/server/game/Conditions/ConditionMgr.cpp b/src/server/game/Conditions/ConditionMgr.cpp index e34b7df0c54..c5e3d26b00a 100644 --- a/src/server/game/Conditions/ConditionMgr.cpp +++ b/src/server/game/Conditions/ConditionMgr.cpp @@ -99,7 +99,8 @@ ConditionMgr::ConditionTypeInfo const ConditionMgr::StaticConditionTypeData[COND { "Distance", true, true, true }, { "Alive", false, false, false }, { "Health Value", true, true, false }, - { "Health Pct", true, true, false } + { "Health Pct", true, true, false }, + { "Realm Achievement", true, false, false } }; // Checks if object meets the condition @@ -416,6 +417,13 @@ bool Condition::Meets(ConditionSourceInfo& sourceInfo) condMeets = creature->GetCreatureTemplate()->type == ConditionValue1; break; } + case CONDITION_REALM_ACHIEVEMENT: + { + AchievementEntry const* achievement = sAchievementMgr->GetAchievement(ConditionValue1); + if (achievement && sAchievementMgr->IsRealmCompleted(achievement, std::numeric_limits<uint32>::max())) + condMeets = true; + break; + } case CONDITION_TERRAIN_SWAP: { condMeets = object->IsInTerrainSwap(ConditionValue1); @@ -590,6 +598,9 @@ uint32 Condition::GetSearcherTypeMaskForCondition() case CONDITION_CREATURE_TYPE: mask |= GRID_MAP_TYPE_MASK_CREATURE; break; + case CONDITION_REALM_ACHIEVEMENT: + mask |= GRID_MAP_TYPE_MASK_ALL; + break; case CONDITION_TERRAIN_SWAP: mask |= GRID_MAP_TYPE_MASK_ALL; break; @@ -2103,6 +2114,16 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond) case CONDITION_AREAID: case CONDITION_ALIVE: break; + case CONDITION_REALM_ACHIEVEMENT: + { + AchievementEntry const* achievement = sAchievementMgr->GetAchievement(cond->ConditionValue1); + if (!achievement) + { + TC_LOG_ERROR("sql.sql", "%s has non existing realm first achivement id (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue1); + return false; + } + break; + } default: break; } diff --git a/src/server/game/Conditions/ConditionMgr.h b/src/server/game/Conditions/ConditionMgr.h index 71da857fd29..26c958cd92e 100644 --- a/src/server/game/Conditions/ConditionMgr.h +++ b/src/server/game/Conditions/ConditionMgr.h @@ -72,8 +72,9 @@ enum ConditionTypes CONDITION_ALIVE = 36, // 0 0 0 true if unit is alive CONDITION_HP_VAL = 37, // hpVal ComparisonType 0 true if unit's hp matches given value CONDITION_HP_PCT = 38, // hpPct ComparisonType 0 true if unit's hp matches given pct - CONDITION_TERRAIN_SWAP = 39, // terrainSwap 0 0 true if object is in terrainswap - CONDITION_MAX = 40 // MAX + CONDITION_REALM_ACHIEVEMENT = 39, // achievement_id 0 0 true if realm achievement is complete + CONDITION_TERRAIN_SWAP = 40, // terrainSwap 0 0 true if object is in terrainswap + CONDITION_MAX = 41 // MAX }; /*! Documentation on implementing a new ConditionSourceType: diff --git a/src/server/game/DataStores/DB2Structure.h b/src/server/game/DataStores/DB2Structure.h index e52acc0e2c3..9aab120cc63 100644 --- a/src/server/game/DataStores/DB2Structure.h +++ b/src/server/game/DataStores/DB2Structure.h @@ -135,7 +135,7 @@ struct ItemEffectEntry uint32 OrderIndex; // 2 uint32 SpellID; // 3 uint32 Trigger; // 4 - uint32 Charges; // 5 + int32 Charges; // 5 int32 Cooldown; // 6 uint32 Category; // 7 int32 CategoryCooldown; // 8 diff --git a/src/server/game/DataStores/DBCStructure.h b/src/server/game/DataStores/DBCStructure.h index c26898abf21..f997aaf776f 100644 --- a/src/server/game/DataStores/DBCStructure.h +++ b/src/server/game/DataStores/DBCStructure.h @@ -1564,8 +1564,8 @@ struct SpellRadiusEntry { uint32 ID; // 0 //float Radius; // 1 - float RadiusMin; // 2 - float RadiusPerLevel; // 3 + float RadiusPerLevel; // 2 + float RadiusMin; // 3 float RadiusMax; // 4 }; diff --git a/src/server/game/DungeonFinding/LFG.cpp b/src/server/game/DungeonFinding/LFG.cpp index ab06eff7148..8ec638128d8 100644 --- a/src/server/game/DungeonFinding/LFG.cpp +++ b/src/server/game/DungeonFinding/LFG.cpp @@ -91,9 +91,6 @@ std::string GetStateString(LfgState state) case LFG_STATE_DUNGEON: entry = LANG_LFG_STATE_DUNGEON; break; - case LFG_STATE_BOOT: - entry = LANG_LFG_STATE_BOOT; - break; case LFG_STATE_FINISHED_DUNGEON: entry = LANG_LFG_STATE_FINISHED_DUNGEON; break; diff --git a/src/server/game/DungeonFinding/LFG.h b/src/server/game/DungeonFinding/LFG.h index 0ee9e7886d5..680781cc9d1 100644 --- a/src/server/game/DungeonFinding/LFG.h +++ b/src/server/game/DungeonFinding/LFG.h @@ -68,8 +68,8 @@ enum LfgState LFG_STATE_ROLECHECK, // Rolecheck active LFG_STATE_QUEUED, // Queued LFG_STATE_PROPOSAL, // Proposal active - LFG_STATE_BOOT, // Vote kick active - LFG_STATE_DUNGEON, // In LFG Group, in a Dungeon + //LFG_STATE_BOOT, // Vote kick active + LFG_STATE_DUNGEON = 5, // In LFG Group, in a Dungeon LFG_STATE_FINISHED_DUNGEON, // In LFG Group, in a finished Dungeon LFG_STATE_RAIDBROWSER // Using Raid finder }; diff --git a/src/server/game/DungeonFinding/LFGGroupData.cpp b/src/server/game/DungeonFinding/LFGGroupData.cpp index 2ab1e0b1e7e..aa6916a39a4 100644 --- a/src/server/game/DungeonFinding/LFGGroupData.cpp +++ b/src/server/game/DungeonFinding/LFGGroupData.cpp @@ -22,7 +22,7 @@ namespace lfg { LfgGroupData::LfgGroupData(): m_State(LFG_STATE_NONE), m_OldState(LFG_STATE_NONE), - m_Leader(), m_Dungeon(0), m_KicksLeft(LFG_GROUP_MAX_KICKS) + m_Leader(), m_Dungeon(0), m_KicksLeft(LFG_GROUP_MAX_KICKS), m_VoteKickActive(false) { } LfgGroupData::~LfgGroupData() @@ -126,4 +126,14 @@ uint8 LfgGroupData::GetKicksLeft() const return m_KicksLeft; } +void LfgGroupData::SetVoteKick(bool active) +{ + m_VoteKickActive = active; +} + +bool LfgGroupData::IsVoteKickActive() const +{ + return m_VoteKickActive; +} + } // namespace lfg diff --git a/src/server/game/DungeonFinding/LFGGroupData.h b/src/server/game/DungeonFinding/LFGGroupData.h index 8d8f1dc0f3d..b573e7c309e 100644 --- a/src/server/game/DungeonFinding/LFGGroupData.h +++ b/src/server/game/DungeonFinding/LFGGroupData.h @@ -66,6 +66,9 @@ class LfgGroupData // VoteKick uint8 GetKicksLeft() const; + void SetVoteKick(bool active); + bool IsVoteKickActive() const; + private: // General LfgState m_State; ///< State if group in LFG @@ -76,6 +79,7 @@ class LfgGroupData uint32 m_Dungeon; ///< Dungeon entry // Vote Kick uint8 m_KicksLeft; ///< Number of kicks left + bool m_VoteKickActive; }; } // namespace lfg diff --git a/src/server/game/DungeonFinding/LFGMgr.cpp b/src/server/game/DungeonFinding/LFGMgr.cpp index 977dcbb216b..db711bd9a47 100644 --- a/src/server/game/DungeonFinding/LFGMgr.cpp +++ b/src/server/game/DungeonFinding/LFGMgr.cpp @@ -309,9 +309,8 @@ void LFGMgr::Update(uint32 diff) ObjectGuid pguid = itVotes->first; if (pguid != boot.victim) SendLfgBootProposalUpdate(pguid, boot); - SetState(pguid, LFG_STATE_DUNGEON); } - SetState(itBoot->first, LFG_STATE_DUNGEON); + SetVoteKick(itBoot->first, false); BootsStore.erase(itBoot); } } @@ -642,7 +641,6 @@ void LFGMgr::LeaveLfg(ObjectGuid guid) break; case LFG_STATE_DUNGEON: case LFG_STATE_FINISHED_DUNGEON: - case LFG_STATE_BOOT: if (guid != gguid) // Player SetState(guid, LFG_STATE_NONE); break; @@ -1159,7 +1157,7 @@ void LFGMgr::RemoveProposal(LfgProposalContainer::iterator itProposal, LfgUpdate */ void LFGMgr::InitBoot(ObjectGuid gguid, ObjectGuid kicker, ObjectGuid victim, std::string const& reason) { - SetState(gguid, LFG_STATE_BOOT); + SetVoteKick(gguid, true); LfgPlayerBoot& boot = BootsStore[gguid]; boot.inProgress = true; @@ -1173,7 +1171,6 @@ void LFGMgr::InitBoot(ObjectGuid gguid, ObjectGuid kicker, ObjectGuid victim, st for (GuidSet::const_iterator itr = players.begin(); itr != players.end(); ++itr) { ObjectGuid guid = (*itr); - SetState(guid, LFG_STATE_BOOT); boot.votes[guid] = LFG_ANSWER_PENDING; } @@ -1230,13 +1227,10 @@ void LFGMgr::UpdateBoot(ObjectGuid guid, bool accept) { ObjectGuid pguid = itVotes->first; if (pguid != boot.victim) - { - SetState(pguid, LFG_STATE_DUNGEON); SendLfgBootProposalUpdate(pguid, boot); - } } - SetState(gguid, LFG_STATE_DUNGEON); + SetVoteKick(gguid, false); if (agreeNum == LFG_GROUP_KICK_VOTES_NEEDED) // Vote passed - Kick player { if (Group* group = sGroupMgr->GetGroupByGUID(gguid)) @@ -1498,12 +1492,12 @@ LfgState LFGMgr::GetState(ObjectGuid guid) if (guid.IsParty()) { state = GroupsStore[guid].GetState(); - TC_LOG_TRACE("lfg.data.group.state.get", "Group: %s, State: %u", guid.ToString().c_str(), state); + TC_LOG_TRACE("lfg.data.group.state.get", "Group: %s, State: %s", guid.ToString().c_str(), GetStateString(state).c_str()); } else { state = PlayersStore[guid].GetState(); - TC_LOG_TRACE("lfg.data.player.state.get", "Player: %s, State: %u", guid.ToString().c_str(), state); + TC_LOG_TRACE("lfg.data.player.state.get", "Player: %s, State: %s", guid.ToString().c_str(), GetStateString(state).c_str()); } return state; @@ -1526,6 +1520,16 @@ LfgState LFGMgr::GetOldState(ObjectGuid guid) return state; } +bool LFGMgr::IsVoteKickActive(ObjectGuid gguid) +{ + ASSERT(gguid.IsParty()); + + bool active = GroupsStore[gguid].IsVoteKickActive(); + TC_LOG_TRACE("lfg.data.group.votekick.get", "Group: %s, Active: %d", gguid.ToString().c_str(), active); + + return active; +} + uint32 LFGMgr::GetDungeon(ObjectGuid guid, bool asId /*= true */) { uint32 dungeon = GroupsStore[guid].GetDungeon(asId); @@ -1686,6 +1690,17 @@ void LFGMgr::SetState(ObjectGuid guid, LfgState state) } } +void LFGMgr::SetVoteKick(ObjectGuid gguid, bool active) +{ + ASSERT(gguid.IsParty()); + + LfgGroupData& data = GroupsStore[gguid]; + TC_LOG_TRACE("lfg.data.group.votekick.set", "Group: %s, New state: %d, Previous: %d", + gguid.ToString().c_str(), active, data.IsVoteKickActive()); + + data.SetVoteKick(active); +} + void LFGMgr::SetDungeon(ObjectGuid guid, uint32 dungeon) { TC_LOG_TRACE("lfg.data.group.dungeon.set", "Group: %s, Dungeon: %u", guid.ToString().c_str(), dungeon); diff --git a/src/server/game/DungeonFinding/LFGMgr.h b/src/server/game/DungeonFinding/LFGMgr.h index 5e7c4e368a2..5fd0decadaf 100644 --- a/src/server/game/DungeonFinding/LFGMgr.h +++ b/src/server/game/DungeonFinding/LFGMgr.h @@ -328,6 +328,8 @@ class LFGMgr LfgDungeonSet const& GetSelectedDungeons(ObjectGuid guid); /// Get current lfg state LfgState GetState(ObjectGuid guid); + /// Get current vote kick state + bool IsVoteKickActive(ObjectGuid gguid); /// Get current dungeon uint32 GetDungeon(ObjectGuid guid, bool asId = true); /// Get the map id of the current dungeon @@ -435,6 +437,7 @@ class LFGMgr void SetSelectedDungeons(ObjectGuid guid, LfgDungeonSet const& dungeons); void DecreaseKicksLeft(ObjectGuid guid); void SetState(ObjectGuid guid, LfgState state); + void SetVoteKick(ObjectGuid gguid, bool active); void RemovePlayerData(ObjectGuid guid); void GetCompatibleDungeons(LfgDungeonSet& dungeons, GuidSet const& players, LfgLockPartyMap& lockMap, bool isContinue); void _SaveToDB(ObjectGuid guid, uint32 db_guid); diff --git a/src/server/game/DungeonFinding/LFGQueue.cpp b/src/server/game/DungeonFinding/LFGQueue.cpp index 7a4ec0f7e1e..97f87a4d814 100644 --- a/src/server/game/DungeonFinding/LFGQueue.cpp +++ b/src/server/game/DungeonFinding/LFGQueue.cpp @@ -377,7 +377,7 @@ LfgCompatibility LFGQueue::CheckCompatibility(GuidList check) // Group with less that MAXGROUPSIZE members always compatible if (check.size() == 1 && numPlayers != MAXGROUPSIZE) { - TC_LOG_DEBUG("lfg.queue.match.compatibility.check", "Guids: (%s) sigle group. Compatibles", strGuids.c_str()); + TC_LOG_DEBUG("lfg.queue.match.compatibility.check", "Guids: (%s) single group. Compatibles", strGuids.c_str()); LfgQueueDataContainer::iterator itQueue = QueueDataStore.find(check.front()); LfgCompatibilityData data(LFG_COMPATIBLES_WITH_LESS_PLAYERS); diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp index dd5ab7fe9d1..0a2b22ea8d5 100644 --- a/src/server/game/Entities/Creature/Creature.cpp +++ b/src/server/game/Entities/Creature/Creature.cpp @@ -1729,7 +1729,7 @@ SpellInfo const* Creature::reachWithSpellAttack(Unit* victim) std::vector<SpellInfo::CostData> costs = spellInfo->CalcPowerCost(this, SpellSchoolMask(spellInfo->SchoolMask)); auto m = std::find_if(costs.begin(), costs.end(), [](SpellInfo::CostData const& cost) { return cost.Power == POWER_MANA; }); if (m != costs.end()) - if (m->Amount > (uint32)GetPower(POWER_MANA)) + if (m->Amount > GetPower(POWER_MANA)) continue; float range = spellInfo->GetMaxRange(false); @@ -1777,7 +1777,7 @@ SpellInfo const* Creature::reachWithSpellCure(Unit* victim) std::vector<SpellInfo::CostData> costs = spellInfo->CalcPowerCost(this, SpellSchoolMask(spellInfo->SchoolMask)); auto m = std::find_if(costs.begin(), costs.end(), [](SpellInfo::CostData const& cost) { return cost.Power == POWER_MANA; }); if (m != costs.end()) - if (m->Amount > (uint32)GetPower(POWER_MANA)) + if (m->Amount > GetPower(POWER_MANA)) continue; float range = spellInfo->GetMaxRange(true); diff --git a/src/server/game/Entities/GameObject/GameObject.h b/src/server/game/Entities/GameObject/GameObject.h index 63a4ece8aef..8ff2a941901 100644 --- a/src/server/game/Entities/GameObject/GameObject.h +++ b/src/server/game/Entities/GameObject/GameObject.h @@ -470,6 +470,7 @@ struct GameObjectTemplate { uint32 chairheight; // 0 chairheight, int, Min value: 0, Max value: 2, Default value: 1 int32 HeightOffset; // 1 Height Offset (inches), int, Min value: -100, Max value: 100, Default value: 0 + uint32 SitAnimKit; // 2 Sit Anim Kit, References: AnimKit, NoValue = 0 } barberChair; // 33 GAMEOBJECT_TYPE_DESTRUCTIBLE_BUILDING struct @@ -587,6 +588,8 @@ struct GameObjectTemplate { int32 mapID; // 0 mapID, References: Map, NoValue = -1 int32 namedset; // 1 named set, int, Min value: -2147483648, Max value: 2147483647, Default value: 0 + uint32 Primarydoodadset; // 2 Primary doodad set, int, Min value: -2147483648, Max value: 2147483647, Default value: 0 + uint32 Secondarydoodadset; // 3 Secondary doodad set, int, Min value: -2147483648, Max value: 2147483647, Default value: 0 } phaseableMO; // 44 GAMEOBJECT_TYPE_GARRISON_MONUMENT struct diff --git a/src/server/game/Entities/Item/Item.h b/src/server/game/Entities/Item/Item.h index 8514643cfad..810bbdac704 100644 --- a/src/server/game/Entities/Item/Item.h +++ b/src/server/game/Entities/Item/Item.h @@ -119,8 +119,9 @@ enum InventoryResult EQUIP_ERR_NOT_DURING_ARENA_MATCH = 78, // You can't do that while in an arena match EQUIP_ERR_TRADE_BOUND_ITEM = 79, // You can't trade a soulbound item. EQUIP_ERR_CANT_EQUIP_RATING = 80, // You don't have the personal, team, or battleground rating required to buy that item - EQUIP_ERR_NO_OUTPUT = 81, + EQUIP_ERR_EVENT_AUTOEQUIP_BIND_CONFIRM = 81, EQUIP_ERR_NOT_SAME_ACCOUNT = 82, // Account-bound items can only be given to your own characters. + EQUIP_ERR_NO_OUTPUT = 83, EQUIP_ERR_ITEM_MAX_LIMIT_CATEGORY_COUNT_EXCEEDED_IS = 84, // You can only carry %d %s EQUIP_ERR_ITEM_MAX_LIMIT_CATEGORY_SOCKETED_EXCEEDED_IS = 85, // You can only equip %d |4item:items in the %s category EQUIP_ERR_SCALING_STAT_ITEM_LEVEL_EXCEEDED = 86, // Your level is too high to use that item @@ -131,6 +132,9 @@ enum InventoryResult EQUIP_ERR_ITEM_INVENTORY_FULL_SATCHEL = 91, // Your inventory is full. Your satchel has been delivered to your mailbox. EQUIP_ERR_SCALING_STAT_ITEM_LEVEL_TOO_LOW = 92, // Your level is too low to use that item EQUIP_ERR_CANT_BUY_QUANTITY = 93, // You can't buy the specified quantity of that item. + EQUIP_ERR_ITEM_IS_BATTLE_PAY_LOCKED = 94, // Your purchased item is still waiting to be unlocked + EQUIP_ERR_REAGENT_BANK_FULL = 95, // Your reagent bank is full + EQUIP_ERR_REAGENT_BANK_LOCKED = 96 }; enum BuyResult diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp index 953d3b9d596..44fbae1e208 100644 --- a/src/server/game/Entities/Object/Object.cpp +++ b/src/server/game/Entities/Object/Object.cpp @@ -1521,37 +1521,37 @@ ByteBuffer& operator<<(ByteBuffer& buf, Position::PositionXYZOStreamer const& st void MovementInfo::OutDebug() { - TC_LOG_INFO("misc", "MOVEMENT INFO"); - TC_LOG_INFO("misc", "%s", guid.ToString().c_str()); - TC_LOG_INFO("misc", "flags %s (%u)", Movement::MovementFlags_ToString(flags).c_str(), flags); - TC_LOG_INFO("misc", "flags2 %s (%u)", Movement::MovementFlagsExtra_ToString(flags2).c_str(), flags2); - TC_LOG_INFO("misc", "time %u current time %u", time, getMSTime()); - TC_LOG_INFO("misc", "position: `%s`", pos.ToString().c_str()); + TC_LOG_DEBUG("misc", "MOVEMENT INFO"); + TC_LOG_DEBUG("misc", "%s", guid.ToString().c_str()); + TC_LOG_DEBUG("misc", "flags %s (%u)", Movement::MovementFlags_ToString(flags).c_str(), flags); + TC_LOG_DEBUG("misc", "flags2 %s (%u)", Movement::MovementFlagsExtra_ToString(flags2).c_str(), flags2); + TC_LOG_DEBUG("misc", "time %u current time %u", time, getMSTime()); + TC_LOG_DEBUG("misc", "position: `%s`", pos.ToString().c_str()); if (!transport.guid.IsEmpty()) { - TC_LOG_INFO("misc", "TRANSPORT:"); - TC_LOG_INFO("misc", "%s", transport.guid.ToString().c_str()); - TC_LOG_INFO("misc", "position: `%s`", transport.pos.ToString().c_str()); - TC_LOG_INFO("misc", "seat: %i", transport.seat); - TC_LOG_INFO("misc", "time: %u", transport.time); + TC_LOG_DEBUG("misc", "TRANSPORT:"); + TC_LOG_DEBUG("misc", "%s", transport.guid.ToString().c_str()); + TC_LOG_DEBUG("misc", "position: `%s`", transport.pos.ToString().c_str()); + TC_LOG_DEBUG("misc", "seat: %i", transport.seat); + TC_LOG_DEBUG("misc", "time: %u", transport.time); if (flags2 & MOVEMENTFLAG2_INTERPOLATED_MOVEMENT) - TC_LOG_INFO("misc", "prevTime: %u", transport.prevTime); + TC_LOG_DEBUG("misc", "prevTime: %u", transport.prevTime); if (transport.vehicleId) - TC_LOG_INFO("misc", "vehicleId: %u", transport.vehicleId); + TC_LOG_DEBUG("misc", "vehicleId: %u", transport.vehicleId); } if ((flags & (MOVEMENTFLAG_SWIMMING | MOVEMENTFLAG_FLYING)) || (flags2 & MOVEMENTFLAG2_ALWAYS_ALLOW_PITCHING)) - TC_LOG_INFO("misc", "pitch: %f", pitch); + TC_LOG_DEBUG("misc", "pitch: %f", pitch); if (flags & MOVEMENTFLAG_FALLING || jump.fallTime) { - TC_LOG_INFO("misc", "fallTime: %u j_zspeed: %f", jump.fallTime, jump.zspeed); + TC_LOG_DEBUG("misc", "fallTime: %u j_zspeed: %f", jump.fallTime, jump.zspeed); if (flags & MOVEMENTFLAG_FALLING) - TC_LOG_INFO("misc", "j_sinAngle: %f j_cosAngle: %f j_xyspeed: %f", jump.sinAngle, jump.cosAngle, jump.xyspeed); + TC_LOG_DEBUG("misc", "j_sinAngle: %f j_cosAngle: %f j_xyspeed: %f", jump.sinAngle, jump.cosAngle, jump.xyspeed); } if (flags & MOVEMENTFLAG_SPLINE_ELEVATION) - TC_LOG_INFO("misc", "splineElevation: %f", splineElevation); + TC_LOG_DEBUG("misc", "splineElevation: %f", splineElevation); } WorldObject::WorldObject(bool isWorldObject) : WorldLocation(), LastUsedScriptID(0), @@ -3380,4 +3380,4 @@ void WorldObject::RebuildWorldMapAreaSwaps() } } } -}
\ No newline at end of file +} diff --git a/src/server/game/Entities/Object/ObjectGuid.h b/src/server/game/Entities/Object/ObjectGuid.h index b4b08d7ace2..72fda2feb5e 100644 --- a/src/server/game/Entities/Object/ObjectGuid.h +++ b/src/server/game/Entities/Object/ObjectGuid.h @@ -24,6 +24,7 @@ #include <boost/functional/hash.hpp> #include <functional> +#include <unordered_set> enum TypeID { @@ -266,6 +267,7 @@ typedef std::set<ObjectGuid> GuidSet; typedef std::list<ObjectGuid> GuidList; typedef std::deque<ObjectGuid> GuidDeque; typedef std::vector<ObjectGuid> GuidVector; +typedef std::unordered_set<ObjectGuid> GuidUnorderedSet; // maximum buffer size for packed guid is 18 bytes #define PACKED_GUID_MIN_BUFFER_SIZE 18 diff --git a/src/server/game/Entities/Pet/Pet.cpp b/src/server/game/Entities/Pet/Pet.cpp index 6a07a56d0af..d96e1c65eda 100644 --- a/src/server/game/Entities/Pet/Pet.cpp +++ b/src/server/game/Entities/Pet/Pet.cpp @@ -1250,7 +1250,7 @@ void Pet::_LoadAuras(uint32 timediff) aura->SetLoadedState(maxDuration, remainTime, remainCharges, stackCount, recalculateMask, info.Amounts.data()); aura->ApplyForTargets(); - TC_LOG_INFO("entities.pet", "Added aura spellid %u, effectmask %u", spellInfo->Id, key.EffectMask); + TC_LOG_DEBUG("entities.pet", "Added aura spellid %u, effectmask %u", spellInfo->Id, key.EffectMask); } } while (auraResult->NextRow()); @@ -1625,7 +1625,7 @@ bool Pet::resetTalents() return true; } -void Pet::resetTalentsForAllPetsOf(Player* owner, Pet* onlinePet /*= NULL*/) +void Pet::resetTalentsForAllPetsOf(Player* /*owner*/, Pet* /*onlinePet*/ /*= NULL*/) { /* TODO: 6.x remove pet talents // not need after this call diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 7e945a0c0b6..284e669cd49 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -6129,7 +6129,7 @@ void Player::SendActionButtons(uint32 state) const packet.Reason = state; SendDirectMessage(packet.Write()); - TC_LOG_INFO("network", "Action Buttons for '%s' group '%u' Sent", GetGUID().ToString().c_str(), GetActiveTalentGroup()); + TC_LOG_DEBUG("network", "Action Buttons for '%s' group '%u' Sent", GetGUID().ToString().c_str(), GetActiveTalentGroup()); } bool Player::IsActionButtonDataValid(uint8 button, uint32 action, uint8 type) @@ -6377,7 +6377,7 @@ void Player::CheckAreaExploreAndOutdoor() GiveXP(XP, NULL); SendExplorationExperience(area, XP); } - TC_LOG_INFO("entities.player", "Player %s discovered a new area: %u", GetGUID().ToString().c_str(), area); + TC_LOG_DEBUG("entities.player", "Player %s discovered a new area: %u", GetGUID().ToString().c_str(), area); } } } @@ -7605,7 +7605,7 @@ void Player::_ApplyItemMods(Item* item, uint8 slot, bool apply) if (item->IsBroken()) return; - TC_LOG_INFO("entities.player.items", "applying mods for item %s", item->GetGUID().ToString().c_str()); + TC_LOG_DEBUG("entities.player.items", "applying mods for item %s", item->GetGUID().ToString().c_str()); uint8 attacktype = Player::GetAttackBySlot(slot); @@ -9454,7 +9454,7 @@ uint32 Player::GetXPRestBonus(uint32 xp) SetRestBonus(GetRestBonus() - rested_bonus); - TC_LOG_INFO("entities.player", "Player gain %u xp (+ %u Rested Bonus). Rested points=%f", xp+rested_bonus, rested_bonus, GetRestBonus()); + TC_LOG_DEBUG("entities.player", "Player gain %u xp (+ %u Rested Bonus). Rested points=%f", xp+rested_bonus, rested_bonus, GetRestBonus()); return rested_bonus; } @@ -12900,21 +12900,43 @@ void Player::SendEquipError(InventoryResult msg, Item* item1 /*= nullptr*/, Item WorldPackets::Item::InventoryChangeFailure failure; failure.BagResult = msg; - if (item1) + if (msg != EQUIP_ERR_OK) { - failure.Item[0] = item1->GetGUID(); - failure.Level = uint32(item1->GetRequiredLevel()); - } + if (item1) + failure.Item[0] = item1->GetGUID(); + + if (item2) + failure.Item[1] = item2->GetGUID(); - if (item2) - failure.Item[1] = item2->GetGUID(); + failure.ContainerBSlot = 0; // bag equip slot, used with EQUIP_ERR_EVENT_AUTOEQUIP_BIND_CONFIRM and EQUIP_ERR_ITEM_DOESNT_GO_INTO_BAG2 - /// @todo: fill remaining values: - /// ContainerBSlot - /// SrcContainer - /// DstContainer - /// SrcSlot - /// LimitCategory + switch (msg) + { + case EQUIP_ERR_CANT_EQUIP_LEVEL_I: + case EQUIP_ERR_PURCHASE_LEVEL_TOO_LOW: + { + failure.Level = uint32(item1 ? item1->GetRequiredLevel() : 0); + break; + } + case EQUIP_ERR_EVENT_AUTOEQUIP_BIND_CONFIRM: // no idea about this one... + { + //failure.SrcContainer + //failure.SrcSlot + //failure.DstContainer + break; + } + case EQUIP_ERR_ITEM_MAX_LIMIT_CATEGORY_COUNT_EXCEEDED_IS: + case EQUIP_ERR_ITEM_MAX_LIMIT_CATEGORY_SOCKETED_EXCEEDED_IS: + case EQUIP_ERR_ITEM_MAX_LIMIT_CATEGORY_EQUIPPED_EXCEEDED_IS: + { + ItemTemplate const* proto = item1 ? item1->GetTemplate() : sObjectMgr->GetItemTemplate(itemId); + failure.LimitCategory = proto ? proto->GetItemLimitCategory() : 0; + break; + } + default: + break; + } + } SendDirectMessage(failure.Write()); } @@ -15665,6 +15687,8 @@ void Player::AreaExploredOrEventHappens(uint32 questId) { q_status.Explored = true; m_QuestStatusSave[questId] = QUEST_DEFAULT_SAVE_TYPE; + SetQuestSlotState(log_slot, QUEST_STATE_COMPLETE); + SendQuestComplete(questId); }**/ } if (CanCompleteQuest(questId)) @@ -17427,7 +17451,7 @@ void Player::_LoadAuras(PreparedQueryResult auraResult, PreparedQueryResult effe aura->SetLoadedState(maxDuration, remainTime, remainCharges, stackCount, recalculateMask, info.Amounts.data()); aura->ApplyForTargets(); - TC_LOG_INFO("entities.player", "Added aura spellid %u, effectmask %u", spellInfo->Id, key.EffectMask); + TC_LOG_DEBUG("entities.player", "Added aura spellid %u, effectmask %u", spellInfo->Id, key.EffectMask); } } while (auraResult->NextRow()); @@ -22045,13 +22069,13 @@ bool Player::IsVisibleGloballyFor(Player const* u) const } template<class T> -inline void UpdateVisibilityOf_helper(GuidSet& s64, T* target, std::set<Unit*>& /*v*/) +inline void UpdateVisibilityOf_helper(GuidUnorderedSet& s64, T* target, std::set<Unit*>& /*v*/) { s64.insert(target->GetGUID()); } template<> -inline void UpdateVisibilityOf_helper(GuidSet& s64, GameObject* target, std::set<Unit*>& /*v*/) +inline void UpdateVisibilityOf_helper(GuidUnorderedSet& s64, GameObject* target, std::set<Unit*>& /*v*/) { // @HACK: This is to prevent objects like deeprun tram from disappearing when player moves far from its spawn point while riding it // But exclude stoppable elevators from this hack - they would be teleporting from one end to another @@ -22062,14 +22086,14 @@ inline void UpdateVisibilityOf_helper(GuidSet& s64, GameObject* target, std::set } template<> -inline void UpdateVisibilityOf_helper(GuidSet& s64, Creature* target, std::set<Unit*>& v) +inline void UpdateVisibilityOf_helper(GuidUnorderedSet& s64, Creature* target, std::set<Unit*>& v) { s64.insert(target->GetGUID()); v.insert(target); } template<> -inline void UpdateVisibilityOf_helper(GuidSet& s64, Player* target, std::set<Unit*>& v) +inline void UpdateVisibilityOf_helper(GuidUnorderedSet& s64, Player* target, std::set<Unit*>& v) { s64.insert(target->GetGUID()); v.insert(target); @@ -22131,7 +22155,7 @@ void Player::UpdateTriggerVisibility() UpdateData udata(GetMapId()); WorldPacket packet; - for (GuidSet::iterator itr = m_clientGUIDs.begin(); itr != m_clientGUIDs.end(); ++itr) + for (auto itr = m_clientGUIDs.begin(); itr != m_clientGUIDs.end(); ++itr) { if (itr->IsCreature()) { @@ -23238,7 +23262,7 @@ void Player::UpdateForQuestWorldObjects() UpdateData udata(GetMapId()); WorldPacket packet; - for (GuidSet::iterator itr = m_clientGUIDs.begin(); itr != m_clientGUIDs.end(); ++itr) + for (auto itr = m_clientGUIDs.begin(); itr != m_clientGUIDs.end(); ++itr) { if (itr->IsGameObject()) { @@ -23694,28 +23718,9 @@ void Player::SetMover(Unit* target) m_mover = target; m_mover->m_movedPlayer = this; - ObjectGuid guid = target->GetGUID(); - - WorldPacket data(SMSG_MOVE_SET_ACTIVE_MOVER, 9); - data.WriteBit(guid[5]); - data.WriteBit(guid[7]); - data.WriteBit(guid[3]); - data.WriteBit(guid[6]); - data.WriteBit(guid[0]); - data.WriteBit(guid[4]); - data.WriteBit(guid[1]); - data.WriteBit(guid[2]); - - data.WriteByteSeq(guid[6]); - data.WriteByteSeq(guid[2]); - data.WriteByteSeq(guid[3]); - data.WriteByteSeq(guid[0]); - data.WriteByteSeq(guid[5]); - data.WriteByteSeq(guid[7]); - data.WriteByteSeq(guid[1]); - data.WriteByteSeq(guid[4]); - - SendDirectMessage(&data); + WorldPackets::Movement::MoveSetActiveMover packet; + packet.MoverGUID = target->GetGUID(); + SendDirectMessage(packet.Write()); } void Player::UpdateZoneDependentAuras(uint32 newZone) @@ -23746,18 +23751,6 @@ void Player::UpdateAreaDependentAuras(uint32 newArea) if (itr->second->autocast && itr->second->IsFitToRequirements(this, m_zoneUpdateId, newArea)) if (!HasAura(itr->second->spellId)) CastSpell(this, itr->second->spellId, true); - - if (newArea == 4273 && GetVehicleCreatureBase() && GetPositionX() > 400) // Ulduar - { - switch (GetVehicleBase()->GetEntry()) - { - case 33062: - case 33109: - case 33060: - GetVehicleCreatureBase()->DespawnOrUnsummon(); - break; - } - } } uint32 Player::GetCorpseReclaimDelay(bool pvp) const @@ -23888,7 +23881,7 @@ PartyResult Player::CanUninviteFromGroup(ObjectGuid guidMember) const return ERR_PARTY_LFG_BOOT_LIMIT; lfg::LfgState state = sLFGMgr->GetState(gguid); - if (state == lfg::LFG_STATE_BOOT) + if (sLFGMgr->IsVoteKickActive(gguid)) return ERR_PARTY_LFG_BOOT_IN_PROGRESS; if (grp->GetMembersCount() <= lfg::LFG_GROUP_KICK_VOTES_NEEDED) @@ -24967,7 +24960,7 @@ bool Player::LearnTalent(uint32 talentId) LearnSpell(spellid, false); - TC_LOG_INFO("misc", "TalentID: %u Spell: %u Group: %u\n", talentId, spellid, GetActiveTalentGroup()); + TC_LOG_DEBUG("misc", "TalentID: %u Spell: %u Group: %u\n", talentId, spellid, GetActiveTalentGroup()); return true; } diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index 6e174995ebd..cdd12792fd0 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -2435,7 +2435,7 @@ class Player : public Unit, public GridObject<Player> WorldLocation GetStartPosition() const; // currently visible objects at player client - GuidSet m_clientGUIDs; + GuidUnorderedSet m_clientGUIDs; bool HaveAtClient(WorldObject const* u) const; diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index a1a08ad15e0..a5596158441 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -2115,9 +2115,9 @@ void Unit::SendMeleeAttackStop(Unit* victim) SendMessageToSet(WorldPackets::Combat::SAttackStop(this, victim).Write(), true); if (victim) - TC_LOG_INFO("entities.unit", "%s stopped attacking %s", GetGUID().ToString().c_str(), victim->GetGUID().ToString().c_str()); + TC_LOG_DEBUG("entities.unit", "%s stopped attacking %s", GetGUID().ToString().c_str(), victim->GetGUID().ToString().c_str()); else - TC_LOG_INFO("entities.unit", "%s stopped attacking", GetGUID().ToString().c_str()); + TC_LOG_DEBUG("entities.unit", "%s stopped attacking", GetGUID().ToString().c_str()); } bool Unit::isSpellBlocked(Unit* victim, SpellInfo const* spellProto, WeaponAttackType /*attackType*/) @@ -6130,7 +6130,7 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere // Used in case when access to whole aura is needed // All procs should be handled like this... -bool Unit::HandleAuraProc(Unit* victim, uint32 /*damage*/, Aura* triggeredByAura, SpellInfo const* procSpell, uint32 /*procFlag*/, uint32 /*procEx*/, uint32 cooldown, bool * handled) +bool Unit::HandleAuraProc(Unit* victim, uint32 /*damage*/, Aura* triggeredByAura, SpellInfo const* /*procSpell*/, uint32 /*procFlag*/, uint32 /*procEx*/, uint32 cooldown, bool * handled) { SpellInfo const* dummySpell = triggeredByAura->GetSpellInfo(); @@ -15722,30 +15722,30 @@ void Unit::StopAttackFaction(uint32 faction_id) void Unit::OutDebugInfo() const { TC_LOG_ERROR("entities.unit", "Unit::OutDebugInfo"); - TC_LOG_INFO("entities.unit", "%s name %s", GetGUID().ToString().c_str(), GetName().c_str()); - TC_LOG_INFO("entities.unit", "Owner %s, Minion %s, Charmer %s, Charmed %s", GetOwnerGUID().ToString().c_str(), GetMinionGUID().ToString().c_str(), GetCharmerGUID().ToString().c_str(), GetCharmGUID().ToString().c_str()); - TC_LOG_INFO("entities.unit", "In world %u, unit type mask %u", (uint32)(IsInWorld() ? 1 : 0), m_unitTypeMask); + TC_LOG_DEBUG("entities.unit", "%s name %s", GetGUID().ToString().c_str(), GetName().c_str()); + TC_LOG_DEBUG("entities.unit", "Owner %s, Minion %s, Charmer %s, Charmed %s", GetOwnerGUID().ToString().c_str(), GetMinionGUID().ToString().c_str(), GetCharmerGUID().ToString().c_str(), GetCharmGUID().ToString().c_str()); + TC_LOG_DEBUG("entities.unit", "In world %u, unit type mask %u", (uint32)(IsInWorld() ? 1 : 0), m_unitTypeMask); if (IsInWorld()) - TC_LOG_INFO("entities.unit", "Mapid %u", GetMapId()); + TC_LOG_DEBUG("entities.unit", "Mapid %u", GetMapId()); std::ostringstream o; o << "Summon Slot: "; for (uint32 i = 0; i < MAX_SUMMON_SLOT; ++i) o << m_SummonSlot[i].ToString() << ", "; - TC_LOG_INFO("entities.unit", "%s", o.str().c_str()); + TC_LOG_DEBUG("entities.unit", "%s", o.str().c_str()); o.str(""); o << "Controlled List: "; for (ControlList::const_iterator itr = m_Controlled.begin(); itr != m_Controlled.end(); ++itr) o << (*itr)->GetGUID().ToString() << ", "; - TC_LOG_INFO("entities.unit", "%s", o.str().c_str()); + TC_LOG_DEBUG("entities.unit", "%s", o.str().c_str()); o.str(""); o << "Aura List: "; for (AuraApplicationMap::const_iterator itr = m_appliedAuras.begin(); itr != m_appliedAuras.end(); ++itr) o << itr->first << ", "; - TC_LOG_INFO("entities.unit", "%s", o.str().c_str()); + TC_LOG_DEBUG("entities.unit", "%s", o.str().c_str()); o.str(""); if (IsVehicle()) @@ -15754,11 +15754,11 @@ void Unit::OutDebugInfo() const for (SeatMap::iterator itr = GetVehicleKit()->Seats.begin(); itr != GetVehicleKit()->Seats.end(); ++itr) if (Unit* passenger = ObjectAccessor::GetUnit(*GetVehicleBase(), itr->second.Passenger.Guid)) o << passenger->GetGUID().ToString() << ", "; - TC_LOG_INFO("entities.unit", "%s", o.str().c_str()); + TC_LOG_DEBUG("entities.unit", "%s", o.str().c_str()); } if (GetVehicle()) - TC_LOG_INFO("entities.unit", "On vehicle %u.", GetVehicleBase()->GetEntry()); + TC_LOG_DEBUG("entities.unit", "On vehicle %u.", GetVehicleBase()->GetEntry()); } uint32 Unit::GetRemainingPeriodicAmount(ObjectGuid caster, uint32 spellId, AuraType auraType, uint8 effectIndex) const @@ -16450,7 +16450,7 @@ bool Unit::IsHighestExclusiveAura(Aura const* aura, bool removeOtherAuraApplicat { if (AuraApplication* aurApp = existingAurEff->GetBase()->GetApplicationOfTarget(GetGUID())) { - bool hasMoreThanOneEffect = base->HasMoreThanOneEffectForType(auraType, GetMap()->GetDifficultyID()); + bool hasMoreThanOneEffect = base->HasMoreThanOneEffectForType(auraType); uint32 removedAuras = m_removedAurasCount; RemoveAura(aurApp); if (hasMoreThanOneEffect || m_removedAurasCount > removedAuras + 1) diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp index acadc036fb3..9bf73c57193 100644 --- a/src/server/game/Globals/ObjectMgr.cpp +++ b/src/server/game/Globals/ObjectMgr.cpp @@ -3358,6 +3358,8 @@ void ObjectMgr::BuildPlayerLevelInfo(uint8 race, uint8 _class, uint8 level, Play } } +int32 const ReputationMgr::Reputation_Cap; + void ObjectMgr::LoadQuests() { uint32 oldMSTime = getMSTime(); diff --git a/src/server/game/Grids/Notifiers/GridNotifiers.cpp b/src/server/game/Grids/Notifiers/GridNotifiers.cpp index 533f2845b17..d5562a9a3c7 100644 --- a/src/server/game/Grids/Notifiers/GridNotifiers.cpp +++ b/src/server/game/Grids/Notifiers/GridNotifiers.cpp @@ -65,7 +65,7 @@ void VisibleNotifier::SendToSelf() } } - for (GuidSet::const_iterator it = vis_guids.begin(); it != vis_guids.end(); ++it) + for (auto it = vis_guids.begin(); it != vis_guids.end(); ++it) { i_player.m_clientGUIDs.erase(*it); i_data.AddOutOfRangeGUID(*it); diff --git a/src/server/game/Grids/Notifiers/GridNotifiers.h b/src/server/game/Grids/Notifiers/GridNotifiers.h index ae8c96aff94..0936f8ff753 100644 --- a/src/server/game/Grids/Notifiers/GridNotifiers.h +++ b/src/server/game/Grids/Notifiers/GridNotifiers.h @@ -45,7 +45,7 @@ namespace Trinity Player &i_player; UpdateData i_data; std::set<Unit*> i_visibleNow; - GuidSet vis_guids; + GuidUnorderedSet vis_guids; VisibleNotifier(Player &player) : i_player(player), i_data(player.GetMapId()), vis_guids(player.m_clientGUIDs) { } template<class T> void Visit(GridRefManager<T> &m); diff --git a/src/server/game/Handlers/BankHandler.cpp b/src/server/game/Handlers/BankHandler.cpp new file mode 100644 index 00000000000..8879b4e2532 --- /dev/null +++ b/src/server/game/Handlers/BankHandler.cpp @@ -0,0 +1,172 @@ +/* + * Copyright (C) 2008-2015 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 "BankPackets.h" +#include "NPCPackets.h" +#include "ObjectMgr.h" +#include "Opcodes.h" +#include "Player.h" +#include "WorldPacket.h" +#include "WorldSession.h" + +void WorldSession::HandleAutoBankItemOpcode(WorldPackets::Bank::AutoBankItem& packet) +{ + TC_LOG_DEBUG("network", "STORAGE: receive bag = %u, slot = %u", packet.Bag, packet.Slot); + + if (!CanUseBank()) + { + TC_LOG_ERROR("network", "WORLD: HandleAutoBankItemOpcode - Unit (%s) not found or you can't interact with him.", m_currentBankerGUID.ToString().c_str()); + return; + } + + Item* item = _player->GetItemByPos(packet.Bag, packet.Slot); + if (!item) + return; + + ItemPosCountVec dest; + InventoryResult msg = _player->CanBankItem(NULL_BAG, NULL_SLOT, dest, item, false); + if (msg != EQUIP_ERR_OK) + { + _player->SendEquipError(msg, item, NULL); + return; + } + + if (dest.size() == 1 && dest[0].pos == item->GetPos()) + { + _player->SendEquipError(EQUIP_ERR_CANT_SWAP, item, NULL); + return; + } + + _player->RemoveItem(packet.Bag, packet.Slot, true); + _player->ItemRemovedQuestCheck(item->GetEntry(), item->GetCount()); + _player->BankItem(dest, item, true); +} + +void WorldSession::HandleBankerActivateOpcode(WorldPackets::NPC::Hello& packet) +{ + Creature* unit = GetPlayer()->GetNPCIfCanInteractWith(packet.Unit, UNIT_NPC_FLAG_BANKER); + if (!unit) + { + TC_LOG_ERROR("network", "WORLD: HandleBankerActivateOpcode - %s not found or you can not interact with him.", packet.Unit.ToString().c_str()); + return; + } + + // remove fake death + if (GetPlayer()->HasUnitState(UNIT_STATE_DIED)) + GetPlayer()->RemoveAurasByType(SPELL_AURA_FEIGN_DEATH); + + // set currentBankerGUID for other bank action + + SendShowBank(packet.Unit); +} + +void WorldSession::HandleAutoStoreBankItemOpcode(WorldPackets::Bank::AutoStoreBankItem& packet) +{ + TC_LOG_DEBUG("network", "STORAGE: receive bag = %u, slot = %u", packet.Bag, packet.Slot); + + if (!CanUseBank()) + { + TC_LOG_ERROR("network", "WORLD: HandleAutoStoreBankItemOpcode - Unit (%s) not found or you can't interact with him.", m_currentBankerGUID.ToString().c_str()); + return; + } + + Item* item = _player->GetItemByPos(packet.Bag, packet.Slot); + if (!item) + return; + + if (_player->IsBankPos(packet.Bag, packet.Slot)) // moving from bank to inventory + { + ItemPosCountVec dest; + InventoryResult msg = _player->CanStoreItem(NULL_BAG, NULL_SLOT, dest, item, false); + if (msg != EQUIP_ERR_OK) + { + _player->SendEquipError(msg, item, NULL); + return; + } + + _player->RemoveItem(packet.Bag, packet.Slot, true); + if (Item const* storedItem = _player->StoreItem(dest, item, true)) + _player->ItemAddedQuestCheck(storedItem->GetEntry(), storedItem->GetCount()); + + } + else // moving from inventory to bank + { + ItemPosCountVec dest; + InventoryResult msg = _player->CanBankItem(NULL_BAG, NULL_SLOT, dest, item, false); + if (msg != EQUIP_ERR_OK) + { + _player->SendEquipError(msg, item, NULL); + return; + } + + _player->RemoveItem(packet.Bag, packet.Slot, true); + _player->BankItem(dest, item, true); + } +} + +void WorldSession::HandleBuyBankSlotOpcode(WorldPackets::Bank::BuyBankSlot& packet) +{ + WorldPacket data(SMSG_BUY_BANK_SLOT_RESULT, 4); + if (!CanUseBank(packet.Guid)) + { + data << uint32(ERR_BANKSLOT_NOTBANKER); + SendPacket(&data); + TC_LOG_ERROR("network", "WORLD: HandleBuyBankSlotOpcode - %s not found or you can't interact with him.", packet.Guid.ToString().c_str()); + return; + } + + uint32 slot = _player->GetBankBagSlotCount(); + + // next slot + ++slot; + + TC_LOG_INFO("network", "PLAYER: Buy bank bag slot, slot number = %u", slot); + + BankBagSlotPricesEntry const* slotEntry = sBankBagSlotPricesStore.LookupEntry(slot); + + if (!slotEntry) + { + data << uint32(ERR_BANKSLOT_FAILED_TOO_MANY); + SendPacket(&data); + return; + } + + uint32 price = slotEntry->Cost; + + if (!_player->HasEnoughMoney(uint64(price))) + { + data << uint32(ERR_BANKSLOT_INSUFFICIENT_FUNDS); + SendPacket(&data); + return; + } + + _player->SetBankBagSlotCount(slot); + _player->ModifyMoney(-int64(price)); + + data << uint32(ERR_BANKSLOT_OK); + SendPacket(&data); + + _player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BUY_BANK_SLOT); +} + +void WorldSession::SendShowBank(ObjectGuid guid) +{ + m_currentBankerGUID = guid; + WorldPackets::NPC::ShowBank packet; + packet.Guid = guid; + SendPacket(packet.Write()); +} diff --git a/src/server/game/Handlers/BlackMarketHandler.cpp b/src/server/game/Handlers/BlackMarketHandler.cpp index 0520d1e18f3..f2b549c58c3 100644 --- a/src/server/game/Handlers/BlackMarketHandler.cpp +++ b/src/server/game/Handlers/BlackMarketHandler.cpp @@ -37,7 +37,7 @@ void WorldSession::HandleBlackMarketOpen(WorldPackets::BlackMarket::BlackMarketO SendBlackMarketOpenResult(packet.Guid, unit); } -void WorldSession::SendBlackMarketOpenResult(ObjectGuid guid, Creature* auctioneer) +void WorldSession::SendBlackMarketOpenResult(ObjectGuid guid, Creature* /*auctioneer*/) { WorldPackets::BlackMarket::BlackMarketOpenResult packet; packet.Guid = guid; diff --git a/src/server/game/Handlers/CharacterHandler.cpp b/src/server/game/Handlers/CharacterHandler.cpp index 7a63d38f4fa..34c50cac180 100644 --- a/src/server/game/Handlers/CharacterHandler.cpp +++ b/src/server/game/Handlers/CharacterHandler.cpp @@ -1394,7 +1394,7 @@ void WorldSession::HandleAlterAppearance(WorldPacket& recvData) return; } - if (_player->GetStandState() != UNIT_STAND_STATE_SIT_LOW_CHAIR + go->GetGOInfo()->barberChair.chairheight) + if (_player->GetStandState() != UnitStandStateType(UNIT_STAND_STATE_SIT_LOW_CHAIR + go->GetGOInfo()->barberChair.chairheight)) { SendBarberShopResult(BARBER_SHOP_RESULT_NOT_ON_CHAIR); return; diff --git a/src/server/game/Handlers/GuildHandler.cpp b/src/server/game/Handlers/GuildHandler.cpp index 2f5c1602a9f..679f1f08dc9 100644 --- a/src/server/game/Handlers/GuildHandler.cpp +++ b/src/server/game/Handlers/GuildHandler.cpp @@ -390,7 +390,7 @@ void WorldSession::HandleDeclineGuildInvites(WorldPackets::Guild::DeclineGuildIn GetPlayer()->ApplyModFlag(PLAYER_FLAGS, PLAYER_FLAGS_AUTO_DECLINE_GUILD, packet.Allow); } -void WorldSession::HandleRequestGuildRewardsList(WorldPackets::Guild::RequestGuildRewardsList& packet) +void WorldSession::HandleRequestGuildRewardsList(WorldPackets::Guild::RequestGuildRewardsList& /*packet*/) { if (sGuildMgr->GetGuildById(_player->GetGuildId())) { diff --git a/src/server/game/Handlers/ItemHandler.cpp b/src/server/game/Handlers/ItemHandler.cpp index e6803832a56..db7b49521c3 100644 --- a/src/server/game/Handlers/ItemHandler.cpp +++ b/src/server/game/Handlers/ItemHandler.cpp @@ -741,140 +741,6 @@ void WorldSession::HandleAutoStoreBagItemOpcode(WorldPackets::Item::AutoStoreBag _player->StoreItem(dest, item, true); } -void WorldSession::HandleBuyBankSlotOpcode(WorldPacket& recvPacket) -{ - TC_LOG_DEBUG("network", "WORLD: CMSG_BUY_BANK_SLOT"); - - ObjectGuid guid; - recvPacket >> guid; - - WorldPacket data(SMSG_BUY_BANK_SLOT_RESULT, 4); - if (!CanUseBank(guid)) - { - data << uint32(ERR_BANKSLOT_NOTBANKER); - SendPacket(&data); - TC_LOG_DEBUG("network", "WORLD: HandleBuyBankSlotOpcode - %s not found or you can't interact with him.", guid.ToString().c_str()); - return; - } - - uint32 slot = _player->GetBankBagSlotCount(); - - // next slot - ++slot; - - TC_LOG_INFO("network", "PLAYER: Buy bank bag slot, slot number = %u", slot); - - BankBagSlotPricesEntry const* slotEntry = sBankBagSlotPricesStore.LookupEntry(slot); - - if (!slotEntry) - { - data << uint32(ERR_BANKSLOT_FAILED_TOO_MANY); - SendPacket(&data); - return; - } - - uint32 price = slotEntry->Cost; - - if (!_player->HasEnoughMoney(uint64(price))) - { - data << uint32(ERR_BANKSLOT_INSUFFICIENT_FUNDS); - SendPacket(&data); - return; - } - - _player->SetBankBagSlotCount(slot); - _player->ModifyMoney(-int64(price)); - - data << uint32(ERR_BANKSLOT_OK); - SendPacket(&data); - - _player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BUY_BANK_SLOT); -} - -void WorldSession::HandleAutoBankItemOpcode(WorldPacket& recvPacket) -{ - TC_LOG_DEBUG("network", "WORLD: CMSG_AUTOBANK_ITEM"); - uint8 srcbag, srcslot; - - recvPacket >> srcbag >> srcslot; - TC_LOG_DEBUG("network", "STORAGE: receive srcbag = %u, srcslot = %u", srcbag, srcslot); - - if (!CanUseBank()) - { - TC_LOG_DEBUG("network", "WORLD: HandleAutoBankItemOpcode - Unit (%s) not found or you can't interact with him.", m_currentBankerGUID.ToString().c_str()); - return; - } - - Item* pItem = _player->GetItemByPos(srcbag, srcslot); - if (!pItem) - return; - - ItemPosCountVec dest; - InventoryResult msg = _player->CanBankItem(NULL_BAG, NULL_SLOT, dest, pItem, false); - if (msg != EQUIP_ERR_OK) - { - _player->SendEquipError(msg, pItem, NULL); - return; - } - - if (dest.size() == 1 && dest[0].pos == pItem->GetPos()) - { - _player->SendEquipError(EQUIP_ERR_CANT_SWAP, pItem, NULL); - return; - } - - _player->RemoveItem(srcbag, srcslot, true); - _player->ItemRemovedQuestCheck(pItem->GetEntry(), pItem->GetCount()); - _player->BankItem(dest, pItem, true); -} - -void WorldSession::HandleAutoStoreBankItemOpcode(WorldPacket& recvPacket) -{ - TC_LOG_DEBUG("network", "WORLD: CMSG_AUTOSTORE_BANK_ITEM"); - uint8 srcbag, srcslot; - - recvPacket >> srcbag >> srcslot; - TC_LOG_DEBUG("network", "STORAGE: receive srcbag = %u, srcslot = %u", srcbag, srcslot); - - if (!CanUseBank()) - { - TC_LOG_DEBUG("network", "WORLD: HandleAutoStoreBankItemOpcode - Unit (%s) not found or you can't interact with him.", m_currentBankerGUID.ToString().c_str()); - return; - } - - Item* pItem = _player->GetItemByPos(srcbag, srcslot); - if (!pItem) - return; - - if (_player->IsBankPos(srcbag, srcslot)) // moving from bank to inventory - { - ItemPosCountVec dest; - InventoryResult msg = _player->CanStoreItem(NULL_BAG, NULL_SLOT, dest, pItem, false); - if (msg != EQUIP_ERR_OK) - { - _player->SendEquipError(msg, pItem, NULL); - return; - } - - _player->RemoveItem(srcbag, srcslot, true); - if (Item const* storedItem = _player->StoreItem(dest, pItem, true)) - _player->ItemAddedQuestCheck(storedItem->GetEntry(), storedItem->GetCount()); - } - else // moving from inventory to bank - { - ItemPosCountVec dest; - InventoryResult msg = _player->CanBankItem(NULL_BAG, NULL_SLOT, dest, pItem, false); - if (msg != EQUIP_ERR_OK) - { - _player->SendEquipError(msg, pItem, NULL); - return; - } - - _player->RemoveItem(srcbag, srcslot, true); - _player->BankItem(dest, pItem, true); - } -} - void WorldSession::SendEnchantmentLog(ObjectGuid target, ObjectGuid caster, uint32 itemId, uint32 enchantId) { WorldPacket data(SMSG_ENCHANTMENT_LOG, (8+8+4+4)); diff --git a/src/server/game/Handlers/LFGHandler.cpp b/src/server/game/Handlers/LFGHandler.cpp index bf1e808d5d0..b291ffb0c9e 100644 --- a/src/server/game/Handlers/LFGHandler.cpp +++ b/src/server/game/Handlers/LFGHandler.cpp @@ -72,7 +72,7 @@ void BuildQuestReward(WorldPacket& data, Quest const* quest, Player* player) { if (uint32 itemId = quest->RewardItemId[i]) { - ItemTemplate const* item = sObjectMgr->GetItemTemplate(itemId); + //ItemTemplate const* item = sObjectMgr->GetItemTemplate(itemId); data << uint32(itemId); data << uint32(/*item ? item->DisplayInfoID :*/ 0); data << uint32(quest->RewardItemCount[i]); diff --git a/src/server/game/Handlers/MiscHandler.cpp b/src/server/game/Handlers/MiscHandler.cpp index 33b9d8fe461..6d813f88cdc 100644 --- a/src/server/game/Handlers/MiscHandler.cpp +++ b/src/server/game/Handlers/MiscHandler.cpp @@ -63,7 +63,7 @@ #include "AchievementPackets.h" #include "WhoPackets.h" -void WorldSession::HandleRepopRequest(WorldPackets::Misc::RepopRequest& packet) +void WorldSession::HandleRepopRequest(WorldPackets::Misc::RepopRequest& /*packet*/) { TC_LOG_DEBUG("network", "WORLD: Recvd CMSG_REPOP_REQUEST Message"); @@ -545,7 +545,7 @@ void WorldSession::HandleBugReportOpcode(WorldPacket& recvData) CharacterDatabase.Execute(stmt); } -void WorldSession::HandleReclaimCorpse(WorldPackets::Misc::ReclaimCorpse& packet) +void WorldSession::HandleReclaimCorpse(WorldPackets::Misc::ReclaimCorpse& /*packet*/) { TC_LOG_DEBUG("network", "WORLD: Received CMSG_RECLAIM_CORPSE"); diff --git a/src/server/game/Handlers/MovementHandler.cpp b/src/server/game/Handlers/MovementHandler.cpp index c47fe33e3b2..c703e02a95c 100644 --- a/src/server/game/Handlers/MovementHandler.cpp +++ b/src/server/game/Handlers/MovementHandler.cpp @@ -369,8 +369,6 @@ void WorldSession::HandleMovementOpcodes(WorldPackets::Movement::ClientPlayerMov plrMover->UpdateFallInformationIfNeed(movementInfo, opcode); - AreaTableEntry const* zone = GetAreaEntryByAreaID(plrMover->GetAreaId()); - if (movementInfo.pos.GetPositionZ() < MAX_MAP_DEPTH) { if (!(plrMover->GetBattleground() && plrMover->GetBattleground()->HandlePlayerUnderMap(_player))) @@ -392,22 +390,16 @@ void WorldSession::HandleMovementOpcodes(WorldPackets::Movement::ClientPlayerMov } } -void WorldSession::HandleForceSpeedChangeAck(WorldPacket &recvData) +void WorldSession::HandleForceSpeedChangeAck(WorldPackets::Movement::MovementSpeedAck& packet) { - /* extract packet */ - MovementInfo movementInfo; - static MovementStatusElements const speedElement = MSEExtraFloat; - Movement::ExtraMovementStatusElement extras(&speedElement); - GetPlayer()->ReadMovementInfo(recvData, &movementInfo, &extras); + OpcodeClient opcode = packet.GetOpcode(); // now can skip not our packet - if (_player->GetGUID() != movementInfo.guid) + if (_player->GetGUID() != packet.movementInfo.guid) { - recvData.rfinish(); // prevent warnings spam return; } - float newspeed = extras.Data.floatData; /*----------------*/ // client ACK send one packet for mounted/run case and need skip all except last from its @@ -427,21 +419,21 @@ void WorldSession::HandleForceSpeedChangeAck(WorldPacket &recvData) "PitchRate" }; - switch (recvData.GetOpcode()) + switch (opcode) { - /* + case CMSG_MOVE_FORCE_WALK_SPEED_CHANGE_ACK: move_type = MOVE_WALK; break; case CMSG_MOVE_FORCE_RUN_SPEED_CHANGE_ACK: move_type = MOVE_RUN; break; case CMSG_MOVE_FORCE_RUN_BACK_SPEED_CHANGE_ACK: move_type = MOVE_RUN_BACK; break; case CMSG_MOVE_FORCE_SWIM_SPEED_CHANGE_ACK: move_type = MOVE_SWIM; break; - case CMSG_MOVE_FORCE_SWIM_BACK_SPEED_CHANGE_ACK: move_type = MOVE_SWIM_BACK; break; - case CMSG_MOVE_FORCE_TURN_RATE_CHANGE_ACK: move_type = MOVE_TURN_RATE; break; + //case CMSG_MOVE_FORCE_SWIM_BACK_SPEED_CHANGE_ACK: move_type = MOVE_SWIM_BACK; break; + //case CMSG_MOVE_FORCE_TURN_RATE_CHANGE_ACK: move_type = MOVE_TURN_RATE; break; case CMSG_MOVE_FORCE_FLIGHT_SPEED_CHANGE_ACK: move_type = MOVE_FLIGHT; break; - case CMSG_MOVE_FORCE_FLIGHT_BACK_SPEED_CHANGE_ACK: move_type = MOVE_FLIGHT_BACK; break; - case CMSG_MOVE_FORCE_PITCH_RATE_CHANGE_ACK: move_type = MOVE_PITCH_RATE; break; - */ + //case CMSG_MOVE_FORCE_FLIGHT_BACK_SPEED_CHANGE_ACK: move_type = MOVE_FLIGHT_BACK; break; + //case CMSG_MOVE_FORCE_PITCH_RATE_CHANGE_ACK: move_type = MOVE_PITCH_RATE; break; + default: - TC_LOG_ERROR("network", "WorldSession::HandleForceSpeedChangeAck: Unknown move type opcode: %u", recvData.GetOpcode()); + TC_LOG_ERROR("network", "WorldSession::HandleForceSpeedChangeAck: Unknown move type opcode: %u", opcode); return; } @@ -454,50 +446,30 @@ void WorldSession::HandleForceSpeedChangeAck(WorldPacket &recvData) return; } - if (!_player->GetTransport() && std::fabs(_player->GetSpeed(move_type) - newspeed) > 0.01f) + if (!_player->GetTransport() && std::fabs(_player->GetSpeed(move_type) - packet.Speed) > 0.01f) { - if (_player->GetSpeed(move_type) > newspeed) // must be greater - just correct + if (_player->GetSpeed(move_type) > packet.Speed) // must be greater - just correct { TC_LOG_ERROR("network", "%sSpeedChange player %s is NOT correct (must be %f instead %f), force set to correct value", - move_type_name[move_type], _player->GetName().c_str(), _player->GetSpeed(move_type), newspeed); + move_type_name[move_type], _player->GetName().c_str(), _player->GetSpeed(move_type), packet.Speed); _player->SetSpeed(move_type, _player->GetSpeedRate(move_type), true); } else // must be lesser - cheating { TC_LOG_DEBUG("misc", "Player %s from account id %u kicked for incorrect speed (must be %f instead %f)", - _player->GetName().c_str(), _player->GetSession()->GetAccountId(), _player->GetSpeed(move_type), newspeed); + _player->GetName().c_str(), _player->GetSession()->GetAccountId(), _player->GetSpeed(move_type), packet.Speed); _player->GetSession()->KickPlayer(); } } } -void WorldSession::HandleSetActiveMoverOpcode(WorldPacket& recvPacket) +void WorldSession::HandleSetActiveMoverOpcode(WorldPackets::Movement::SetActiveMover& packet) { TC_LOG_DEBUG("network", "WORLD: Recvd CMSG_SET_ACTIVE_MOVER"); - ObjectGuid guid; - - guid[7] = recvPacket.ReadBit(); - guid[2] = recvPacket.ReadBit(); - guid[1] = recvPacket.ReadBit(); - guid[0] = recvPacket.ReadBit(); - guid[4] = recvPacket.ReadBit(); - guid[5] = recvPacket.ReadBit(); - guid[6] = recvPacket.ReadBit(); - guid[3] = recvPacket.ReadBit(); - - recvPacket.ReadByteSeq(guid[3]); - recvPacket.ReadByteSeq(guid[2]); - recvPacket.ReadByteSeq(guid[4]); - recvPacket.ReadByteSeq(guid[0]); - recvPacket.ReadByteSeq(guid[5]); - recvPacket.ReadByteSeq(guid[1]); - recvPacket.ReadByteSeq(guid[6]); - recvPacket.ReadByteSeq(guid[7]); - if (GetPlayer()->IsInWorld()) - if (_player->m_mover->GetGUID() != guid) - TC_LOG_DEBUG("network", "HandleSetActiveMoverOpcode: incorrect mover guid: mover is %s and should be %s" , guid.ToString().c_str(), _player->m_mover->GetGUID().ToString().c_str()); + if (_player->m_mover->GetGUID() != packet.ActiveMover) + TC_LOG_DEBUG("network", "HandleSetActiveMoverOpcode: incorrect mover guid: mover is %s and should be %s" , packet.ActiveMover.ToString().c_str(), _player->m_mover->GetGUID().ToString().c_str()); } void WorldSession::HandleMoveNotActiveMover(WorldPacket &recvData) diff --git a/src/server/game/Handlers/NPCHandler.cpp b/src/server/game/Handlers/NPCHandler.cpp index 80a2284aa7d..999b71d69a3 100644 --- a/src/server/game/Handlers/NPCHandler.cpp +++ b/src/server/game/Handlers/NPCHandler.cpp @@ -73,31 +73,6 @@ void WorldSession::SendTabardVendorActivate(ObjectGuid guid) SendPacket(packet.Write()); } -void WorldSession::HandleBankerActivateOpcode(WorldPackets::NPC::Hello& packet) -{ - TC_LOG_DEBUG("network", "WORLD: Received CMSG_BANKER_ACTIVATE"); - - Creature* unit = GetPlayer()->GetNPCIfCanInteractWith(packet.Unit, UNIT_NPC_FLAG_BANKER); - if (!unit) - { - TC_LOG_DEBUG("network", "WORLD: HandleBankerActivateOpcode - %s not found or you can not interact with him.", packet.Unit.ToString().c_str()); - return; - } - - // remove fake death - if (GetPlayer()->HasUnitState(UNIT_STATE_DIED)) - GetPlayer()->RemoveAurasByType(SPELL_AURA_FEIGN_DEATH); - - SendShowBank(packet.Unit); -} - -void WorldSession::SendShowBank(ObjectGuid guid) -{ - WorldPackets::NPC::ShowBank packet; - packet.Guid = guid; - SendPacket(packet.Write()); -} - void WorldSession::SendShowMailBox(ObjectGuid guid) { WorldPacket data(SMSG_SHOW_MAILBOX, 8); @@ -145,10 +120,8 @@ void WorldSession::SendTrainerList(ObjectGuid guid, const std::string& strTitle) // reputation discount float fDiscountMod = _player->GetReputationPriceDiscount(unit); - bool can_learn_primary_prof = GetPlayer()->GetFreePrimaryProfessionPoints() > 0; - packet.Spells.resize(trainer_spells->spellList.size()); - uint32 count = 0; + packet.Spells.reserve(trainer_spells->spellList.size()); for (TrainerSpellMap::const_iterator itr = trainer_spells->spellList.begin(); itr != trainer_spells->spellList.end(); ++itr) { TrainerSpell const* tSpell = &itr->second; @@ -168,12 +141,13 @@ void WorldSession::SendTrainerList(ObjectGuid guid, const std::string& strTitle) if (learnedSpellInfo && learnedSpellInfo->IsPrimaryProfessionFirstRank()) primary_prof_first_rank = true; } + if (!valid) continue; TrainerSpellState state = _player->GetTrainerSpellState(tSpell); - WorldPackets::NPC::TrainerListSpell& spell = packet.Spells[count]; + WorldPackets::NPC::TrainerListSpell spell; spell.SpellID = tSpell->SpellID; spell.MoneyCost = floor(tSpell->MoneyCost * fDiscountMod); spell.ReqSkillLine = tSpell->ReqSkillLine; @@ -182,39 +156,34 @@ void WorldSession::SendTrainerList(ObjectGuid guid, const std::string& strTitle) spell.Usable = (state == TRAINER_SPELL_GREEN_DISABLED ? TRAINER_SPELL_GREEN : state); uint8 maxReq = 0; - /// @todo Update this when new spell system is ready - /*for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) + for (uint8 i = 0; i < MAX_TRAINERSPELL_ABILITY_REQS; ++i) { if (!tSpell->ReqAbility[i]) continue; + if (uint32 prevSpellId = sSpellMgr->GetPrevSpellInChain(tSpell->ReqAbility[i])) { spell.ReqAbility[maxReq] = prevSpellId; ++maxReq; } + if (maxReq == 2) break; + SpellsRequiringSpellMapBounds spellsRequired = sSpellMgr->GetSpellsRequiredForSpellBounds(tSpell->ReqAbility[i]); for (SpellsRequiringSpellMap::const_iterator itr2 = spellsRequired.first; itr2 != spellsRequired.second && maxReq < 3; ++itr2) { spell.ReqAbility[maxReq] = itr2->second; ++maxReq; } + if (maxReq == 2) break; - }*/ - while (maxReq < MAX_TRAINERSPELL_ABILITY_REQS) - { - spell.ReqAbility[maxReq] = 0; - ++maxReq; } - ++count; + packet.Spells.push_back(spell); } - // Shrink to actual data size - packet.Spells.resize(count); - SendPacket(packet.Write()); } diff --git a/src/server/game/Handlers/PetHandler.cpp b/src/server/game/Handlers/PetHandler.cpp index 280055f8337..c7e98e75dfa 100644 --- a/src/server/game/Handlers/PetHandler.cpp +++ b/src/server/game/Handlers/PetHandler.cpp @@ -33,6 +33,7 @@ #include "SpellHistory.h" #include "SpellInfo.h" #include "Player.h" +#include "SpellPackets.h" void WorldSession::HandleDismissCritter(WorldPacket& recvData) { @@ -751,54 +752,41 @@ void WorldSession::HandlePetSpellAutocastOpcode(WorldPacket& recvPacket) charmInfo->SetSpellAutocast(spellInfo, state != 0); } -void WorldSession::HandlePetCastSpellOpcode(WorldPackets::Spells::PetCastSpell& castRequest) +void WorldSession::HandlePetCastSpellOpcode(WorldPackets::Spells::PetCastSpell& petCastSpell) { - TC_LOG_DEBUG("network", "WORLD: Received CMSG_PET_CAST_SPELL"); - /* - ObjectGuid guid; - uint8 castCount; - uint32 spellId; - uint8 castFlags; - - recvPacket >> guid >> castCount >> spellId >> castFlags; - - TC_LOG_DEBUG("network", "WORLD: CMSG_PET_CAST_SPELL, %s, castCount: %u, spellId %u, castFlags %u", guid.ToString().c_str(), castCount, spellId, castFlags); + SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(petCastSpell.Cast.SpellID); + if (!spellInfo) + { + TC_LOG_ERROR("network", "WORLD: unknown PET spell id %i", petCastSpell.Cast.SpellID); + 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, guid); + Unit* caster = ObjectAccessor::GetUnit(*_player, petCastSpell.PetGUID); if (!caster || (caster != _player->GetGuardianPet() && caster != _player->GetCharm())) { - TC_LOG_ERROR("network", "HandlePetCastSpellOpcode: %s isn't pet of player %s (%s).", guid.ToString().c_str(), GetPlayer()->GetName().c_str(), GetPlayer()->GetGUID().ToString().c_str()); - return; - } - - SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId); - if (!spellInfo) - { - TC_LOG_ERROR("network", "WORLD: unknown PET spell id %i", spellId); + 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()); return; } // do not cast not learned spells - if (!caster->HasSpell(spellId) || spellInfo->IsPassive()) + if (!caster->HasSpell(spellInfo->Id) || spellInfo->IsPassive()) return; - SpellCastTargets targets; - targets.Read(recvPacket, caster); - HandleClientCastFlags(recvPacket, castFlags, targets); + SpellCastTargets targets(caster, petCastSpell.Cast); caster->ClearUnitState(UNIT_STATE_FOLLOW); Spell* spell = new Spell(caster, spellInfo, TRIGGERED_NONE); - spell->m_cast_count = castCount; // probably pending spell cast + spell->m_cast_count = petCastSpell.Cast.CastID; + spell->m_misc.Data = petCastSpell.Cast.Misc; spell->m_targets = targets; SpellCastResult result = spell->CheckPetCast(NULL); - if (result == SPELL_CAST_OK) { if (Creature* creature = caster->ToCreature()) @@ -810,22 +798,22 @@ void WorldSession::HandlePetCastSpellOpcode(WorldPackets::Spells::PetCastSpell& if (pet->getPetType() == SUMMON_PET && (urand(0, 100) < 10)) pet->SendPetTalk(PET_TALK_SPECIAL_SPELL); else - pet->SendPetAIReaction(guid); + pet->SendPetAIReaction(petCastSpell.PetGUID); } } - spell->prepare(&(spell->m_targets)); + spell->prepare(&targets); } else { spell->SendPetCastResult(result); - if (!caster->GetSpellHistory()->HasCooldown(spellId)) - caster->GetSpellHistory()->ResetCooldown(spellId, true); + if (!caster->GetSpellHistory()->HasCooldown(spellInfo->Id)) + caster->GetSpellHistory()->ResetCooldown(spellInfo->Id, true); spell->finish(false); delete spell; - }*/ + } } void WorldSession::SendPetNameInvalid(uint32 error, const std::string& name, DeclinedName *declinedName) @@ -840,15 +828,3 @@ void WorldSession::SendPetNameInvalid(uint32 error, const std::string& name, Dec SendPacket(&data); } - -void WorldSession::HandlePetLearnTalent(WorldPacket& recvData) -{ - /* TODO: 6.x remove pet talents (add pet specializations) - - ObjectGuid guid; - uint32 talentId, requestedRank; - recvData >> guid >> talentId >> requestedRank; - - _player->LearnPetTalent(guid, talentId, requestedRank); - _player->SendTalentsInfoData(true);*/ -} diff --git a/src/server/game/Handlers/PetitionsHandler.cpp b/src/server/game/Handlers/PetitionsHandler.cpp index 6dd8d95bbf6..97935d5837e 100644 --- a/src/server/game/Handlers/PetitionsHandler.cpp +++ b/src/server/game/Handlers/PetitionsHandler.cpp @@ -241,7 +241,6 @@ void WorldSession::HandlePetitionRenameGuild(WorldPackets::Petition::PetitionRen TC_LOG_DEBUG("network", "Received CMSG_PETITION_RENAME_GUILD"); TC_LOG_DEBUG("network", "Received opcode CMSG_PETITION_RENAME_GUILD"); - uint8 type = 0; Item* item = _player->GetItemByGuid(packet.PetitionGuid); if (!item) return; @@ -292,7 +291,7 @@ void WorldSession::HandleSignPetition(WorldPackets::Petition::SignPetition& pack Field* fields = result->Fetch(); ObjectGuid ownerGuid = ObjectGuid::Create<HighGuid::Player>(fields[0].GetUInt64()); - uint64 signs = fields[1].GetUInt64(); + //uint64 signs = fields[1].GetUInt64(); if (ownerGuid == _player->GetGUID()) return; diff --git a/src/server/game/Handlers/QuestHandler.cpp b/src/server/game/Handlers/QuestHandler.cpp index 56126fb9250..df5fae683fe 100644 --- a/src/server/game/Handlers/QuestHandler.cpp +++ b/src/server/game/Handlers/QuestHandler.cpp @@ -619,7 +619,7 @@ void WorldSession::HandleQuestgiverStatusMultipleQuery(WorldPackets::Quest::Ques WorldPackets::Quest::QuestGiverStatusMultiple response; - for (GuidSet::const_iterator itr = _player->m_clientGUIDs.begin(); itr != _player->m_clientGUIDs.end(); ++itr) + for (auto itr = _player->m_clientGUIDs.begin(); itr != _player->m_clientGUIDs.end(); ++itr) { if (itr->IsAnyTypeCreature()) { diff --git a/src/server/game/Handlers/SpellHandler.cpp b/src/server/game/Handlers/SpellHandler.cpp index 0553d99dd8f..1cbfd7057b7 100644 --- a/src/server/game/Handlers/SpellHandler.cpp +++ b/src/server/game/Handlers/SpellHandler.cpp @@ -129,42 +129,35 @@ void WorldSession::HandleUseItemOpcode(WorldPackets::Spells::UseItem& packet) } } -void WorldSession::HandleOpenItemOpcode(WorldPacket& recvPacket) +void WorldSession::HandleOpenItemOpcode(WorldPackets::Spells::OpenItem& packet) { - TC_LOG_DEBUG("network", "WORLD: CMSG_OPEN_ITEM packet, data length = %i", (uint32)recvPacket.size()); - - Player* pUser = _player; + Player* player = _player; // ignore for remote control state - if (pUser->m_mover != pUser) + if (player->m_mover != player) return; + TC_LOG_INFO("network", "bagIndex: %u, slot: %u", packet.Slot, packet.PackSlot); - uint8 bagIndex, slot; - - recvPacket >> bagIndex >> slot; - - TC_LOG_INFO("network", "bagIndex: %u, slot: %u", bagIndex, slot); - - Item* item = pUser->GetItemByPos(bagIndex, slot); + Item* item = player->GetItemByPos(packet.Slot, packet.PackSlot); if (!item) { - pUser->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, NULL, NULL); + player->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, NULL, NULL); return; } ItemTemplate const* proto = item->GetTemplate(); if (!proto) { - pUser->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, item, NULL); + player->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, item, NULL); return; } // Verify that the bag is an actual bag or wrapped item that can be used "normally" if (!(proto->GetFlags() & ITEM_PROTO_FLAG_OPENABLE) && !item->HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAG_WRAPPED)) { - pUser->SendEquipError(EQUIP_ERR_CLIENT_LOCKED_OUT, item, NULL); + player->SendEquipError(EQUIP_ERR_CLIENT_LOCKED_OUT, item, NULL); TC_LOG_ERROR("network", "Possible hacking attempt: Player %s [%s] tried to open item [%s, entry: %u] which is not openable!", - pUser->GetName().c_str(), pUser->GetGUID().ToString().c_str(), item->GetGUID().ToString().c_str(), proto->GetId()); + player->GetName().c_str(), player->GetGUID().ToString().c_str(), item->GetGUID().ToString().c_str(), proto->GetId()); return; } @@ -176,7 +169,7 @@ void WorldSession::HandleOpenItemOpcode(WorldPacket& recvPacket) if (!lockInfo) { - pUser->SendEquipError(EQUIP_ERR_ITEM_LOCKED, item, NULL); + player->SendEquipError(EQUIP_ERR_ITEM_LOCKED, item, NULL); TC_LOG_ERROR("network", "WORLD::OpenItem: item [%s] has an unknown lockId: %u!", item->GetGUID().ToString().c_str(), lockId); return; } @@ -184,7 +177,7 @@ void WorldSession::HandleOpenItemOpcode(WorldPacket& recvPacket) // was not unlocked yet if (item->IsLocked()) { - pUser->SendEquipError(EQUIP_ERR_ITEM_LOCKED, item, NULL); + player->SendEquipError(EQUIP_ERR_ITEM_LOCKED, item, NULL); return; } } @@ -206,12 +199,12 @@ void WorldSession::HandleOpenItemOpcode(WorldPacket& recvPacket) item->SetGuidValue(ITEM_FIELD_GIFTCREATOR, ObjectGuid::Empty); item->SetEntry(entry); item->SetUInt32Value(ITEM_FIELD_FLAGS, flags); - item->SetState(ITEM_CHANGED, pUser); + item->SetState(ITEM_CHANGED, player); } else { TC_LOG_ERROR("network", "Wrapped item %s don't have record in character_gifts table and will deleted", item->GetGUID().ToString().c_str()); - pUser->DestroyItem(item->GetBagSlot(), item->GetSlot(), true); + player->DestroyItem(item->GetBagSlot(), item->GetSlot(), true); return; } @@ -222,7 +215,7 @@ void WorldSession::HandleOpenItemOpcode(WorldPacket& recvPacket) CharacterDatabase.Execute(stmt); } else - pUser->SendLoot(item->GetGUID(), LOOT_CORPSE); + player->SendLoot(item->GetGUID(), LOOT_CORPSE); } void WorldSession::HandleGameObjectUseOpcode(WorldPackets::GameObject::GameObjectUse& packet) @@ -344,7 +337,7 @@ void WorldSession::HandleCancelAuraOpcode(WorldPackets::Spells::CancelAura& canc if (spellInfo->IsChanneled()) { if (Spell* curSpell = _player->GetCurrentSpell(CURRENT_CHANNELED_SPELL)) - if (curSpell->GetSpellInfo()->Id == cancelAura.SpellID) + if (curSpell->GetSpellInfo()->Id == uint32(cancelAura.SpellID)) _player->InterruptSpell(CURRENT_CHANNELED_SPELL); return; } diff --git a/src/server/game/Instances/InstanceScript.cpp b/src/server/game/Instances/InstanceScript.cpp index 904da4c0d3c..280d95f6f76 100644 --- a/src/server/game/Instances/InstanceScript.cpp +++ b/src/server/game/Instances/InstanceScript.cpp @@ -191,6 +191,12 @@ void InstanceScript::UpdateDoorState(GameObject* door) door->SetGoState(open ? GO_STATE_ACTIVE : GO_STATE_READY); } +BossInfo* InstanceScript::GetBossInfo(uint32 id) +{ + ASSERT(id < bosses.size()); + return &bosses[id]; +} + void InstanceScript::AddObject(Creature* obj, bool add) { ObjectInfoMap::const_iterator j = _creatureInfo.find(obj->GetEntry()); diff --git a/src/server/game/Instances/InstanceScript.h b/src/server/game/Instances/InstanceScript.h index acd511a402b..8c34e37976c 100644 --- a/src/server/game/Instances/InstanceScript.h +++ b/src/server/game/Instances/InstanceScript.h @@ -261,12 +261,16 @@ class InstanceScript : public ZoneScript void AddObject(GameObject* obj, bool add); void AddObject(WorldObject* obj, uint32 type, bool add); - void AddDoor(GameObject* door, bool add); + virtual void AddDoor(GameObject* door, bool add); void AddMinion(Creature* minion, bool add); - void UpdateDoorState(GameObject* door); + virtual void UpdateDoorState(GameObject* door); void UpdateMinionState(Creature* minion, EncounterState state); + // Exposes private data that should never be modified unless exceptional cases. + // Pay very much attention at how the returned BossInfo data is modified to avoid issues. + BossInfo* GetBossInfo(uint32 id); + // Instance Load and Save bool ReadSaveDataHeaders(std::istringstream& data); void ReadSaveDataBossStates(std::istringstream& data); diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp index 0b106c0b391..d15b54b9b6c 100644 --- a/src/server/game/Maps/Map.cpp +++ b/src/server/game/Maps/Map.cpp @@ -136,9 +136,9 @@ void Map::LoadMMap(int gx, int gy) bool mmapLoadResult = MMAP::MMapFactory::createOrGetMMapManager()->loadMap((sWorld->GetDataPath() + "mmaps").c_str(), GetId(), gx, gy); if (mmapLoadResult) - TC_LOG_INFO("maps", "MMAP loaded name:%s, id:%d, x:%d, y:%d (mmap rep.: x:%d, y:%d)", GetMapName(), GetId(), gx, gy, gx, gy); + TC_LOG_DEBUG("maps", "MMAP loaded name:%s, id:%d, x:%d, y:%d (mmap rep.: x:%d, y:%d)", GetMapName(), GetId(), gx, gy, gx, gy); else - TC_LOG_INFO("maps", "Could not load MMAP name:%s, id:%d, x:%d, y:%d (mmap rep.: x:%d, y:%d)", GetMapName(), GetId(), gx, gy, gx, gy); + TC_LOG_ERROR("maps", "Could not load MMAP name:%s, id:%d, x:%d, y:%d (mmap rep.: x:%d, y:%d)", GetMapName(), GetId(), gx, gy, gx, gy); } void Map::LoadVMap(int gx, int gy) @@ -150,10 +150,10 @@ void Map::LoadVMap(int gx, int gy) switch (vmapLoadResult) { case VMAP::VMAP_LOAD_RESULT_OK: - TC_LOG_INFO("maps", "VMAP loaded name:%s, id:%d, x:%d, y:%d (vmap rep.: x:%d, y:%d)", GetMapName(), GetId(), gx, gy, gx, gy); + TC_LOG_DEBUG("maps", "VMAP loaded name:%s, id:%d, x:%d, y:%d (vmap rep.: x:%d, y:%d)", GetMapName(), GetId(), gx, gy, gx, gy); break; case VMAP::VMAP_LOAD_RESULT_ERROR: - TC_LOG_INFO("maps", "Could not load VMAP name:%s, id:%d, x:%d, y:%d (vmap rep.: x:%d, y:%d)", GetMapName(), GetId(), gx, gy, gx, gy); + TC_LOG_ERROR("maps", "Could not load VMAP name:%s, id:%d, x:%d, y:%d (vmap rep.: x:%d, y:%d)", GetMapName(), GetId(), gx, gy, gx, gy); break; case VMAP::VMAP_LOAD_RESULT_IGNORED: TC_LOG_DEBUG("maps", "Ignored VMAP name:%s, id:%d, x:%d, y:%d (vmap rep.: x:%d, y:%d)", GetMapName(), GetId(), gx, gy, gx, gy); @@ -183,7 +183,7 @@ void Map::LoadMap(int gx, int gy, bool reload) //map already load, delete it before reloading (Is it necessary? Do we really need the ability the reload maps during runtime?) if (GridMaps[gx][gy]) { - TC_LOG_INFO("maps", "Unloading previously loaded map %u before reloading.", GetId()); + TC_LOG_DEBUG("maps", "Unloading previously loaded map %u before reloading.", GetId()); sScriptMgr->OnUnloadGridMap(this, GridMaps[gx][gy], gx, gy); delete (GridMaps[gx][gy]); @@ -195,7 +195,7 @@ void Map::LoadMap(int gx, int gy, bool reload) int len = sWorld->GetDataPath().length() + strlen("maps/%03u%02u%02u.map") + 1; tmp = new char[len]; snprintf(tmp, len, (char *)(sWorld->GetDataPath() + "maps/%03u%02u%02u.map").c_str(), GetId(), gx, gy); - TC_LOG_INFO("maps", "Loading map %s", tmp); + TC_LOG_DEBUG("maps", "Loading map %s", tmp); // loading data GridMaps[gx][gy] = new GridMap(); if (!GridMaps[gx][gy]->loadData(tmp)) @@ -2511,7 +2511,7 @@ void Map::UpdateObjectsVisibilityFor(Player* player, Cell cell, CellCoord cellpa void Map::SendInitSelf(Player* player) { - TC_LOG_INFO("maps", "Creating player data for himself %s", player->GetGUID().ToString().c_str()); + TC_LOG_DEBUG("maps", "Creating player data for himself %s", player->GetGUID().ToString().c_str()); UpdateData data(player->GetMapId()); @@ -2888,7 +2888,7 @@ bool InstanceMap::CanEnter(Player* player) uint32 maxPlayers = GetMaxPlayers(); if (GetPlayersCountExceptGMs() >= maxPlayers) { - TC_LOG_INFO("maps", "MAP: Instance '%u' of map '%s' cannot have more than '%u' players. Player '%s' rejected", GetInstanceId(), GetMapName(), maxPlayers, player->GetName().c_str()); + TC_LOG_WARN("maps", "MAP: Instance '%u' of map '%s' cannot have more than '%u' players. Player '%s' rejected", GetInstanceId(), GetMapName(), maxPlayers, player->GetName().c_str()); player->SendTransferAborted(GetId(), TRANSFER_ABORT_MAX_PLAYERS); return false; } @@ -2957,7 +2957,7 @@ bool InstanceMap::AddPlayerToMap(Player* player) InstanceSave* mapSave = sInstanceSaveMgr->GetInstanceSave(GetInstanceId()); if (!mapSave) { - TC_LOG_INFO("maps", "InstanceMap::Add: creating instance save for map %d spawnmode %d with instance id %d", GetId(), GetSpawnMode(), GetInstanceId()); + TC_LOG_DEBUG("maps", "InstanceMap::Add: creating instance save for map %d spawnmode %d with instance id %d", GetId(), GetSpawnMode(), GetInstanceId()); mapSave = sInstanceSaveMgr->AddInstanceSave(GetId(), GetInstanceId(), Difficulty(GetSpawnMode()), 0, true); } @@ -3034,7 +3034,7 @@ bool InstanceMap::AddPlayerToMap(Player* player) // first player enters (no players yet) SetResetSchedule(false); - TC_LOG_INFO("maps", "MAP: Player '%s' entered instance '%u' of map '%s'", player->GetName().c_str(), GetInstanceId(), GetMapName()); + TC_LOG_DEBUG("maps", "MAP: Player '%s' entered instance '%u' of map '%s'", player->GetName().c_str(), GetInstanceId(), GetMapName()); // initialize unload state m_unloadTimer = 0; m_resetAfterUnload = false; @@ -3060,7 +3060,7 @@ void InstanceMap::Update(const uint32 t_diff) void InstanceMap::RemovePlayerFromMap(Player* player, bool remove) { - TC_LOG_INFO("maps", "MAP: Removing player '%s' from instance '%u' of map '%s' before relocating to another map", player->GetName().c_str(), GetInstanceId(), GetMapName()); + TC_LOG_DEBUG("maps", "MAP: Removing player '%s' from instance '%u' of map '%s' before relocating to another map", player->GetName().c_str(), GetInstanceId(), GetMapName()); //if last player set unload timer if (!m_unloadTimer && m_mapRefManager.getSize() == 1) m_unloadTimer = m_unloadWhenEmpty ? MIN_UNLOAD_DELAY : std::max(sWorld->getIntConfig(CONFIG_INSTANCE_UNLOAD_DELAY), (uint32)MIN_UNLOAD_DELAY); @@ -3312,7 +3312,7 @@ bool BattlegroundMap::AddPlayerToMap(Player* player) void BattlegroundMap::RemovePlayerFromMap(Player* player, bool remove) { - TC_LOG_INFO("maps", "MAP: Removing player '%s' from bg '%u' of map '%s' before relocating to another map", player->GetName().c_str(), GetInstanceId(), GetMapName()); + TC_LOG_DEBUG("maps", "MAP: Removing player '%s' from bg '%u' of map '%s' before relocating to another map", player->GetName().c_str(), GetInstanceId(), GetMapName()); Map::RemovePlayerFromMap(player, remove); } diff --git a/src/server/game/Miscellaneous/Language.h b/src/server/game/Miscellaneous/Language.h index 446ee2606e1..0e89c3f7a0d 100644 --- a/src/server/game/Miscellaneous/Language.h +++ b/src/server/game/Miscellaneous/Language.h @@ -215,7 +215,9 @@ enum TrinityStrings LANG_PHASING_PHASEMASK = 182, LANG_PHASING_REPORT_STATUS = 183, LANG_PHASING_NO_DEFINITIONS = 184, // Phasing - // Room for more level 1 185-199 not used + + LANG_GRID_POSITION = 185, + // Room for more level 1 186-199 not used // level 2 chat LANG_NO_SELECTION = 200, diff --git a/src/server/game/Miscellaneous/SharedDefines.h b/src/server/game/Miscellaneous/SharedDefines.h index 5142eebbaa2..0f01ba2dfae 100644 --- a/src/server/game/Miscellaneous/SharedDefines.h +++ b/src/server/game/Miscellaneous/SharedDefines.h @@ -1252,7 +1252,13 @@ enum SpellEffectName SPELL_EFFECT_242 = 242, SPELL_EFFECT_243 = 243, SPELL_EFFECT_244 = 244, - TOTAL_SPELL_EFFECTS = 245, + SPELL_EFFECT_245 = 245, + SPELL_EFFECT_246 = 246, + SPELL_EFFECT_247 = 247, + SPELL_EFFECT_248 = 248, + SPELL_EFFECT_249 = 249, + SPELL_EFFECT_250 = 250, + TOTAL_SPELL_EFFECTS = 251, }; enum SpellCastResult // 19702 @@ -1984,6 +1990,26 @@ enum Targets TARGET_UNK_125 = 125, TARGET_UNK_126 = 126, TARGET_UNK_127 = 127, + TARGET_UNK_128 = 128, + TARGET_UNK_129 = 129, + TARGET_UNK_130 = 130, + TARGET_UNK_131 = 131, + TARGET_UNK_132 = 132, + TARGET_UNK_133 = 133, + TARGET_UNK_134 = 134, + TARGET_UNK_135 = 135, + TARGET_UNK_136 = 136, + TARGET_UNK_137 = 137, + TARGET_UNK_138 = 138, + TARGET_UNK_139 = 139, + TARGET_UNK_140 = 140, + TARGET_UNK_141 = 141, + TARGET_UNK_142 = 142, + TARGET_UNK_143 = 143, + TARGET_UNK_144 = 144, + TARGET_UNK_145 = 145, + TARGET_UNK_146 = 146, + TARGET_UNK_147 = 147, TOTAL_SPELL_TARGETS }; diff --git a/src/server/game/Movement/MotionMaster.cpp b/src/server/game/Movement/MotionMaster.cpp index 7eb38f3e637..5177bf5c9de 100644 --- a/src/server/game/Movement/MotionMaster.cpp +++ b/src/server/game/Movement/MotionMaster.cpp @@ -381,6 +381,43 @@ void MotionMaster::MoveJump(float x, float y, float z, float speedXY, float spee Mutate(new EffectMovementGenerator(id), MOTION_SLOT_CONTROLLED); } +void MotionMaster::MoveCirclePath(float x, float y, float z, float radius, bool clockwise, uint8 stepCount) +{ + float step = 2 * float(M_PI) / stepCount * (clockwise ? -1.0f : 1.0f); + Position const& pos = { x, y, z, 0.0f }; + float angle = pos.GetAngle(_owner->GetPositionX(), _owner->GetPositionY()); + + Movement::MoveSplineInit init(_owner); + + for (uint8 i = 0; i < stepCount; angle += step, ++i) + { + G3D::Vector3 point; + point.x = x + radius * cosf(angle); + point.y = y + radius * sinf(angle); + + if (_owner->IsFlying()) + point.z = z; + else + point.z = _owner->GetMap()->GetHeight(_owner->GetPhaseMask(), point.x, point.y, z); + + init.Path().push_back(point); + } + + if (_owner->IsFlying()) + { + init.SetFly(); + init.SetCyclic(); + init.SetAnimation(Movement::ToFly); + } + else + { + init.SetWalk(true); + init.SetCyclic(); + } + + init.Launch(); +} + void MotionMaster::MoveFall(uint32 id /*=0*/) { // use larger distance for vmap height search than in most other cases diff --git a/src/server/game/Movement/MotionMaster.h b/src/server/game/Movement/MotionMaster.h index 2821cd5a59b..0b547d96e7f 100644 --- a/src/server/game/Movement/MotionMaster.h +++ b/src/server/game/Movement/MotionMaster.h @@ -184,6 +184,7 @@ class MotionMaster //: private std::stack<MovementGenerator *> void MoveJump(Position const& pos, float speedXY, float speedZ, uint32 id = EVENT_JUMP) { MoveJump(pos.m_positionX, pos.m_positionY, pos.m_positionZ, speedXY, speedZ, id); }; void MoveJump(float x, float y, float z, float speedXY, float speedZ, uint32 id = EVENT_JUMP); + void MoveCirclePath(float x, float y, float z, float radius, bool clockwise, uint8 stepCount); void MoveFall(uint32 id = 0); void MoveSeekAssistance(float x, float y, float z); diff --git a/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.cpp index 9c17a2277c0..0222087c168 100755 --- a/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.cpp @@ -382,9 +382,9 @@ void FlightPathMovementGenerator::PreloadEndGrid() // Load the grid if (endMap) { - TC_LOG_INFO("misc", "Preloading rid (%f, %f) for map %u at node index %u/%u", _endGridX, _endGridY, _endMapId, _preloadTargetNode, (uint32)(i_path->size()-1)); + TC_LOG_DEBUG("misc", "Preloading rid (%f, %f) for map %u at node index %u/%u", _endGridX, _endGridY, _endMapId, _preloadTargetNode, (uint32)(i_path->size()-1)); endMap->LoadGrid(_endGridX, _endGridY); } else - TC_LOG_INFO("misc", "Unable to determine map to preload flightmaster grid"); + TC_LOG_DEBUG("misc", "Unable to determine map to preload flightmaster grid"); } diff --git a/src/server/game/Quests/QuestDef.cpp b/src/server/game/Quests/QuestDef.cpp index cd5b79c95c3..da0830734e5 100644 --- a/src/server/game/Quests/QuestDef.cpp +++ b/src/server/game/Quests/QuestDef.cpp @@ -334,7 +334,7 @@ bool Quest::IsAllowedInRaid(Difficulty difficulty) const return sWorld->getBoolConfig(CONFIG_QUEST_IGNORE_RAID); } -uint32 Quest::CalculateHonorGain(uint8 level) const +uint32 Quest::CalculateHonorGain(uint8 /*level*/) const { uint32 honor = 0; diff --git a/src/server/game/Scripting/ScriptLoader.cpp b/src/server/game/Scripting/ScriptLoader.cpp index 603089b0a6b..553c752ccce 100644 --- a/src/server/game/Scripting/ScriptLoader.cpp +++ b/src/server/game/Scripting/ScriptLoader.cpp @@ -368,7 +368,6 @@ void AddSC_dustwallow_marsh(); void AddSC_felwood(); void AddSC_feralas(); void AddSC_moonglade(); -void AddSC_mulgore(); void AddSC_orgrimmar(); void AddSC_silithus(); void AddSC_stonetalon_mountains(); @@ -1090,7 +1089,6 @@ void AddKalimdorScripts() AddSC_felwood(); AddSC_feralas(); AddSC_moonglade(); - AddSC_mulgore(); AddSC_orgrimmar(); AddSC_silithus(); AddSC_stonetalon_mountains(); diff --git a/src/server/game/Server/Packets/BankPackets.cpp b/src/server/game/Server/Packets/BankPackets.cpp new file mode 100644 index 00000000000..0f6af30bed0 --- /dev/null +++ b/src/server/game/Server/Packets/BankPackets.cpp @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2008-2015 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 "BankPackets.h" +#include "ItemPackets.h" + +void WorldPackets::Bank::AutoBankItem::Read() +{ + _worldPacket >> Inv + >> Bag + >> Slot; +} + +void WorldPackets::Bank::AutoStoreBankItem::Read() +{ + _worldPacket >> Inv + >> Bag + >> Slot; +} + +void WorldPackets::Bank::BuyBankSlot::Read() +{ + _worldPacket >> Guid; +} diff --git a/src/server/game/Server/Packets/BankPackets.h b/src/server/game/Server/Packets/BankPackets.h new file mode 100644 index 00000000000..dc7883c3643 --- /dev/null +++ b/src/server/game/Server/Packets/BankPackets.h @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2008-2015 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 BankPackets_h__ +#define BankPackets_h__ + +#include "ItemPackets.h" +#include "Packet.h" +#include "ObjectGuid.h" +#include "WorldSession.h" + +namespace WorldPackets +{ + namespace Bank + { + class AutoBankItem final : public ClientPacket + { + public: + AutoBankItem(WorldPacket&& packet) : ClientPacket(CMSG_AUTOBANK_ITEM, std::move(packet)) { } + + void Read() override; + + WorldPackets::Item::InvUpdate Inv; + uint8 Bag = 0; + uint8 Slot = 0; + }; + + class AutoStoreBankItem final : public ClientPacket + { + public: + AutoStoreBankItem(WorldPacket&& packet) : ClientPacket(CMSG_AUTOSTORE_BANK_ITEM, std::move(packet)) { } + + void Read() override; + + WorldPackets::Item::InvUpdate Inv; + uint8 Bag = 0; + uint8 Slot = 0; + }; + + class BuyBankSlot final : public ClientPacket + { + public: + BuyBankSlot(WorldPacket&& packet) : ClientPacket(CMSG_BUY_BANK_SLOT, std::move(packet)) { } + + void Read() override; + + ObjectGuid Guid; + }; + } +} +#endif // BankPackets_h__ diff --git a/src/server/game/Server/Packets/GuildPackets.cpp b/src/server/game/Server/Packets/GuildPackets.cpp index ef0c01c5cb7..82b003fef23 100644 --- a/src/server/game/Server/Packets/GuildPackets.cpp +++ b/src/server/game/Server/Packets/GuildPackets.cpp @@ -509,6 +509,7 @@ WorldPacket const* WorldPackets::Guild::GuildPartyState::Write() ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Guild::GuildRewardItem const& rewardItem) { data << rewardItem.ItemID; + data << rewardItem.Unk4; data << uint32(rewardItem.AchievementsRequired.size()); data << rewardItem.RaceMask; data << rewardItem.MinGuildLevel; diff --git a/src/server/game/Server/Packets/GuildPackets.h b/src/server/game/Server/Packets/GuildPackets.h index 9d146587c46..ff59831612a 100644 --- a/src/server/game/Server/Packets/GuildPackets.h +++ b/src/server/game/Server/Packets/GuildPackets.h @@ -671,6 +671,7 @@ namespace WorldPackets struct GuildRewardItem { uint32 ItemID = 0; + uint32 Unk4 = 0; std::vector<uint32> AchievementsRequired; uint32 RaceMask = 0; int32 MinGuildLevel = 0; diff --git a/src/server/game/Server/Packets/ItemPackets.cpp b/src/server/game/Server/Packets/ItemPackets.cpp index e9a0c213aee..57620737190 100644 --- a/src/server/game/Server/Packets/ItemPackets.cpp +++ b/src/server/game/Server/Packets/ItemPackets.cpp @@ -208,7 +208,7 @@ WorldPacket const* WorldPackets::Item::InventoryChangeFailure::Write() _worldPacket << int8(BagResult); _worldPacket << Item[0]; _worldPacket << Item[1]; - _worldPacket << uint8(ContainerBSlot); // bag type subclass, used with EQUIP_ERR_EVENT_AUTOEQUIP_BIND_CONFIRM and EQUIP_ERR_ITEM_DOESNT_GO_INTO_BAG2 + _worldPacket << uint8(ContainerBSlot); // bag type subclass, used with EQUIP_ERR_EVENT_AUTOEQUIP_BIND_CONFIRM and EQUIP_ERR_WRONG_BAG_TYPE_2 switch (BagResult) { @@ -216,7 +216,16 @@ WorldPacket const* WorldPackets::Item::InventoryChangeFailure::Write() case EQUIP_ERR_PURCHASE_LEVEL_TOO_LOW: _worldPacket << int32(Level); break; - /// @todo: add more cases + case EQUIP_ERR_EVENT_AUTOEQUIP_BIND_CONFIRM: + _worldPacket << SrcContainer; + _worldPacket << int32(SrcSlot); + _worldPacket << DstContainer; + break; + case EQUIP_ERR_ITEM_MAX_LIMIT_CATEGORY_COUNT_EXCEEDED_IS: + case EQUIP_ERR_ITEM_MAX_LIMIT_CATEGORY_SOCKETED_EXCEEDED_IS: + case EQUIP_ERR_ITEM_MAX_LIMIT_CATEGORY_EQUIPPED_EXCEEDED_IS: + _worldPacket << int32(LimitCategory); + break; default: break; } diff --git a/src/server/game/Server/Packets/MailPackets.cpp b/src/server/game/Server/Packets/MailPackets.cpp index d558b4682c1..425feac5d9f 100644 --- a/src/server/game/Server/Packets/MailPackets.cpp +++ b/src/server/game/Server/Packets/MailPackets.cpp @@ -240,8 +240,6 @@ WorldPackets::Mail::MailQueryNextTimeResult::MailNextTimeEntry::MailNextTimeEntr { case MAIL_NORMAL: SenderGuid = ObjectGuid::Create<HighGuid::Player>(mail->sender); - SenderHint.NativeRealmAddress.Set(GetVirtualRealmAddress()); - SenderHint.VirtualRealmAddress.Set(GetVirtualRealmAddress()); break; case MAIL_AUCTION: case MAIL_CREATURE: @@ -264,8 +262,6 @@ WorldPacket const* WorldPackets::Mail::MailQueryNextTimeResult::Write() for (auto const& entry : Next) { _worldPacket << entry.SenderGuid; - _worldPacket << entry.SenderHint; - _worldPacket << float(entry.TimeLeft); _worldPacket << int32(entry.AltSenderID); _worldPacket << int8(entry.AltSenderType); diff --git a/src/server/game/Server/Packets/MailPackets.h b/src/server/game/Server/Packets/MailPackets.h index 281a48b7248..e79469a76d8 100644 --- a/src/server/game/Server/Packets/MailPackets.h +++ b/src/server/game/Server/Packets/MailPackets.h @@ -223,7 +223,6 @@ namespace WorldPackets MailNextTimeEntry(::Mail const* mail); ObjectGuid SenderGuid; - Query::PlayerGuidLookupHint SenderHint; float TimeLeft = 0.0f; int32 AltSenderID = 0; int8 AltSenderType = 0; diff --git a/src/server/game/Server/Packets/MovementPackets.cpp b/src/server/game/Server/Packets/MovementPackets.cpp index edac75346f8..836c00b70ca 100644 --- a/src/server/game/Server/Packets/MovementPackets.cpp +++ b/src/server/game/Server/Packets/MovementPackets.cpp @@ -595,3 +595,28 @@ void WorldPackets::Movement::MoveTeleportAck::Read() _worldPacket >> AckIndex; _worldPacket >> MoveTime; } + +void WorldPackets::Movement::MovementAck::Read() +{ + _worldPacket >> movementInfo; + _worldPacket >> AckIndex; +} + +void WorldPackets::Movement::MovementSpeedAck::Read() +{ + _worldPacket >> movementInfo; + _worldPacket >> AckIndex; + _worldPacket >> Speed; +} + +void WorldPackets::Movement::SetActiveMover::Read() +{ + _worldPacket >> ActiveMover; +} + +WorldPacket const* WorldPackets::Movement::MoveSetActiveMover::Write() +{ + _worldPacket << MoverGUID; + + return &_worldPacket; +} diff --git a/src/server/game/Server/Packets/MovementPackets.h b/src/server/game/Server/Packets/MovementPackets.h index 85156234477..0b57cdaddb0 100644 --- a/src/server/game/Server/Packets/MovementPackets.h +++ b/src/server/game/Server/Packets/MovementPackets.h @@ -285,6 +285,49 @@ namespace WorldPackets int32 AckIndex = 0; int32 MoveTime = 0; }; + + class MovementAck final : public ClientPacket + { + public: + MovementAck(WorldPacket&& packet) : ClientPacket(std::move(packet)) { } + + void Read() override; + + MovementInfo movementInfo; + int32 AckIndex = 0; + }; + + class MovementSpeedAck final : public ClientPacket + { + public: + MovementSpeedAck(WorldPacket&& packet) : ClientPacket(std::move(packet)) { } + + void Read() override; + + MovementInfo movementInfo; + int32 AckIndex = 0; + float Speed = 0.0f; + }; + + class SetActiveMover final : public ClientPacket + { + public: + SetActiveMover(WorldPacket&& packet) : ClientPacket(CMSG_SET_ACTIVE_MOVER, std::move(packet)) { } + + void Read() override; + + ObjectGuid ActiveMover; + }; + + class MoveSetActiveMover final : public ServerPacket + { + public: + MoveSetActiveMover() : ServerPacket(SMSG_MOVE_SET_ACTIVE_MOVER, 8) { } + + WorldPacket const* Write() override; + + ObjectGuid MoverGUID; + }; } ByteBuffer& operator<<(ByteBuffer& data, Movement::MonsterSplineFilterKey const& monsterSplineFilterKey); diff --git a/src/server/game/Server/Packets/NPCPackets.h b/src/server/game/Server/Packets/NPCPackets.h index b4c7a377187..849013fb5d8 100644 --- a/src/server/game/Server/Packets/NPCPackets.h +++ b/src/server/game/Server/Packets/NPCPackets.h @@ -59,7 +59,7 @@ namespace WorldPackets int32 QuestLevel = 0; bool Repeatable = false; std::string QuestTitle; - int32 QuestFlags[2]; + int32 QuestFlags[2] = { }; }; class GossipMessage final : public ServerPacket @@ -130,7 +130,7 @@ namespace WorldPackets int32 MoneyCost = 0; int32 ReqSkillLine = 0; int32 ReqSkillRank = 0; - int32 ReqAbility[MAX_TRAINERSPELL_ABILITY_REQS]; + int32 ReqAbility[MAX_TRAINERSPELL_ABILITY_REQS] = { }; uint8 Usable = 0; uint8 ReqLevel = 0; }; diff --git a/src/server/game/Server/Packets/SpellPackets.cpp b/src/server/game/Server/Packets/SpellPackets.cpp index fabecce0d34..4dfbd67f44f 100644 --- a/src/server/game/Server/Packets/SpellPackets.cpp +++ b/src/server/game/Server/Packets/SpellPackets.cpp @@ -500,9 +500,9 @@ WorldPacket const* WorldPackets::Spells::ClearCooldowns::Write() WorldPacket const* WorldPackets::Spells::ClearCooldown::Write() { - _worldPacket << CasterGUID; _worldPacket << uint32(SpellID); _worldPacket.WriteBit(ClearOnHold); + _worldPacket.WriteBit(Unk20); _worldPacket.FlushBits(); return &_worldPacket; @@ -626,3 +626,9 @@ void WorldPackets::Spells::CancelCast::Read() _worldPacket >> SpellID; _worldPacket >> CastID; } + +void WorldPackets::Spells::OpenItem::Read() +{ + _worldPacket >> Slot + >> PackSlot; +} diff --git a/src/server/game/Server/Packets/SpellPackets.h b/src/server/game/Server/Packets/SpellPackets.h index 634f4b40e7f..865e856aa6f 100644 --- a/src/server/game/Server/Packets/SpellPackets.h +++ b/src/server/game/Server/Packets/SpellPackets.h @@ -439,9 +439,9 @@ namespace WorldPackets WorldPacket const* Write() override; - ObjectGuid CasterGUID; int32 SpellID = 0; bool ClearOnHold = false; + bool Unk20 = false; }; class ModifyCooldown final : public ServerPacket @@ -588,6 +588,17 @@ namespace WorldPackets uint32 SpellID = 0; uint8 CastID = 0; }; + + class OpenItem final : public ClientPacket + { + public: + OpenItem(WorldPacket&& packet) : ClientPacket(CMSG_OPEN_ITEM, std::move(packet)) { } + + void Read() override; + + uint8 Slot = 0; + uint8 PackSlot = 0; + }; } } diff --git a/src/server/game/Server/Protocol/Opcodes.cpp b/src/server/game/Server/Protocol/Opcodes.cpp index 7a22c3384c2..26a35c0ff18 100644 --- a/src/server/game/Server/Protocol/Opcodes.cpp +++ b/src/server/game/Server/Protocol/Opcodes.cpp @@ -20,6 +20,7 @@ #include "WorldSession.h" #include "Packets/AchievementPackets.h" #include "Packets/AuctionHousePackets.h" +#include "Packets/BankPackets.h" #include "Packets/BlackMarketPackets.h" #include "Packets/CharacterPackets.h" #include "Packets/ChannelPackets.h" @@ -178,15 +179,15 @@ void OpcodeTable::Initialize() DEFINE_OPCODE_HANDLER_OLD(CMSG_AUCTION_SELL_ITEM, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleAuctionSellItem ); DEFINE_HANDLER(CMSG_AUTH_CONTINUED_SESSION, STATUS_NEVER, PROCESS_INPLACE, WorldPacket, &WorldSession::Handle_EarlyProccess); DEFINE_HANDLER(CMSG_AUTH_SESSION, STATUS_NEVER, PROCESS_INPLACE, WorldPacket, &WorldSession::Handle_EarlyProccess); - DEFINE_OPCODE_HANDLER_OLD(CMSG_AUTOBANK_ITEM, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleAutoBankItemOpcode ); + DEFINE_HANDLER(CMSG_AUTOBANK_ITEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Bank::AutoBankItem, &WorldSession::HandleAutoBankItemOpcode); DEFINE_OPCODE_HANDLER_OLD(CMSG_AUTOEQUIP_GROUND_ITEM, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); - DEFINE_HANDLER(CMSG_AUTOEQUIP_ITEM, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, WorldPackets::Item::AutoEquipItem, &WorldSession::HandleAutoEquipItemOpcode); + DEFINE_HANDLER(CMSG_AUTOEQUIP_ITEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Item::AutoEquipItem, &WorldSession::HandleAutoEquipItemOpcode); DEFINE_OPCODE_HANDLER_OLD(CMSG_AUTOEQUIP_ITEM_SLOT, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleAutoEquipItemSlotOpcode ); - DEFINE_HANDLER(CMSG_AUTOSTORE_BAG_ITEM, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, WorldPackets::Item::AutoStoreBagItem, &WorldSession::HandleAutoStoreBagItemOpcode); - DEFINE_OPCODE_HANDLER_OLD(CMSG_AUTOSTORE_BANK_ITEM, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleAutoStoreBankItemOpcode ); + DEFINE_HANDLER(CMSG_AUTOSTORE_BAG_ITEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Item::AutoStoreBagItem, &WorldSession::HandleAutoStoreBagItemOpcode); + DEFINE_HANDLER(CMSG_AUTOSTORE_BANK_ITEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Bank::AutoStoreBankItem, &WorldSession::HandleAutoStoreBankItemOpcode); DEFINE_OPCODE_HANDLER_OLD(CMSG_AUTOSTORE_GROUND_ITEM, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); - DEFINE_HANDLER(CMSG_AUTOSTORE_LOOT_ITEM, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, WorldPackets::Loot::AutoStoreLootItem, &WorldSession::HandleAutostoreLootItemOpcode); - DEFINE_HANDLER(CMSG_BANKER_ACTIVATE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, WorldPackets::NPC::Hello, &WorldSession::HandleBankerActivateOpcode); + DEFINE_HANDLER(CMSG_AUTOSTORE_LOOT_ITEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Loot::AutoStoreLootItem, &WorldSession::HandleAutostoreLootItemOpcode); + DEFINE_HANDLER(CMSG_BANKER_ACTIVATE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::NPC::Hello, &WorldSession::HandleBankerActivateOpcode); DEFINE_OPCODE_HANDLER_OLD(CMSG_BATTLEFIELD_JOIN, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); DEFINE_OPCODE_HANDLER_OLD(CMSG_BATTLEFIELD_LEAVE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::HandleBattlefieldLeaveOpcode ); DEFINE_OPCODE_HANDLER_OLD(CMSG_BATTLEFIELD_LIST, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleBattlefieldListOpcode ); @@ -228,7 +229,7 @@ void OpcodeTable::Initialize() DEFINE_OPCODE_HANDLER_OLD(CMSG_BUG_REPORT, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleBugReportOpcode ); DEFINE_OPCODE_HANDLER_OLD(CMSG_BUSY_TRADE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleBusyTradeOpcode ); DEFINE_HANDLER(CMSG_BUY_BACK_ITEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Item::BuyBackItem, &WorldSession::HandleBuybackItem); - DEFINE_OPCODE_HANDLER_OLD(CMSG_BUY_BANK_SLOT, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleBuyBankSlotOpcode ); + DEFINE_HANDLER(CMSG_BUY_BANK_SLOT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Bank::BuyBankSlot, &WorldSession::HandleBuyBankSlotOpcode); DEFINE_HANDLER(CMSG_BUY_ITEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Item::BuyItem, &WorldSession::HandleBuyItemOpcode); DEFINE_OPCODE_HANDLER_OLD(CMSG_CAGE_BATTLE_PET, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); DEFINE_OPCODE_HANDLER_OLD(CMSG_CALENDAR_ADD_EVENT, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleCalendarAddEvent ); @@ -322,7 +323,7 @@ void OpcodeTable::Initialize() DEFINE_OPCODE_HANDLER_OLD(CMSG_DANCE_QUERY, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); DEFINE_HANDLER(CMSG_DB_QUERY_BULK, STATUS_AUTHED, PROCESS_INPLACE, WorldPackets::Query::DBQueryBulk, &WorldSession::HandleDBQueryBulk); DEFINE_HANDLER(CMSG_DECLINE_GUILD_INVITES, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, WorldPackets::Guild::DeclineGuildInvites, &WorldSession::HandleDeclineGuildInvites); - DEFINE_HANDLER(CMSG_DECLINE_PETITION, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, WorldPackets::Petition::DeclinePetition, &WorldSession::HandleDeclinePetition); + DEFINE_HANDLER(CMSG_DECLINE_PETITION, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Petition::DeclinePetition, &WorldSession::HandleDeclinePetition); DEFINE_OPCODE_HANDLER_OLD(CMSG_DELETE_EQUIPMENT_SET, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleEquipmentSetDelete ); DEFINE_HANDLER(CMSG_DEL_FRIEND, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Social::DelFriend, &WorldSession::HandleDelFriendOpcode); DEFINE_HANDLER(CMSG_DEL_IGNORE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Social::DelIgnore, &WorldSession::HandleDelIgnoreOpcode); @@ -396,7 +397,7 @@ void OpcodeTable::Initialize() DEFINE_OPCODE_HANDLER_OLD(CMSG_GROUP_CANCEL, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); DEFINE_OPCODE_HANDLER_OLD(CMSG_GROUP_REQUEST_JOIN_UPDATES, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleGroupRequestJoinUpdates ); DEFINE_OPCODE_HANDLER_OLD(CMSG_GUILD_ADD_BATTLENET_FRIEND, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); - DEFINE_HANDLER(CMSG_GUILD_ADD_RANK, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, WorldPackets::Guild::GuildAddRank, &WorldSession::HandleGuildAddRank); + DEFINE_HANDLER(CMSG_GUILD_ADD_RANK, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Guild::GuildAddRank, &WorldSession::HandleGuildAddRank); DEFINE_HANDLER(CMSG_GUILD_ASSIGN_MEMBER_RANK, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, WorldPackets::Guild::GuildAssignMemberRank, &WorldSession::HandleGuildAssignRank); DEFINE_OPCODE_HANDLER_OLD(CMSG_GUILD_AUTO_DECLINE_INVITATION, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); DEFINE_HANDLER(CMSG_GUILD_BANK_ACTIVATE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Guild::GuildBankActivate, &WorldSession::HandleGuildBankActivate); @@ -410,10 +411,10 @@ void OpcodeTable::Initialize() DEFINE_HANDLER(CMSG_GUILD_BANK_TEXT_QUERY, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, WorldPackets::Guild::GuildBankTextQuery, &WorldSession::HandleGuildBankTextQuery); DEFINE_HANDLER(CMSG_GUILD_BANK_UPDATE_TAB, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, WorldPackets::Guild::GuildBankUpdateTab, &WorldSession::HandleGuildBankUpdateTab); DEFINE_HANDLER(CMSG_GUILD_BANK_WITHDRAW_MONEY, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, WorldPackets::Guild::GuildBankWithdrawMoney, &WorldSession::HandleGuildBankWithdrawMoney); - DEFINE_HANDLER(CMSG_GUILD_CHALLENGE_UPDATE_REQUEST, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, WorldPackets::Guild::GuildChallengeUpdateRequest, &WorldSession::HandleGuildChallengeUpdateRequest); + DEFINE_HANDLER(CMSG_GUILD_CHALLENGE_UPDATE_REQUEST, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Guild::GuildChallengeUpdateRequest, &WorldSession::HandleGuildChallengeUpdateRequest); DEFINE_OPCODE_HANDLER_OLD(CMSG_GUILD_CHANGE_NAME_REQUEST, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); DEFINE_HANDLER(CMSG_GUILD_DECLINE_INVITATION, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, WorldPackets::Guild::GuildDeclineInvitation, &WorldSession::HandleGuildDeclineInvitation); - DEFINE_HANDLER(CMSG_GUILD_DELETE_RANK, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, WorldPackets::Guild::GuildDeleteRank, &WorldSession::HandleGuildDeleteRank); + DEFINE_HANDLER(CMSG_GUILD_DELETE_RANK, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Guild::GuildDeleteRank, &WorldSession::HandleGuildDeleteRank); DEFINE_HANDLER(CMSG_GUILD_DEMOTE_MEMBER, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, WorldPackets::Guild::GuildDemoteMember, &WorldSession::HandleGuildDemoteMember); DEFINE_HANDLER(CMSG_GUILD_DELETE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, WorldPackets::Guild::GuildDelete, &WorldSession::HandleGuildDelete); DEFINE_HANDLER(CMSG_GUILD_EVENT_LOG_QUERY, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, WorldPackets::Guild::GuildEventLogQuery, &WorldSession::HandleGuildEventLogQuery); @@ -430,7 +431,7 @@ void OpcodeTable::Initialize() DEFINE_HANDLER(CMSG_GUILD_QUERY, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, WorldPackets::Guild::QueryGuildInfo, &WorldSession::HandleGuildQueryOpcode); DEFINE_OPCODE_HANDLER_OLD(CMSG_GUILD_QUERY_MEMBERS_FOR_RECIPE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); DEFINE_OPCODE_HANDLER_OLD(CMSG_GUILD_QUERY_MEMBER_RECIPES, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); - DEFINE_HANDLER(CMSG_GUILD_QUERY_NEWS, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Guild::GuildQueryNews, &WorldSession::HandleGuildQueryNews); + DEFINE_HANDLER(CMSG_GUILD_QUERY_NEWS, STATUS_LOGGEDIN, PROCESS_INPLACE, WorldPackets::Guild::GuildQueryNews, &WorldSession::HandleGuildQueryNews); DEFINE_OPCODE_HANDLER_OLD(CMSG_GUILD_QUERY_RECIPES, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); DEFINE_OPCODE_HANDLER_OLD(CMSG_GUILD_REPLACE_GUILD_MASTER, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); DEFINE_HANDLER(CMSG_GUILD_REQUEST_PARTY_STATE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Guild::RequestGuildPartyState, &WorldSession::HandleGuildRequestPartyState); @@ -488,7 +489,7 @@ void OpcodeTable::Initialize() DEFINE_OPCODE_HANDLER_OLD(CMSG_LF_GUILD_SET_GUILD_POST, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildFinderSetGuildPost ); DEFINE_HANDLER(CMSG_LIST_INVENTORY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::NPC::Hello, &WorldSession::HandleListInventoryOpcode); DEFINE_HANDLER(CMSG_LOAD_SCREEN, STATUS_AUTHED, PROCESS_THREADUNSAFE, WorldPackets::Character::LoadingScreenNotify, &WorldSession::HandleLoadScreenOpcode); - DEFINE_HANDLER(CMSG_LOGOUT_CANCEL, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, WorldPackets::Character::LogoutCancel, &WorldSession::HandleLogoutCancelOpcode); + DEFINE_HANDLER(CMSG_LOGOUT_CANCEL, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Character::LogoutCancel, &WorldSession::HandleLogoutCancelOpcode); DEFINE_OPCODE_HANDLER_OLD(CMSG_LOGOUT_INSTANT, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); DEFINE_HANDLER(CMSG_LOGOUT_REQUEST, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Character::LogoutRequest, &WorldSession::HandleLogoutRequestOpcode); DEFINE_HANDLER(CMSG_LOG_DISCONNECT, STATUS_NEVER, PROCESS_INPLACE, WorldPacket, &WorldSession::Handle_EarlyProccess); @@ -503,11 +504,11 @@ void OpcodeTable::Initialize() DEFINE_OPCODE_HANDLER_OLD(CMSG_LOW_LEVEL_RAID1, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); DEFINE_OPCODE_HANDLER_OLD(CMSG_LOW_LEVEL_RAID2, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); DEFINE_HANDLER(CMSG_MAIL_CREATE_TEXT_ITEM, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, WorldPackets::Mail::MailCreateTextItem, &WorldSession::HandleMailCreateTextItem); - DEFINE_HANDLER(CMSG_MAIL_DELETE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, WorldPackets::Mail::MailDelete, &WorldSession::HandleMailDelete); - DEFINE_HANDLER(CMSG_MAIL_MARK_AS_READ, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, WorldPackets::Mail::MailMarkAsRead, &WorldSession::HandleMailMarkAsRead); + DEFINE_HANDLER(CMSG_MAIL_DELETE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Mail::MailDelete, &WorldSession::HandleMailDelete); + DEFINE_HANDLER(CMSG_MAIL_MARK_AS_READ, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Mail::MailMarkAsRead, &WorldSession::HandleMailMarkAsRead); DEFINE_HANDLER(CMSG_MAIL_RETURN_TO_SENDER, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, WorldPackets::Mail::MailReturnToSender, &WorldSession::HandleMailReturnToSender); - DEFINE_HANDLER(CMSG_MAIL_TAKE_ITEM, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, WorldPackets::Mail::MailTakeItem, &WorldSession::HandleMailTakeItem); - DEFINE_HANDLER(CMSG_MAIL_TAKE_MONEY, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, WorldPackets::Mail::MailTakeMoney, &WorldSession::HandleMailTakeMoney); + DEFINE_HANDLER(CMSG_MAIL_TAKE_ITEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Mail::MailTakeItem, &WorldSession::HandleMailTakeItem); + 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_INPLACE, &WorldSession::Handle_NULL ); DEFINE_OPCODE_HANDLER_OLD(CMSG_MEETINGSTONE_INFO, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); DEFINE_OPCODE_HANDLER_OLD(CMSG_MESSAGECHAT_ADDON_CHANNEL, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); @@ -544,17 +545,17 @@ void OpcodeTable::Initialize() DEFINE_HANDLER(CMSG_MOVE_FALL_LAND, STATUS_LOGGEDIN, PROCESS_THREADSAFE, WorldPackets::Movement::ClientPlayerMovement, &WorldSession::HandleMovementOpcodes); DEFINE_HANDLER(CMSG_MOVE_FALL_RESET, STATUS_LOGGEDIN, PROCESS_THREADSAFE, WorldPackets::Movement::ClientPlayerMovement, &WorldSession::HandleMovementOpcodes); DEFINE_OPCODE_HANDLER_OLD(CMSG_MOVE_FEATHER_FALL_ACK, STATUS_UNHANDLED, PROCESS_THREADSAFE, &WorldSession::HandleFeatherFallAck ); - DEFINE_OPCODE_HANDLER_OLD(CMSG_MOVE_FORCE_FLIGHT_BACK_SPEED_CHANGE_ACK, STATUS_UNHANDLED, PROCESS_THREADSAFE, &WorldSession::HandleForceSpeedChangeAck ); - DEFINE_OPCODE_HANDLER_OLD(CMSG_MOVE_FORCE_FLIGHT_SPEED_CHANGE_ACK, STATUS_UNHANDLED, PROCESS_THREADSAFE, &WorldSession::HandleForceSpeedChangeAck ); - DEFINE_OPCODE_HANDLER_OLD(CMSG_MOVE_FORCE_PITCH_RATE_CHANGE_ACK, STATUS_UNHANDLED, PROCESS_THREADSAFE, &WorldSession::HandleForceSpeedChangeAck ); + DEFINE_HANDLER(CMSG_MOVE_FORCE_FLIGHT_BACK_SPEED_CHANGE_ACK, STATUS_UNHANDLED, PROCESS_THREADSAFE, WorldPackets::Movement::MovementSpeedAck, &WorldSession::HandleForceSpeedChangeAck); + DEFINE_HANDLER(CMSG_MOVE_FORCE_FLIGHT_SPEED_CHANGE_ACK, STATUS_LOGGEDIN, PROCESS_THREADSAFE, WorldPackets::Movement::MovementSpeedAck, &WorldSession::HandleForceSpeedChangeAck); + DEFINE_HANDLER(CMSG_MOVE_FORCE_PITCH_RATE_CHANGE_ACK, STATUS_UNHANDLED, PROCESS_THREADSAFE, WorldPackets::Movement::MovementSpeedAck, &WorldSession::HandleForceSpeedChangeAck); DEFINE_OPCODE_HANDLER_OLD(CMSG_MOVE_FORCE_ROOT_ACK, STATUS_UNHANDLED, PROCESS_THREADSAFE, &WorldSession::HandleMoveRootAck ); - DEFINE_OPCODE_HANDLER_OLD(CMSG_MOVE_FORCE_RUN_BACK_SPEED_CHANGE_ACK, STATUS_UNHANDLED, PROCESS_THREADSAFE, &WorldSession::HandleForceSpeedChangeAck ); - DEFINE_OPCODE_HANDLER_OLD(CMSG_MOVE_FORCE_RUN_SPEED_CHANGE_ACK, STATUS_UNHANDLED, PROCESS_THREADSAFE, &WorldSession::HandleForceSpeedChangeAck ); - DEFINE_OPCODE_HANDLER_OLD(CMSG_MOVE_FORCE_SWIM_BACK_SPEED_CHANGE_ACK, STATUS_UNHANDLED, PROCESS_THREADSAFE, &WorldSession::HandleForceSpeedChangeAck ); - DEFINE_OPCODE_HANDLER_OLD(CMSG_MOVE_FORCE_SWIM_SPEED_CHANGE_ACK, STATUS_UNHANDLED, PROCESS_THREADSAFE, &WorldSession::HandleForceSpeedChangeAck ); - DEFINE_OPCODE_HANDLER_OLD(CMSG_MOVE_FORCE_TURN_RATE_CHANGE_ACK, STATUS_UNHANDLED, PROCESS_THREADSAFE, &WorldSession::HandleForceSpeedChangeAck ); + DEFINE_HANDLER(CMSG_MOVE_FORCE_RUN_BACK_SPEED_CHANGE_ACK, STATUS_LOGGEDIN, PROCESS_THREADSAFE, WorldPackets::Movement::MovementSpeedAck, &WorldSession::HandleForceSpeedChangeAck); + DEFINE_HANDLER(CMSG_MOVE_FORCE_RUN_SPEED_CHANGE_ACK, STATUS_LOGGEDIN, PROCESS_THREADSAFE, WorldPackets::Movement::MovementSpeedAck, &WorldSession::HandleForceSpeedChangeAck); + DEFINE_HANDLER(CMSG_MOVE_FORCE_SWIM_BACK_SPEED_CHANGE_ACK, STATUS_UNHANDLED, PROCESS_THREADSAFE, WorldPackets::Movement::MovementSpeedAck, &WorldSession::HandleForceSpeedChangeAck); + DEFINE_HANDLER(CMSG_MOVE_FORCE_SWIM_SPEED_CHANGE_ACK, STATUS_LOGGEDIN, PROCESS_THREADSAFE, WorldPackets::Movement::MovementSpeedAck, &WorldSession::HandleForceSpeedChangeAck); + DEFINE_HANDLER(CMSG_MOVE_FORCE_TURN_RATE_CHANGE_ACK, STATUS_UNHANDLED, PROCESS_THREADSAFE, WorldPackets::Movement::MovementSpeedAck, &WorldSession::HandleForceSpeedChangeAck); DEFINE_OPCODE_HANDLER_OLD(CMSG_MOVE_FORCE_UNROOT_ACK, STATUS_UNHANDLED, PROCESS_THREADSAFE, &WorldSession::HandleMoveUnRootAck ); - DEFINE_OPCODE_HANDLER_OLD(CMSG_MOVE_FORCE_WALK_SPEED_CHANGE_ACK, STATUS_UNHANDLED, PROCESS_THREADSAFE, &WorldSession::HandleForceSpeedChangeAck ); + DEFINE_HANDLER(CMSG_MOVE_FORCE_WALK_SPEED_CHANGE_ACK, STATUS_LOGGEDIN, PROCESS_THREADSAFE, WorldPackets::Movement::MovementSpeedAck, &WorldSession::HandleForceSpeedChangeAck); DEFINE_OPCODE_HANDLER_OLD(CMSG_MOVE_GRAVITY_DISABLE_ACK, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); DEFINE_OPCODE_HANDLER_OLD(CMSG_MOVE_GRAVITY_ENABLE_ACK, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); DEFINE_HANDLER(CMSG_MOVE_HEARTBEAT, STATUS_LOGGEDIN, PROCESS_THREADSAFE, WorldPackets::Movement::ClientPlayerMovement, &WorldSession::HandleMovementOpcodes); @@ -600,7 +601,7 @@ void OpcodeTable::Initialize() DEFINE_OPCODE_HANDLER_OLD(CMSG_MOVE_TOGGLE_COLLISION_ACK, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); DEFINE_OPCODE_HANDLER_OLD(CMSG_MOVE_TOGGLE_COLLISION_CHEAT, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); DEFINE_OPCODE_HANDLER_OLD(CMSG_MOVE_WATER_WALK_ACK, STATUS_UNHANDLED, PROCESS_THREADSAFE, &WorldSession::HandleMoveWaterWalkAck ); - DEFINE_HANDLER(CMSG_MOVE_WORLDPORT_ACK, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Movement::WorldPortAck, &WorldSession::HandleMoveWorldportAckOpcode); + DEFINE_HANDLER(CMSG_MOVE_WORLDPORT_ACK, STATUS_TRANSFER, PROCESS_THREADUNSAFE, WorldPackets::Movement::WorldPortAck, &WorldSession::HandleMoveWorldportAckOpcode); DEFINE_HANDLER(CMSG_NAME_QUERY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Query::QueryPlayerName, &WorldSession::HandleNameQueryOpcode); DEFINE_OPCODE_HANDLER_OLD(CMSG_NEUTRAL_PLAYER_SELECT_FACTION, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); DEFINE_OPCODE_HANDLER_OLD(CMSG_NEW_SPELL_SLOT, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); @@ -611,7 +612,7 @@ void OpcodeTable::Initialize() DEFINE_HANDLER(CMSG_OFFER_PETITION, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, WorldPackets::Petition::OfferPetition, &WorldSession::HandleOfferPetition); DEFINE_OPCODE_HANDLER_OLD(CMSG_OPENING_CINEMATIC, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleOpeningCinematic ); DEFINE_OPCODE_HANDLER_OLD(CMSG_OPEN_GARRISON_MISSION_NPC, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); - DEFINE_OPCODE_HANDLER_OLD(CMSG_OPEN_ITEM, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleOpenItemOpcode ); + DEFINE_HANDLER(CMSG_OPEN_ITEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Spells::OpenItem, &WorldSession::HandleOpenItemOpcode ); DEFINE_OPCODE_HANDLER_OLD(CMSG_OPEN_SHIPMENT_GAME_OBJ, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); DEFINE_OPCODE_HANDLER_OLD(CMSG_OPEN_SHIPMENT_NPC, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); DEFINE_OPCODE_HANDLER_OLD(CMSG_OPT_OUT_OF_LOOT, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleOptOutOfLootOpcode ); @@ -621,13 +622,13 @@ void OpcodeTable::Initialize() DEFINE_OPCODE_HANDLER_OLD(CMSG_PARTY_SILENCE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); DEFINE_OPCODE_HANDLER_OLD(CMSG_PARTY_UNINVITE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleGroupUninviteOpcode ); DEFINE_OPCODE_HANDLER_OLD(CMSG_PARTY_UNSILENCE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); - DEFINE_HANDLER(CMSG_PETITION_BUY, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, WorldPackets::Petition::PetitionBuy, &WorldSession::HandlePetitionBuy); + DEFINE_HANDLER(CMSG_PETITION_BUY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Petition::PetitionBuy, &WorldSession::HandlePetitionBuy); DEFINE_HANDLER(CMSG_PETITION_RENAME_GUILD, STATUS_UNHANDLED, 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_UNHANDLED, PROCESS_THREADUNSAFE, WorldPackets::Petition::PetitionShowSignatures, &WorldSession::HandlePetitionShowSignatures); + 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_OPCODE_HANDLER_OLD(CMSG_PET_ACTION, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandlePetAction ); - DEFINE_OPCODE_HANDLER_OLD(CMSG_PET_BATTLE_FINAL_NOTIF, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + DEFINE_OPCODE_HANDLER_OLD(CMSG_PET_BATTLE_FINAL_NOTIFY, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); DEFINE_OPCODE_HANDLER_OLD(CMSG_PET_BATTLE_INPUT, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); DEFINE_OPCODE_HANDLER_OLD(CMSG_PET_BATTLE_QUEUE_PROPOSE_MATCH_RESULT, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); DEFINE_OPCODE_HANDLER_OLD(CMSG_PET_BATTLE_QUIT_NOTIFY, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); @@ -636,8 +637,7 @@ void OpcodeTable::Initialize() DEFINE_OPCODE_HANDLER_OLD(CMSG_PET_BATTLE_REQUEST_WILD, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); DEFINE_OPCODE_HANDLER_OLD(CMSG_PET_BATTLE_SCRIPT_ERROR_NOTIFY, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); DEFINE_OPCODE_HANDLER_OLD(CMSG_PET_CANCEL_AURA, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandlePetCancelAuraOpcode ); - DEFINE_HANDLER(CMSG_PET_CAST_SPELL, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, WorldPackets::Spells::PetCastSpell, &WorldSession::HandlePetCastSpellOpcode); - DEFINE_OPCODE_HANDLER_OLD(CMSG_PET_LEARN_TALENT, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandlePetLearnTalent ); + DEFINE_HANDLER(CMSG_PET_CAST_SPELL, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Spells::PetCastSpell, &WorldSession::HandlePetCastSpellOpcode); DEFINE_OPCODE_HANDLER_OLD(CMSG_PET_NAME_CACHE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); DEFINE_OPCODE_HANDLER_OLD(CMSG_PET_NAME_QUERY, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandlePetNameQuery ); DEFINE_OPCODE_HANDLER_OLD(CMSG_PET_RENAME, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandlePetRename ); @@ -664,15 +664,16 @@ void OpcodeTable::Initialize() DEFINE_OPCODE_HANDLER_OLD(CMSG_QUESTGIVER_CANCEL, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); DEFINE_HANDLER(CMSG_QUESTGIVER_CHOOSE_REWARD, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Quest::QuestGiverChooseReward, &WorldSession::HandleQuestgiverChooseRewardOpcode); DEFINE_HANDLER(CMSG_QUESTGIVER_COMPLETE_QUEST, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Quest::QuestGiverCompleteQuest, &WorldSession::HandleQuestgiverCompleteQuest); - DEFINE_HANDLER(CMSG_QUESTGIVER_HELLO, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, WorldPackets::Quest::QuestGiverHello, &WorldSession::HandleQuestgiverHelloOpcode); + DEFINE_HANDLER(CMSG_QUESTGIVER_HELLO, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Quest::QuestGiverHello, &WorldSession::HandleQuestgiverHelloOpcode); DEFINE_HANDLER(CMSG_QUESTGIVER_QUERY_QUEST, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Quest::QuestGiverQueryQuest, &WorldSession::HandleQuestgiverQueryQuestOpcode); DEFINE_OPCODE_HANDLER_OLD(CMSG_QUESTGIVER_QUEST_AUTOLAUNCH, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); - DEFINE_HANDLER(CMSG_QUESTGIVER_REQUEST_REWARD, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, WorldPackets::Quest::QuestGiverRequestReward, &WorldSession::HandleQuestgiverRequestRewardOpcode); + DEFINE_HANDLER(CMSG_QUESTGIVER_REQUEST_REWARD, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Quest::QuestGiverRequestReward, &WorldSession::HandleQuestgiverRequestRewardOpcode); DEFINE_HANDLER(CMSG_QUESTGIVER_STATUS_MULTIPLE_QUERY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Quest::QuestGiverStatusMultipleQuery, &WorldSession::HandleQuestgiverStatusMultipleQuery); DEFINE_HANDLER(CMSG_QUESTGIVER_STATUS_QUERY, STATUS_LOGGEDIN, PROCESS_INPLACE, WorldPackets::Quest::QuestGiverStatusQuery, &WorldSession::HandleQuestgiverStatusQueryOpcode); DEFINE_HANDLER(CMSG_QUESTLOG_REMOVE_QUEST, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Quest::QuestLogRemoveQuest, &WorldSession::HandleQuestLogRemoveQuest); DEFINE_OPCODE_HANDLER_OLD(CMSG_QUESTLOG_SWAP_QUEST, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); DEFINE_OPCODE_HANDLER_OLD(CMSG_QUEST_CONFIRM_ACCEPT, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestConfirmAccept ); + DEFINE_OPCODE_HANDLER_OLD(CMSG_QUEST_CLOSE_AUTOACCEPT_QUEST, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::Handle_NULL ); DEFINE_OPCODE_HANDLER_OLD(CMSG_QUERY_QUEST_COMPLETION_NPCS, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestNPCQuery ); DEFINE_OPCODE_HANDLER_OLD(CMSG_QUEST_POI_QUERY, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestPOIQuery ); DEFINE_OPCODE_HANDLER_OLD(CMSG_QUEST_PUSH_RESULT, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestPushResult ); @@ -691,7 +692,7 @@ void OpcodeTable::Initialize() DEFINE_HANDLER(CMSG_REPAIR_ITEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Item::RepairItem, &WorldSession::HandleRepairItemOpcode); DEFINE_OPCODE_HANDLER_OLD(CMSG_REPLACE_ACCOUNT_DATA, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); DEFINE_OPCODE_HANDLER_OLD(CMSG_REPLACE_TROPHY, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); - DEFINE_HANDLER(CMSG_REPOP_REQUEST, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, WorldPackets::Misc::RepopRequest, &WorldSession::HandleRepopRequest); + DEFINE_HANDLER(CMSG_REPOP_REQUEST, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Misc::RepopRequest, &WorldSession::HandleRepopRequest); DEFINE_OPCODE_HANDLER_OLD(CMSG_REPORT_FILTERED, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); DEFINE_OPCODE_HANDLER_OLD(CMSG_REPORT_IGNORED, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleChatIgnoredOpcode ); DEFINE_OPCODE_HANDLER_OLD(CMSG_REPORT_PVP_AFK, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleReportPvPAFK ); @@ -702,7 +703,7 @@ void OpcodeTable::Initialize() DEFINE_HANDLER(CMSG_REQUEST_CEMETERY_LIST, STATUS_LOGGEDIN, PROCESS_INPLACE, WorldPackets::Misc::RequestCemeteryList, &WorldSession::HandleRequestCemeteryList); DEFINE_OPCODE_HANDLER_OLD(CMSG_REQUEST_CONQUEST_FORMULA_CONSTANTS, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); DEFINE_OPCODE_HANDLER_OLD(CMSG_REQUEST_FORCED_REACTIONS, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); - DEFINE_HANDLER(CMSG_REQUEST_GUILD_REWARDS_LIST, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Guild::RequestGuildRewardsList, &WorldSession::HandleRequestGuildRewardsList); + DEFINE_HANDLER(CMSG_REQUEST_GUILD_REWARDS_LIST, STATUS_LOGGEDIN, PROCESS_INPLACE, WorldPackets::Guild::RequestGuildRewardsList, &WorldSession::HandleRequestGuildRewardsList); DEFINE_HANDLER(CMSG_REQUEST_HONOR_STATS, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, WorldPackets::Inspect::RequestHonorStats, &WorldSession::HandleRequestHonorStatsOpcode); DEFINE_OPCODE_HANDLER_OLD(CMSG_REQUEST_LFG_LIST_BLACKLIST, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); DEFINE_OPCODE_HANDLER_OLD(CMSG_REQUEST_PARTY_JOIN_UPDATES, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); @@ -742,7 +743,7 @@ void OpcodeTable::Initialize() DEFINE_OPCODE_HANDLER_OLD(CMSG_SET_ACHIEVEMENTS_HIDDEN, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); DEFINE_HANDLER(CMSG_SET_ACTIONBAR_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_OPCODE_HANDLER_OLD(CMSG_SET_ACTIVE_MOVER, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleSetActiveMoverOpcode ); + 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_OPCODE_HANDLER_OLD(CMSG_SET_ADVANCED_COMBAT_LOGGING, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); DEFINE_OPCODE_HANDLER_OLD(CMSG_SET_ASSISTANT_LEADER, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::HandleGroupAssistantLeaderOpcode); @@ -795,7 +796,7 @@ void OpcodeTable::Initialize() DEFINE_OPCODE_HANDLER_OLD(CMSG_SPELLCLICK, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleSpellClick ); DEFINE_OPCODE_HANDLER_OLD(CMSG_SPIRIT_HEALER_ACTIVATE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleSpiritHealerActivateOpcode); DEFINE_HANDLER(CMSG_SPLIT_ITEM, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, WorldPackets::Item::SplitItem, &WorldSession::HandleSplitItemOpcode); - DEFINE_HANDLER(CMSG_STAND_STATE_CHANGE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, WorldPackets::Misc::StandStateChange, &WorldSession::HandleStandStateChangeOpcode); + DEFINE_HANDLER(CMSG_STAND_STATE_CHANGE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Misc::StandStateChange, &WorldSession::HandleStandStateChangeOpcode); DEFINE_OPCODE_HANDLER_OLD(CMSG_START_QUEST, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); DEFINE_OPCODE_HANDLER_OLD(CMSG_START_SPECTATOR_WAR_GAME, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); DEFINE_OPCODE_HANDLER_OLD(CMSG_START_WARGAME, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); @@ -808,7 +809,7 @@ void OpcodeTable::Initialize() DEFINE_OPCODE_HANDLER_OLD(CMSG_SUSPEND_COMMS_ACK, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); DEFINE_OPCODE_HANDLER_OLD(CMSG_SUSPEND_TOKEN_RESPONSE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); DEFINE_HANDLER(CMSG_SWAP_INV_ITEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Item::SwapInvItem, &WorldSession::HandleSwapInvItemOpcode); - DEFINE_HANDLER(CMSG_SWAP_ITEM, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, WorldPackets::Item::SwapItem, &WorldSession::HandleSwapItem); + DEFINE_HANDLER(CMSG_SWAP_ITEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Item::SwapItem, &WorldSession::HandleSwapItem); DEFINE_OPCODE_HANDLER_OLD(CMSG_SWAP_SUB_GROUPS, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::HandleGroupSwapSubGroupOpcode ); DEFINE_OPCODE_HANDLER_OLD(CMSG_SYNC_DANCE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); DEFINE_HANDLER(CMSG_TABARD_VENDOR_ACTIVATE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, WorldPackets::NPC::Hello, &WorldSession::HandleTabardVendorActivateOpcode); @@ -835,6 +836,7 @@ void OpcodeTable::Initialize() DEFINE_HANDLER(CMSG_TURN_IN_PETITION, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, WorldPackets::Petition::TurnInPetition, &WorldSession::HandleTurnInPetition); DEFINE_HANDLER(CMSG_TUTORIAL_FLAG, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Misc::TutorialSetFlag, &WorldSession::HandleTutorialFlag); DEFINE_HANDLER(CMSG_UI_TIME_REQUEST, STATUS_LOGGEDIN, PROCESS_INPLACE, WorldPackets::Misc::UITimeRequest, &WorldSession::HandleUITimeRequest); + DEFINE_OPCODE_HANDLER_OLD(CMSG_TWITTER_GET_STATUS, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL); DEFINE_OPCODE_HANDLER_OLD(CMSG_UNACCEPT_TRADE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleUnacceptTradeOpcode ); DEFINE_HANDLER(CMSG_UNDELETE_CHARACTER, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, WorldPackets::Character::UndeleteCharacter, &WorldSession::HandleCharUndeleteOpcode); DEFINE_OPCODE_HANDLER_OLD(CMSG_UNLEARN_SKILL, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleUnlearnSkillOpcode ); @@ -1017,7 +1019,7 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_BREAK_TARGET, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_BUY_BANK_SLOT_RESULT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_BUY_FAILED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_BUY_SUCCEEDED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_BUY_SUCCEEDED, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_CALENDAR_ACTION_PENDING, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_CALENDAR_ARENA_TEAM, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_CALENDAR_CLEAR_PENDING_ACTION, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); @@ -1093,7 +1095,7 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_CHECK_WARGAME_ENTRY, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_CLEAR_ALL_SPELL_CHARGES, STATUS_UNHANDLED, CONNECTION_TYPE_INSTANCE); DEFINE_SERVER_OPCODE_HANDLER(SMSG_CLEAR_BOSS_EMOTES, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_CLEAR_COOLDOWN, STATUS_UNHANDLED, CONNECTION_TYPE_INSTANCE); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_CLEAR_COOLDOWN, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); DEFINE_SERVER_OPCODE_HANDLER(SMSG_CLEAR_COOLDOWNS, STATUS_UNHANDLED, CONNECTION_TYPE_INSTANCE); DEFINE_SERVER_OPCODE_HANDLER(SMSG_CLEAR_FAR_SIGHT_IMMEDIATE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_CLEAR_LOSS_OF_CONTROL, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); @@ -1262,7 +1264,7 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_BANK_TEXT_QUERY_RESULT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_CANCEL, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_CHALLENGE_COMPLETED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_CHALLENGE_UPDATE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_CHALLENGE_UPDATE, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_CHANGE_NAME_RESULT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_COMMAND_RESULT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_CRITERIA_DELETED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); @@ -1290,13 +1292,13 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_INVITE_EXPIRED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_KNOWN_RECIPES, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_MEMBERS_WITH_RECIPE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_MEMBER_DAILY_RESET, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_MEMBER_DAILY_RESET, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_MEMBER_RECIPES, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_MEMBER_UPDATE_NOTE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_MOVED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_MOVE_STARTING, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_NAME_CHANGED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_NEWS, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_NEWS, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_NEWS_DELETED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_PARTY_STATE_RESPONSE, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_PERMISSIONS_QUERY_RESULTS, STATUS_NEVER, CONNECTION_TYPE_REALM); @@ -1304,7 +1306,7 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_RANKS, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_REPUTATION_REACTION_CHANGED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_RESET, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_REWARDS_LIST, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_REWARDS_LIST, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_ROSTER, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_ROSTER_UPDATE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_SEND_RANK_CHANGE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); @@ -1342,13 +1344,13 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_INVALIDATE_DANCE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_INVALIDATE_PLAYER, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_INVALID_PROMOTION_CODE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_INVENTORY_CHANGE_FAILURE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_INVENTORY_CHANGE_FAILURE, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_IS_QUEST_COMPLETE_RESPONSE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_ITEM_COOLDOWN, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_ITEM_ENCHANT_TIME_UPDATE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_ITEM_EXPIRE_PURCHASE_REFUND, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_ITEM_PURCHASE_REFUND_RESULT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_ITEM_PUSH_RESULT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_ITEM_PUSH_RESULT, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_ITEM_REFUND_INFO_RESPONSE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_ITEM_TIME_UPDATE, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_ITEM_UPGRADE_RESULT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); @@ -1407,7 +1409,7 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_LOOT_MONEY_NOTIFY, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_LOOT_RELEASE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_LOOT_RELEASE_ALL, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_LOOT_REMOVED, STATUS_UNHANDLED, CONNECTION_TYPE_INSTANCE); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_LOOT_REMOVED, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); DEFINE_SERVER_OPCODE_HANDLER(SMSG_LOOT_RESPONSE, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); DEFINE_SERVER_OPCODE_HANDLER(SMSG_LOOT_ROLL, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_LOOT_ROLLS_COMPLETE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); @@ -1438,14 +1440,14 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_APPLY_MOVEMENT_FORCE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_DISABLE_CAN_TRANSITION_BETWEEN_SWIM_AND_FLY, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_DISABLE_COLLISION, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_DISABLE_GRAVITY, STATUS_UNHANDLED, CONNECTION_TYPE_INSTANCE); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_DISABLE_GRAVITY, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_ENABLE_CAN_TRANSITION_BETWEEN_SWIM_AND_FLY, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_ENABLE_COLLISION, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_ENABLE_GRAVITY, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_ENABLE_GRAVITY, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_KNOCK_BACK, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_REMOVE_MOVEMENT_FORCE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_ROOT, STATUS_NEVER, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_SET_ACTIVE_MOVER, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_SET_ACTIVE_MOVER, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_SET_ANIM_KIT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_SET_CAN_FLY, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_SET_CAN_TURN_WHILE_FALLING, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); @@ -1530,7 +1532,7 @@ void OpcodeTable::Initialize() 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_MONEY, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_NOTIFY_RECEIVED_MAIL, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_NOTIFY_RECEIVED_MAIL, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_NPC_TEXT_UPDATE, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); DEFINE_SERVER_OPCODE_HANDLER(SMSG_NPC_WONT_TALK, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_OFFER_PETITION_ERROR, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); @@ -1555,7 +1557,7 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_PETITION_ALREADY_SIGNED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_PETITION_DECLINED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_PETITION_RENAME_GUILD_RESPONSE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_PETITION_SHOW_LIST, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_PETITION_SHOW_LIST, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_PETITION_SHOW_SIGNATURES, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_PETITION_SIGN_RESULTS, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_PET_ACTION_FEEDBACK, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); @@ -1596,7 +1598,7 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_PET_TAME_FAILURE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_PET_UPDATE_COMBO_POINTS, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_PLAYED_TIME, STATUS_NEVER, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_PLAYER_BOUND, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_PLAYER_BOUND, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_PLAYER_SKINNED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_PLAYER_VEHICLE_DATA, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_PLAY_DANCE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); @@ -1711,7 +1713,7 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_SCRIPT_CAST, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_SELL_RESPONSE, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_SEND_ITEM_PASSIVES, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_SEND_MAIL_RESULT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_SEND_MAIL_RESULT, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_SEND_RAID_TARGET_UPDATE_ALL, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_SEND_RAID_TARGET_UPDATE_SINGLE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_SEND_SPELL_CHARGES, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); @@ -1754,7 +1756,7 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_TIME_ZONE_INFORMATION, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_VEHICLE_REC_ID, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_VIGNETTE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_SHOW_BANK, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_SHOW_BANK, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_SHOW_MAILBOX, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_SHOW_NEUTRAL_PLAYER_FACTION_SELECT_UI, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_SHOW_RATINGS, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); @@ -1804,7 +1806,7 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_SUPPRESS_NPC_GREETINGS, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_SUSPEND_COMMS, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_SUSPEND_TOKEN, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_TABARD_VENDOR_ACTIVATE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_TABARD_VENDOR_ACTIVATE, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_TALENTS_ERROR, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_TALENTS_INFO, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); DEFINE_SERVER_OPCODE_HANDLER(SMSG_TALENTS_INVOLUNTARILY_RESET, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); @@ -1827,8 +1829,8 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_TRAINER_LIST, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); DEFINE_SERVER_OPCODE_HANDLER(SMSG_TRANSFER_ABORTED, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_TRANSFER_PENDING, STATUS_NEVER, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_TRIGGER_CINEMATIC, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_TRIGGER_MOVIE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_TRIGGER_CINEMATIC, STATUS_NEVER, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_TRIGGER_MOVIE, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_TURN_IN_PETITION_RESULTS, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_TUTORIAL_FLAGS, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_UI_TIME, STATUS_NEVER, CONNECTION_TYPE_REALM); diff --git a/src/server/game/Server/Protocol/Opcodes.h b/src/server/game/Server/Protocol/Opcodes.h index da7adf5d748..8f55575fe53 100644 --- a/src/server/game/Server/Protocol/Opcodes.h +++ b/src/server/game/Server/Protocol/Opcodes.h @@ -50,12 +50,12 @@ enum OpcodeClient : uint32 CMSG_ACCEPT_LEVEL_GRANT = 0xBADD, CMSG_ACCEPT_TRADE = 0xBADD, CMSG_ACCEPT_WARGAME_INVITE = 0xBADD, - CMSG_ACTIVATE_TAXI = 0xBADD, + CMSG_ACTIVATE_TAXI = 0x0823, CMSG_ACTIVATE_TAXI_EXPRESS = 0xBADD, CMSG_ADD_BATTLENET_FRIEND = 0xBADD, CMSG_ADD_FRIEND = 0x15E2, CMSG_ADD_IGNORE = 0x1D33, - CMSG_ALTER_APPEARANCE = 0xBADD, + CMSG_ALTER_APPEARANCE = 0x0822, CMSG_AREATRIGGER = 0x1904, CMSG_AREA_SPIRIT_HEALER_QUERY = 0x093A, CMSG_AREA_SPIRIT_HEALER_QUEUE = 0xBADD, @@ -73,21 +73,21 @@ enum OpcodeClient : uint32 CMSG_ATTACKSWING = 0x048B, CMSG_AUCTION_HELLO_REQUEST = 0x06E3, CMSG_AUCTION_LIST_BIDDER_ITEMS = 0x0C81, - CMSG_AUCTION_LIST_ITEMS = 0xBADD, + CMSG_AUCTION_LIST_ITEMS = 0x05C3, CMSG_AUCTION_LIST_OWNER_ITEMS = 0x082A, CMSG_AUCTION_LIST_PENDING_SALES = 0x0D82, CMSG_AUCTION_PLACE_BID = 0x09E1, - CMSG_AUCTION_REMOVE_ITEM = 0xBADD, + CMSG_AUCTION_REMOVE_ITEM = 0x1309, CMSG_AUCTION_REPLICATE_ITEMS = 0xBADD, - CMSG_AUCTION_SELL_ITEM = 0xBADD, + CMSG_AUCTION_SELL_ITEM = 0x09A3, CMSG_AUTH_CONTINUED_SESSION = 0x1A72, CMSG_AUTH_SESSION = 0x1872, - CMSG_AUTOBANK_ITEM = 0xBADD, + CMSG_AUTOBANK_ITEM = 0x00C6, CMSG_AUTOEQUIP_GROUND_ITEM = 0xBADD, - CMSG_AUTOEQUIP_ITEM = 0xBADD, - CMSG_AUTOEQUIP_ITEM_SLOT = 0xBADD, - CMSG_AUTOSTORE_BAG_ITEM = 0xBADD, - CMSG_AUTOSTORE_BANK_ITEM = 0xBADD, + CMSG_AUTOEQUIP_ITEM = 0x0235, + CMSG_AUTOEQUIP_ITEM_SLOT = 0x0076, + CMSG_AUTOSTORE_BAG_ITEM = 0x00E5, + CMSG_AUTOSTORE_BANK_ITEM = 0x00D5, CMSG_AUTOSTORE_GROUND_ITEM = 0xBADD, CMSG_AUTOSTORE_LOOT_ITEM = 0x0843, CMSG_BANKER_ACTIVATE = 0x0931, @@ -115,7 +115,7 @@ enum OpcodeClient : uint32 CMSG_BATTLE_PET_DELETE_PET = 0xBADD, CMSG_BATTLE_PET_DELETE_PET_CHEAT = 0xBADD, CMSG_BATTLE_PET_MODIFY_NAME = 0x1131, - CMSG_BATTLE_PET_NAME_QUERY = 0xBADD, + CMSG_BATTLE_PET_NAME_QUERY = 0x1184, CMSG_BATTLE_PET_REQUEST_JOURNAL = 0x1773, CMSG_BATTLE_PET_REQUEST_JOURNAL_LOCK = 0x1B24, CMSG_BATTLE_PET_REQUEST_UPDATE = 0xBADD, @@ -158,7 +158,7 @@ enum OpcodeClient : uint32 CMSG_CANCEL_CHANNELLING = 0xBADD, CMSG_CANCEL_GROWTH_AURA = 0xBADD, CMSG_CANCEL_MASTER_LOOT_ROLL = 0xBADD, - CMSG_CANCEL_MOD_SPEED_NO_CONTROL_AURAS = 0xBADD, + CMSG_CANCEL_MOD_SPEED_NO_CONTROL_AURAS = 0x0851, CMSG_CANCEL_MOUNT_AURA = 0x0B4C, CMSG_CANCEL_QUEUED_SPELL = 0xBADD, CMSG_CANCEL_TEMP_ENCHANTMENT = 0xBADD, @@ -201,7 +201,7 @@ enum OpcodeClient : uint32 CMSG_CHAR_RENAME = 0xBADD, CMSG_CHAR_UNDELETE_ENUM = 0xBADD, CMSG_CHECK_RAF_EMAIL_ENABLED = 0xBADD, - CMSG_CHOICE_RESPONSE = 0xBADD, + CMSG_CHOICE_RESPONSE = 0x094C, CMSG_CLEAR_RAID_MARKER = 0xBADD, CMSG_CLEAR_TRADE_ITEM = 0xBADD, CMSG_CLOSE_INTERACTION = 0x0A3A, @@ -215,25 +215,25 @@ enum OpcodeClient : uint32 CMSG_COMMENTATOR_SKIRMISH_QUEUE_COMMAND = 0xBADD, CMSG_COMMENTATOR_START_WARGAME = 0xBADD, CMSG_COMPLAIN = 0xBADD, - CMSG_COMPLETE_CINEMATIC = 0xBADD, - CMSG_COMPLETE_MOVIE = 0xBADD, + CMSG_COMPLETE_CINEMATIC = 0x0EC4, + CMSG_COMPLETE_MOVIE = 0x1319, CMSG_CONFIRM_RESPEC_WIPE = 0xBADD, CMSG_CONNECT_TO_FAILED = 0x15B4, CMSG_CONVERSATION_UNK1 = 0xBADD, CMSG_CONVERT_RAID = 0x1329, - CMSG_CREATE_SHIPMENT = 0xBADD, + CMSG_CREATE_SHIPMENT = 0x1B94, CMSG_CREATURE_QUERY = 0x007C, CMSG_DANCE_QUERY = 0xBADD, CMSG_DB_QUERY_BULK = 0x1731, CMSG_DECLINE_GUILD_INVITES = 0xBADD, - CMSG_DECLINE_PETITION = 0xBADD, + CMSG_DECLINE_PETITION = 0x0932, CMSG_DELETE_EQUIPMENT_SET = 0x1599, CMSG_DEL_FRIEND = 0x1B71, CMSG_DEL_IGNORE = 0x1BB3, CMSG_DEPOSIT_REAGENT_BANK = 0x1142, CMSG_DESTROY_ITEM = 0x0651, CMSG_DF_BOOT_PLAYER_VOTE = 0xBADD, - CMSG_DF_JOIN = 0xBADD, + CMSG_DF_JOIN = 0x1D39, CMSG_DF_LEAVE = 0xBADD, CMSG_DF_PROPOSAL_RESPONSE = 0xBADD, CMSG_DF_SEARCH_JOIN = 0xBADD, @@ -251,17 +251,17 @@ enum OpcodeClient : uint32 CMSG_ENABLE_NAGLE = 0x1433, CMSG_ENABLE_TAXI_NODE = 0x13D9, CMSG_EQUIPMENT_SET_SAVE = 0x0A7C, - CMSG_FAR_SIGHT = 0xBADD, + CMSG_FAR_SIGHT = 0x0181, CMSG_GAMEOBJECT_QUERY = 0x021A, CMSG_GAMEOBJ_REPORT_USE = 0x087C, CMSG_GAMEOBJ_USE = 0x0EE4, CMSG_GAMESPEED_SET = 0xBADD, CMSG_GAMETIME_SET = 0xBADD, CMSG_GARRISON_ASSIGN_FOLLOWER_TO_BUILDING = 0xBADD, - CMSG_GARRISON_COMPLETE_MISSION = 0xBADD, - CMSG_GARRISON_MISSION_BONUS_ROLL = 0xBADD, + CMSG_GARRISON_COMPLETE_MISSION = 0x15C3, + CMSG_GARRISON_MISSION_BONUS_ROLL = 0x1B83, CMSG_GARRISON_OPEN_TRADESKILL_NPC = 0xBADD, - CMSG_GARRISON_PURCHASE_BUILDING = 0xBADD, + CMSG_GARRISON_PURCHASE_BUILDING = 0x0E24, CMSG_GARRISON_RECRUIT_FOLLOWER = 0xBADD, CMSG_GARRISON_REMOVE_FOLLOWER = 0xBADD, CMSG_GARRISON_REMOVE_FOLLOWER_FROM_BUILDING = 0xBADD, @@ -271,7 +271,7 @@ enum OpcodeClient : uint32 CMSG_GARRISON_SET_BUILDING_ACTIVE = 0xBADD, CMSG_GARRISON_SET_FOLLOWER_INACTIVE = 0xBADD, CMSG_GARRISON_SET_RECRUITMENT_PREFERENCES = 0xBADD, - CMSG_GARRISON_START_MISSION = 0xBADD, + CMSG_GARRISON_START_MISSION = 0x0023, CMSG_GARRISON_SWAP_BUILDINGS = 0xBADD, CMSG_GARRISON_UNK1 = 0xBADD, CMSG_GETDEATHBINDZONE = 0xBADD, @@ -279,8 +279,8 @@ enum OpcodeClient : uint32 CMSG_GET_GARRISON_INFO = 0x0352, CMSG_GET_ITEM_PURCHASE_DATA = 0x0CE4, CMSG_GET_MAIL_LIST = 0x0979, - CMSG_GET_MIRROR_IMAGE_DATA = 0xBADD, - CMSG_GET_SHIPMENT_INFO = 0xBADD, + CMSG_GET_MIRROR_IMAGE_DATA = 0x1952, + CMSG_GET_SHIPMENT_INFO = 0x0321, CMSG_GET_TROPHY_LIST = 0xBADD, CMSG_GET_UNDELETE_COOLDOWN_STATUS = 0x196A, CMSG_GHOST = 0xBADD, @@ -288,7 +288,7 @@ enum OpcodeClient : uint32 CMSG_GM_LAG_REPORT = 0xBADD, CMSG_GM_NUKE = 0xBADD, CMSG_GM_SET_SECURITY_GROUP = 0xBADD, - CMSG_GM_SURVEY_SUBMIT = 0xBADD, + CMSG_GM_SURVEY_SUBMIT = 0x1BAB, CMSG_GM_TICKET_ACKNOWLEDGE_SURVEY = 0xBADD, CMSG_GM_TICKET_CREATE = 0x19A4, CMSG_GM_TICKET_DELETE_TICKET = 0x1B39, @@ -303,9 +303,9 @@ enum OpcodeClient : uint32 CMSG_GROUP_CANCEL = 0xBADD, CMSG_GROUP_REQUEST_JOIN_UPDATES = 0xBADD, CMSG_GUILD_ADD_BATTLENET_FRIEND = 0xBADD, - CMSG_GUILD_ADD_RANK = 0xBADD, + CMSG_GUILD_ADD_RANK = 0x038E, CMSG_GUILD_ASSIGN_MEMBER_RANK = 0xBADD, - CMSG_GUILD_AUTO_DECLINE_INVITATION = 0xBADD, + CMSG_GUILD_AUTO_DECLINE_INVITATION = 0x0386, CMSG_GUILD_BANK_ACTIVATE = 0x0B64, CMSG_GUILD_BANK_BUY_TAB = 0xBADD, CMSG_GUILD_BANK_DEPOSIT_MONEY = 0xBADD, @@ -318,11 +318,11 @@ enum OpcodeClient : uint32 CMSG_GUILD_BANK_TEXT_QUERY = 0xBADD, CMSG_GUILD_BANK_UPDATE_TAB = 0xBADD, CMSG_GUILD_BANK_WITHDRAW_MONEY = 0xBADD, - CMSG_GUILD_CHALLENGE_UPDATE_REQUEST = 0xBADD, + CMSG_GUILD_CHALLENGE_UPDATE_REQUEST = 0x03B0, CMSG_GUILD_CHANGE_NAME_REQUEST = 0xBADD, CMSG_GUILD_DECLINE_INVITATION = 0xBADD, CMSG_GUILD_DELETE = 0xBADD, - CMSG_GUILD_DELETE_RANK = 0xBADD, + CMSG_GUILD_DELETE_RANK = 0x019D, CMSG_GUILD_DEMOTE_MEMBER = 0xBADD, CMSG_GUILD_EVENT_LOG_QUERY = 0xBADD, CMSG_GUILD_GET_ACHIEVEMENT_MEMBERS = 0xBADD, @@ -338,9 +338,9 @@ enum OpcodeClient : uint32 CMSG_GUILD_PROMOTE_MEMBER = 0xBADD, CMSG_GUILD_QUERY = 0x19B3, CMSG_GUILD_QUERY_MEMBERS_FOR_RECIPE = 0xBADD, - CMSG_GUILD_QUERY_MEMBER_RECIPES = 0xBADD, - CMSG_GUILD_QUERY_NEWS = 0xBADD, - CMSG_GUILD_QUERY_RECIPES = 0xBADD, + CMSG_GUILD_QUERY_MEMBER_RECIPES = 0x0110, + CMSG_GUILD_QUERY_NEWS = 0x01A5, + CMSG_GUILD_QUERY_RECIPES = 0x0538, CMSG_GUILD_REPLACE_GUILD_MASTER = 0xBADD, CMSG_GUILD_REQUEST_PARTY_STATE = 0x0B52, CMSG_GUILD_SET_ACHIEVEMENT_TRACKING = 0x039E, @@ -391,13 +391,13 @@ enum OpcodeClient : uint32 CMSG_LF_GUILD_BROWSE = 0x11E4, CMSG_LF_GUILD_DECLINE_RECRUIT = 0xBADD, CMSG_LF_GUILD_GET_APPLICATIONS = 0xBADD, - CMSG_LF_GUILD_GET_GUILD_POST = 0xBADD, + CMSG_LF_GUILD_GET_GUILD_POST = 0x012E, CMSG_LF_GUILD_GET_RECRUITS = 0xBADD, CMSG_LF_GUILD_REMOVE_RECRUIT = 0xBADD, CMSG_LF_GUILD_SET_GUILD_POST = 0xBADD, CMSG_LIST_INVENTORY = 0x06C4, CMSG_LOAD_SCREEN = 0x13E4, - CMSG_LOGOUT_CANCEL = 0xBADD, + CMSG_LOGOUT_CANCEL = 0x0DC1, CMSG_LOGOUT_INSTANT = 0xBADD, CMSG_LOGOUT_REQUEST = 0x0824, CMSG_LOG_DISCONNECT = 0x1432, @@ -412,11 +412,11 @@ enum OpcodeClient : uint32 CMSG_LOW_LEVEL_RAID1 = 0xBADD, CMSG_LOW_LEVEL_RAID2 = 0xBADD, CMSG_MAIL_CREATE_TEXT_ITEM = 0xBADD, - CMSG_MAIL_DELETE = 0xBADD, - CMSG_MAIL_MARK_AS_READ = 0xBADD, + CMSG_MAIL_DELETE = 0x0C89, + CMSG_MAIL_MARK_AS_READ = 0x13C9, CMSG_MAIL_RETURN_TO_SENDER = 0xBADD, - CMSG_MAIL_TAKE_ITEM = 0xBADD, - CMSG_MAIL_TAKE_MONEY = 0xBADD, + CMSG_MAIL_TAKE_ITEM = 0x0D84, + CMSG_MAIL_TAKE_MONEY = 0x0861, CMSG_MASTER_LOOT_ITEM = 0xBADD, CMSG_MEETINGSTONE_INFO = 0xBADD, CMSG_MESSAGECHAT_ADDON_CHANNEL = 0x108C, @@ -441,7 +441,7 @@ enum OpcodeClient : uint32 CMSG_MESSAGECHAT_YELL = 0x1481, CMSG_MINIGAME_MOVE = 0xBADD, CMSG_MINIMAP_PING = 0xBADD, - CMSG_MISSILE_TRAJECTORY_COLLISION = 0xBADD, + CMSG_MISSILE_TRAJECTORY_COLLISION = 0x085A, CMSG_MOUNT_SET_FAVORITE = 0x15B1, CMSG_MOUNT_SPECIAL_ANIM = 0xBADD, CMSG_MOVE_APPLY_MOVEMENT_FORCE_ACK = 0xBADD, @@ -452,7 +452,7 @@ enum OpcodeClient : uint32 CMSG_MOVE_ENABLE_SWIM_TO_FLY_TRANS_ACK = 0x038B, CMSG_MOVE_FALL_LAND = 0x0DEA, CMSG_MOVE_FALL_RESET = 0x0F89, - CMSG_MOVE_FEATHER_FALL_ACK = 0x0F89, + CMSG_MOVE_FEATHER_FALL_ACK = 0x02B1, CMSG_MOVE_FORCE_FLIGHT_BACK_SPEED_CHANGE_ACK = 0xBADD, CMSG_MOVE_FORCE_FLIGHT_SPEED_CHANGE_ACK = 0x09CB, CMSG_MOVE_FORCE_PITCH_RATE_CHANGE_ACK = 0xBADD, @@ -513,14 +513,14 @@ enum OpcodeClient : uint32 CMSG_NAME_QUERY = 0x15A2, CMSG_NEUTRAL_PLAYER_SELECT_FACTION = 0xBADD, CMSG_NEW_SPELL_SLOT = 0xBADD, - CMSG_NEXT_CINEMATIC_CAMERA = 0xBADD, + CMSG_NEXT_CINEMATIC_CAMERA = 0x110B, CMSG_NPC_TEXT_QUERY = 0x0E44, CMSG_OBJECT_UPDATE_FAILED = 0xBADD, CMSG_OBJECT_UPDATE_RESCUED = 0x0C8A, CMSG_OFFER_PETITION = 0xBADD, CMSG_OPENING_CINEMATIC = 0xBADD, CMSG_OPEN_GARRISON_MISSION_NPC = 0x1911, - CMSG_OPEN_ITEM = 0xBADD, + CMSG_OPEN_ITEM = 0x0E51, CMSG_OPEN_SHIPMENT_GAME_OBJ = 0xBADD, CMSG_OPEN_SHIPMENT_NPC = 0x0E41, CMSG_OPT_OUT_OF_LOOT = 0xBADD, @@ -530,25 +530,24 @@ enum OpcodeClient : uint32 CMSG_PARTY_SILENCE = 0xBADD, CMSG_PARTY_UNINVITE = 0xBADD, CMSG_PARTY_UNSILENCE = 0xBADD, - CMSG_PETITION_BUY = 0xBADD, + CMSG_PETITION_BUY = 0x159B, CMSG_PETITION_RENAME_GUILD = 0xBADD, CMSG_PETITION_SHOW_LIST = 0x06E1, - CMSG_PETITION_SHOW_SIGNATURES = 0xBADD, + CMSG_PETITION_SHOW_SIGNATURES = 0x115A, CMSG_PET_ABANDON = 0xBADD, CMSG_PET_ACTION = 0x114A, - CMSG_PET_BATTLE_FINAL_NOTIF = 0xBADD, - CMSG_PET_BATTLE_INPUT = 0xBADD, + CMSG_PET_BATTLE_FINAL_NOTIFY = 0x004B, + CMSG_PET_BATTLE_INPUT = 0x1B34, CMSG_PET_BATTLE_QUEUE_PROPOSE_MATCH_RESULT = 0xBADD, CMSG_PET_BATTLE_QUIT_NOTIFY = 0xBADD, - CMSG_PET_BATTLE_REPLACE_FRONT_PET = 0xBADD, + CMSG_PET_BATTLE_REPLACE_FRONT_PET = 0x192A, CMSG_PET_BATTLE_REQUEST_PVP = 0xBADD, CMSG_PET_BATTLE_REQUEST_WILD = 0x084C, CMSG_PET_BATTLE_SCRIPT_ERROR_NOTIFY = 0xBADD, CMSG_PET_CANCEL_AURA = 0xBADD, - CMSG_PET_CAST_SPELL = 0xBADD, - CMSG_PET_LEARN_TALENT = 0xBADD, + CMSG_PET_CAST_SPELL = 0x1FC1, CMSG_PET_NAME_CACHE = 0xBADD, - CMSG_PET_NAME_QUERY = 0xBADD, + CMSG_PET_NAME_QUERY = 0x0CCB, CMSG_PET_RENAME = 0x1333, CMSG_PET_SET_ACTION = 0xBADD, CMSG_PET_SET_SPECIALIZATION = 0xBADD, @@ -574,14 +573,15 @@ enum OpcodeClient : uint32 CMSG_QUESTGIVER_CANCEL = 0xBADD, CMSG_QUESTGIVER_CHOOSE_REWARD = 0x0CE1, CMSG_QUESTGIVER_COMPLETE_QUEST = 0x0A69, - CMSG_QUESTGIVER_HELLO = 0xBADD, + CMSG_QUESTGIVER_HELLO = 0x0B2A, CMSG_QUESTGIVER_QUERY_QUEST = 0x131A, CMSG_QUESTGIVER_QUEST_AUTOLAUNCH = 0xBADD, - CMSG_QUESTGIVER_REQUEST_REWARD = 0xBADD, + CMSG_QUESTGIVER_REQUEST_REWARD = 0x1509, CMSG_QUESTGIVER_STATUS_MULTIPLE_QUERY = 0x0A39, CMSG_QUESTGIVER_STATUS_QUERY = 0x0A7B, CMSG_QUESTLOG_REMOVE_QUEST = 0x04C3, CMSG_QUESTLOG_SWAP_QUEST = 0xBADD, + CMSG_QUEST_CLOSE_AUTOACCEPT_QUEST = 0x150A, CMSG_QUEST_CONFIRM_ACCEPT = 0xBADD, CMSG_QUEST_POI_QUERY = 0x1B2A, CMSG_QUEST_PUSH_RESULT = 0xBADD, @@ -591,32 +591,32 @@ enum OpcodeClient : uint32 CMSG_RANDOM_ROLL = 0x1BE2, CMSG_READY_CHECK_RESPONSE = 0xBADD, CMSG_READ_ITEM = 0xBADD, - CMSG_REAGENT_BANK_BUY_TAB = 0xBADD, + CMSG_REAGENT_BANK_BUY_TAB = 0x0A3C, CMSG_REALM_NAME_QUERY = 0x17BC, CMSG_RECLAIM_CORPSE = 0x093B, CMSG_RECRUIT_A_FRIEND = 0xBADD, - CMSG_REGISTER_ADDON_PREFIXES = 0xBADD, + CMSG_REGISTER_ADDON_PREFIXES = 0x063B, CMSG_REORDER_CHARACTERS = 0x1729, CMSG_REPAIR_ITEM = 0x05E2, CMSG_REPLACE_ACCOUNT_DATA = 0xBADD, CMSG_REPLACE_TROPHY = 0xBADD, - CMSG_REPOP_REQUEST = 0xBADD, + CMSG_REPOP_REQUEST = 0x0B3B, CMSG_REPORT_FILTERED = 0xBADD, CMSG_REPORT_IGNORED = 0xBADD, CMSG_REPORT_PVP_AFK = 0xBADD, CMSG_REQUEST_ACCOUNT_DATA = 0x1934, - CMSG_REQUEST_ARTIFACT_COMPLETION_HISTORY = 0xBADD, + CMSG_REQUEST_ARTIFACT_COMPLETION_HISTORY = 0x025A, CMSG_REQUEST_BATTLEFIELD_STATUS = 0x17EC, CMSG_REQUEST_CATEGORY_COOLDOWNS = 0x0C72, CMSG_REQUEST_CEMETERY_LIST = 0x0421, CMSG_REQUEST_CONQUEST_FORMULA_CONSTANTS = 0x1342, CMSG_REQUEST_FORCED_REACTIONS = 0x012A, - CMSG_REQUEST_GUILD_REWARDS_LIST = 0xBADD, + CMSG_REQUEST_GUILD_REWARDS_LIST = 0x015A, CMSG_REQUEST_HONOR_STATS = 0xBADD, CMSG_REQUEST_LFG_LIST_BLACKLIST = 0xBADD, - CMSG_REQUEST_PARTY_JOIN_UPDATES = 0xBADD, - CMSG_REQUEST_PARTY_MEMBER_STATS = 0xBADD, - CMSG_REQUEST_PET_INFO = 0xBADD, + CMSG_REQUEST_PARTY_JOIN_UPDATES = 0x1339, + CMSG_REQUEST_PARTY_MEMBER_STATS = 0x1972, + CMSG_REQUEST_PET_INFO = 0x0981, CMSG_REQUEST_PVP_OPTIONS_ENABLED = 0xBADD, CMSG_REQUEST_PVP_REWARDS = 0xBADD, CMSG_REQUEST_RAID_INFO = 0x1163, @@ -653,7 +653,7 @@ enum OpcodeClient : uint32 CMSG_SET_ACTION_BUTTON = 0x13BA, CMSG_SET_ACTIVE_MOVER = 0x07CC, CMSG_SET_ACTIVE_VOICE_CHANNEL = 0xBADD, - CMSG_SET_ADVANCED_COMBAT_LOGGING = 0xBADD, + CMSG_SET_ADVANCED_COMBAT_LOGGING = 0x017C, CMSG_SET_ASSISTANT_LEADER = 0xBADD, CMSG_SET_BACKPACK_AUTOSORT_DISABLED = 0xBADD, CMSG_SET_BANK_AUTOSORT_DISABLED = 0xBADD, @@ -673,7 +673,7 @@ enum OpcodeClient : uint32 CMSG_SET_PARTY_ASSIGNMENT = 0xBADD, CMSG_SET_PARTY_LEADER = 0x1932, CMSG_SET_PET_SLOT = 0xBADD, - CMSG_SET_PLAYER_DECLINED_NAMES = 0xBADD, + CMSG_SET_PLAYER_DECLINED_NAMES = 0x1331, CMSG_SET_PREFERED_CEMETERY = 0xBADD, CMSG_SET_PVP = 0xBADD, CMSG_SET_RAID_DIFFICULTY = 0x1162, @@ -698,19 +698,19 @@ enum OpcodeClient : uint32 CMSG_SIGN_PETITION = 0xBADD, CMSG_SILENCE_PARTY_TALKER = 0xBADD, CMSG_SOCKET_GEMS = 0xBADD, - CMSG_SORT_BAGS = 0xBADD, + CMSG_SORT_BAGS = 0x0254, CMSG_SORT_BANK_BAGS = 0x1901, CMSG_SORT_REAGENT_BANK_BAGS = 0xBADD, CMSG_SPELLCLICK = 0x0DE3, CMSG_SPIRIT_HEALER_ACTIVATE = 0x0CA4, CMSG_SPLIT_ITEM = 0x0095, - CMSG_STAND_STATE_CHANGE = 0xBADD, + CMSG_STAND_STATE_CHANGE = 0x037A, CMSG_START_QUEST = 0xBADD, CMSG_START_SPECTATOR_WAR_GAME = 0xBADD, CMSG_START_WARGAME = 0xBADD, CMSG_STOP_DANCE = 0xBADD, CMSG_STORE_LOOT_IN_SLOT = 0xBADD, - CMSG_SUMMON_RESPONSE = 0xBADD, + CMSG_SUMMON_RESPONSE = 0x1BFA, CMSG_SUPPORT_TICKET_SUBMIT_BUG = 0x11BB, CMSG_SUPPORT_TICKET_SUBMIT_COMPLAINT = 0x1BB1, CMSG_SUPPORT_TICKET_SUBMIT_SUGGESTION = 0x1B63, @@ -725,7 +725,7 @@ enum OpcodeClient : uint32 CMSG_TAXIENABLEALLNODES = 0xBADD, CMSG_TAXISHOWNODES = 0xBADD, CMSG_TAXI_NODE_STATUS_QUERY = 0x0EA1, - CMSG_TAXI_QUERY_AVAILABLE_NODES = 0x0B2A, + CMSG_TAXI_QUERY_AVAILABLE_NODES = 0x0A3B, CMSG_TELEPORT_TO_UNIT = 0xBADD, CMSG_TEXT_EMOTE = 0x0B2B, CMSG_TIME_ADJUSTMENT_RESPONSE = 0xBADD, @@ -736,13 +736,14 @@ enum OpcodeClient : uint32 CMSG_TOGGLE_PVP = 0x10A2, CMSG_TOTEM_DESTROYED = 0x1189, CMSG_TOY_SET_FAVORITE = 0xBADD, - CMSG_TRAINER_BUY_SPELL = 0xBADD, + CMSG_TRAINER_BUY_SPELL = 0x151A, CMSG_TRAINER_LIST = 0x130C, CMSG_TRANSMOGRIFY_ITEMS = 0xBADD, CMSG_TRIGGER_CINEMATIC_CHEAT = 0xBADD, CMSG_TROPHY_MONUMENT_LOAD_SELECTED_TROPHY_ID = 0xBADD, CMSG_TURN_IN_PETITION = 0xBADD, CMSG_TUTORIAL_FLAG = 0x1132, + CMSG_TWITTER_GET_STATUS = 0x1128, CMSG_UI_TIME_REQUEST = 0x1B7B, CMSG_UNACCEPT_TRADE = 0xBADD, CMSG_UNDELETE_CHARACTER = 0xBADD, @@ -761,13 +762,13 @@ enum OpcodeClient : uint32 CMSG_USE_EQUIPMENT_SET = 0x0026, CMSG_USE_ITEM = 0x0A5A, CMSG_USE_PARTY_GARRISON = 0xBADD, - CMSG_USE_TOY = 0xBADD, + CMSG_USE_TOY = 0x1BC3, CMSG_VIOLENCE_LEVEL = 0x0071, CMSG_VOICE_ADD_IGNORE = 0xBADD, CMSG_VOICE_DEL_IGNORE = 0xBADD, CMSG_VOICE_SESSION_ENABLE = 0x153A, CMSG_VOID_STORAGE_QUERY = 0x17C3, - CMSG_VOID_STORAGE_TRANSFER = 0xBADD, + CMSG_VOID_STORAGE_TRANSFER = 0x0674, CMSG_VOID_STORAGE_UNLOCK = 0xBADD, CMSG_VOID_SWAP_ITEM = 0xBADD, CMSG_WARDEN_DATA = 0x11E3, @@ -809,7 +810,7 @@ enum OpcodeServer : uint32 SMSG_ACHIEVEMENT_DELETED = 0x0B2C, SMSG_ACHIEVEMENT_EARNED = 0x1D8C, SMSG_ACTION_BUTTONS = 0x153B, - SMSG_ACTIVATE_TAXI_REPLY = 0xBADD, + SMSG_ACTIVATE_TAXI_REPLY = 0x1B8A, SMSG_ADDON_INFO = 0x1F5C, SMSG_ADD_BATTLENET_FRIEND_RESPONSE = 0xBADD, SMSG_ADD_ITEM_PASSIVE = 0xBADD, @@ -828,7 +829,7 @@ enum OpcodeServer : uint32 SMSG_AREA_SPIRIT_HEALER_TIME = 0xBADD, SMSG_AREA_TRIGGER_DEBUG_PLAYER_INSIDE = 0xBADD, SMSG_AREA_TRIGGER_DEBUG_SWEEP = 0xBADD, - SMSG_AREA_TRIGGER_DENIED = 0xBADD, + SMSG_AREA_TRIGGER_DENIED = 0x19FC, SMSG_AREA_TRIGGER_MESSAGE = 0xBADD, SMSG_AREA_TRIGGER_NO_CORPSE = 0xBADD, SMSG_AREA_TRIGGER_RE_PATH = 0xBADD, @@ -868,7 +869,7 @@ enum OpcodeServer : uint32 SMSG_AUTH_RESPONSE = 0x0B61, SMSG_AVAILABLE_VOICE_CHANNEL = 0xBADD, SMSG_AVERAGE_ITEM_LEVEL_INFORM = 0xBADD, - SMSG_BARBER_SHOP_RESULT = 0xBADD, + SMSG_BARBER_SHOP_RESULT = 0x1B89, SMSG_BATTLEFIELD_LIST = 0xBADD, SMSG_BATTLEFIELD_MGR_DROP_TIMER_CANCELED = 0xBADD, SMSG_BATTLEFIELD_MGR_DROP_TIMER_STARTED = 0xBADD, @@ -881,19 +882,19 @@ enum OpcodeServer : uint32 SMSG_BATTLEFIELD_MGR_QUEUE_REQUEST_RESPONSE = 0xBADD, SMSG_BATTLEFIELD_MGR_STATE_CHANGED = 0xBADD, SMSG_BATTLEFIELD_PORT_DENIED = 0xBADD, - SMSG_BATTLEFIELD_RATED_INFO = 0xBADD, + SMSG_BATTLEFIELD_RATED_INFO = 0x1322, SMSG_BATTLEFIELD_STATUS_ACTIVE = 0xBADD, SMSG_BATTLEFIELD_STATUS_FAILED = 0xBADD, SMSG_BATTLEFIELD_STATUS_NEEDCONFIRMATION = 0xBADD, SMSG_BATTLEFIELD_STATUS_NONE = 0xBADD, - SMSG_BATTLEFIELD_STATUS_QUEUED = 0xBADD, + SMSG_BATTLEFIELD_STATUS_QUEUED = 0x135A, SMSG_BATTLEFIELD_STATUS_WAITFORGROUPS = 0xBADD, SMSG_BATTLEGROUND_INFO_THROTTLED = 0xBADD, SMSG_BATTLEGROUND_INIT = 0xBADD, SMSG_BATTLEGROUND_PLAYER_JOINED = 0xBADD, SMSG_BATTLEGROUND_PLAYER_LEFT = 0xBADD, - SMSG_BATTLEGROUND_PLAYER_POSITIONS = 0xBADD, - SMSG_BATTLEGROUND_POINTS = 0xBADD, + SMSG_BATTLEGROUND_PLAYER_POSITIONS = 0x1962, + SMSG_BATTLEGROUND_POINTS = 0x15AB, SMSG_BATTLENET_CHALLENGE_ABORT = 0xBADD, SMSG_BATTLENET_CHALLENGE_START = 0xBADD, SMSG_BATTLE_PAY_ACK_FAILED = 0xBADD, @@ -927,10 +928,10 @@ enum OpcodeServer : uint32 SMSG_BLACK_MARKET_REQUEST_ITEMS_RESULT = 0xBADD, SMSG_BLACK_MARKET_WON = 0xBADD, SMSG_BONUS_ROLL_EMPTY = 0xBADD, - SMSG_BREAK_TARGET = 0xBADD, + SMSG_BREAK_TARGET = 0x159A, SMSG_BUY_BANK_SLOT_RESULT = 0xBADD, SMSG_BUY_FAILED = 0xBADD, - SMSG_BUY_SUCCEEDED = 0xBADD, + SMSG_BUY_SUCCEEDED = 0x117B, SMSG_CALENDAR_ACTION_PENDING = 0xBADD, SMSG_CALENDAR_ARENA_TEAM = 0xBADD, SMSG_CALENDAR_CLEAR_PENDING_ACTION = 0xBADD, @@ -949,10 +950,10 @@ enum OpcodeServer : uint32 SMSG_CALENDAR_EVENT_STATUS = 0xBADD, SMSG_CALENDAR_EVENT_UPDATED_ALERT = 0xBADD, SMSG_CALENDAR_FILTER_GUILD = 0xBADD, - SMSG_CALENDAR_RAID_LOCKOUT_ADDED = 0xBADD, + SMSG_CALENDAR_RAID_LOCKOUT_ADDED = 0x0C83, SMSG_CALENDAR_RAID_LOCKOUT_REMOVED = 0xBADD, SMSG_CALENDAR_RAID_LOCKOUT_UPDATED = 0xBADD, - SMSG_CALENDAR_SEND_CALENDAR = 0xBADD, + SMSG_CALENDAR_SEND_CALENDAR = 0x1562, SMSG_CALENDAR_SEND_EVENT = 0xBADD, SMSG_CALENDAR_SEND_NUM_PENDING = 0x17B1, SMSG_CALENDAR_UPDATE_INVITE_LIST = 0xBADD, @@ -1006,14 +1007,14 @@ enum OpcodeServer : uint32 SMSG_CHECK_WARGAME_ENTRY = 0xBADD, SMSG_CLEAR_ALL_SPELL_CHARGES = 0xBADD, SMSG_CLEAR_BOSS_EMOTES = 0xBADD, - SMSG_CLEAR_COOLDOWN = 0xBADD, + SMSG_CLEAR_COOLDOWN = 0x0964, SMSG_CLEAR_COOLDOWNS = 0xBADD, SMSG_CLEAR_FAR_SIGHT_IMMEDIATE = 0xBADD, SMSG_CLEAR_LOSS_OF_CONTROL = 0xBADD, SMSG_CLEAR_SPELL_CHARGES = 0xBADD, SMSG_CLEAR_TARGET = 0x17FA, SMSG_CLIENTCACHE_VERSION = 0x116C, - SMSG_CLIENT_CONTROL_UPDATE = 0xBADD, + SMSG_CLIENT_CONTROL_UPDATE = 0x1B4C, SMSG_COIN_REMOVED = 0x11A4, SMSG_COMBAT_EVENT_FAILED = 0x19D9, SMSG_COMBAT_LOG_MULTIPLE = 0xBADD, @@ -1024,7 +1025,7 @@ enum OpcodeServer : uint32 SMSG_COMMENTATOR_SKIRMISH_QUEUE_RESULT2 = 0xBADD, SMSG_COMMENTATOR_STATE_CHANGED = 0xBADD, SMSG_COMPLAINT_RESULT = 0xBADD, - SMSG_COMPLETE_SHIPMENT_RESPONSE = 0x173C, + SMSG_COMPLETE_SHIPMENT_RESPONSE = 0xBADD, SMSG_COMPRESSED_MOVES = 0xBADD, SMSG_COMPRESSED_PACKET = 0x0689, SMSG_COMSAT_CONNECT_FAIL = 0xBADD, @@ -1040,7 +1041,7 @@ enum OpcodeServer : uint32 SMSG_CORPSE_LOCATION = 0x0A63, SMSG_CORPSE_RECLAIM_DELAY = 0x1B9C, SMSG_CORPSE_TRANSPORT_QUERY = 0x0B6C, - SMSG_CREATE_SHIPMENT_RESPONSE = 0xBADD, + SMSG_CREATE_SHIPMENT_RESPONSE = 0x0839, SMSG_CREATURE_QUERY_RESPONSE = 0x0DC2, SMSG_CRITERIA_DELETED = 0x0B2A, SMSG_CRITERIA_UPDATE = 0x115A, @@ -1067,28 +1068,28 @@ enum OpcodeServer : uint32 SMSG_DISMOUNT = 0x1371, SMSG_DISMOUNT_RESULT = 0xBADD, SMSG_DISPEL_FAILED = 0xBADD, - SMSG_DISPLAY_GAME_ERROR = 0xBADD, - SMSG_DISPLAY_PLAYER_CHOICE = 0xBADD, + SMSG_DISPLAY_GAME_ERROR = 0x173B, + SMSG_DISPLAY_PLAYER_CHOICE = 0x087C, SMSG_DISPLAY_PROMOTION = 0x01E2, SMSG_DISPLAY_QUEST_POPUP = 0xBADD, SMSG_DISPLAY_TOAST = 0x17DA, SMSG_DONT_AUTO_PUSH_SPELLS_TO_ACTION_BAR = 0xBADD, SMSG_DROP_NEW_CONNECTION = 0xBADD, - SMSG_DUEL_COMPLETE = 0xBADD, + SMSG_DUEL_COMPLETE = 0x1531, SMSG_DUEL_COUNTDOWN = 0x1B1A, - SMSG_DUEL_IN_BOUNDS = 0xBADD, - SMSG_DUEL_OUT_OF_BOUNDS = 0xBADD, + SMSG_DUEL_IN_BOUNDS = 0x13A3, + SMSG_DUEL_OUT_OF_BOUNDS = 0x15F4, SMSG_DUEL_REQUESTED = 0x0983, - SMSG_DUEL_WINNER = 0xBADD, + SMSG_DUEL_WINNER = 0x1519, SMSG_DUMP_RIDE_TICKETS_RESPONSE = 0xBADD, SMSG_DURABILITY_DAMAGE_DEATH = 0x1BCA, SMSG_DYNAMIC_DROP_ROLL_RESULT = 0xBADD, SMSG_ECHO_PARTY_SQUELCH = 0xBADD, SMSG_EMOTE = 0x171C, - SMSG_ENABLE_BARBER_SHOP = 0xBADD, + SMSG_ENABLE_BARBER_SHOP = 0x1D5C, SMSG_ENCHANTMENT_LOG = 0x1563, - SMSG_ENCOUNTER_END = 0xBADD, - SMSG_ENCOUNTER_START = 0xBADD, + SMSG_ENCOUNTER_END = 0x0EC4, + SMSG_ENCOUNTER_START = 0x1B5C, SMSG_ENVIRONMENTALDAMAGELOG = 0x0679, SMSG_EQUIPMENT_SET_LIST = 0x111A, SMSG_EQUIPMENT_SET_SAVED = 0xBADD, @@ -1127,21 +1128,21 @@ enum OpcodeServer : uint32 SMSG_GARRISON_ADD_MISSION_RESULT = 0xBADD, SMSG_GARRISON_ASSIGN_FOLLOWER_TO_BUILDING_RESULT = 0xBADD, SMSG_GARRISON_BUILDING_ACTIVATED = 0x07AA, - SMSG_GARRISON_BUILDING_REMOVED = 0xBADD, + SMSG_GARRISON_BUILDING_REMOVED = 0x0723, SMSG_GARRISON_BUILDING_SET_ACTIVE_SPECIALIZATION_RESULT = 0xBADD, - SMSG_GARRISON_COMPLETE_MISSION_RESULT = 0xBADD, + SMSG_GARRISON_COMPLETE_MISSION_RESULT = 0x02C2, SMSG_GARRISON_DELETE_RESULT = 0xBADD, - SMSG_GARRISON_FOLLOWER_CHANGED_XP = 0x07AC, + SMSG_GARRISON_FOLLOWER_CHANGED_XP = 0xBADD, SMSG_GARRISON_LANDINGPAGE_SHIPMENTS = 0xBADD, - SMSG_GARRISON_LEARN_BLUEPRINT_RESULT = 0xBADD, + SMSG_GARRISON_LEARN_BLUEPRINT_RESULT = 0x0701, SMSG_GARRISON_LEARN_SPECIALIZATION_RESULT = 0xBADD, - SMSG_GARRISON_LIST_FOLLOWERS_CHEAT_RESULT = 0x0081, + SMSG_GARRISON_LIST_FOLLOWERS_CHEAT_RESULT = 0xBADD, SMSG_GARRISON_MISSION_BONUS_ROLL_RESULT = 0xBADD, SMSG_GARRISON_MONUMENT_SELECTED_TROPHY_ID_LOADED = 0xBADD, SMSG_GARRISON_OPEN_ARCHITECT = 0xBADD, SMSG_GARRISON_OPEN_MISSION_NPC = 0xBADD, SMSG_GARRISON_OPEN_TRADESKILL_NPC_RESPONSE = 0xBADD, - SMSG_GARRISON_PLACE_BUILDING_RESULT = 0xBADD, + SMSG_GARRISON_PLACE_BUILDING_RESULT = 0x07CA, SMSG_GARRISON_PLOT_PLACED = 0xBADD, SMSG_GARRISON_PLOT_REMOVED = 0xBADD, SMSG_GARRISON_REMOTE_INFO = 0x0C39, @@ -1149,7 +1150,7 @@ enum OpcodeServer : uint32 SMSG_GARRISON_REMOVE_FOLLOWER_RESULT = 0xBADD, SMSG_GARRISON_REQUEST_BLUEPRINT_AND_SPECIALIZATION_DATA_RESULT = 0xBADD, SMSG_GARRISON_SET_NUM_FOLLOWER_ACTIVATIONS_REMAINING = 0xBADD, - SMSG_GARRISON_START_MISSION_RESULT = 0xBADD, + SMSG_GARRISON_START_MISSION_RESULT = 0x0AA1, SMSG_GARRISON_UNK1 = 0xBADD, SMSG_GARRISON_UNK3 = 0xBADD, SMSG_GARRISON_UPGRADEABLE_RESULT = 0xBADD, @@ -1157,7 +1158,7 @@ enum OpcodeServer : uint32 SMSG_GARRISON_UPGRADE_RESULT = 0xBADD, SMSG_GET_ACCOUNT_CHARACTER_LIST_RESULT = 0xBADD, SMSG_GET_GARRISON_INFO_RESULT = 0x0733, - SMSG_GET_SHIPMENT_INFO_RESPONSE = 0xBADD, + SMSG_GET_SHIPMENT_INFO_RESPONSE = 0x1F09, SMSG_GET_TROPHY_LIST_RESPONSE = 0xBADD, SMSG_GHOST = 0xBADD, SMSG_GHOSTEE_GONE = 0xBADD, @@ -1179,7 +1180,7 @@ enum OpcodeServer : uint32 SMSG_GOD_MODE = 0xBADD, SMSG_GOSSIP_COMPLETE = 0x07A8, SMSG_GOSSIP_MESSAGE = 0x0117, - SMSG_GOSSIP_POI = 0xBADD, + SMSG_GOSSIP_POI = 0x1BBC, SMSG_GROUP_ACTION_THROTTLED = 0xBADD, SMSG_GROUP_CANCEL = 0xBADD, SMSG_GROUP_DECLINE = 0xBADD, @@ -1195,7 +1196,7 @@ enum OpcodeServer : uint32 SMSG_GUILD_BANK_TEXT_QUERY_RESULT = 0xBADD, SMSG_GUILD_CANCEL = 0xBADD, SMSG_GUILD_CHALLENGE_COMPLETED = 0xBADD, - SMSG_GUILD_CHALLENGE_UPDATE = 0xBADD, + SMSG_GUILD_CHALLENGE_UPDATE = 0x04F3, SMSG_GUILD_CHANGE_NAME_RESULT = 0xBADD, SMSG_GUILD_COMMAND_RESULT = 0x0B94, SMSG_GUILD_CRITERIA_DELETED = 0x09B4, @@ -1221,24 +1222,24 @@ enum OpcodeServer : uint32 SMSG_GUILD_INVITE_CANCEL = 0xBADD, SMSG_GUILD_INVITE_DECLINED = 0xBADD, SMSG_GUILD_INVITE_EXPIRED = 0xBADD, - SMSG_GUILD_KNOWN_RECIPES = 0xBADD, + SMSG_GUILD_KNOWN_RECIPES = 0x04B3, SMSG_GUILD_MEMBERS_WITH_RECIPE = 0xBADD, - SMSG_GUILD_MEMBER_DAILY_RESET = 0xBADD, + SMSG_GUILD_MEMBER_DAILY_RESET = 0x08D4, SMSG_GUILD_MEMBER_RECIPES = 0xBADD, SMSG_GUILD_MEMBER_UPDATE_NOTE = 0xBADD, SMSG_GUILD_MOVED = 0xBADD, SMSG_GUILD_MOVE_STARTING = 0xBADD, SMSG_GUILD_NAME_CHANGED = 0xBADD, - SMSG_GUILD_NEWS = 0xBADD, - SMSG_GUILD_NEWS_DELETED = 0xBADD, + SMSG_GUILD_NEWS = 0x05F4, + SMSG_GUILD_NEWS_DELETED = 0x0194, SMSG_GUILD_PARTY_STATE_RESPONSE = 0x0BD4, SMSG_GUILD_PERMISSIONS_QUERY_RESULTS = 0x07D4, SMSG_GUILD_QUERY_RESPONSE = 0x06F3, SMSG_GUILD_RANKS = 0x01D3, SMSG_GUILD_RECIPES = 0xBADD, - SMSG_GUILD_REPUTATION_REACTION_CHANGED = 0xBADD, + SMSG_GUILD_REPUTATION_REACTION_CHANGED = 0x0293, SMSG_GUILD_RESET = 0xBADD, - SMSG_GUILD_REWARDS_LIST = 0xBADD, + SMSG_GUILD_REWARDS_LIST = 0x04D3, SMSG_GUILD_ROSTER = 0x07F3, SMSG_GUILD_ROSTER_UPDATE = 0xBADD, SMSG_GUILD_SEND_RANK_CHANGE = 0xBADD, @@ -1277,8 +1278,8 @@ enum OpcodeServer : uint32 SMSG_INVALIDATE_DANCE = 0xBADD, SMSG_INVALIDATE_PLAYER = 0x1799, SMSG_INVALID_PROMOTION_CODE = 0xBADD, - SMSG_INVENTORY_CHANGE_FAILURE = 0xBADD, - SMSG_IS_QUEST_COMPLETE_RESPONSE = 0xBADD, + SMSG_INVENTORY_CHANGE_FAILURE = 0x05E1, + SMSG_IS_QUEST_COMPLETE_RESPONSE = 0x0108, SMSG_ITEM_COOLDOWN = 0x05A3, SMSG_ITEM_ENCHANT_TIME_UPDATE = 0x176A, SMSG_ITEM_EXPIRE_PURCHASE_REFUND = 0x112B, @@ -1296,7 +1297,7 @@ enum OpcodeServer : uint32 SMSG_LFG_BOOT_PLAYER = 0xBADD, SMSG_LFG_BOOT_PROPOSAL_UPDATE = 0xBADD, SMSG_LFG_DISABLED = 0xBADD, - SMSG_LFG_JOIN_RESULT = 0xBADD, + SMSG_LFG_JOIN_RESULT = 0x01BA, SMSG_LFG_LIST_JOIN_RESULT = 0xBADD, SMSG_LFG_LIST_UPDATE_BLACKLIST = 0xBADD, SMSG_LFG_LIST_UPDATE_STATUS = 0xBADD, @@ -1306,23 +1307,23 @@ enum OpcodeServer : uint32 SMSG_LFG_PLAYER_INFO = 0x03FA, SMSG_LFG_PLAYER_REWARD = 0xBADD, SMSG_LFG_PROPOSAL_UPDATE = 0xBADD, - SMSG_LFG_QUEUE_STATUS = 0xBADD, - SMSG_LFG_ROLE_CHECK_UPDATE = 0xBADD, + SMSG_LFG_QUEUE_STATUS = 0x0292, + SMSG_LFG_ROLE_CHECK_UPDATE = 0x01D9, SMSG_LFG_ROLE_CHOSEN = 0xBADD, SMSG_LFG_SEARCH_RESULTS = 0xBADD, - SMSG_LFG_SLOT_INVALID = 0xBADD, + SMSG_LFG_SLOT_INVALID = 0x0191, SMSG_LFG_TELEPORT_DENIED = 0xBADD, SMSG_LFG_UPDATE_LIST = 0xBADD, SMSG_LFG_UPDATE_SEARCH = 0xBADD, - SMSG_LFG_UPDATE_STATUS = 0xBADD, + SMSG_LFG_UPDATE_STATUS = 0x02B1, SMSG_LF_GUILD_APPLICANT_LIST_UPDATED = 0xBADD, SMSG_LF_GUILD_APPLICATIONS = 0xBADD, SMSG_LF_GUILD_APPLICATIONS_LIST_CHANGED = 0xBADD, SMSG_LF_GUILD_BROWSE = 0xBADD, SMSG_LF_GUILD_COMMAND_RESULT = 0xBADD, SMSG_LF_GUILD_MEMBERSHIP_LIST_UPDATED = 0xBADD, - SMSG_LF_GUILD_POST = 0xBADD, - SMSG_LF_GUILD_RECRUITS = 0xBADD, + SMSG_LF_GUILD_POST = 0x0BD3, + SMSG_LF_GUILD_RECRUITS = 0x0CB3, SMSG_LIST_INVENTORY = 0x17A1, SMSG_LIST_TARGETS = 0xBADD, SMSG_LIVE_REGION_ACCOUNT_RESTORE_RESULT = 0xBADD, @@ -1334,7 +1335,7 @@ enum OpcodeServer : uint32 SMSG_LOGOUT_CANCEL_ACK = 0x1D8A, SMSG_LOGOUT_COMPLETE = 0x17AA, SMSG_LOGOUT_RESPONSE = 0x05C3, - SMSG_LOG_XPGAIN = 0xBADD, + SMSG_LOG_XPGAIN = 0x1B8B, SMSG_LOOT_ALL_PASSED = 0xBADD, SMSG_LOOT_CONTENTS = 0x1334, SMSG_LOOT_ITEM_LIST = 0xBADD, @@ -1371,18 +1372,18 @@ enum OpcodeServer : uint32 SMSG_MODIFY_COOLDOWN = 0x15EA, SMSG_MONEY_NOTIFY = 0xBADD, SMSG_MOTD = 0x12FB, - SMSG_MOUNT_RESULT = 0xBADD, - SMSG_MOVE_APPLY_MOVEMENT_FORCE = 0xBADD, + SMSG_MOUNT_RESULT = 0x1BAC, + SMSG_MOVE_APPLY_MOVEMENT_FORCE = 0x033A, SMSG_MOVE_CHARACTER_CHEAT_FAILURE = 0xBADD, SMSG_MOVE_CHARACTER_CHEAT_SUCCESS = 0xBADD, SMSG_MOVE_DISABLE_CAN_TRANSITION_BETWEEN_SWIM_AND_FLY = 0x0C12, - SMSG_MOVE_DISABLE_COLLISION = 0xBADD, - SMSG_MOVE_DISABLE_GRAVITY = 0xBADD, + SMSG_MOVE_DISABLE_COLLISION = 0x027C, + SMSG_MOVE_DISABLE_GRAVITY = 0x0124, SMSG_MOVE_ENABLE_CAN_TRANSITION_BETWEEN_SWIM_AND_FLY = 0x0AC9, - SMSG_MOVE_ENABLE_COLLISION = 0xBADD, - SMSG_MOVE_ENABLE_GRAVITY = 0xBADD, + SMSG_MOVE_ENABLE_COLLISION = 0x0512, + SMSG_MOVE_ENABLE_GRAVITY = 0x0024, SMSG_MOVE_KNOCK_BACK = 0x048B, - SMSG_MOVE_REMOVE_MOVEMENT_FORCE = 0xBADD, + SMSG_MOVE_REMOVE_MOVEMENT_FORCE = 0x0361, SMSG_MOVE_ROOT = 0x0031, SMSG_MOVE_SET_ACTIVE_MOVER = 0x024C, SMSG_MOVE_SET_ANIM_KIT = 0x1F9B, @@ -1407,10 +1408,10 @@ enum OpcodeServer : uint32 SMSG_MOVE_SET_WALK_IN_AIR = 0xBADD, SMSG_MOVE_SET_WALK_SPEED = 0x024A, SMSG_MOVE_SET_WATER_WALK = 0x0D62, - SMSG_MOVE_SKIP_TIME = 0xBADD, - SMSG_MOVE_SPLINE_DISABLE_COLLISION = 0xBADD, + SMSG_MOVE_SKIP_TIME = 0x0359, + SMSG_MOVE_SPLINE_DISABLE_COLLISION = 0x1392, SMSG_MOVE_SPLINE_DISABLE_GRAVITY = 0x002A, - SMSG_MOVE_SPLINE_ENABLE_COLLISION = 0xBADD, + SMSG_MOVE_SPLINE_ENABLE_COLLISION = 0x0152, SMSG_MOVE_SPLINE_ENABLE_GRAVITY = 0x0641, SMSG_MOVE_SPLINE_ROOT = 0x0A4B, SMSG_MOVE_SPLINE_SET_ANIM = 0xBADD, @@ -1445,7 +1446,7 @@ enum OpcodeServer : uint32 SMSG_MOVE_UNSET_IGNORE_MOVEMENT_FORCES = 0x0E31, SMSG_MOVE_UNSET_WALK_IN_AIR = 0xBADD, SMSG_MOVE_UPDATE = 0x1514, - SMSG_MOVE_UPDATE_APPLY_MOVEMENT_FORCE = 0xBADD, + SMSG_MOVE_UPDATE_APPLY_MOVEMENT_FORCE = 0x1193, SMSG_MOVE_UPDATE_COLLISION_HEIGHT = 0x0624, SMSG_MOVE_UPDATE_FLIGHT_BACK_SPEED = 0x036B, SMSG_MOVE_UPDATE_FLIGHT_SPEED = 0x0D72, @@ -1467,17 +1468,17 @@ enum OpcodeServer : uint32 SMSG_NOTIFICATION = 0xBADD, SMSG_NOTIFY_DANCE = 0xBADD, SMSG_NOTIFY_DEST_LOC_SPELL_CAST = 0xBADD, - SMSG_NOTIFY_MISSILE_TRAJECTORY_COLLISION = 0xBADD, + SMSG_NOTIFY_MISSILE_TRAJECTORY_COLLISION = 0x1F49, SMSG_NOTIFY_MONEY = 0xBADD, - SMSG_NOTIFY_RECEIVED_MAIL = 0xBADD, + SMSG_NOTIFY_RECEIVED_MAIL = 0x136C, SMSG_NPC_TEXT_UPDATE = 0x0A31, SMSG_NPC_WONT_TALK = 0xBADD, SMSG_OFFER_PETITION_ERROR = 0xBADD, - SMSG_ON_CANCEL_EXPECTED_RIDE_VEHICLE_AURA = 0xBADD, + SMSG_ON_CANCEL_EXPECTED_RIDE_VEHICLE_AURA = 0x096C, SMSG_ON_MONSTER_MOVE = 0x0B09, SMSG_OPEN_CONTAINER = 0xBADD, SMSG_OPEN_LFG_DUNGEON_FINDER = 0xBADD, - SMSG_OPEN_SHIPMENT_NPC_FROM_GOSSIP = 0xBADD, + SMSG_OPEN_SHIPMENT_NPC_FROM_GOSSIP = 0x11F2, SMSG_OPEN_SHIPMENT_NPC_RESULT = 0xBADD, SMSG_OVERRIDE_LIGHT = 0xBADD, SMSG_PAGE_TEXT = 0xBADD, @@ -1485,17 +1486,17 @@ enum OpcodeServer : uint32 SMSG_PARTY_COMMAND_RESULT = 0xBADD, SMSG_PARTY_INVITE = 0x1F9C, SMSG_PARTY_KILL_LOG = 0x0CA4, - SMSG_PARTY_MEMBER_STATE = 0xBADD, + SMSG_PARTY_MEMBER_STATE = 0x1564, SMSG_PARTY_MEMBER_STATS = 0xBADD, SMSG_PARTY_MEMBER_STATS_FULL = 0xBADD, - SMSG_PARTY_UPDATE = 0xBADD, + SMSG_PARTY_UPDATE = 0x0981, SMSG_PAUSE_MIRROR_TIMER = 0xBADD, SMSG_PENDING_RAID_LOCK = 0xBADD, SMSG_PERIODICAURALOG = 0x184B, SMSG_PETITION_ALREADY_SIGNED = 0xBADD, SMSG_PETITION_DECLINED = 0xBADD, SMSG_PETITION_RENAME_GUILD_RESPONSE = 0xBADD, - SMSG_PETITION_SHOW_LIST = 0xBADD, + SMSG_PETITION_SHOW_LIST = 0x1134, SMSG_PETITION_SHOW_SIGNATURES = 0xBADD, SMSG_PETITION_SIGN_RESULTS = 0xBADD, SMSG_PET_ACTION_FEEDBACK = 0xBADD, @@ -1503,40 +1504,40 @@ enum OpcodeServer : uint32 SMSG_PET_ADDED = 0xBADD, SMSG_PET_BATTLE_CHAT_RESTRICTED = 0xBADD, SMSG_PET_BATTLE_DEBUG_QUEUE_DUMP_RESPONSE = 0xBADD, - SMSG_PET_BATTLE_FINALIZE_LOCATION = 0xBADD, - SMSG_PET_BATTLE_FINAL_ROUND = 0xBADD, - SMSG_PET_BATTLE_FINISHED = 0xBADD, - SMSG_PET_BATTLE_FIRST_ROUND = 0xBADD, - SMSG_PET_BATTLE_INITIAL_UPDATE = 0xBADD, + SMSG_PET_BATTLE_FINALIZE_LOCATION = 0x1D24, + SMSG_PET_BATTLE_FINAL_ROUND = 0x0B29, + SMSG_PET_BATTLE_FINISHED = 0x15FC, + SMSG_PET_BATTLE_FIRST_ROUND = 0x11CA, + SMSG_PET_BATTLE_INITIAL_UPDATE = 0x153A, SMSG_PET_BATTLE_MAX_GAME_LENGTH_WARNING = 0xBADD, SMSG_PET_BATTLE_PVP_CHALLENGE = 0xBADD, SMSG_PET_BATTLE_QUEUE_PROPOSE_MATCH = 0xBADD, SMSG_PET_BATTLE_QUEUE_STATUS = 0xBADD, SMSG_PET_BATTLE_REPLACEMENTS_MADE = 0xBADD, SMSG_PET_BATTLE_REQUEST_FAILED = 0xBADD, - SMSG_PET_BATTLE_ROUND_RESULT = 0xBADD, + SMSG_PET_BATTLE_ROUND_RESULT = 0x15F9, SMSG_PET_BATTLE_SLOT_UPDATES = 0xBADD, SMSG_PET_BROKEN = 0xBADD, SMSG_PET_CAST_FAILED = 0xBADD, - SMSG_PET_CLEAR_SPELLS = 0xBADD, + SMSG_PET_CLEAR_SPELLS = 0x0EEA, SMSG_PET_DISMISS_SOUND = 0x11BC, SMSG_PET_GOD_MODE = 0xBADD, SMSG_PET_GUIDS = 0x198A, SMSG_PET_LEARNED_SPELL = 0xBADD, - SMSG_PET_MODE = 0xBADD, + SMSG_PET_MODE = 0x196B, SMSG_PET_NAME_INVALID = 0xBADD, SMSG_PET_NAME_QUERY_RESPONSE = 0x15A9, SMSG_PET_REMOVED_SPELL = 0xBADD, SMSG_PET_RENAMEABLE = 0xBADD, SMSG_PET_SLOT_UPDATED = 0xBADD, SMSG_PET_SPECIALIZATION = 0xBADD, - SMSG_PET_SPELLS = 0xBADD, + SMSG_PET_SPELLS = 0x1283, SMSG_PET_STABLE_LIST = 0x04E2, SMSG_PET_STABLE_RESULT = 0xBADD, SMSG_PET_TAME_FAILURE = 0xBADD, SMSG_PET_UPDATE_COMBO_POINTS = 0xBADD, SMSG_PLAYED_TIME = 0x0B71, - SMSG_PLAYER_BOUND = 0xBADD, + SMSG_PLAYER_BOUND = 0x19A1, SMSG_PLAYER_SKINNED = 0xBADD, SMSG_PLAYER_VEHICLE_DATA = 0xBADD, SMSG_PLAY_DANCE = 0xBADD, @@ -1579,7 +1580,7 @@ enum OpcodeServer : uint32 SMSG_QUESTGIVER_STATUS_MULTIPLE = 0x030F, SMSG_QUEST_COMPLETION_NPC_RESPONSE = 0x071D, SMSG_QUEST_CONFIRM_ACCEPT = 0xBADD, - SMSG_QUEST_FORCE_REMOVED = 0xBADD, + SMSG_QUEST_FORCE_REMOVED = 0x0120, SMSG_QUEST_LOG_FULL = 0xBADD, SMSG_QUEST_POI_QUERY_RESPONSE = 0x01AE, SMSG_QUEST_PUSH_RESULT = 0xBADD, @@ -1593,7 +1594,7 @@ enum OpcodeServer : uint32 SMSG_RAF_EMAIL_ENABLED_RESPONSE = 0xBADD, SMSG_RAID_GROUP_ONLY = 0xBADD, SMSG_RAID_INSTANCE_INFO = 0xBADD, - SMSG_RAID_INSTANCE_MESSAGE = 0xBADD, + SMSG_RAID_INSTANCE_MESSAGE = 0x12F3, SMSG_RAID_MARKERS_CHANGED = 0xBADD, SMSG_RANDOMIZE_CHAR_NAME = 0x195B, SMSG_RANDOM_ROLL = 0x04C1, @@ -1612,19 +1613,19 @@ enum OpcodeServer : uint32 SMSG_REFER_A_FRIEND_EXPIRED = 0xBADD, SMSG_REFER_A_FRIEND_FAILURE = 0xBADD, SMSG_REFRESH_COMPONENT = 0xBADD, - SMSG_REFRESH_SPELL_HISTORY = 0xBADD, + SMSG_REFRESH_SPELL_HISTORY = 0x072B, SMSG_REMOVE_ITEM_PASSIVE = 0xBADD, SMSG_REMOVE_LOSS_OF_CONTROL = 0xBADD, SMSG_REPLACE_TROPHY_RESPONSE = 0xBADD, SMSG_REPORT_PVP_AFK_RESULT = 0xBADD, SMSG_REQUEST_CEMETERY_LIST_RESPONSE = 0x15BB, - SMSG_REQUEST_PVP_REWARDS_RESPONSE = 0xBADD, + SMSG_REQUEST_PVP_REWARDS_RESPONSE = 0x1B74, SMSG_RESEARCH_COMPLETE = 0xBADD, - SMSG_RESEARCH_SETUP_HISTORY = 0xBADD, + SMSG_RESEARCH_SETUP_HISTORY = 0x1D8B, SMSG_RESET_AREA_TRIGGER = 0xBADD, SMSG_RESET_COMPRESSION_CONTEXT = 0xBADD, SMSG_RESET_FAILED_NOTIFY = 0xBADD, - SMSG_RESET_RANGED_COMBAT_TIMER = 0xBADD, + SMSG_RESET_RANGED_COMBAT_TIMER = 0x135C, SMSG_RESET_WEEKLY_CURRENCY = 0xBADD, SMSG_RESISTLOG = 0xBADD, SMSG_RESPEC_WIPE_CONFIRM = 0xBADD, @@ -1658,7 +1659,7 @@ enum OpcodeServer : uint32 SMSG_SCRIPT_MESSAGE = 0xBADD, SMSG_SELL_RESPONSE = 0x0933, SMSG_SEND_ITEM_PASSIVES = 0xBADD, - SMSG_SEND_MAIL_RESULT = 0xBADD, + SMSG_SEND_MAIL_RESULT = 0x01C4, SMSG_SEND_RAID_TARGET_UPDATE_ALL = 0xBADD, SMSG_SEND_RAID_TARGET_UPDATE_SINGLE = 0xBADD, SMSG_SEND_SPELL_CHARGES = 0x0CEB, @@ -1686,15 +1687,15 @@ enum OpcodeServer : uint32 SMSG_SET_FACTION_STANDING = 0x1129, SMSG_SET_FACTION_VISIBLE = 0x0A72, SMSG_SET_FLAT_SPELL_MODIFIER = 0x120B, - SMSG_SET_FORCED_REACTIONS = 0xBADD, + SMSG_SET_FORCED_REACTIONS = 0x0EC2, SMSG_SET_ITEM_PURCHASE_DATA = 0xBADD, SMSG_SET_LFG_TIME_WALKER = 0xBADD, SMSG_SET_LOOT_METHOD_FAILED = 0xBADD, - SMSG_SET_MAX_WEEKLY_QUANTITY = 0xBADD, + SMSG_SET_MAX_WEEKLY_QUANTITY = 0x1372, SMSG_SET_MELEE_ANIM_KIT = 0x1B2C, SMSG_SET_PCT_SPELL_MODIFIER = 0x0E59, SMSG_SET_PHASE_SHIFT_CHANGE = 0x17F9, - SMSG_SET_PLAYER_DECLINED_NAMES_RESULT = 0xBADD, + SMSG_SET_PLAYER_DECLINED_NAMES_RESULT = 0x1363, SMSG_SET_PLAY_HOVER_ANIM = 0x01C3, SMSG_SET_PROFICIENCY = 0x092A, SMSG_SET_PROJECTILE_POSITION = 0xBADD, @@ -1749,7 +1750,7 @@ enum OpcodeServer : uint32 SMSG_STOP_DANCE = 0xBADD, SMSG_STOP_ELAPSED_TIMER = 0x092B, SMSG_STOP_MIRROR_TIMER = 0x0D81, - SMSG_STREAMING_MOVIE = 0xBADD, + SMSG_STREAMING_MOVIE = 0x0A7B, SMSG_SUMMON_CANCEL = 0xBADD, SMSG_SUMMON_RAID_MEMBER_VALIDATE_FAILED = 0xBADD, SMSG_SUMMON_REQUEST = 0xBADD, @@ -1757,7 +1758,7 @@ enum OpcodeServer : uint32 SMSG_SUPPRESS_NPC_GREETINGS = 0x118B, SMSG_SUSPEND_COMMS = 0x068B, SMSG_SUSPEND_TOKEN = 0x1BB4, - SMSG_TABARD_VENDOR_ACTIVATE = 0xBADD, + SMSG_TABARD_VENDOR_ACTIVATE = 0x15BC, SMSG_TALENTS_ERROR = 0xBADD, SMSG_TALENTS_INFO = 0x04C4, SMSG_TALENTS_INVOLUNTARILY_RESET = 0xBADD, @@ -1769,9 +1770,9 @@ enum OpcodeServer : uint32 SMSG_THREAT_UPDATE = 0x0B33, SMSG_TIME_ADJUSTMENT = 0xBADD, SMSG_TIME_SYNC_REQ = 0x0A01, - SMSG_TITLE_EARNED = 0xBADD, - SMSG_TITLE_LOST = 0xBADD, - SMSG_TOTEM_CREATED = 0xBADD, + SMSG_TITLE_EARNED = 0x0D83, + SMSG_TITLE_LOST = 0x083B, + SMSG_TOTEM_CREATED = 0x1F5A, SMSG_TOTEM_MOVED = 0xBADD, SMSG_TRADE_STATUS = 0xBADD, SMSG_TRADE_UPDATED = 0xBADD, @@ -1780,8 +1781,8 @@ enum OpcodeServer : uint32 SMSG_TRAINER_LIST = 0x1F4B, SMSG_TRANSFER_ABORTED = 0x1B7C, SMSG_TRANSFER_PENDING = 0x1BDB, - SMSG_TRIGGER_CINEMATIC = 0xBADD, - SMSG_TRIGGER_MOVIE = 0xBADD, + SMSG_TRIGGER_CINEMATIC = 0x0863, + SMSG_TRIGGER_MOVIE = 0x1B3C, SMSG_TURN_IN_PETITION_RESULTS = 0xBADD, SMSG_TUTORIAL_FLAGS = 0x0A39, SMSG_UI_TIME = 0x05E3, @@ -1815,10 +1816,10 @@ enum OpcodeServer : uint32 SMSG_VOICE_SESSION_ROSTER_UPDATE = 0xBADD, SMSG_VOICE_SET_TALKER_MUTED = 0xBADD, SMSG_VOID_ITEM_SWAP_RESPONSE = 0xBADD, - SMSG_VOID_STORAGE_CONTENTS = 0xBADD, + SMSG_VOID_STORAGE_CONTENTS = 0x1122, SMSG_VOID_STORAGE_FAILED = 0xBADD, - SMSG_VOID_STORAGE_TRANSFER_CHANGES = 0xBADD, - SMSG_VOID_TRANSFER_RESULT = 0xBADD, + SMSG_VOID_STORAGE_TRANSFER_CHANGES = 0x1BAB, + SMSG_VOID_TRANSFER_RESULT = 0x192C, SMSG_WAIT_QUEUE_FINISH = 0xBADD, SMSG_WAIT_QUEUE_UPDATE = 0xBADD, SMSG_WARDEN_DATA = 0x110A, @@ -1838,173 +1839,19 @@ enum OpcodeServer : uint32 inline bool IsInstanceOnlyOpcode(uint32 opcode) { - // TODO: Use names when known switch (opcode) { - /*case SMSG_MOUNT_RESULT: // Client - case SMSG_DUEL_OUT_OF_BOUNDS: // Client - case SMSG_DUEL_IN_BOUNDS: // Client - case 0x0549: // Client - case 0x055A: // Client - case 0x055C: // Client - case 0x057A: // Client - case 0x057C: // Client - case 0x05C9: // Client - case 0x05CA: // Client - case 0x05D9: // Client - case 0x05DA: // Client - case 0x05DC: // Client - case 0x05E9: // Client - case 0x05F9: // Client - case 0x05FC: // Client - case 0x074B: // Client - case 0x074C: // Client - case 0x075B: // Client - case 0x075C: // Client - case 0x076C: // Client - case 0x07CB: // Client - case 0x07CC: // Client - case 0x07DB: // Client - case 0x07DC: // Client - case 0x07EC: // Client + case SMSG_QUESTGIVER_STATUS: // ClientQuest case SMSG_DUEL_REQUESTED: // Client + case SMSG_DUEL_IN_BOUNDS: // Client + case SMSG_QUERY_TIME_RESPONSE: // Client case SMSG_DUEL_WINNER: // Client - case 0x0F0F: // ClientSpell - case 0x0F10: // ClientSpell - case 0x0F30: // ClientSpell - case 0x0F3B: // ClientSpell - case 0x0F8B: // ClientSpell - case 0x0F8C: // ClientSpell - case 0x0F90: // ClientSpell - case 0x0F9F: // ClientSpell - case 0x0FA0: // ClientSpell - case SMSG_ATTACKSTOP: // Client case SMSG_DUEL_COMPLETE: // Client - case 0x154B: // Client - case 0x154C: // Client - case 0x155A: // Client - case 0x155B: // Client - case 0x155C: // Client - case SMSG_QUESTGIVER_STATUS: // ClientQuest - case 0x156B: // Client - case 0x1579: // Client - case 0x157B: // Client - case 0x15CB: // Client - case 0x15CC: // Client - case 0x15DB: // Client - case 0x15DC: // Client - case 0x15EB: // Client - case 0x15FB: // Client - case 0x1710: // ClientSpell - case 0x1720: // ClientSpell - case 0x172B: // ClientSpell - case 0x172C: // ClientSpell - case 0x172F: // ClientSpell - case 0x1730: // ClientSpell - case 0x173C: // ClientSpell - case 0x178B: // ClientSpell - case 0x178C: // ClientSpell - case 0x178F: // ClientSpell - case 0x1790: // ClientSpell - case 0x179B: // ClientSpell - case 0x179F: // ClientSpell + case SMSG_DUEL_OUT_OF_BOUNDS: // Client + case SMSG_ATTACKSTOP: // Client case SMSG_ATTACKSTART: // Client - case 0x1D82: // ClientQuest - case 0x1D83: // ClientQuest - case 0x1D84: // ClientQuest - case 0x1D86: // ClientQuest - case 0x1D91: // ClientQuest - case 0x1D92: // ClientQuest - case 0x1D94: // ClientQuest - case 0x1D96: // ClientQuest - case 0x1D97: // ClientQuest - case 0x1DA1: // ClientQuest - case 0x1DA2: // ClientQuest - case 0x1DA3: // ClientQuest - case 0x1DA4: // ClientQuest - case 0x1DA5: // ClientQuest - case 0x1DA7: // ClientQuest - case SMSG_QUERY_TIME_RESPONSE: // Client - case 0x1DC4: // ClientQuest - case 0x1DC8: // ClientQuest - case 0x1DD1: // ClientQuest - case 0x1DD2: // ClientQuest - case 0x1DD3: // ClientQuest - case 0x1DD4: // ClientQuest - case 0x1DD6: // ClientQuest - case 0x1DE1: // ClientQuest - case 0x1DE2: // ClientQuest - case 0x1DE3: // ClientQuest - case 0x1DE4: // ClientQuest - case 0x1DE5: // ClientQuest - case 0x1DE7: // ClientQuest - case 0x1F04: // ClientQuest - case 0x1F08: // ClientQuest - case 0x1F10: // ClientSpell - case 0x1F11: // ClientQuest - case 0x1F12: // ClientQuest - case 0x1F13: // ClientQuest - case 0x1F14: // ClientQuest - case 0x1F16: // ClientQuest - case 0x1F20: // ClientSpell - case 0x1F21: // ClientQuest - case 0x1F22: // ClientQuest - case 0x1F23: // ClientQuest - case 0x1F24: // ClientQuest - case 0x1F25: // ClientQuest - case 0x1F27: // ClientQuest - case 0x1F2B: // ClientSpell - case 0x1F2C: // ClientSpell - case 0x1F2F: // ClientSpell - case 0x1F30: // ClientSpell - case 0x1F3C: // ClientSpell - case 0x1F41: // ClientQuest - case 0x1F42: // ClientQuest - case 0x1F44: // ClientQuest - case 0x1F46: // ClientQuest - case 0x1F47: // ClientQuest - case 0x1F48: // ClientQuest - case 0x1F52: // ClientQuest - case 0x1F53: // ClientQuest - case 0x1F55: // ClientQuest - case 0x1F57: // ClientQuest - case 0x1F61: // ClientQuest - case 0x1F63: // ClientQuest - case 0x1F64: // ClientQuest - case 0x1F65: // ClientQuest - case 0x1F67: // ClientQuest - case 0x1F84: // ClientQuest - case 0x1F87: // ClientQuest - case 0x1F8B: // ClientSpell - case 0x1F8C: // ClientSpell - case 0x1F8F: // ClientSpell - case 0x1F90: // ClientSpell - case 0x1F91: // ClientQuest - case 0x1F95: // ClientQuest - case 0x1F96: // ClientQuest - case 0x1F97: // ClientQuest - case 0x1F9B: // ClientSpell - case 0x1F9F: // ClientSpell - case 0x1FA1: // ClientQuest - case 0x1FA2: // ClientQuest - case 0x1FA3: // ClientQuest - case 0x1FA4: // ClientQuest - case 0x1FA5: // ClientQuest - case 0x1FA7: // ClientQuest - case 0x1FC4: // ClientQuest - case 0x1FC8: // ClientQuest - case 0x1FD1: // ClientQuest - case 0x1FD2: // ClientQuest - case 0x1FD3: // ClientQuest - case 0x1FD4: // ClientQuest - case 0x1FD6: // ClientQuest - case 0x1FE1: // ClientQuest - case 0x1FE2: // ClientQuest - case 0x1FE3: // ClientQuest - case 0x1FE4: // ClientQuest - case 0x1FE5: // ClientQuest - case 0x1FE7: // ClientQuest - return true;*/ + case SMSG_MOUNT_RESULT: // Client + return true; default: return false; } diff --git a/src/server/game/Server/WorldSession.cpp b/src/server/game/Server/WorldSession.cpp index 15a06a29cb7..6c889b51631 100644 --- a/src/server/game/Server/WorldSession.cpp +++ b/src/server/game/Server/WorldSession.cpp @@ -272,8 +272,8 @@ void WorldSession::SendPacket(WorldPacket const* packet, bool forced /*= false*/ { uint64 minTime = uint64(cur_time - lastTime); uint64 fullTime = uint64(lastTime - firstTime); - TC_LOG_INFO("misc", "Send all time packets count: " UI64FMTD " bytes: " UI64FMTD " avr.count/sec: %f avr.bytes/sec: %f time: %u", sendPacketCount, sendPacketBytes, float(sendPacketCount)/fullTime, float(sendPacketBytes)/fullTime, uint32(fullTime)); - TC_LOG_INFO("misc", "Send last min packets count: " UI64FMTD " bytes: " UI64FMTD " avr.count/sec: %f avr.bytes/sec: %f", sendLastPacketCount, sendLastPacketBytes, float(sendLastPacketCount)/minTime, float(sendLastPacketBytes)/minTime); + TC_LOG_DEBUG("misc", "Send all time packets count: " UI64FMTD " bytes: " UI64FMTD " avr.count/sec: %f avr.bytes/sec: %f time: %u", sendPacketCount, sendPacketBytes, float(sendPacketCount)/fullTime, float(sendPacketBytes)/fullTime, uint32(fullTime)); + TC_LOG_DEBUG("misc", "Send last min packets count: " UI64FMTD " bytes: " UI64FMTD " avr.count/sec: %f avr.bytes/sec: %f", sendLastPacketCount, sendLastPacketBytes, float(sendLastPacketCount)/minTime, float(sendLastPacketBytes)/minTime); lastTime = cur_time; sendLastPacketCount = 1; @@ -865,7 +865,7 @@ void WorldSession::ReadAddonsInfo(ByteBuffer& data) addonInfo >> enabled >> crc >> unk1; - TC_LOG_INFO("misc", "ADDON: Name: %s, Enabled: 0x%x, CRC: 0x%x, Unknown2: 0x%x", addonName.c_str(), enabled, crc, unk1); + TC_LOG_DEBUG("misc", "ADDON: Name: %s, Enabled: 0x%x, CRC: 0x%x, Unknown2: 0x%x", addonName.c_str(), enabled, crc, unk1); AddonInfo addon(addonName, enabled, crc, 2, true); @@ -873,15 +873,15 @@ void WorldSession::ReadAddonsInfo(ByteBuffer& data) if (savedAddon) { if (addon.CRC != savedAddon->CRC) - TC_LOG_INFO("misc", "ADDON: %s was known, but didn't match known CRC (0x%x)!", addon.Name.c_str(), savedAddon->CRC); + TC_LOG_ERROR("misc", "ADDON: %s was known, but didn't match known CRC (0x%x)!", addon.Name.c_str(), savedAddon->CRC); else - TC_LOG_INFO("misc", "ADDON: %s was known, CRC is correct (0x%x)", addon.Name.c_str(), savedAddon->CRC); + TC_LOG_DEBUG("misc", "ADDON: %s was known, CRC is correct (0x%x)", addon.Name.c_str(), savedAddon->CRC); } else { AddonMgr::SaveAddon(addon); - TC_LOG_INFO("misc", "ADDON: %s (0x%x) was not known, saving...", addon.Name.c_str(), addon.CRC); + TC_LOG_DEBUG("misc", "ADDON: %s (0x%x) was not known, saving...", addon.Name.c_str(), addon.CRC); } /// @todo Find out when to not use CRC/pubkey, and other possible states. @@ -1174,7 +1174,7 @@ bool WorldSession::DosProtection::EvaluateOpcode(WorldPacket& p, time_t time) co return true; case POLICY_KICK: { - TC_LOG_INFO("network", "AntiDOS: Player kicked!"); + TC_LOG_WARN("network", "AntiDOS: Player kicked!"); Session->KickPlayer(); return false; } @@ -1190,7 +1190,7 @@ bool WorldSession::DosProtection::EvaluateOpcode(WorldPacket& p, time_t time) co case BAN_IP: nameOrIp = Session->GetRemoteAddress(); break; } sWorld->BanAccount(bm, nameOrIp, duration, "DOS (Packet Flooding/Spoofing", "Server: AutoDOS"); - TC_LOG_INFO("network", "AntiDOS: Player automatically banned for %u seconds.", duration); + TC_LOG_WARN("network", "AntiDOS: Player automatically banned for %u seconds.", duration); Session->KickPlayer(); return false; } diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h index 71ce6546d3c..e1ad57bbc77 100644 --- a/src/server/game/Server/WorldSession.h +++ b/src/server/game/Server/WorldSession.h @@ -90,6 +90,13 @@ namespace WorldPackets enum class ConnectToSerial : uint32; } + namespace Bank + { + class AutoBankItem; + class AutoStoreBankItem; + class BuyBankSlot; + } + namespace BlackMarket { class BlackMarketOpen; @@ -287,6 +294,9 @@ namespace WorldPackets class ClientPlayerMovement; class WorldPortAck; class MoveTeleportAck; + class MovementAck; + class MovementSpeedAck; + class SetActiveMover; } namespace NPC @@ -352,6 +362,7 @@ namespace WorldPackets class CastSpell; class PetCastSpell; class UseItem; + class OpenItem; class SetActionButton; } @@ -838,7 +849,7 @@ class WorldSession void HandleMoveKnockBackAck(WorldPacket& recvPacket); void HandleMoveTeleportAck(WorldPackets::Movement::MoveTeleportAck& packet); - void HandleForceSpeedChangeAck(WorldPacket& recvData); + void HandleForceSpeedChangeAck(WorldPackets::Movement::MovementSpeedAck& packet); void HandleSetCollisionHeightAck(WorldPacket& recvPacket); void HandlePingOpcode(WorldPacket& recvPacket); @@ -910,7 +921,7 @@ class WorldSession void HandleMoveWorldportAckOpcode(); // for server-side calls void HandleMovementOpcodes(WorldPackets::Movement::ClientPlayerMovement& packet); - void HandleSetActiveMoverOpcode(WorldPacket& recvData); + void HandleSetActiveMoverOpcode(WorldPackets::Movement::SetActiveMover& packet); void HandleMoveNotActiveMover(WorldPacket& recvData); void HandleDismissControlledVehicle(WorldPacket& recvData); void HandleRequestVehicleExit(WorldPacket& recvData); @@ -999,7 +1010,6 @@ class WorldSession void HandleTabardVendorActivateOpcode(WorldPackets::NPC::Hello& packet); void HandleBankerActivateOpcode(WorldPackets::NPC::Hello& packet); - void HandleBuyBankSlotOpcode(WorldPacket& recvPacket); void HandleTrainerListOpcode(WorldPackets::NPC::Hello& packet); void HandleTrainerBuySpellOpcode(WorldPacket& recvPacket); void HandlePetitionShowList(WorldPackets::Petition::PetitionShowList& packet); @@ -1043,6 +1053,11 @@ class WorldSession void HandleAuctionPlaceBid(WorldPacket& recvData); void HandleAuctionListPendingSales(WorldPacket& recvData); + // Bank + void HandleAutoBankItemOpcode(WorldPackets::Bank::AutoBankItem& packet); + void HandleAutoStoreBankItemOpcode(WorldPackets::Bank::AutoStoreBankItem& packet); + void HandleBuyBankSlotOpcode(WorldPackets::Bank::BuyBankSlot& packet); + // Black Market void HandleBlackMarketOpen(WorldPackets::BlackMarket::BlackMarketOpen& packet); @@ -1072,8 +1087,6 @@ class WorldSession void HandleAutoEquipItemSlotOpcode(WorldPacket& recvPacket); void HandleSwapItem(WorldPackets::Item::SwapItem& swapItem); void HandleBuybackItem(WorldPackets::Item::BuyBackItem& packet); - void HandleAutoBankItemOpcode(WorldPacket& recvPacket); - void HandleAutoStoreBankItemOpcode(WorldPacket& recvPacket); void HandleWrapItemOpcode(WorldPacket& recvPacket); void HandleAttackSwingOpcode(WorldPackets::Combat::AttackSwing& packet); @@ -1081,7 +1094,7 @@ class WorldSession void HandleSetSheathedOpcode(WorldPackets::Combat::SetSheathed& packet); void HandleUseItemOpcode(WorldPackets::Spells::UseItem& packet); - void HandleOpenItemOpcode(WorldPacket& recvPacket); + void HandleOpenItemOpcode(WorldPackets::Spells::OpenItem& packet); void HandleCastSpellOpcode(WorldPackets::Spells::CastSpell& castRequest); void HandleCancelCastOpcode(WorldPackets::Spells::CancelCast& packet); void HandleCancelAuraOpcode(WorldPackets::Spells::CancelAura& cancelAura); @@ -1165,8 +1178,7 @@ class WorldSession void HandlePetRename(WorldPacket& recvData); void HandlePetCancelAuraOpcode(WorldPacket& recvPacket); void HandlePetSpellAutocastOpcode(WorldPacket& recvPacket); - void HandlePetCastSpellOpcode(WorldPackets::Spells::PetCastSpell& castRequest); - void HandlePetLearnTalent(WorldPacket& recvPacket); + void HandlePetCastSpellOpcode(WorldPackets::Spells::PetCastSpell& petCastSpell); void HandleSetActionBarToggles(WorldPackets::Character::SetActionBarToggles& packet); diff --git a/src/server/game/Server/WorldSocket.cpp b/src/server/game/Server/WorldSocket.cpp index ba0d2c7d48e..01035154214 100644 --- a/src/server/game/Server/WorldSocket.cpp +++ b/src/server/game/Server/WorldSocket.cpp @@ -212,14 +212,12 @@ bool WorldSocket::ReadDataHandler() OpcodeClient opcode = static_cast<OpcodeClient>(cmd); - std::string opcodeName = GetOpcodeNameForLogging(opcode); - WorldPacket packet(opcode, std::move(_packetBuffer), GetConnectionType()); if (sPacketLog->CanLogPacket()) sPacketLog->LogPacket(packet, CLIENT_TO_SERVER, GetRemoteIpAddress(), GetRemotePort(), GetConnectionType()); - TC_LOG_TRACE("network.opcode", "C->S: %s %s", (_worldSession ? _worldSession->GetPlayerInfo() : GetRemoteIpAddress().to_string()).c_str(), opcodeName.c_str()); + TC_LOG_TRACE("network.opcode", "C->S: %s %s", (_worldSession ? _worldSession->GetPlayerInfo() : GetRemoteIpAddress().to_string()).c_str(), GetOpcodeNameForLogging(opcode).c_str()); switch (opcode) { @@ -253,17 +251,17 @@ bool WorldSocket::ReadDataHandler() break; } case CMSG_KEEP_ALIVE: - TC_LOG_DEBUG("network", "%s", opcodeName.c_str()); + TC_LOG_DEBUG("network", "%s", GetOpcodeNameForLogging(opcode).c_str()); sScriptMgr->OnPacketReceive(_worldSession, packet); break; case CMSG_LOG_DISCONNECT: packet.rfinish(); // contains uint32 disconnectReason; - TC_LOG_DEBUG("network", "%s", opcodeName.c_str()); + TC_LOG_DEBUG("network", "%s", GetOpcodeNameForLogging(opcode).c_str()); sScriptMgr->OnPacketReceive(_worldSession, packet); return true; case CMSG_ENABLE_NAGLE: { - TC_LOG_DEBUG("network", "%s", opcodeName.c_str()); + TC_LOG_DEBUG("network", "%s", GetOpcodeNameForLogging(opcode).c_str()); sScriptMgr->OnPacketReceive(_worldSession, packet); if (_worldSession) _worldSession->HandleEnableNagleAlgorithm(); @@ -627,7 +625,7 @@ void WorldSocket::HandleAuthSession(WorldPackets::Auth::AuthSession& authSession if (allowedAccountType > SEC_PLAYER && AccountTypes(security) < allowedAccountType) { SendAuthResponseError(AUTH_UNAVAILABLE); - TC_LOG_INFO("network", "WorldSocket::HandleAuthSession: User tries to login but his security level is not enough"); + TC_LOG_DEBUG("network", "WorldSocket::HandleAuthSession: User tries to login but his security level is not enough"); sScriptMgr->OnFailedAccountLogin(id); DelayedCloseSocket(); return; diff --git a/src/server/game/Server/WorldSocketMgr.cpp b/src/server/game/Server/WorldSocketMgr.cpp index 11d77b082e8..0a2b3cb4edf 100644 --- a/src/server/game/Server/WorldSocketMgr.cpp +++ b/src/server/game/Server/WorldSocketMgr.cpp @@ -51,6 +51,8 @@ WorldSocketMgr::~WorldSocketMgr() delete _instanceAcceptor; } +int const boost::asio::socket_base::max_connections; + bool WorldSocketMgr::StartNetwork(boost::asio::io_service& service, std::string const& bindIp, uint16 port) { _tcpNoDelay = sConfigMgr->GetBoolDefault("Network.TcpNodelay", true); diff --git a/src/server/game/Spells/Auras/SpellAuraDefines.h b/src/server/game/Spells/Auras/SpellAuraDefines.h index 112893fbc75..7e60ac9b5da 100644 --- a/src/server/game/Spells/Auras/SpellAuraDefines.h +++ b/src/server/game/Spells/Auras/SpellAuraDefines.h @@ -535,7 +535,12 @@ enum AuraType SPELL_AURA_476 = 476, SPELL_AURA_477 = 477, SPELL_AURA_478 = 478, - TOTAL_AURAS = 479 // 6.0.3 + SPELL_AURA_479 = 479, + SPELL_AURA_480 = 480, + SPELL_AURA_481 = 481, + SPELL_AURA_482 = 482, + SPELL_AURA_483 = 483, + TOTAL_AURAS = 484 }; enum AuraObjectType diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp index 2766109fafc..dd29b7c1b4b 100644 --- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp +++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp @@ -539,6 +539,11 @@ pAuraEffectHandler AuraEffectHandler[TOTAL_AURAS]= &AuraEffect::HandleNULL, //476 &AuraEffect::HandleNULL, //477 &AuraEffect::HandleNULL, //478 + &AuraEffect::HandleNULL, //479 + &AuraEffect::HandleNULL, //480 + &AuraEffect::HandleNULL, //481 + &AuraEffect::HandleNULL, //482 + &AuraEffect::HandleNULL, //483 }; AuraEffect::AuraEffect(Aura* base, uint32 effIndex, int32 *baseAmount, Unit* caster) : diff --git a/src/server/game/Spells/Auras/SpellAuras.cpp b/src/server/game/Spells/Auras/SpellAuras.cpp index 0af38131740..e85d38ee30c 100644 --- a/src/server/game/Spells/Auras/SpellAuras.cpp +++ b/src/server/game/Spells/Auras/SpellAuras.cpp @@ -1003,11 +1003,11 @@ void Aura::RefreshSpellMods() player->RestoreAllSpellMods(0, this); } -bool Aura::HasMoreThanOneEffectForType(AuraType auraType, uint32 difficulty) const +bool Aura::HasMoreThanOneEffectForType(AuraType auraType) const { uint32 count = 0; for (SpellEffectInfo const* effect : GetSpellEffectInfos()) - if (effect && HasEffect(effect->EffectIndex) && AuraType(effect->ApplyAuraName) == auraType) + if (effect && HasEffect(effect->EffectIndex) && AuraType(effect->ApplyAuraName) == auraType) ++count; return count > 1; diff --git a/src/server/game/Spells/Auras/SpellAuras.h b/src/server/game/Spells/Auras/SpellAuras.h index 77ef04009b8..acc9de2587d 100644 --- a/src/server/game/Spells/Auras/SpellAuras.h +++ b/src/server/game/Spells/Auras/SpellAuras.h @@ -183,7 +183,7 @@ class Aura uint8 GetCasterLevel() const { return m_casterLevel; } - bool HasMoreThanOneEffectForType(AuraType auraType, uint32 difficulty) const; + bool HasMoreThanOneEffectForType(AuraType auraType) const; bool IsArea() const; bool IsPassive() const; bool IsDeathPersistent() const; diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index 919f11a5db4..ffc39e40713 100644 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -523,23 +523,23 @@ void SpellCastTargets::Update(Unit* caster) void SpellCastTargets::OutDebug() const { if (!m_targetMask) - TC_LOG_INFO("spells", "No targets"); + TC_LOG_DEBUG("spells", "No targets"); - TC_LOG_INFO("spells", "target mask: %u", m_targetMask); + TC_LOG_DEBUG("spells", "target mask: %u", m_targetMask); if (m_targetMask & (TARGET_FLAG_UNIT_MASK | TARGET_FLAG_CORPSE_MASK | TARGET_FLAG_GAMEOBJECT_MASK)) - TC_LOG_INFO("spells", "Object target: %s", m_objectTargetGUID.ToString().c_str()); + TC_LOG_DEBUG("spells", "Object target: %s", m_objectTargetGUID.ToString().c_str()); if (m_targetMask & TARGET_FLAG_ITEM) - TC_LOG_INFO("spells", "Item target: %s", m_itemTargetGUID.ToString().c_str()); + TC_LOG_DEBUG("spells", "Item target: %s", m_itemTargetGUID.ToString().c_str()); if (m_targetMask & TARGET_FLAG_TRADE_ITEM) - TC_LOG_INFO("spells", "Trade item target: %s", m_itemTargetGUID.ToString().c_str()); + TC_LOG_DEBUG("spells", "Trade item target: %s", m_itemTargetGUID.ToString().c_str()); if (m_targetMask & TARGET_FLAG_SOURCE_LOCATION) - TC_LOG_INFO("spells", "Source location: transport guid:%s trans offset: %s position: %s", m_src._transportGUID.ToString().c_str(), m_src._transportOffset.ToString().c_str(), m_src._position.ToString().c_str()); + TC_LOG_DEBUG("spells", "Source location: transport guid:%s trans offset: %s position: %s", m_src._transportGUID.ToString().c_str(), m_src._transportOffset.ToString().c_str(), m_src._position.ToString().c_str()); if (m_targetMask & TARGET_FLAG_DEST_LOCATION) - TC_LOG_INFO("spells", "Destination location: transport guid:%s trans offset: %s position: %s", m_dst._transportGUID.ToString().c_str(), m_dst._transportOffset.ToString().c_str(), m_dst._position.ToString().c_str()); + TC_LOG_DEBUG("spells", "Destination location: transport guid:%s trans offset: %s position: %s", m_dst._transportGUID.ToString().c_str(), m_dst._transportOffset.ToString().c_str(), m_dst._position.ToString().c_str()); if (m_targetMask & TARGET_FLAG_STRING) - TC_LOG_INFO("spells", "String: %s", m_strTarget.c_str()); - TC_LOG_INFO("spells", "speed: %f", m_speed); - TC_LOG_INFO("spells", "pitch: %f", m_pitch); + TC_LOG_DEBUG("spells", "String: %s", m_strTarget.c_str()); + TC_LOG_DEBUG("spells", "speed: %f", m_speed); + TC_LOG_DEBUG("spells", "pitch: %f", m_pitch); } SpellValue::SpellValue(Difficulty diff, SpellInfo const* proto) @@ -6408,7 +6408,7 @@ void Spell::Delayed() // only called in DealDamage() else m_timer += delaytime; - TC_LOG_INFO("spells", "Spell %u partially interrupted for (%d) ms at damage", m_spellInfo->Id, delaytime); + TC_LOG_DEBUG("spells", "Spell %u partially interrupted for (%d) ms at damage", m_spellInfo->Id, delaytime); WorldPacket data(SMSG_SPELL_DELAYED, 8+4); data << m_caster->GetPackGUID(); diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp index fe86b623893..e2537461979 100644 --- a/src/server/game/Spells/SpellEffects.cpp +++ b/src/server/game/Spells/SpellEffects.cpp @@ -317,6 +317,12 @@ pEffect SpellEffects[TOTAL_SPELL_EFFECTS]= &Spell::EffectNULL, //242 SPELL_EFFECT_242 &Spell::EffectNULL, //243 SPELL_EFFECT_243 &Spell::EffectNULL, //244 SPELL_EFFECT_244 + &Spell::EffectNULL, //244 SPELL_EFFECT_245 + &Spell::EffectNULL, //244 SPELL_EFFECT_246 + &Spell::EffectNULL, //244 SPELL_EFFECT_247 + &Spell::EffectNULL, //244 SPELL_EFFECT_248 + &Spell::EffectNULL, //244 SPELL_EFFECT_249 + &Spell::EffectNULL, //244 SPELL_EFFECT_250 }; void Spell::EffectNULL(SpellEffIndex /*effIndex*/) @@ -3926,7 +3932,7 @@ void Spell::EffectStuck(SpellEffIndex /*effIndex*/) return; TC_LOG_DEBUG("spells", "Spell Effect: Stuck"); - TC_LOG_INFO("spells", "Player %s (%s) used auto-unstuck future at map %u (%f, %f, %f)", player->GetName().c_str(), player->GetGUID().ToString().c_str(), player->GetMapId(), player->GetPositionX(), player->GetPositionY(), player->GetPositionZ()); + TC_LOG_DEBUG("spells", "Player %s (%s) used auto-unstuck future at map %u (%f, %f, %f)", player->GetName().c_str(), player->GetGUID().ToString().c_str(), player->GetMapId(), player->GetPositionX(), player->GetPositionY(), player->GetPositionZ()); if (player->IsInFlight()) return; diff --git a/src/server/game/Spells/SpellHistory.cpp b/src/server/game/Spells/SpellHistory.cpp index 658498e7455..db8cb880d28 100644 --- a/src/server/game/Spells/SpellHistory.cpp +++ b/src/server/game/Spells/SpellHistory.cpp @@ -579,7 +579,6 @@ void SpellHistory::ResetCooldown(CooldownStorageType::iterator& itr, bool update if (Player* playerOwner = GetPlayerOwner()) { WorldPackets::Spells::ClearCooldown clearCooldown; - clearCooldown.CasterGUID = _owner->GetGUID(); clearCooldown.SpellID = itr->first; clearCooldown.ClearOnHold = false; playerOwner->SendDirectMessage(clearCooldown.Write()); diff --git a/src/server/game/Spells/SpellInfo.cpp b/src/server/game/Spells/SpellInfo.cpp index 2a72cdc49be..eb09cc60a1f 100644 --- a/src/server/game/Spells/SpellInfo.cpp +++ b/src/server/game/Spells/SpellInfo.cpp @@ -642,6 +642,11 @@ float SpellEffectInfo::CalcRadius(Unit* caster, Spell* spell) const return 0.0f; float radius = entry->RadiusMin; + + // Client uses max if min is 0 + if (radius == 0.0f) + radius = entry->RadiusMax; + if (caster) { radius += entry->RadiusPerLevel * caster->getLevel(); diff --git a/src/server/game/Support/SupportMgr.cpp b/src/server/game/Support/SupportMgr.cpp index 9183c2f7fde..f7a85a91faa 100644 --- a/src/server/game/Support/SupportMgr.cpp +++ b/src/server/game/Support/SupportMgr.cpp @@ -34,26 +34,26 @@ void Ticket::TeleportTo(Player* player) const player->TeleportTo(_mapId, _pos.x, _pos.y, _pos.z, 0.0f, 0); } -std::string Ticket::FormatViewMessageString(ChatHandler& handler, const char* szClosedName, const char* szAssignedToName, const char* szUnassignedName, const char* szDeletedName, const char* szCompletedName) const +std::string Ticket::FormatViewMessageString(ChatHandler& handler, char const* closedName, char const* assignedToName, char const* unassignedName, char const* deletedName, char const* /*completedName*/) const { std::stringstream ss; ss << handler.PGetParseString(LANG_COMMAND_TICKETLISTGUID, _id); ss << handler.PGetParseString(LANG_COMMAND_TICKETLISTNAME, GetPlayer()->GetName().c_str()); - if (szClosedName) - ss << handler.PGetParseString(LANG_COMMAND_TICKETCLOSED, szClosedName); - if (szAssignedToName) - ss << handler.PGetParseString(LANG_COMMAND_TICKETLISTASSIGNEDTO, szAssignedToName); - if (szUnassignedName) - ss << handler.PGetParseString(LANG_COMMAND_TICKETLISTUNASSIGNED, szUnassignedName); - if (szDeletedName) - ss << handler.PGetParseString(LANG_COMMAND_TICKETDELETED, szDeletedName); + if (closedName) + ss << handler.PGetParseString(LANG_COMMAND_TICKETCLOSED, closedName); + if (assignedToName) + ss << handler.PGetParseString(LANG_COMMAND_TICKETLISTASSIGNEDTO, assignedToName); + if (unassignedName) + ss << handler.PGetParseString(LANG_COMMAND_TICKETLISTUNASSIGNED, unassignedName); + if (deletedName) + ss << handler.PGetParseString(LANG_COMMAND_TICKETDELETED, deletedName); return ss.str(); } GmTicket::GmTicket() : _lastModifiedTime(0), _completed(false), _escalatedStatus(TICKET_UNASSIGNED), _viewed(false), _needResponse(false), _needMoreHelp(false) { } GmTicket::GmTicket(Player* player) : Ticket(player), _lastModifiedTime(time(nullptr)), _completed(false), _escalatedStatus(TICKET_UNASSIGNED), -_viewed(false), _needResponse(false), _needMoreHelp(false) +_viewed(false), _needResponse(false), _needMoreHelp(false) { _id = sSupportMgr->GenerateGmTicketId(); } @@ -71,9 +71,9 @@ void GmTicket::SetUnassigned() _assignedTo.Clear(); switch (_escalatedStatus) { - case TICKET_ASSIGNED: _escalatedStatus = TICKET_UNASSIGNED; + case TICKET_ASSIGNED: _escalatedStatus = TICKET_UNASSIGNED; break; - case TICKET_ESCALATED_ASSIGNED: _escalatedStatus = TICKET_IN_ESCALATION_QUEUE; + case TICKET_ESCALATED_ASSIGNED: _escalatedStatus = TICKET_IN_ESCALATION_QUEUE; break; case TICKET_UNASSIGNED: case TICKET_IN_ESCALATION_QUEUE: @@ -219,7 +219,7 @@ std::string GmTicket::FormatViewMessageString(ChatHandler& handler, const char* BugTicket::BugTicket() : _facing(0.0f) { } -BugTicket::BugTicket(Player* player) : Ticket(player) +BugTicket::BugTicket(Player* player) : Ticket(player), _facing(0.0f) { _id = sSupportMgr->GenerateBugId(); } @@ -246,7 +246,7 @@ void BugTicket::LoadFromDB(Field* fields) _closedBy.SetRawValue(0, uint64(closedBy)); else _closedBy = ObjectGuid::Create<HighGuid::Player>(uint64(closedBy)); - + uint64 assignedTo = fields[++idx].GetUInt64(); if (assignedTo == 0) _assignedTo = ObjectGuid::Empty; @@ -330,7 +330,7 @@ void ComplaintTicket::LoadFromDB(Field* fields) int32 reportLineIndex = fields[++idx].GetInt32(); if (reportLineIndex != -1) _chatLog.ReportLineIndex.Set(reportLineIndex); - + int64 closedBy = fields[++idx].GetInt64(); if (closedBy == 0) _closedBy = ObjectGuid::Empty; @@ -344,7 +344,7 @@ void ComplaintTicket::LoadFromDB(Field* fields) _assignedTo = ObjectGuid::Empty; else _assignedTo = ObjectGuid::Create<HighGuid::Player>(assignedTo); - + _comment = fields[++idx].GetString(); } @@ -373,7 +373,7 @@ void ComplaintTicket::SaveToDB(SQLTransaction& trans) const stmt->setUInt8(++idx, _complaintType); if (_chatLog.ReportLineIndex.HasValue) stmt->setInt32(++idx, _chatLog.ReportLineIndex.Value); - else + else stmt->setInt32(++idx, -1); // empty ReportLineIndex stmt->setInt64(++idx, _closedBy.GetCounter()); stmt->setUInt64(++idx, _assignedTo.GetCounter()); @@ -393,7 +393,7 @@ void ComplaintTicket::SaveToDB(SQLTransaction& trans) const trans->Append(stmt); ++lineIndex; } - + if (!isInTransaction) CharacterDatabase.CommitTransaction(trans); } @@ -432,7 +432,7 @@ std::string ComplaintTicket::FormatViewMessageString(ChatHandler& handler, bool SuggestionTicket::SuggestionTicket() : _facing(0.0f) { } -SuggestionTicket::SuggestionTicket(Player* player) : Ticket(player) +SuggestionTicket::SuggestionTicket(Player* player) : Ticket(player), _facing(0.0f) { _id = sSupportMgr->GenerateSuggestionId(); } @@ -517,7 +517,7 @@ std::string SuggestionTicket::FormatViewMessageString(ChatHandler& handler, bool return ss.str(); } -SupportMgr::SupportMgr() : _lastGmTicketId(0), _lastBugId(0), _lastComplaintId(0), _lastSuggestionId(0), _openGmTicketCount(0), +SupportMgr::SupportMgr() : _lastGmTicketId(0), _lastBugId(0), _lastComplaintId(0), _lastSuggestionId(0), _openGmTicketCount(0), _openBugTicketCount(0), _openComplaintTicketCount(0), _openSuggestionTicketCount(0) { } SupportMgr::~SupportMgr() @@ -701,7 +701,7 @@ void SupportMgr::LoadComplaintTickets() uint32 count = 0; PreparedStatement* chatLogStmt; PreparedQueryResult chatLogResult; - do + do { Field* fields = result->Fetch(); ComplaintTicket* complaint = new ComplaintTicket(); @@ -715,7 +715,8 @@ void SupportMgr::LoadComplaintTickets() _lastComplaintId = id; chatLogStmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_GM_COMPLAINT_CHATLINES); - chatLogResult = CharacterDatabase.Query(stmt); + chatLogStmt->setUInt32(0, id); + chatLogResult = CharacterDatabase.Query(chatLogStmt); if (chatLogResult) { diff --git a/src/server/scripts/CMakeLists.txt b/src/server/scripts/CMakeLists.txt index 7df42e158de..79d3cea0868 100644 --- a/src/server/scripts/CMakeLists.txt +++ b/src/server/scripts/CMakeLists.txt @@ -51,6 +51,7 @@ include_directories( ${CMAKE_SOURCE_DIR}/dep/recastnavigation/Recast/Include ${CMAKE_SOURCE_DIR}/dep/g3dlite/include ${CMAKE_SOURCE_DIR}/dep/SFMT + ${CMAKE_SOURCE_DIR}/dep/cppformat ${CMAKE_SOURCE_DIR}/dep/zlib ${CMAKE_SOURCE_DIR}/src/server/shared ${CMAKE_SOURCE_DIR}/src/server/shared/Configuration @@ -63,6 +64,7 @@ include_directories( ${CMAKE_SOURCE_DIR}/src/server/shared/Logging ${CMAKE_SOURCE_DIR}/src/server/shared/Packets ${CMAKE_SOURCE_DIR}/src/server/shared/Threading + ${CMAKE_SOURCE_DIR}/src/server/shared/Updater ${CMAKE_SOURCE_DIR}/src/server/shared/Utilities ${CMAKE_SOURCE_DIR}/src/server/ipc ${CMAKE_SOURCE_DIR}/src/server/collision diff --git a/src/server/scripts/Commands/cs_learn.cpp b/src/server/scripts/Commands/cs_learn.cpp index 7a34ba55110..d41c9c5d2c2 100644 --- a/src/server/scripts/Commands/cs_learn.cpp +++ b/src/server/scripts/Commands/cs_learn.cpp @@ -211,7 +211,7 @@ public: return true; } - static bool HandleLearnAllMyPetTalentsCommand(ChatHandler* handler, char const* /*args*/) + static bool HandleLearnAllMyPetTalentsCommand(ChatHandler* /*handler*/, char const* /*args*/) { /* TODO: 6.x remove pet talents Player* player = handler->GetSession()->GetPlayer(); diff --git a/src/server/scripts/Commands/cs_misc.cpp b/src/server/scripts/Commands/cs_misc.cpp index d437e72b933..b57efc07a74 100644 --- a/src/server/scripts/Commands/cs_misc.cpp +++ b/src/server/scripts/Commands/cs_misc.cpp @@ -238,7 +238,8 @@ public: zoneId, (zoneEntry ? zoneEntry->ZoneName : unknown), areaId, (areaEntry ? areaEntry->ZoneName : unknown), object->GetPhaseMask(), - object->GetPositionX(), object->GetPositionY(), object->GetPositionZ(), object->GetOrientation(), + object->GetPositionX(), object->GetPositionY(), object->GetPositionZ(), object->GetOrientation()); + handler->PSendSysMessage(LANG_GRID_POSITION, cell.GridX(), cell.GridY(), cell.CellX(), cell.CellY(), object->GetInstanceId(), zoneX, zoneY, groundZ, floorZ, haveMap, haveVMap, haveMMap); @@ -2625,7 +2626,7 @@ public: return true; } - static bool HandleAurasCommand(ChatHandler* handler, char const* args) + static bool HandleAurasCommand(ChatHandler* handler, char const* /*args*/) { Unit* target = handler->GetSession()->GetPlayer()->GetSelectedUnit(); diff --git a/src/server/scripts/Commands/cs_modify.cpp b/src/server/scripts/Commands/cs_modify.cpp index 5af9b150572..c1f90c7ac96 100644 --- a/src/server/scripts/Commands/cs_modify.cpp +++ b/src/server/scripts/Commands/cs_modify.cpp @@ -418,7 +418,7 @@ public: } //Edit Player TP - static bool HandleModifyTalentCommand (ChatHandler* handler, const char* args) + static bool HandleModifyTalentCommand(ChatHandler* /*handler*/, const char* /*args*/) { /* TODO: 6.x remove this if (!*args) diff --git a/src/server/scripts/EasternKingdoms/Karazhan/karazhan.cpp b/src/server/scripts/EasternKingdoms/Karazhan/karazhan.cpp index 59f2ce1a2c9..92c3f83034d 100644 --- a/src/server/scripts/EasternKingdoms/Karazhan/karazhan.cpp +++ b/src/server/scripts/EasternKingdoms/Karazhan/karazhan.cpp @@ -360,17 +360,17 @@ public: case GOSSIP_ACTION_INFO_DEF+3: player->CLOSE_GOSSIP_MENU(); pBarnesAI->m_uiEventId = EVENT_OZ; - TC_LOG_INFO("scripts", "player (%s) manually set Opera event to EVENT_OZ", player->GetGUID().ToString().c_str()); + TC_LOG_DEBUG("scripts", "player (%s) manually set Opera event to EVENT_OZ", player->GetGUID().ToString().c_str()); break; case GOSSIP_ACTION_INFO_DEF+4: player->CLOSE_GOSSIP_MENU(); pBarnesAI->m_uiEventId = EVENT_HOOD; - TC_LOG_INFO("scripts", "player (%s) manually set Opera event to EVENT_HOOD", player->GetGUID().ToString().c_str()); + TC_LOG_DEBUG("scripts", "player (%s) manually set Opera event to EVENT_HOOD", player->GetGUID().ToString().c_str()); break; case GOSSIP_ACTION_INFO_DEF+5: player->CLOSE_GOSSIP_MENU(); pBarnesAI->m_uiEventId = EVENT_RAJ; - TC_LOG_INFO("scripts", "player (%s) manually set Opera event to EVENT_RAJ", player->GetGUID().ToString().c_str()); + TC_LOG_DEBUG("scripts", "player (%s) manually set Opera event to EVENT_RAJ", player->GetGUID().ToString().c_str()); break; } diff --git a/src/server/scripts/EasternKingdoms/zone_undercity.cpp b/src/server/scripts/EasternKingdoms/zone_undercity.cpp index 9ce694fb76c..ca281bab60a 100644 --- a/src/server/scripts/EasternKingdoms/zone_undercity.cpp +++ b/src/server/scripts/EasternKingdoms/zone_undercity.cpp @@ -40,25 +40,44 @@ EndContentData */ enum Sylvanas { - QUEST_JOURNEY_TO_UNDERCITY = 9180, - EMOTE_LAMENT_END = 0, - SAY_LAMENT_END = 1, + QUEST_JOURNEY_TO_UNDERCITY = 9180, - SOUND_CREDIT = 10896, - ENTRY_HIGHBORNE_LAMENTER = 21628, - ENTRY_HIGHBORNE_BUNNY = 21641, + EMOTE_LAMENT_END = 0, + SAY_LAMENT_END = 1, + EMOTE_LAMENT = 2, - SPELL_HIGHBORNE_AURA = 37090, - SPELL_SYLVANAS_CAST = 36568, - SPELL_RIBBON_OF_SOULS = 34432, // the real one to use might be 37099 + // Ambassador Sunsorrow + SAY_SUNSORROW_WHISPER = 0, + + SOUND_CREDIT = 10896, + + NPC_HIGHBORNE_LAMENTER = 21628, + NPC_HIGHBORNE_BUNNY = 21641, + NPC_AMBASSADOR_SUNSORROW = 16287, + + SPELL_HIGHBORNE_AURA = 37090, + SPELL_SYLVANAS_CAST = 36568, + //SPELL_RIBBON_OF_SOULS = 34432, the real one to use might be 37099 + SPELL_RIBBON_OF_SOULS = 37099, // Combat spells - SPELL_BLACK_ARROW = 59712, - SPELL_FADE = 20672, - SPELL_FADE_BLINK = 29211, - SPELL_MULTI_SHOT = 59713, - SPELL_SHOT = 59710, - SPELL_SUMMON_SKELETON = 59711 + SPELL_BLACK_ARROW = 59712, + SPELL_FADE = 20672, + SPELL_FADE_BLINK = 29211, + SPELL_MULTI_SHOT = 59713, + SPELL_SHOT = 59710, + SPELL_SUMMON_SKELETON = 59711, + + // Events + EVENT_FADE = 1, + EVENT_SUMMON_SKELETON = 2, + EVENT_BLACK_ARROW = 3, + EVENT_SHOOT = 4, + EVENT_MULTI_SHOT = 5, + EVENT_LAMENT_OF_THE_HIGHBORN = 6, + EVENT_SUNSORROW_WHISPER = 7, + + GUID_EVENT_INVOKER = 1, }; float HighborneLoc[4][3]= @@ -77,26 +96,14 @@ class npc_lady_sylvanas_windrunner : public CreatureScript public: npc_lady_sylvanas_windrunner() : CreatureScript("npc_lady_sylvanas_windrunner") { } - bool OnQuestReward(Player* /*player*/, Creature* creature, const Quest *_Quest, uint32 /*slot*/) override + bool OnQuestReward(Player* player, Creature* creature, const Quest *_Quest, uint32 /*slot*/) override { if (_Quest->GetQuestId() == QUEST_JOURNEY_TO_UNDERCITY) - { - ENSURE_AI(npc_lady_sylvanas_windrunner::npc_lady_sylvanas_windrunnerAI, creature->AI())->LamentEvent = true; - ENSURE_AI(npc_lady_sylvanas_windrunner::npc_lady_sylvanas_windrunnerAI, creature->AI())->DoPlaySoundToSet(creature, SOUND_CREDIT); - creature->CastSpell(creature, SPELL_SYLVANAS_CAST, false); - - for (uint8 i = 0; i < 4; ++i) - creature->SummonCreature(ENTRY_HIGHBORNE_LAMENTER, HighborneLoc[i][0], HighborneLoc[i][1], HIGHBORNE_LOC_Y, HighborneLoc[i][2], TEMPSUMMON_TIMED_DESPAWN, 160000); - } + creature->AI()->SetGUID(player->GetGUID(), GUID_EVENT_INVOKER); return true; } - CreatureAI* GetAI(Creature* creature) const override - { - return new npc_lady_sylvanas_windrunnerAI(creature); - } - struct npc_lady_sylvanas_windrunnerAI : public ScriptedAI { npc_lady_sylvanas_windrunnerAI(Creature* creature) : ScriptedAI(creature) @@ -106,41 +113,51 @@ public: void Initialize() { - LamentEventTimer = 5000; LamentEvent = false; targetGUID.Clear(); - - FadeTimer = 30000; - SummonSkeletonTimer = 20000; - BlackArrowTimer = 15000; - ShotTimer = 8000; - MultiShotTimer = 10000; + playerGUID.Clear(); } - uint32 LamentEventTimer; - bool LamentEvent; - ObjectGuid targetGUID; - - uint32 FadeTimer; - uint32 SummonSkeletonTimer; - uint32 BlackArrowTimer; - uint32 ShotTimer; - uint32 MultiShotTimer; - void Reset() override { Initialize(); + _events.Reset(); } - void EnterCombat(Unit* /*who*/) override { } + void EnterCombat(Unit* /*who*/) override + { + _events.ScheduleEvent(EVENT_FADE, 30000); + _events.ScheduleEvent(EVENT_SUMMON_SKELETON, 20000); + _events.ScheduleEvent(EVENT_BLACK_ARROW, 15000); + _events.ScheduleEvent(EVENT_SHOOT, 8000); + _events.ScheduleEvent(EVENT_MULTI_SHOT, 10000); + } + + void SetGUID(ObjectGuid guid, int32 type) override + { + if (type == GUID_EVENT_INVOKER) + { + Talk(EMOTE_LAMENT); + DoPlaySoundToSet(me, SOUND_CREDIT); + DoCast(me, SPELL_SYLVANAS_CAST, false); + playerGUID = guid; + LamentEvent = true; + + for (uint8 i = 0; i < 4; ++i) + me->SummonCreature(NPC_HIGHBORNE_LAMENTER, HighborneLoc[i][0], HighborneLoc[i][1], HIGHBORNE_LOC_Y, HighborneLoc[i][2], TEMPSUMMON_TIMED_DESPAWN, 160000); + + _events.ScheduleEvent(EVENT_LAMENT_OF_THE_HIGHBORN, 2000); + _events.ScheduleEvent(EVENT_SUNSORROW_WHISPER, 10000); + } + } void JustSummoned(Creature* summoned) override { - if (summoned->GetEntry() == ENTRY_HIGHBORNE_BUNNY) + if (summoned->GetEntry() == NPC_HIGHBORNE_BUNNY) { if (Creature* target = ObjectAccessor::GetCreature(*summoned, targetGUID)) { - target->MonsterMoveWithSpeed(target->GetPositionX(), target->GetPositionY(), me->GetPositionZ()+15.0f, 0); + target->GetMotionMaster()->MoveJump(target->GetPositionX(), target->GetPositionY(), me->GetPositionZ() + 15.0f, 0); target->SetPosition(target->GetPositionX(), target->GetPositionY(), me->GetPositionZ()+15.0f, 0.0f); summoned->CastSpell(target, SPELL_RIBBON_OF_SOULS, false); } @@ -152,75 +169,86 @@ public: void UpdateAI(uint32 diff) override { - if (LamentEvent) - { - if (LamentEventTimer <= diff) - { - DoSummon(ENTRY_HIGHBORNE_BUNNY, me, 10.0f, 3000, TEMPSUMMON_TIMED_DESPAWN); - - LamentEventTimer = 2000; - if (!me->HasAura(SPELL_SYLVANAS_CAST)) - { - Talk(SAY_LAMENT_END); - Talk(EMOTE_LAMENT_END); - LamentEvent = false; - } - } else LamentEventTimer -= diff; - } - - if (!UpdateVictim()) + if (!UpdateVictim() && !LamentEvent) return; - // Combat spells - - if (FadeTimer <= diff) - { - DoCast(me, SPELL_FADE); - // add a blink to simulate a stealthed movement and reappearing elsewhere - DoCast(me, SPELL_FADE_BLINK); - FadeTimer = 30000 + rand32() % 5000; - // if the victim is out of melee range she cast multi shot - if (Unit* victim = me->GetVictim()) - if (me->GetDistance(victim) > 10.0f) - DoCast(victim, SPELL_MULTI_SHOT); - } else FadeTimer -= diff; - - if (SummonSkeletonTimer <= diff) - { - DoCast(me, SPELL_SUMMON_SKELETON); - SummonSkeletonTimer = 20000 + rand32() % 10000; - } else SummonSkeletonTimer -= diff; - - if (BlackArrowTimer <= diff) - { - if (Unit* victim = me->GetVictim()) - { - DoCast(victim, SPELL_BLACK_ARROW); - BlackArrowTimer = 15000 + rand32() % 5000; - } - } else BlackArrowTimer -= diff; + _events.Update(diff); - if (ShotTimer <= diff) - { - if (Unit* victim = me->GetVictim()) - { - DoCast(victim, SPELL_SHOT); - ShotTimer = 8000 + rand32() % 2000; - } - } else ShotTimer -= diff; + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; - if (MultiShotTimer <= diff) + while (uint32 eventId = _events.ExecuteEvent()) { - if (Unit* victim = me->GetVictim()) + switch (eventId) { - DoCast(victim, SPELL_MULTI_SHOT); - MultiShotTimer = 10000 + rand32() % 3000; + case EVENT_FADE: + DoCast(me, SPELL_FADE); + // add a blink to simulate a stealthed movement and reappearing elsewhere + DoCast(me, SPELL_FADE_BLINK); + // if the victim is out of melee range she cast multi shot + if (Unit* victim = me->GetVictim()) + if (me->GetDistance(victim) > 10.0f) + DoCast(victim, SPELL_MULTI_SHOT); + _events.ScheduleEvent(EVENT_FADE, urand(30000, 35000)); + break; + case EVENT_SUMMON_SKELETON: + DoCast(me, SPELL_SUMMON_SKELETON); + _events.ScheduleEvent(EVENT_SUMMON_SKELETON, urand(20000, 30000)); + break; + case EVENT_BLACK_ARROW: + if (Unit* victim = me->GetVictim()) + DoCast(victim, SPELL_BLACK_ARROW); + _events.ScheduleEvent(EVENT_BLACK_ARROW, urand(15000, 20000)); + break; + case EVENT_SHOOT: + if (Unit* victim = me->GetVictim()) + DoCast(victim, SPELL_SHOT); + _events.ScheduleEvent(EVENT_SHOOT, urand(8000, 10000)); + break; + case EVENT_MULTI_SHOT: + if (Unit* victim = me->GetVictim()) + DoCast(victim, SPELL_MULTI_SHOT); + _events.ScheduleEvent(EVENT_MULTI_SHOT, urand(10000, 13000)); + break; + case EVENT_LAMENT_OF_THE_HIGHBORN: + if (!me->HasAura(SPELL_SYLVANAS_CAST)) + { + Talk(SAY_LAMENT_END); + Talk(EMOTE_LAMENT_END); + LamentEvent = false; + me->HandleEmoteCommand(EMOTE_ONESHOT_KNEEL); + Reset(); + } + else + { + DoSummon(NPC_HIGHBORNE_BUNNY, me, 10.0f, 3000, TEMPSUMMON_TIMED_DESPAWN); + _events.ScheduleEvent(EVENT_LAMENT_OF_THE_HIGHBORN, 2000); + } + break; + case EVENT_SUNSORROW_WHISPER: + if (Creature* ambassador = me->FindNearestCreature(NPC_AMBASSADOR_SUNSORROW, 20.0f)) + if (Player* player = ObjectAccessor::GetPlayer(*me, playerGUID)) + ambassador->AI()->Talk(SAY_SUNSORROW_WHISPER, player); + break; + default: + break; } - } else MultiShotTimer -= diff; + } DoMeleeAttackIfReady(); } + + private: + EventMap _events; + bool LamentEvent; + ObjectGuid targetGUID; + ObjectGuid playerGUID; }; + + CreatureAI* GetAI(Creature* creature) const override + { + return new npc_lady_sylvanas_windrunnerAI(creature); + } }; /*###### diff --git a/src/server/scripts/Kalimdor/CMakeLists.txt b/src/server/scripts/Kalimdor/CMakeLists.txt index d5e445230bd..8c3f3216e91 100644 --- a/src/server/scripts/Kalimdor/CMakeLists.txt +++ b/src/server/scripts/Kalimdor/CMakeLists.txt @@ -92,7 +92,6 @@ set(scripts_STAT_SRCS Kalimdor/RuinsOfAhnQiraj/boss_moam.cpp Kalimdor/RuinsOfAhnQiraj/ruins_of_ahnqiraj.h Kalimdor/RuinsOfAhnQiraj/boss_kurinnaxx.cpp - Kalimdor/zone_mulgore.cpp Kalimdor/zone_bloodmyst_isle.cpp Kalimdor/zone_thunder_bluff.cpp Kalimdor/zone_azshara.cpp diff --git a/src/server/scripts/Kalimdor/zone_mulgore.cpp b/src/server/scripts/Kalimdor/zone_mulgore.cpp deleted file mode 100644 index b6db431d0b2..00000000000 --- a/src/server/scripts/Kalimdor/zone_mulgore.cpp +++ /dev/null @@ -1,178 +0,0 @@ -/* - * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/> - * Copyright (C) 2006-2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/> - * - * 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/>. - */ - -/* ScriptData -SDName: Mulgore -SD%Complete: 100 -SDComment: Support for quest: 11129, 861 -SDCategory: Mulgore -EndScriptData */ - -/* ContentData -npc_kyle_frenzied -EndContentData */ - -#include "ScriptMgr.h" -#include "ScriptedCreature.h" -#include "ScriptedGossip.h" -#include "Player.h" -#include "SpellInfo.h" - -/*##### -# npc_kyle_frenzied -######*/ - -enum KyleFrenzied -{ - EMOTE_SEE_LUNCH = 0, - EMOTE_EAT_LUNCH = 1, - EMOTE_DANCE = 2, - - SPELL_LUNCH = 42222, - NPC_KYLE_FRENZIED = 23616, - NPC_KYLE_FRIENDLY = 23622, - POINT_ID = 1 -}; - -class npc_kyle_frenzied : public CreatureScript -{ -public: - npc_kyle_frenzied() : CreatureScript("npc_kyle_frenzied") { } - - CreatureAI* GetAI(Creature* creature) const override - { - return new npc_kyle_frenziedAI (creature); - } - - struct npc_kyle_frenziedAI : public ScriptedAI - { - npc_kyle_frenziedAI(Creature* creature) : ScriptedAI(creature) - { - Initialize(); - } - - void Initialize() - { - EventActive = false; - IsMovingToLunch = false; - PlayerGUID.Clear(); - EventTimer = 5000; - EventPhase = 0; - } - - bool EventActive; - bool IsMovingToLunch; - ObjectGuid PlayerGUID; - uint32 EventTimer; - uint8 EventPhase; - - void Reset() override - { - Initialize(); - - if (me->GetEntry() == NPC_KYLE_FRIENDLY) - me->UpdateEntry(NPC_KYLE_FRENZIED); - } - - void SpellHit(Unit* Caster, SpellInfo const* Spell) - { - if (!me->GetVictim() && !EventActive && Spell->Id == SPELL_LUNCH) - { - if (Caster->GetTypeId() == TYPEID_PLAYER) - PlayerGUID = Caster->GetGUID(); - - if (me->GetMotionMaster()->GetCurrentMovementGeneratorType() == WAYPOINT_MOTION_TYPE) - { - me->GetMotionMaster()->MovementExpired(); - me->GetMotionMaster()->MoveIdle(); - me->StopMoving(); - } - - EventActive = true; - Talk(EMOTE_SEE_LUNCH); - me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_CREATURE_SPECIAL); - } - } - - void MovementInform(uint32 type, uint32 pointId) override - { - if (type != POINT_MOTION_TYPE || !EventActive) - return; - - if (pointId == POINT_ID) - IsMovingToLunch = false; - } - - void UpdateAI(uint32 diff) override - { - if (EventActive) - { - if (IsMovingToLunch) - return; - - if (EventTimer <= diff) - { - EventTimer = 5000; - ++EventPhase; - - switch (EventPhase) - { - case 1: - if (Unit* unit = ObjectAccessor::GetUnit(*me, PlayerGUID)) - { - if (GameObject* go = unit->GetGameObject(SPELL_LUNCH)) - { - IsMovingToLunch = true; - me->GetMotionMaster()->MovePoint(POINT_ID, go->GetPositionX(), go->GetPositionY(), go->GetPositionZ()); - } - } - break; - case 2: - Talk(EMOTE_EAT_LUNCH); - me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_USE_STANDING); - break; - case 3: - if (Player* unit = ObjectAccessor::GetPlayer(*me, PlayerGUID)) - unit->TalkedToCreature(me->GetEntry(), me->GetGUID()); - - me->UpdateEntry(NPC_KYLE_FRIENDLY); - break; - case 4: - EventTimer = 30000; - Talk(EMOTE_DANCE); - me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_DANCESPECIAL); - break; - case 5: - me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_NONE); - Reset(); - me->GetMotionMaster()->Clear(); - break; - } - } - else - EventTimer -= diff; - } - } - }; - -}; - -void AddSC_mulgore() -{ - new npc_kyle_frenzied(); -} diff --git a/src/server/scripts/Kalimdor/zone_the_barrens.cpp b/src/server/scripts/Kalimdor/zone_the_barrens.cpp index 232261df951..1c9d5cf2c62 100644 --- a/src/server/scripts/Kalimdor/zone_the_barrens.cpp +++ b/src/server/scripts/Kalimdor/zone_the_barrens.cpp @@ -654,6 +654,7 @@ public: if (quest->GetQuestId() == QUEST_ESCAPE) { creature->setFaction(FACTION_RATCHET); + creature->AI()->Talk(SAY_START); if (npc_escortAI* pEscortAI = CAST_AI(npc_wizzlecrank_shredder::npc_wizzlecrank_shredderAI, creature->AI())) pEscortAI->Start(true, false, player->GetGUID()); } diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/instance_trial_of_the_crusader.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/instance_trial_of_the_crusader.cpp index 7148d0149af..b751c1db10d 100644 --- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/instance_trial_of_the_crusader.cpp +++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/instance_trial_of_the_crusader.cpp @@ -255,12 +255,6 @@ class instance_trial_of_the_crusader : public InstanceMapScript if (GetBossState(BOSS_VALKIRIES) == SPECIAL) state = DONE; break; - case DONE: - if (instance->GetPlayers().getFirst()->GetSource()->GetTeam() == ALLIANCE) - EventStage = 4020; - else - EventStage = 4030; - break; default: break; } @@ -336,7 +330,7 @@ class instance_trial_of_the_crusader : public InstanceMapScript if (type < MAX_ENCOUNTERS) { - TC_LOG_INFO("scripts", "[ToCr] BossState(type %u) %u = state %u;", type, GetBossState(type), state); + TC_LOG_DEBUG("scripts", "[ToCr] BossState(type %u) %u = state %u;", type, GetBossState(type), state); if (state == FAIL) { if (instance->IsHeroic()) diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/trial_of_the_crusader.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/trial_of_the_crusader.cpp index 16526b694e9..974bd4672f1 100644 --- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/trial_of_the_crusader.cpp +++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/trial_of_the_crusader.cpp @@ -133,7 +133,7 @@ class npc_announcer_toc10 : public CreatureScript char const* _message = "We are ready!"; - if (player->IsInCombat() || instance->IsEncounterInProgress() || instance->GetData(TYPE_EVENT)) + if (player->IsInCombat() || instance->IsEncounterInProgress()) return true; uint8 i = 0; @@ -199,17 +199,11 @@ class npc_announcer_toc10 : public CreatureScript } else if (instance->GetBossState(BOSS_LICH_KING) != DONE) { - if (GameObject* floor = ObjectAccessor::GetGameObject(*player, instance->GetGuidData(GO_ARGENT_COLISEUM_FLOOR))) - floor->SetDestructibleState(GO_DESTRUCTIBLE_DAMAGED); - - creature->CastSpell(creature, SPELL_CORPSE_TELEPORT, false); - creature->CastSpell(creature, SPELL_DESTROY_FLOOR_KNOCKUP, false); - - if (!ObjectAccessor::GetCreature(*creature, instance->GetGuidData(NPC_ANUBARAK))) - creature->SummonCreature(NPC_ANUBARAK, AnubarakLoc[0], TEMPSUMMON_CORPSE_TIMED_DESPAWN, DESPAWN_TIME); - - if (creature->IsVisible()) - creature->SetVisible(false); + if (creature->GetMap()->GetPlayers().getFirst()->GetSource()->GetTeam() == ALLIANCE) + instance->SetData(TYPE_EVENT, 4020); + else + instance->SetData(TYPE_EVENT, 4030); + instance->SetBossState(BOSS_LICH_KING, NOT_STARTED); } creature->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); return true; diff --git a/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.cpp b/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.cpp index 5b3be128b32..20add695394 100644 --- a/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.cpp +++ b/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.cpp @@ -2640,13 +2640,7 @@ class npc_quel_delar_sword : public CreatureScript break; case EVENT_QUEL_DELAR_FLIGHT: { - Movement::MoveSplineInit init(me); - FillCirclePath(QuelDelarCenterPos, 18.0f, 718.046f, init.Path(), true); - init.SetFly(); - init.SetCyclic(); - init.SetAnimation(Movement::ToFly); - init.Launch(); - + me->GetMotionMaster()->MoveCirclePath(QuelDelarCenterPos.GetPositionX(), QuelDelarCenterPos.GetPositionY(), 718.046f, 18.0f, true, 16); _events.ScheduleEvent(EVENT_QUEL_DELAR_LAND, 15000); break; } @@ -2694,21 +2688,6 @@ class npc_quel_delar_sword : public CreatureScript } private: - void FillCirclePath(Position const& centerPos, float radius, float z, Movement::PointsArray& path, bool clockwise) - { - float step = clockwise ? -M_PI / 8.0f : M_PI / 8.0f; - float angle = centerPos.GetAngle(me->GetPositionX(), me->GetPositionY()); - - for (uint8 i = 0; i < 16; angle += step, ++i) - { - G3D::Vector3 point; - point.x = centerPos.GetPositionX() + radius * cosf(angle); - point.y = centerPos.GetPositionY() + radius * sinf(angle); - point.z = z; - path.push_back(point); - } - } - EventMap _events; InstanceScript* _instance; bool _intro; diff --git a/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp b/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp index abbc7acb004..0c79b42f20c 100644 --- a/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp +++ b/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp @@ -520,11 +520,7 @@ public: _despawned = false; break; case ACTION_CYCLIC_MOVEMENT: - Movement::MoveSplineInit init(me); - FillCirclePath(MalygosPositions[3], 120.0f, 283.2763f, init.Path(), true); - init.SetFly(); - init.SetCyclic(); - init.Launch(); + me->GetMotionMaster()->MoveCirclePath(MalygosPositions[3].GetPositionX(), MalygosPositions[3].GetPositionY(), 283.2763f, 120.0f, true, 16); break; } } @@ -1020,22 +1016,6 @@ public: } private: - // Used to generate perfect cyclic movements (Enter Circle). - void FillCirclePath(Position const& centerPos, float radius, float z, Movement::PointsArray& path, bool clockwise) - { - float step = clockwise ? float(-M_PI) / 8.0f : float(M_PI) / 8.0f; - float angle = centerPos.GetAngle(me->GetPositionX(), me->GetPositionY()); - - for (uint8 i = 0; i < 16; angle += step, ++i) - { - G3D::Vector3 point; - point.x = centerPos.GetPositionX() + radius * cosf(angle); - point.y = centerPos.GetPositionY() + radius * sinf(angle); - point.z = z; // Don't use any height getters unless all bugs are fixed. - path.push_back(point); - } - } - uint8 _phase; // Counter for phases used with a getter. uint8 _summonDeaths; // Keeps count of arcane trash. uint8 _preparingPulsesChecker; // In retail they use 2 preparing pulses with 7 sec CD, after they pass 2 seconds. @@ -1326,11 +1306,7 @@ public: { if (action < ACTION_DELAYED_DESPAWN) { - Movement::MoveSplineInit init(me); - FillCirclePath(MalygosPositions[3], 35.0f, 282.3402f, init.Path(), true); - init.SetFly(); - init.SetCyclic(); - init.Launch(); + me->GetMotionMaster()->MoveCirclePath(MalygosPositions[3].GetPositionX(), MalygosPositions[3].GetPositionY(), 282.3402f, 35.0f, true, 16); } else { @@ -1339,21 +1315,6 @@ public: } private: - void FillCirclePath(Position const& centerPos, float radius, float z, Movement::PointsArray& path, bool clockwise) - { - float step = clockwise ? float(-M_PI) / 9.0f : float(M_PI) / 9.0f; - float angle = centerPos.GetAngle(me->GetPositionX(), me->GetPositionY()); - - for (uint8 i = 0; i < 18; angle += step, ++i) - { - G3D::Vector3 point; - point.x = centerPos.GetPositionX() + radius * cosf(angle); - point.y = centerPos.GetPositionY() + radius * sinf(angle); - point.z = z; // Don't use any height getters unless all bugs are fixed. - path.push_back(point); - } - } - InstanceScript* _instance; }; diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_yogg_saron.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_yogg_saron.cpp index c37cf28ab78..134783ccf07 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_yogg_saron.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_yogg_saron.cpp @@ -1126,30 +1126,11 @@ class npc_ominous_cloud : public CreatureScript DoCast(me, SPELL_OMINOUS_CLOUD_VISUAL); } - void FillCirclePath(Position const& centerPos, float radius, float z, Movement::PointsArray& path, bool clockwise) - { - float step = clockwise ? float(-M_PI) / 8.0f : float(M_PI) / 8.0f; - float angle = centerPos.GetAngle(me->GetPositionX(), me->GetPositionY()); - - for (uint8 i = 0; i < 16; angle += step, ++i) - { - G3D::Vector3 point; - point.x = centerPos.GetPositionX() + radius * cosf(angle); - point.y = centerPos.GetPositionY() + radius * sinf(angle); - point.z = me->GetMap()->GetHeight(me->GetPhaseMask(), point.x, point.y, z + 5.0f); - path.push_back(point); - } - } - void UpdateAI(uint32 /*diff*/) override { } - void DoAction(int32 action) override + void DoAction(int32 /*action*/) override { - Movement::MoveSplineInit init(me); - FillCirclePath(YoggSaronSpawnPos, me->GetDistance2d(YoggSaronSpawnPos.GetPositionX(), YoggSaronSpawnPos.GetPositionY()), me->GetPositionZ(), init.Path(), action != 0); - init.SetWalk(true); - init.SetCyclic(); - init.Launch(); + me->GetMotionMaster()->MoveCirclePath(YoggSaronSpawnPos.GetPositionX(), YoggSaronSpawnPos.GetPositionY(), me->GetPositionZ() + 5.0f, me->GetDistance2d(YoggSaronSpawnPos.GetPositionX(), YoggSaronSpawnPos.GetPositionY()), true, 16); } }; diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/instance_ulduar.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/instance_ulduar.cpp index 56148480e11..32d3b35f35c 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/instance_ulduar.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/instance_ulduar.cpp @@ -16,6 +16,7 @@ */ #include "InstanceScript.h" +#include "Vehicle.h" #include "Player.h" #include "ScriptedCreature.h" #include "ScriptMgr.h" @@ -91,6 +92,7 @@ class instance_ulduar : public InstanceMapScript // Creatures ObjectGuid LeviathanGUID; + GuidVector LeviathanVehicleGUIDs; ObjectGuid IgnisGUID; ObjectGuid RazorscaleGUID; ObjectGuid RazorscaleController; @@ -217,6 +219,11 @@ class instance_ulduar : public InstanceMapScript case NPC_LEVIATHAN: LeviathanGUID = creature->GetGUID(); break; + case NPC_SALVAGED_DEMOLISHER: + case NPC_SALVAGED_SIEGE_ENGINE: + case NPC_SALVAGED_CHOPPER: + LeviathanVehicleGUIDs.push_back(creature->GetGUID()); + break; case NPC_IGNIS: IgnisGUID = creature->GetGUID(); break; @@ -682,6 +689,24 @@ class instance_ulduar : public InstanceMapScript switch (type) { case BOSS_LEVIATHAN: + if (state == DONE) + { + // Eject all players from vehicles and make them untargetable. + // They will be despawned after a while + for (auto const& vehicleGuid : LeviathanVehicleGUIDs) + { + if (Creature* vehicleCreature = instance->GetCreature(vehicleGuid)) + { + if (Vehicle* vehicle = vehicleCreature->GetVehicleKit()) + { + vehicle->RemoveAllPassengers(); + vehicleCreature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + vehicleCreature->DespawnOrUnsummon(5 * MINUTE * IN_MILLISECONDS); + } + } + } + } + break; case BOSS_IGNIS: case BOSS_RAZORSCALE: case BOSS_XT002: @@ -1143,6 +1168,34 @@ class instance_ulduar : public InstanceMapScript } } + void UpdateDoorState(GameObject* door) override + { + // Leviathan doors are set to DOOR_TYPE_ROOM except the one it uses to enter the room + // which has to be set to DOOR_TYPE_PASSAGE + if (door->GetEntry() == GO_LEVIATHAN_DOOR && door->GetPositionX() > 400.f) + door->SetGoState(GetBossState(BOSS_LEVIATHAN) == DONE ? GO_STATE_ACTIVE : GO_STATE_READY); + else + InstanceScript::UpdateDoorState(door); + } + + void AddDoor(GameObject* door, bool add) override + { + // Leviathan doors are South except the one it uses to enter the room + // which is North and should not be used for boundary checks in BossAI::CheckBoundary() + if (door->GetEntry() == GO_LEVIATHAN_DOOR && door->GetPositionX() > 400.f) + { + if (add) + GetBossInfo(BOSS_LEVIATHAN)->door[DOOR_TYPE_PASSAGE].insert(door->GetGUID()); + else + GetBossInfo(BOSS_LEVIATHAN)->door[DOOR_TYPE_PASSAGE].erase(door->GetGUID()); + + if (add) + UpdateDoorState(door); + } + else + InstanceScript::AddDoor(door, add); + } + private: EventMap _events; uint32 _algalonTimer; diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/ulduar.h b/src/server/scripts/Northrend/Ulduar/Ulduar/ulduar.h index ddf293dd8b8..d40fb698658 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/ulduar.h +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/ulduar.h @@ -54,6 +54,7 @@ enum UlduarNPCs NPC_LEVIATHAN = 33113, NPC_SALVAGED_DEMOLISHER = 33109, NPC_SALVAGED_SIEGE_ENGINE = 33060, + NPC_SALVAGED_CHOPPER = 33062, NPC_IGNIS = 33118, NPC_RAZORSCALE = 33186, NPC_RAZORSCALE_CONTROLLER = 33233, diff --git a/src/server/scripts/Northrend/VioletHold/instance_violet_hold.cpp b/src/server/scripts/Northrend/VioletHold/instance_violet_hold.cpp index 3e3ce5cde75..a462c68e084 100644 --- a/src/server/scripts/Northrend/VioletHold/instance_violet_hold.cpp +++ b/src/server/scripts/Northrend/VioletHold/instance_violet_hold.cpp @@ -133,6 +133,7 @@ public: uiCyanigosaEventTimer = 3 * IN_MILLISECONDS; bActive = false; + bWiped = false; bIsDoorSpellCast = false; bCrystalActivated = false; defenseless = true; diff --git a/src/server/scripts/Northrend/zone_borean_tundra.cpp b/src/server/scripts/Northrend/zone_borean_tundra.cpp index f6b9f9fb6be..b58d9419e95 100644 --- a/src/server/scripts/Northrend/zone_borean_tundra.cpp +++ b/src/server/scripts/Northrend/zone_borean_tundra.cpp @@ -29,7 +29,6 @@ npc_corastrasza npc_sinkhole_kill_credit npc_khunok_the_behemoth npc_nerubar_victim -npc_keristrasza npc_nesingwary_trapper npc_lurgglbr npc_nexus_drake_hatchling @@ -223,48 +222,6 @@ public: }; /*###### -## npc_keristrasza -######*/ - -enum Keristrasza -{ - SPELL_TELEPORT_TO_SARAGOSA = 46772 -}; - -#define GOSSIP_HELLO_KERI "I am prepared to face Saragosa!" - -class npc_keristrasza : public CreatureScript -{ -public: - npc_keristrasza() : CreatureScript("npc_keristrasza") { } - - bool OnGossipHello(Player* player, Creature* creature) override - { - if (creature->IsQuestGiver()) - player->PrepareQuestMenu(creature->GetGUID()); - - if (player->GetQuestStatus(11957) == QUEST_STATUS_INCOMPLETE) - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HELLO_KERI, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1); - - player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); - - return true; - } - - bool OnGossipSelect(Player* player, Creature* /*creature*/, uint32 /*sender*/, uint32 action) override - { - player->PlayerTalkClass->ClearMenus(); - if (action == GOSSIP_ACTION_INFO_DEF + 1) - { - player->CLOSE_GOSSIP_MENU(); - player->CastSpell(player, SPELL_TELEPORT_TO_SARAGOSA, true); - } - - return true; - } -}; - -/*###### ## npc_corastrasza ######*/ @@ -2488,7 +2445,6 @@ void AddSC_borean_tundra() { new npc_sinkhole_kill_credit(); new npc_khunok_the_behemoth(); - new npc_keristrasza(); new npc_corastrasza(); new npc_iruk(); new npc_nerubar_victim(); diff --git a/src/server/scripts/Spells/spell_mage.cpp b/src/server/scripts/Spells/spell_mage.cpp index 8105f7de5ff..91ef240a1a3 100644 --- a/src/server/scripts/Spells/spell_mage.cpp +++ b/src/server/scripts/Spells/spell_mage.cpp @@ -548,7 +548,7 @@ class spell_mage_fire_frost_ward : public SpellScriptLoader } } - void Absorb(AuraEffect* aurEff, DamageInfo& dmgInfo, uint32& absorbAmount) + void Absorb(AuraEffect* /*aurEff*/, DamageInfo& /*dmgInfo*/, uint32& /*absorbAmount*/) { /*Unit* target = GetTarget(); if (AuraEffect* talentAurEff = target->GetAuraEffectOfRankedSpell(SPELL_MAGE_FROST_WARDING_R1, EFFECT_0)) diff --git a/src/server/scripts/Spells/spell_quest.cpp b/src/server/scripts/Spells/spell_quest.cpp index 287e3591f5d..f3c8396832c 100644 --- a/src/server/scripts/Spells/spell_quest.cpp +++ b/src/server/scripts/Spells/spell_quest.cpp @@ -2495,6 +2495,36 @@ public: } }; +class spell_q12414_hand_over_reins : public SpellScriptLoader +{ + public: + spell_q12414_hand_over_reins() : SpellScriptLoader("spell_q12414_hand_over_reins") { } + + class spell_q12414_hand_over_reins_SpellScript : public SpellScript + { + PrepareSpellScript(spell_q12414_hand_over_reins_SpellScript); + + void HandleScript(SpellEffIndex /*effIndex*/) + { + Creature* caster = GetCaster()->ToCreature(); + GetHitUnit()->ExitVehicle(); + + if (caster) + caster->DespawnOrUnsummon(); + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_q12414_hand_over_reins_SpellScript::HandleScript, EFFECT_1, SPELL_EFFECT_SCRIPT_EFFECT); + } + }; + + SpellScript* GetSpellScript() const override + { + return new spell_q12414_hand_over_reins_SpellScript(); + } +}; + void AddSC_quest_spell_scripts() { new spell_q55_sacred_cleansing(); @@ -2555,4 +2585,5 @@ void AddSC_quest_spell_scripts() new spell_q10929_fumping(); new spell_q28813_get_our_boys_back_dummy(); new spell_q28813_set_health_random(); + new spell_q12414_hand_over_reins(); } diff --git a/src/server/shared/CMakeLists.txt b/src/server/shared/CMakeLists.txt index 24902a7d91e..657b3fde349 100644 --- a/src/server/shared/CMakeLists.txt +++ b/src/server/shared/CMakeLists.txt @@ -22,6 +22,7 @@ file(GLOB_RECURSE sources_Networking Networking/*.cpp Networking/*.h) file(GLOB_RECURSE sources_Packets Packets/*.cpp Packets/*.h) file(GLOB_RECURSE sources_Realm Realm/*.cpp Realm/*.h) file(GLOB_RECURSE sources_Threading Threading/*.cpp Threading/*.h) +file(GLOB_RECURSE sources_Updater Updater/*.cpp Updater/*.h) file(GLOB_RECURSE sources_Utilities Utilities/*.cpp Utilities/*.h) file(GLOB sources_localdir *.cpp *.h) @@ -53,6 +54,7 @@ set(shared_STAT_SRCS ${sources_Packets} ${sources_Realm} ${sources_Threading} + ${sources_Updater} ${sources_Utilities} ${sources_localdir} ) @@ -61,7 +63,9 @@ include_directories( ${CMAKE_BINARY_DIR} ${CMAKE_SOURCE_DIR}/dep/recastnavigation/Detour ${CMAKE_SOURCE_DIR}/dep/SFMT + ${CMAKE_SOURCE_DIR}/dep/cppformat ${CMAKE_SOURCE_DIR}/dep/utf8cpp + ${CMAKE_SOURCE_DIR}/dep/process ${CMAKE_SOURCE_DIR}/src/server ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/Configuration @@ -76,6 +80,7 @@ include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/Realm ${CMAKE_CURRENT_SOURCE_DIR}/Threading ${CMAKE_CURRENT_SOURCE_DIR}/Utilities + ${CMAKE_CURRENT_SOURCE_DIR}/Updater ${CMAKE_SOURCE_DIR}/src/server/game/Entities/Object ${MYSQL_INCLUDE_DIR} ${OPENSSL_INCLUDE_DIR} diff --git a/src/server/shared/Database/DatabaseLoader.cpp b/src/server/shared/Database/DatabaseLoader.cpp new file mode 100644 index 00000000000..25c400fdfa8 --- /dev/null +++ b/src/server/shared/Database/DatabaseLoader.cpp @@ -0,0 +1,193 @@ +/* + * Copyright (C) 2008-2015 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 "DatabaseLoader.h" +#include "DBUpdater.h" +#include "Config.h" + +#include <mysqld_error.h> + +DatabaseLoader::DatabaseLoader(std::string const& logger, uint32 const defaultUpdateMask) + : _logger(logger), _autoSetup(sConfigMgr->GetBoolDefault("Updates.AutoSetup", true)), + _updateFlags(sConfigMgr->GetIntDefault("Updates.EnableDatabases", defaultUpdateMask)) +{ +} + +template <class T> +DatabaseLoader& DatabaseLoader::AddDatabase(DatabaseWorkerPool<T>& pool, std::string const& name) +{ + bool const updatesEnabledForThis = DBUpdater<T>::IsEnabled(_updateFlags); + + _open.push(std::make_pair([this, name, updatesEnabledForThis, &pool]() -> bool + { + std::string const dbString = sConfigMgr->GetStringDefault(name + "DatabaseInfo", ""); + if (dbString.empty()) + { + TC_LOG_ERROR(_logger.c_str(), "Database %s not specified in configuration file!", name.c_str()); + return false; + } + + uint8 const asyncThreads = uint8(sConfigMgr->GetIntDefault(name + "Database.WorkerThreads", 1)); + if (asyncThreads < 1 || asyncThreads > 32) + { + TC_LOG_ERROR(_logger.c_str(), "%s database: invalid number of worker threads specified. " + "Please pick a value between 1 and 32.", name.c_str()); + return false; + } + + uint8 const synchThreads = uint8(sConfigMgr->GetIntDefault(name + "Database.SynchThreads", 1)); + + pool.SetConnectionInfo(dbString, asyncThreads, synchThreads); + if (uint32 error = pool.Open()) + { + // Database does not exist + if ((error == ER_BAD_DB_ERROR) && updatesEnabledForThis && _autoSetup) + { + // Try to create the database and connect again if auto setup is enabled + if (DBUpdater<T>::Create(pool) && (!pool.Open())) + error = 0; + } + + // If the error wasn't handled quit + if (error) + { + TC_LOG_ERROR("sql.driver", "\nDatabasePool %s NOT opened. There were errors opening the MySQL connections. Check your SQLDriverLogFile " + "for specific errors. Read wiki at http://collab.kpsn.org/display/tc/TrinityCore+Home", name.c_str()); + + return false; + } + } + return true; + }, + [&pool]() + { + pool.Close(); + })); + + // Populate and update only if updates are enabled for this pool + if (updatesEnabledForThis) + { + _populate.push([this, name, &pool]() -> bool + { + if (!DBUpdater<T>::Populate(pool)) + { + TC_LOG_ERROR(_logger.c_str(), "Could not populate the %s database, see log for details.", name.c_str()); + return false; + } + return true; + }); + + _update.push([this, name, &pool]() -> bool + { + if (!DBUpdater<T>::Update(pool)) + { + TC_LOG_ERROR(_logger.c_str(), "Could not update the %s database, see log for details.", name.c_str()); + return false; + } + return true; + }); + } + + _prepare.push([this, name, &pool]() -> bool + { + if (!pool.PrepareStatements()) + { + TC_LOG_ERROR(_logger.c_str(), "Could not prepare statements of the %s database, see log for details.", name.c_str()); + return false; + } + return true; + }); + + return *this; +} + +bool DatabaseLoader::Load() +{ + if (!OpenDatabases()) + return false; + + if (!PopulateDatabases()) + return false; + + if (!UpdateDatabases()) + return false; + + if (!PrepareStatements()) + return false; + + return true; +} + +bool DatabaseLoader::OpenDatabases() +{ + while (!_open.empty()) + { + std::pair<Predicate, std::function<void()>> const load = _open.top(); + if (load.first()) + _close.push(load.second); + else + { + // Close all loaded databases + while (!_close.empty()) + { + _close.top()(); + _close.pop(); + } + return false; + } + + _open.pop(); + } + return true; +} + +// Processes the elements of the given stack until a predicate returned false. +bool DatabaseLoader::Process(std::stack<Predicate>& stack) +{ + while (!stack.empty()) + { + if (!stack.top()()) + return false; + + stack.pop(); + } + return true; +} + +bool DatabaseLoader::PopulateDatabases() +{ + return Process(_populate); +} + +bool DatabaseLoader::UpdateDatabases() +{ + return Process(_update); +} + +bool DatabaseLoader::PrepareStatements() +{ + return Process(_prepare); +} + +template +DatabaseLoader& DatabaseLoader::AddDatabase<LoginDatabaseConnection>(DatabaseWorkerPool<LoginDatabaseConnection>& pool, std::string const& name); +template +DatabaseLoader& DatabaseLoader::AddDatabase<WorldDatabaseConnection>(DatabaseWorkerPool<WorldDatabaseConnection>& pool, std::string const& name); +template +DatabaseLoader& DatabaseLoader::AddDatabase<CharacterDatabaseConnection>(DatabaseWorkerPool<CharacterDatabaseConnection>& pool, std::string const& name); +template +DatabaseLoader& DatabaseLoader::AddDatabase<HotfixDatabaseConnection>(DatabaseWorkerPool<HotfixDatabaseConnection>& pool, std::string const& name); diff --git a/src/server/shared/Database/DatabaseLoader.h b/src/server/shared/Database/DatabaseLoader.h new file mode 100644 index 00000000000..3bbf7e75771 --- /dev/null +++ b/src/server/shared/Database/DatabaseLoader.h @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2008-2015 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 DatabaseLoader_h__ +#define DatabaseLoader_h__ + +#include "DatabaseWorkerPool.h" +#include "DatabaseEnv.h" + +#include <stack> +#include <functional> + +// A helper class to initiate all database worker pools, +// handles updating, delays preparing of statements and cleans up on failure. +class DatabaseLoader +{ +public: + DatabaseLoader(std::string const& logger, uint32 const defaultUpdateMask); + + // Register a database to the loader (lazy implemented) + template <class T> + DatabaseLoader& AddDatabase(DatabaseWorkerPool<T>& pool, std::string const& name); + + // Load all databases + bool Load(); + + enum DatabaseTypeFlags + { + DATABASE_NONE = 0, + + DATABASE_LOGIN = 1, + DATABASE_CHARACTER = 2, + DATABASE_WORLD = 4, + DATABASE_HOTFIX = 8, + + DATABASE_MASK_ALL = DATABASE_LOGIN | DATABASE_CHARACTER | DATABASE_WORLD | DATABASE_HOTFIX + }; + +private: + bool OpenDatabases(); + bool PopulateDatabases(); + bool UpdateDatabases(); + bool PrepareStatements(); + + using Predicate = std::function<bool()>; + + static bool Process(std::stack<Predicate>& stack); + + std::string const _logger; + bool const _autoSetup; + uint32 const _updateFlags; + + std::stack<std::pair<Predicate, std::function<void()>>> _open; + std::stack<std::function<void()>> _close; + std::stack<Predicate> _populate, _update, _prepare; +}; + +#endif // DatabaseLoader_h__ diff --git a/src/server/shared/Database/DatabaseWorkerPool.h b/src/server/shared/Database/DatabaseWorkerPool.h index f1c6a7acbf5..6210986ff8b 100644 --- a/src/server/shared/Database/DatabaseWorkerPool.h +++ b/src/server/shared/Database/DatabaseWorkerPool.h @@ -30,6 +30,7 @@ #include "AdhocStatement.h" #include <mysqld_error.h> +#include <memory> #define MIN_MYSQL_SERVER_VERSION 50100u #define MIN_MYSQL_CLIENT_VERSION 50100u @@ -57,9 +58,9 @@ class DatabaseWorkerPool public: /* Activity state */ - DatabaseWorkerPool() : _connectionInfo(NULL) + DatabaseWorkerPool() : _queue(new ProducerConsumerQueue<SQLOperation*>()), + _async_threads(0), _synch_threads(0) { - _queue = new ProducerConsumerQueue<SQLOperation*>(); memset(_connectionCount, 0, sizeof(_connectionCount)); _connections.resize(IDX_SIZE); @@ -70,31 +71,37 @@ class DatabaseWorkerPool ~DatabaseWorkerPool() { _queue->Cancel(); + } - delete _queue; + void SetConnectionInfo(std::string const& infoString, uint8 const asyncThreads, uint8 const synchThreads) + { + _connectionInfo.reset(new MySQLConnectionInfo(infoString)); - delete _connectionInfo; + _async_threads = asyncThreads; + _synch_threads = synchThreads; } - bool Open(const std::string& infoString, uint8 async_threads, uint8 synch_threads) + uint32 Open() { - _connectionInfo = new MySQLConnectionInfo(infoString); + WPFatal(_connectionInfo.get(), "Connection info was not set!"); TC_LOG_INFO("sql.driver", "Opening DatabasePool '%s'. Asynchronous connections: %u, synchronous connections: %u.", - GetDatabaseName(), async_threads, synch_threads); + GetDatabaseName(), _async_threads, _synch_threads); - bool res = OpenConnections(IDX_ASYNC, async_threads); + uint32 error = OpenConnections(IDX_ASYNC, _async_threads); - if (!res) - return res; + if (error) + return error; - res = OpenConnections(IDX_SYNCH, synch_threads); + error = OpenConnections(IDX_SYNCH, _synch_threads); - if (res) + if (!error) + { TC_LOG_INFO("sql.driver", "DatabasePool '%s' opened successfully. %u total connections running.", GetDatabaseName(), (_connectionCount[IDX_SYNCH] + _connectionCount[IDX_ASYNC])); + } - return res; + return error; } void Close() @@ -120,6 +127,32 @@ class DatabaseWorkerPool TC_LOG_INFO("sql.driver", "All connections on DatabasePool '%s' closed.", GetDatabaseName()); } + //! Prepares all prepared statements + bool PrepareStatements() + { + for (uint8 i = 0; i < IDX_SIZE; ++i) + for (uint32 c = 0; c < _connectionCount[i]; ++c) + { + T* t = _connections[i][c]; + t->LockIfReady(); + if (!t->PrepareStatements()) + { + t->Unlock(); + Close(); + return false; + } + else + t->Unlock(); + } + + return true; + } + + inline MySQLConnectionInfo const* GetConnectionInfo() const + { + return _connectionInfo.get(); + } + /** Delayed one-way statement methods. */ @@ -461,7 +494,7 @@ class DatabaseWorkerPool } private: - bool OpenConnections(InternalIndex type, uint8 numConnections) + uint32 OpenConnections(InternalIndex type, uint8 numConnections) { _connections[type].resize(numConnections); for (uint8 i = 0; i < numConnections; ++i) @@ -469,7 +502,7 @@ class DatabaseWorkerPool T* t; if (type == IDX_ASYNC) - t = new T(_queue, *_connectionInfo); + t = new T(_queue.get(), *_connectionInfo); else if (type == IDX_SYNCH) t = new T(*_connectionInfo); else @@ -478,35 +511,32 @@ class DatabaseWorkerPool _connections[type][i] = t; ++_connectionCount[type]; - bool res = t->Open(); + uint32 error = t->Open(); - if (res) + if (!error) { if (mysql_get_server_version(t->GetHandle()) < MIN_MYSQL_SERVER_VERSION) { TC_LOG_ERROR("sql.driver", "TrinityCore does not support MySQL versions below 5.1"); - res = false; + error = 1; } } // Failed to open a connection or invalid version, abort and cleanup - if (!res) + if (error) { - TC_LOG_ERROR("sql.driver", "DatabasePool %s NOT opened. There were errors opening the MySQL connections. Check your SQLDriverLogFile " - "for specific errors. Read wiki at http://collab.kpsn.org/display/tc/TrinityCore+Home", GetDatabaseName()); - while (_connectionCount[type] != 0) { T* t = _connections[type][i--]; delete t; --_connectionCount[type]; } - - return false; + return error; } } - return true; + // Everything is fine + return 0; } unsigned long EscapeString(char *to, const char *from, unsigned long length) @@ -546,10 +576,13 @@ class DatabaseWorkerPool return _connectionInfo->database.c_str(); } - ProducerConsumerQueue<SQLOperation*>* _queue; //! Queue shared by async worker threads. - std::vector< std::vector<T*> > _connections; - uint32 _connectionCount[2]; //! Counter of MySQL connections; - MySQLConnectionInfo* _connectionInfo; + //! Queue shared by async worker threads. + std::unique_ptr<ProducerConsumerQueue<SQLOperation*>> _queue; + std::vector<std::vector<T*>> _connections; + //! Counter of MySQL connections; + uint32 _connectionCount[IDX_SIZE]; + std::unique_ptr<MySQLConnectionInfo> _connectionInfo; + uint8 _async_threads, _synch_threads; }; #endif diff --git a/src/server/shared/Database/MySQLConnection.cpp b/src/server/shared/Database/MySQLConnection.cpp index 1a9f973d47b..1fa3f01a5e1 100644 --- a/src/server/shared/Database/MySQLConnection.cpp +++ b/src/server/shared/Database/MySQLConnection.cpp @@ -72,7 +72,7 @@ void MySQLConnection::Close() delete this; } -bool MySQLConnection::Open() +uint32 MySQLConnection::Open() { MYSQL *mysqlInit; mysqlInit = mysql_init(NULL); @@ -137,13 +137,13 @@ bool MySQLConnection::Open() // set connection properties to UTF8 to properly handle locales for different // server configs - core sends data in UTF8, so MySQL must expect UTF8 too mysql_set_character_set(m_Mysql, "utf8"); - return PrepareStatements(); + return 0; } else { - TC_LOG_ERROR("sql.sql", "Could not connect to MySQL database at %s: %s\n", m_connectionInfo.host.c_str(), mysql_error(mysqlInit)); + TC_LOG_ERROR("sql.sql", "Could not connect to MySQL database at %s: %s", m_connectionInfo.host.c_str(), mysql_error(mysqlInit)); mysql_close(mysqlInit); - return false; + return mysql_errno(mysqlInit); } } diff --git a/src/server/shared/Database/MySQLConnection.h b/src/server/shared/Database/MySQLConnection.h index d486f5b4679..78d8d2fb5dd 100644 --- a/src/server/shared/Database/MySQLConnection.h +++ b/src/server/shared/Database/MySQLConnection.h @@ -72,9 +72,11 @@ class MySQLConnection MySQLConnection(ProducerConsumerQueue<SQLOperation*>* queue, MySQLConnectionInfo& connInfo); //! Constructor for asynchronous connections. virtual ~MySQLConnection(); - virtual bool Open(); + virtual uint32 Open(); void Close(); + bool PrepareStatements(); + public: bool Execute(const char* sql); bool Execute(PreparedStatement* stmt); @@ -111,7 +113,6 @@ class MySQLConnection MySQLPreparedStatement* GetPreparedStatement(uint32 index); void PrepareStatement(uint32 index, const char* sql, ConnectionFlags flags); - bool PrepareStatements(); virtual void DoPrepareStatements() = 0; protected: diff --git a/src/server/shared/Debugging/WheatyExceptionReport.cpp b/src/server/shared/Debugging/WheatyExceptionReport.cpp index e9f4f9ca9ac..f8f641a9ea7 100644 --- a/src/server/shared/Debugging/WheatyExceptionReport.cpp +++ b/src/server/shared/Debugging/WheatyExceptionReport.cpp @@ -1068,7 +1068,7 @@ bool logChildren) { case btChar: case btStdString: - FormatOutputValue(buffer, basicType, length, (PVOID)offset, sizeof(buffer)); + FormatOutputValue(buffer, basicType, length, (PVOID)offset, sizeof(buffer), elementsCount); symbolDetails.top().Value = buffer; break; default: @@ -1196,7 +1196,8 @@ void WheatyExceptionReport::FormatOutputValue(char * pszCurrBuffer, BasicType basicType, DWORD64 length, PVOID pAddress, -size_t bufferSize) +size_t bufferSize, +size_t countOverride) { __try { @@ -1204,10 +1205,15 @@ size_t bufferSize) { case btChar: { - if (strlen((char*)pAddress) > bufferSize - 6) + // Special case handling for char[] type + if (countOverride != 0) + length = countOverride; + else + length = strlen((char*)pAddress); + if (length > bufferSize - 6) pszCurrBuffer += sprintf(pszCurrBuffer, "\"%.*s...\"", bufferSize - 6, (char*)pAddress); else - pszCurrBuffer += sprintf(pszCurrBuffer, "\"%s\"", (char*)pAddress); + pszCurrBuffer += sprintf(pszCurrBuffer, "\"%.*s\"", length, (char*)pAddress); break; } case btStdString: diff --git a/src/server/shared/Debugging/WheatyExceptionReport.h b/src/server/shared/Debugging/WheatyExceptionReport.h index 9137b91aac9..b7731daaa2b 100644 --- a/src/server/shared/Debugging/WheatyExceptionReport.h +++ b/src/server/shared/Debugging/WheatyExceptionReport.h @@ -172,7 +172,7 @@ class WheatyExceptionReport static char * DumpTypeIndex(char *, DWORD64, DWORD, unsigned, DWORD_PTR, bool &, const char*, char*, bool, bool); - static void FormatOutputValue(char * pszCurrBuffer, BasicType basicType, DWORD64 length, PVOID pAddress, size_t bufferSize); + static void FormatOutputValue(char * pszCurrBuffer, BasicType basicType, DWORD64 length, PVOID pAddress, size_t bufferSize, size_t countOverride = 0); static BasicType GetBasicType(DWORD typeIndex, DWORD64 modBase); static DWORD_PTR DereferenceUnsafePointer(DWORD_PTR address); diff --git a/src/server/shared/Logging/Appender.cpp b/src/server/shared/Logging/Appender.cpp index dff931e3da8..ca40a857419 100644 --- a/src/server/shared/Logging/Appender.cpp +++ b/src/server/shared/Logging/Appender.cpp @@ -18,6 +18,10 @@ #include "Appender.h" #include "Common.h" #include "Util.h" +#include "StringFormat.h" + +#include <utility> +#include <sstream> std::string LogMessage::getTimeStr(time_t time) { @@ -68,38 +72,36 @@ void Appender::setLogLevel(LogLevel _level) level = _level; } -void Appender::write(LogMessage& message) +void Appender::write(LogMessage* message) { - if (!level || level > message.level) + if (!level || level > message->level) return; - message.prefix.clear(); + std::ostringstream ss; + if (flags & APPENDER_FLAGS_PREFIX_TIMESTAMP) - message.prefix.append(message.getTimeStr()); + ss << message->getTimeStr(); if (flags & APPENDER_FLAGS_PREFIX_LOGLEVEL) { - if (!message.prefix.empty()) - message.prefix.push_back(' '); + if (ss.rdbuf()->in_avail() == 0) + ss << ' '; - char text[MAX_QUERY_LEN]; - snprintf(text, MAX_QUERY_LEN, "%-5s", Appender::getLogLevelString(message.level)); - message.prefix.append(text); + ss << Trinity::StringFormat("%-5s", Appender::getLogLevelString(message->level)); } if (flags & APPENDER_FLAGS_PREFIX_LOGFILTERTYPE) { - if (!message.prefix.empty()) - message.prefix.push_back(' '); + if (ss.rdbuf()->in_avail() == 0) + ss << ' '; - message.prefix.push_back('['); - message.prefix.append(message.type); - message.prefix.push_back(']'); + ss << '[' << message->type << ']'; } - if (!message.prefix.empty()) - message.prefix.push_back(' '); + if (ss.rdbuf()->in_avail() == 0) + ss << ' '; + message->prefix = std::move(ss.str()); _write(message); } diff --git a/src/server/shared/Logging/Appender.h b/src/server/shared/Logging/Appender.h index 6f38eb6aaf7..38c45b3bcf1 100644 --- a/src/server/shared/Logging/Appender.h +++ b/src/server/shared/Logging/Appender.h @@ -21,6 +21,7 @@ #include <unordered_map> #include <string> #include <time.h> +#include <type_traits> #include "Define.h" // Values assigned have their equivalent in enum ACE_Log_Priority @@ -57,16 +58,16 @@ enum AppenderFlags struct LogMessage { - LogMessage(LogLevel _level, std::string const& _type, std::string const& _text) - : level(_level), type(_type), text(_text), mtime(time(NULL)) + LogMessage(LogLevel _level, std::string const& _type, std::string&& _text) + : level(_level), type(_type), text(std::forward<std::string>(_text)), mtime(time(NULL)) { } static std::string getTimeStr(time_t time); std::string getTimeStr(); - LogLevel level; - std::string type; - std::string text; + LogLevel const level; + std::string const type; + std::string const text; std::string prefix; std::string param1; time_t mtime; @@ -91,11 +92,11 @@ class Appender AppenderFlags getFlags() const; void setLogLevel(LogLevel); - void write(LogMessage& message); + void write(LogMessage* message); static const char* getLogLevelString(LogLevel level); private: - virtual void _write(LogMessage const& /*message*/) = 0; + virtual void _write(LogMessage const* /*message*/) = 0; uint8 id; std::string name; diff --git a/src/server/shared/Logging/AppenderConsole.cpp b/src/server/shared/Logging/AppenderConsole.cpp index ae27337fb9a..2efa4db4d2e 100644 --- a/src/server/shared/Logging/AppenderConsole.cpp +++ b/src/server/shared/Logging/AppenderConsole.cpp @@ -158,14 +158,14 @@ void AppenderConsole::ResetColor(bool stdout_stream) #endif } -void AppenderConsole::_write(LogMessage const& message) +void AppenderConsole::_write(LogMessage const* message) { - bool stdout_stream = !(message.level == LOG_LEVEL_ERROR || message.level == LOG_LEVEL_FATAL); + bool stdout_stream = !(message->level == LOG_LEVEL_ERROR || message->level == LOG_LEVEL_FATAL); if (_colored) { uint8 index; - switch (message.level) + switch (message->level) { case LOG_LEVEL_TRACE: index = 5; @@ -189,9 +189,9 @@ void AppenderConsole::_write(LogMessage const& message) } SetColor(stdout_stream, _colors[index]); - utf8printf(stdout_stream ? stdout : stderr, "%s%s", message.prefix.c_str(), message.text.c_str()); + utf8printf(stdout_stream ? stdout : stderr, "%s%s\n", message->prefix.c_str(), message->text.c_str()); ResetColor(stdout_stream); } else - utf8printf(stdout_stream ? stdout : stderr, "%s%s", message.prefix.c_str(), message.text.c_str()); + utf8printf(stdout_stream ? stdout : stderr, "%s%s\n", message->prefix.c_str(), message->text.c_str()); } diff --git a/src/server/shared/Logging/AppenderConsole.h b/src/server/shared/Logging/AppenderConsole.h index 0f9536b3111..0acf7636e35 100644 --- a/src/server/shared/Logging/AppenderConsole.h +++ b/src/server/shared/Logging/AppenderConsole.h @@ -51,7 +51,7 @@ class AppenderConsole: public Appender private: void SetColor(bool stdout_stream, ColorTypes color); void ResetColor(bool stdout_stream); - void _write(LogMessage const& message) override; + void _write(LogMessage const* message) override; bool _colored; ColorTypes _colors[MaxLogLevels]; }; diff --git a/src/server/shared/Logging/AppenderDB.cpp b/src/server/shared/Logging/AppenderDB.cpp index 99ae822af34..8a329ea3a0f 100644 --- a/src/server/shared/Logging/AppenderDB.cpp +++ b/src/server/shared/Logging/AppenderDB.cpp @@ -23,18 +23,18 @@ AppenderDB::AppenderDB(uint8 id, std::string const& name, LogLevel level) AppenderDB::~AppenderDB() { } -void AppenderDB::_write(LogMessage const& message) +void AppenderDB::_write(LogMessage const* message) { // Avoid infinite loop, PExecute triggers Logging with "sql.sql" type - if (!enabled || (message.type.find("sql") != std::string::npos)) + if (!enabled || (message->type.find("sql") != std::string::npos)) return; PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_INS_LOG); - stmt->setUInt64(0, message.mtime); + stmt->setUInt64(0, message->mtime); stmt->setUInt32(1, realmId); - stmt->setString(2, message.type); - stmt->setUInt8(3, uint8(message.level)); - stmt->setString(4, message.text); + stmt->setString(2, message->type); + stmt->setUInt8(3, uint8(message->level)); + stmt->setString(4, message->text); LoginDatabase.Execute(stmt); } diff --git a/src/server/shared/Logging/AppenderDB.h b/src/server/shared/Logging/AppenderDB.h index e20ceaf77b4..09affdb46f1 100644 --- a/src/server/shared/Logging/AppenderDB.h +++ b/src/server/shared/Logging/AppenderDB.h @@ -31,7 +31,7 @@ class AppenderDB: public Appender private: uint32 realmId; bool enabled; - void _write(LogMessage const& message) override; + void _write(LogMessage const* message) override; }; #endif diff --git a/src/server/shared/Logging/AppenderFile.cpp b/src/server/shared/Logging/AppenderFile.cpp index 07a88a367ae..3892adbe3be 100644 --- a/src/server/shared/Logging/AppenderFile.cpp +++ b/src/server/shared/Logging/AppenderFile.cpp @@ -43,21 +43,21 @@ AppenderFile::~AppenderFile() CloseFile(); } -void AppenderFile::_write(LogMessage const& message) +void AppenderFile::_write(LogMessage const* message) { - bool exceedMaxSize = maxFileSize > 0 && (fileSize.load() + message.Size()) > maxFileSize; + bool exceedMaxSize = maxFileSize > 0 && (fileSize.load() + message->Size()) > maxFileSize; if (dynamicName) { char namebuf[TRINITY_PATH_MAX]; - snprintf(namebuf, TRINITY_PATH_MAX, filename.c_str(), message.param1.c_str()); + snprintf(namebuf, TRINITY_PATH_MAX, filename.c_str(), message->param1.c_str()); // always use "a" with dynamic name otherwise it could delete the log we wrote in last _write() call FILE* file = OpenFile(namebuf, "a", backup || exceedMaxSize); if (!file) return; - fprintf(file, "%s%s", message.prefix.c_str(), message.text.c_str()); + fprintf(file, "%s%s", message->prefix.c_str(), message->text.c_str()); fflush(file); - fileSize += uint64(message.Size()); + fileSize += uint64(message->Size()); fclose(file); return; } @@ -67,9 +67,9 @@ void AppenderFile::_write(LogMessage const& message) if (!logfile) return; - fprintf(logfile, "%s%s", message.prefix.c_str(), message.text.c_str()); + fprintf(logfile, "%s%s\n", message->prefix.c_str(), message->text.c_str()); fflush(logfile); - fileSize += uint64(message.Size()); + fileSize += uint64(message->Size()); } FILE* AppenderFile::OpenFile(std::string const &filename, std::string const &mode, bool backup) diff --git a/src/server/shared/Logging/AppenderFile.h b/src/server/shared/Logging/AppenderFile.h index 23651fc1129..36afdd23ad1 100644 --- a/src/server/shared/Logging/AppenderFile.h +++ b/src/server/shared/Logging/AppenderFile.h @@ -30,7 +30,7 @@ class AppenderFile: public Appender private: void CloseFile(); - void _write(LogMessage const& message) override; + void _write(LogMessage const* message) override; FILE* logfile; std::string filename; std::string logDir; diff --git a/src/server/shared/Logging/Log.cpp b/src/server/shared/Logging/Log.cpp index aa432128171..c9a4432039f 100644 --- a/src/server/shared/Logging/Log.cpp +++ b/src/server/shared/Logging/Log.cpp @@ -199,6 +199,9 @@ void Log::CreateLoggerFromConfig(std::string const& appenderName) return; } + if (level < lowestLogLevel) + lowestLogLevel = level; + logger.Create(name, level); //fprintf(stdout, "Log::CreateLoggerFromConfig: Created Logger %s, Level %u\n", name.c_str(), level); @@ -261,30 +264,18 @@ void Log::ReadLoggersFromConfig() } } -void Log::vlog(std::string const& filter, LogLevel level, char const* str, va_list argptr) -{ - char text[MAX_QUERY_LEN]; - vsnprintf(text, MAX_QUERY_LEN, str, argptr); - write(new LogMessage(level, filter, text)); -} - -void Log::write(LogMessage* msg) const +void Log::write(std::unique_ptr<LogMessage>&& msg) const { Logger const* logger = GetLoggerByType(msg->type); - msg->text.append("\n"); if (_ioService) { - auto logOperation = std::shared_ptr<LogOperation>(new LogOperation(logger, msg)); + auto logOperation = std::shared_ptr<LogOperation>(new LogOperation(logger, std::forward<std::unique_ptr<LogMessage>>(msg))); _ioService->post(_strand->wrap([logOperation](){ logOperation->call(); })); - } else - { - logger->write(*msg); - delete msg; - } + logger->write(msg.get()); } std::string Log::GetTimestampStr() @@ -321,6 +312,9 @@ bool Log::SetLogLevel(std::string const& name, const char* newLevelc, bool isLog return false; it->second.setLogLevel(newLevel); + + if (newLevel != LOG_LEVEL_DISABLED && newLevel < lowestLogLevel) + lowestLogLevel = newLevel; } else { @@ -343,33 +337,13 @@ void Log::outCharDump(char const* str, uint32 accountId, uint64 guid, char const ss << "== START DUMP == (account: " << accountId << " guid: " << guid << " name: " << name << ")\n" << str << "\n== END DUMP ==\n"; - LogMessage* msg = new LogMessage(LOG_LEVEL_INFO, "entities.player.dump", ss.str()); + std::unique_ptr<LogMessage> msg(new LogMessage(LOG_LEVEL_INFO, "entities.player.dump", ss.str())); std::ostringstream param; param << guid << '_' << name; msg->param1 = param.str(); - write(msg); -} - -void Log::outCommand(uint32 account, const char * str, ...) -{ - if (!str || !ShouldLog("commands.gm", LOG_LEVEL_INFO)) - return; - - va_list ap; - va_start(ap, str); - char text[MAX_QUERY_LEN]; - vsnprintf(text, MAX_QUERY_LEN, str, ap); - va_end(ap); - - LogMessage* msg = new LogMessage(LOG_LEVEL_INFO, "commands.gm", text); - - std::ostringstream ss; - ss << account; - msg->param1 = ss.str(); - - write(msg); + write(std::move(msg)); } void Log::SetRealmId(uint32 id) @@ -394,6 +368,7 @@ void Log::LoadFromConfig() { Close(); + lowestLogLevel = LOG_LEVEL_FATAL; AppenderId = 0; m_logsDir = sConfigMgr->GetStringDefault("LogsDir", ""); if (!m_logsDir.empty()) diff --git a/src/server/shared/Logging/Log.h b/src/server/shared/Logging/Log.h index 1d67ff87f76..20d83d2dcf0 100644 --- a/src/server/shared/Logging/Log.h +++ b/src/server/shared/Logging/Log.h @@ -22,12 +22,14 @@ #include "Define.h" #include "Appender.h" #include "Logger.h" -#include <stdarg.h> +#include "StringFormat.h" #include <boost/asio/io_service.hpp> #include <boost/asio/strand.hpp> +#include <stdarg.h> #include <unordered_map> #include <string> +#include <memory> #define LOGGER_ROOT "root" @@ -59,17 +61,34 @@ class Log bool ShouldLog(std::string const& type, LogLevel level) const; bool SetLogLevel(std::string const& name, char const* level, bool isLogger = true); - void outMessage(std::string const& f, LogLevel level, char const* str, ...) ATTR_PRINTF(4, 5); + template<typename... Args> + inline void outMessage(std::string const& filter, LogLevel const level, const char* fmt, Args const&... args) + { + write(std::move(std::unique_ptr<LogMessage>(new LogMessage(level, filter, std::move(Trinity::StringFormat(fmt, args...)))))); + } + + template<typename... Args> + void outCommand(uint32 account, const char* fmt, Args const&... args) + { + if (!ShouldLog("commands.gm", LOG_LEVEL_INFO)) + return; + + std::unique_ptr<LogMessage> msg(new LogMessage(LOG_LEVEL_INFO, "commands.gm", std::move(Trinity::StringFormat(fmt, args...)))); + + std::ostringstream ss; + ss << account; + msg->param1 = ss.str(); + + write(std::move(msg)); + } - void outCommand(uint32 account, const char * str, ...) ATTR_PRINTF(3, 4); void outCharDump(char const* str, uint32 account_id, uint64 guid, char const* name); void SetRealmId(uint32 id); private: static std::string GetTimestampStr(); - void vlog(std::string const& f, LogLevel level, char const* str, va_list argptr); - void write(LogMessage* msg) const; + void write(std::unique_ptr<LogMessage>&& msg) const; Logger const* GetLoggerByType(std::string const& type) const; Appender* GetAppenderByName(std::string const& name); @@ -82,6 +101,7 @@ class Log AppenderMap appenders; LoggerMap loggers; uint8 AppenderId; + LogLevel lowestLogLevel; std::string m_logsDir; std::string m_logsTimestamp; @@ -113,6 +133,10 @@ inline bool Log::ShouldLog(std::string const& type, LogLevel level) const // Speed up in cases where requesting "Type.sub1.sub2" but only configured // Logger "Type" + // Don't even look for a logger if the LogLevel is lower than lowest log levels across all loggers + if (level < lowestLogLevel) + return false; + Logger const* logger = GetLoggerByType(type); if (!logger) return false; @@ -121,23 +145,34 @@ inline bool Log::ShouldLog(std::string const& type, LogLevel level) const return logLevel != LOG_LEVEL_DISABLED && logLevel <= level; } -inline void Log::outMessage(std::string const& filter, LogLevel level, const char * str, ...) -{ - va_list ap; - va_start(ap, str); - - vlog(filter, level, str, ap); - - va_end(ap); -} - #define sLog Log::instance() +#define LOG_EXCEPTION_FREE(filterType__, level__, ...) \ + { \ + try \ + { \ + sLog->outMessage(filterType__, level__, __VA_ARGS__); \ + } \ + catch (std::exception& e) \ + { \ + sLog->outMessage("server", LOG_LEVEL_ERROR, "Wrong format occurred (%s) at %s:%u.", \ + e.what(), __FILE__, __LINE__); \ + } \ + } + #if PLATFORM != PLATFORM_WINDOWS +void check_args(const char* format, ...) ATTR_PRINTF(1, 2); + +// This will catch format errors on build time #define TC_LOG_MESSAGE_BODY(filterType__, level__, ...) \ do { \ if (sLog->ShouldLog(filterType__, level__)) \ - sLog->outMessage(filterType__, level__, __VA_ARGS__); \ + { \ + if (false) \ + check_args(__VA_ARGS__); \ + \ + LOG_EXCEPTION_FREE(filterType__, level__, __VA_ARGS__); \ + } \ } while (0) #else #define TC_LOG_MESSAGE_BODY(filterType__, level__, ...) \ @@ -145,7 +180,7 @@ inline void Log::outMessage(std::string const& filter, LogLevel level, const cha __pragma(warning(disable:4127)) \ do { \ if (sLog->ShouldLog(filterType__, level__)) \ - sLog->outMessage(filterType__, level__, __VA_ARGS__); \ + LOG_EXCEPTION_FREE(filterType__, level__, __VA_ARGS__); \ } while (0) \ __pragma(warning(pop)) #endif diff --git a/src/server/shared/Logging/LogOperation.cpp b/src/server/shared/Logging/LogOperation.cpp index 9afb28a49c2..bcd923c705e 100644 --- a/src/server/shared/Logging/LogOperation.cpp +++ b/src/server/shared/Logging/LogOperation.cpp @@ -18,14 +18,8 @@ #include "LogOperation.h" #include "Logger.h" -LogOperation::~LogOperation() -{ - delete msg; -} - int LogOperation::call() { - if (logger && msg) - logger->write(*msg); + logger->write(msg.get()); return 0; } diff --git a/src/server/shared/Logging/LogOperation.h b/src/server/shared/Logging/LogOperation.h index b8655413273..ffdd35c3c09 100644 --- a/src/server/shared/Logging/LogOperation.h +++ b/src/server/shared/Logging/LogOperation.h @@ -18,23 +18,25 @@ #ifndef LOGOPERATION_H #define LOGOPERATION_H +#include <memory> + class Logger; struct LogMessage; class LogOperation { public: - LogOperation(Logger const* _logger, LogMessage* _msg) - : logger(_logger), msg(_msg) + LogOperation(Logger const* _logger, std::unique_ptr<LogMessage>&& _msg) + : logger(_logger), msg(std::forward<std::unique_ptr<LogMessage>>(_msg)) { } - ~LogOperation(); + ~LogOperation() { } int call(); protected: Logger const* logger; - LogMessage* msg; + std::unique_ptr<LogMessage> msg; }; #endif diff --git a/src/server/shared/Logging/Logger.cpp b/src/server/shared/Logging/Logger.cpp index 615732deb30..3b02eb47575 100644 --- a/src/server/shared/Logging/Logger.cpp +++ b/src/server/shared/Logging/Logger.cpp @@ -50,9 +50,9 @@ void Logger::setLogLevel(LogLevel _level) level = _level; } -void Logger::write(LogMessage& message) const +void Logger::write(LogMessage* message) const { - if (!level || level > message.level || message.text.empty()) + if (!level || level > message->level || message->text.empty()) { //fprintf(stderr, "Logger::write: Logger %s, Level %u. Msg %s Level %u WRONG LEVEL MASK OR EMPTY MSG\n", getName().c_str(), getLogLevel(), message.text.c_str(), message.level); return; diff --git a/src/server/shared/Logging/Logger.h b/src/server/shared/Logging/Logger.h index a81ee8d7bd2..1aee75c5d72 100644 --- a/src/server/shared/Logging/Logger.h +++ b/src/server/shared/Logging/Logger.h @@ -32,7 +32,7 @@ class Logger std::string const& getName() const; LogLevel getLogLevel() const; void setLogLevel(LogLevel level); - void write(LogMessage& message) const; + void write(LogMessage* message) const; private: std::string name; diff --git a/src/server/shared/Networking/SocketMgr.h b/src/server/shared/Networking/SocketMgr.h index 0c1940b0e33..e18a2077288 100644 --- a/src/server/shared/Networking/SocketMgr.h +++ b/src/server/shared/Networking/SocketMgr.h @@ -100,7 +100,7 @@ public: } catch (boost::system::system_error const& err) { - TC_LOG_INFO("network", "Failed to retrieve client's remote address %s", err.what()); + TC_LOG_WARN("network", "Failed to retrieve client's remote address %s", err.what()); } } diff --git a/src/server/shared/Updater/DBUpdater.cpp b/src/server/shared/Updater/DBUpdater.cpp new file mode 100644 index 00000000000..10119e08deb --- /dev/null +++ b/src/server/shared/Updater/DBUpdater.cpp @@ -0,0 +1,414 @@ +/* + * Copyright (C) 2008-2015 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 "DBUpdater.h" +#include "Log.h" +#include "revision.h" +#include "UpdateFetcher.h" +#include "DatabaseLoader.h" +#include "Config.h" + +#include <fstream> +#include <iostream> +#include <unordered_map> +#include <boost/process.hpp> +#include <boost/process/mitigate.hpp> +#include <boost/iostreams/device/file_descriptor.hpp> +#include <boost/system/system_error.hpp> + +using namespace boost::process; +using namespace boost::process::initializers; +using namespace boost::iostreams; + +template<class T> +std::string DBUpdater<T>::GetSourceDirectory() +{ + std::string const entry = sConfigMgr->GetStringDefault("Updates.SourcePath", ""); + if (!entry.empty()) + return entry; + else + return _SOURCE_DIRECTORY; +} + +template<class T> +std::string DBUpdater<T>::GetMySqlCli() +{ + std::string const entry = sConfigMgr->GetStringDefault("Updates.MySqlCLIPath", ""); + if (!entry.empty()) + return entry; + else + return _MYSQL_EXECUTABLE; +} + +// Auth Database +template<> +std::string DBUpdater<LoginDatabaseConnection>::GetConfigEntry() +{ + return "Updates.Auth"; +} + +template<> +std::string DBUpdater<LoginDatabaseConnection>::GetTableName() +{ + return "Auth"; +} + +template<> +std::string DBUpdater<LoginDatabaseConnection>::GetBaseFile() +{ + return DBUpdater<LoginDatabaseConnection>::GetSourceDirectory() + "/sql/base/auth_database.sql"; +} + +template<> +bool DBUpdater<LoginDatabaseConnection>::IsEnabled(uint32 const updateMask) +{ + // This way silences warnings under msvc + return (updateMask & DatabaseLoader::DATABASE_LOGIN) ? true : false; +} + +// World Database +template<> +std::string DBUpdater<WorldDatabaseConnection>::GetConfigEntry() +{ + return "Updates.World"; +} + +template<> +std::string DBUpdater<WorldDatabaseConnection>::GetTableName() +{ + return "World"; +} + +template<> +std::string DBUpdater<WorldDatabaseConnection>::GetBaseFile() +{ + return _FULL_DATABASE; +} + +template<> +bool DBUpdater<WorldDatabaseConnection>::IsEnabled(uint32 const updateMask) +{ + // This way silences warnings under msvc + return (updateMask & DatabaseLoader::DATABASE_WORLD) ? true : false; +} + +template<> +BaseLocation DBUpdater<WorldDatabaseConnection>::GetBaseLocationType() +{ + return LOCATION_DOWNLOAD; +} + +// Character Database +template<> +std::string DBUpdater<CharacterDatabaseConnection>::GetConfigEntry() +{ + return "Updates.Character"; +} + +template<> +std::string DBUpdater<CharacterDatabaseConnection>::GetTableName() +{ + return "Character"; +} + +template<> +std::string DBUpdater<CharacterDatabaseConnection>::GetBaseFile() +{ + return DBUpdater<CharacterDatabaseConnection>::GetSourceDirectory() + "/sql/base/characters_database.sql"; +} + +template<> +bool DBUpdater<CharacterDatabaseConnection>::IsEnabled(uint32 const updateMask) +{ + // This way silences warnings under msvc + return (updateMask & DatabaseLoader::DATABASE_CHARACTER) ? true : false; +} + +// Hotfix Database +template<> +std::string DBUpdater<HotfixDatabaseConnection>::GetConfigEntry() +{ + return "Updates.Hotfix"; +} + +template<> +std::string DBUpdater<HotfixDatabaseConnection>::GetTableName() +{ + return "Hotfixes"; +} + +template<> +std::string DBUpdater<HotfixDatabaseConnection>::GetBaseFile() +{ + return _HOTFIXES_DATABASE; +} + +template<> +bool DBUpdater<HotfixDatabaseConnection>::IsEnabled(uint32 const updateMask) +{ + // This way silences warnings under msvc + return (updateMask & DatabaseLoader::DATABASE_HOTFIX) ? true : false; +} + +template<> +BaseLocation DBUpdater<HotfixDatabaseConnection>::GetBaseLocationType() +{ + return LOCATION_DOWNLOAD; +} + +// All +template<class T> +BaseLocation DBUpdater<T>::GetBaseLocationType() +{ + return LOCATION_REPOSITORY; +} + +template<class T> +bool DBUpdater<T>::CheckExecutable() +{ + DBUpdater<T>::Path const exe(DBUpdater<T>::GetMySqlCli()); + if (!exists(exe)) + { + // Check for mysql in path + std::vector<std::string> args = {"--version"}; + uint32 ret; + try + { + child c = execute(run_exe("mysql"), set_args(args), throw_on_error(), close_stdout()); + ret = wait_for_exit(c); + } + catch (boost::system::system_error&) + { + ret = EXIT_FAILURE; + } + + if (ret == EXIT_FAILURE) + { + TC_LOG_FATAL("sql.updates", "Didn't find executeable mysql binary at \'%s\', correct the path in the *.conf (\"Updates.MySqlCLIPath\").", + absolute(exe).generic_string().c_str()); + + return false; + } + } + return true; +} + +template<class T> +bool DBUpdater<T>::Create(DatabaseWorkerPool<T>& pool) +{ + TC_LOG_INFO("sql.updates", "Database \"%s\" does not exist, do you want to create it? [yes (default) / no]: ", + pool.GetConnectionInfo()->database.c_str()); + + std::string answer; + std::getline(std::cin, answer); + if (!answer.empty() && !(answer.substr(0, 1) == "y")) + return false; + + TC_LOG_INFO("sql.updates", "Creating database \"%s\"...", pool.GetConnectionInfo()->database.c_str()); + + // Path of temp file + static Path const temp("create_table.sql"); + + // Create temporary query to use external mysql cli + std::ofstream file(temp.generic_string()); + if (!file.is_open()) + { + TC_LOG_FATAL("sql.updates", "Failed to create temporary query file \"%s\"!", temp.generic_string().c_str()); + return false; + } + + file << "CREATE DATABASE `" << pool.GetConnectionInfo()->database << "` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci\n\n"; + + file.close(); + + try + { + DBUpdater<T>::ApplyFile(pool, pool.GetConnectionInfo()->host, pool.GetConnectionInfo()->user, pool.GetConnectionInfo()->password, + pool.GetConnectionInfo()->port_or_socket, "", temp); + } + catch (UpdateException&) + { + TC_LOG_FATAL("sql.updates", "Failed to create database %s! Has the user `CREATE` priviliges?", pool.GetConnectionInfo()->database.c_str()); + boost::filesystem::remove(temp); + return false; + } + + TC_LOG_INFO("sql.updates", "Done."); + boost::filesystem::remove(temp); + return true; +} + +template<class T> +bool DBUpdater<T>::Update(DatabaseWorkerPool<T>& pool) +{ + if (!DBUpdater<T>::CheckExecutable()) + return false; + + TC_LOG_INFO("sql.updates", "Updating %s database...", DBUpdater<T>::GetTableName().c_str()); + + Path const sourceDirectory(GetSourceDirectory()); + + if (!is_directory(sourceDirectory)) + { + TC_LOG_ERROR("sql.updates", "DBUpdater: Given source directory %s does not exist, skipped!", sourceDirectory.generic_string().c_str()); + return false; + } + + UpdateFetcher updateFetcher(sourceDirectory, [&](std::string const& query) { DBUpdater<T>::Apply(pool, query); }, + [&](Path const& file) { DBUpdater<T>::ApplyFile(pool, file); }, + [&](std::string const& query) -> QueryResult { return DBUpdater<T>::Retrieve(pool, query); }); + + uint32 const count = updateFetcher.Update( + sConfigMgr->GetBoolDefault("Updates.Redundancy", true), + sConfigMgr->GetBoolDefault("Updates.AllowRehash", true), + sConfigMgr->GetBoolDefault("Updates.ArchivedRedundancy", false), + sConfigMgr->GetIntDefault("Updates.CleanDeadRefMaxCount", 3)); + + if (!count) + TC_LOG_INFO("sql.updates", ">> %s database is up-to-date!", DBUpdater<T>::GetTableName().c_str()); + else + TC_LOG_INFO("sql.updates", ">> Applied %d %s.", count, count == 1 ? "query" : "queries"); + + return true; +} + +template<class T> +bool DBUpdater<T>::Populate(DatabaseWorkerPool<T>& pool) +{ + { + QueryResult const result = Retrieve(pool, "SHOW TABLES"); + if (result && (result->GetRowCount() > 0)) + return true; + } + + if (!DBUpdater<T>::CheckExecutable()) + return false; + + TC_LOG_INFO("sql.updates", "Database %s is empty, auto populating it...", DBUpdater<T>::GetTableName().c_str()); + + std::string const p = DBUpdater<T>::GetBaseFile(); + if (p.empty()) + { + TC_LOG_INFO("sql.updates", ">> No base file provided, skipped!"); + return true; + } + + Path const base(p); + if (!exists(base)) + { + switch (DBUpdater<T>::GetBaseLocationType()) + { + case LOCATION_REPOSITORY: + { + TC_LOG_ERROR("sql.updates", ">> Base file \"%s\" is missing, try to clone the source again.", + base.generic_string().c_str()); + + break; + } + case LOCATION_DOWNLOAD: + { + TC_LOG_ERROR("sql.updates", ">> File \"%s\" is missing, download it from \"http://www.trinitycore.org/f/files/category/1-database/\"" \ + " and place it in your server directory.", base.filename().generic_string().c_str()); + break; + } + } + return false; + } + + // Update database + TC_LOG_INFO("sql.updates", ">> Applying \'%s\'...", base.generic_string().c_str()); + ApplyFile(pool, base); + + TC_LOG_INFO("sql.updates", ">> Done!"); + return true; +} + +template<class T> +QueryResult DBUpdater<T>::Retrieve(DatabaseWorkerPool<T>& pool, std::string const& query) +{ + return pool.PQuery(query.c_str()); +} + +template<class T> +void DBUpdater<T>::Apply(DatabaseWorkerPool<T>& pool, std::string const& query) +{ + pool.DirectExecute(query.c_str()); +} + +template<class T> +void DBUpdater<T>::ApplyFile(DatabaseWorkerPool<T>& pool, Path const& path) +{ + DBUpdater<T>::ApplyFile(pool, pool.GetConnectionInfo()->host, pool.GetConnectionInfo()->user, pool.GetConnectionInfo()->password, + pool.GetConnectionInfo()->port_or_socket, pool.GetConnectionInfo()->database, path); +} + +template<class T> +void DBUpdater<T>::ApplyFile(DatabaseWorkerPool<T>& pool, std::string const& host, std::string const& user, + std::string const& password, std::string const& port_or_socket, std::string const& database, Path const& path) +{ + std::vector<std::string> args; + args.reserve(7); + + // CLI Client connection info + args.push_back("-h" + host); + args.push_back("-u" + user); + args.push_back("-p" + password); + args.push_back("-P" + port_or_socket); + + // Set the default charset to utf8 + args.push_back("--default-character-set=utf8"); + + // Set max allowed packet to 1 GB + args.push_back("--max-allowed-packet=1GB"); + + // Database + if (!database.empty()) + args.push_back(database); + + // ToDo: use the existing query in memory as virtual file if possible + file_descriptor_source source(path); + + uint32 ret; + try + { + child c = execute(run_exe(DBUpdater<T>::GetMySqlCli().empty() ? "mysql" : + boost::filesystem::absolute(DBUpdater<T>::GetMySqlCli()).generic_string()), + set_args(args), bind_stdin(source), throw_on_error()); + + ret = wait_for_exit(c); + } + catch (boost::system::system_error&) + { + ret = EXIT_FAILURE; + } + + source.close(); + + if (ret != EXIT_SUCCESS) + { + TC_LOG_FATAL("sql.updates", "Applying of file \'%s\' to database \'%s\' failed!" \ + " If you are an user pull the latest revision from the repository. If you are a developer fix your sql query.", + path.generic_string().c_str(), pool.GetConnectionInfo()->database.c_str()); + + throw UpdateException("update failed"); + } +} + +template class DBUpdater<LoginDatabaseConnection>; +template class DBUpdater<WorldDatabaseConnection>; +template class DBUpdater<CharacterDatabaseConnection>; +template class DBUpdater<HotfixDatabaseConnection>; diff --git a/src/server/shared/Updater/DBUpdater.h b/src/server/shared/Updater/DBUpdater.h new file mode 100644 index 00000000000..0caf8a438fb --- /dev/null +++ b/src/server/shared/Updater/DBUpdater.h @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2008-2015 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 DBUpdater_h__ +#define DBUpdater_h__ + +#include "DatabaseEnv.h" + +#include <string> +#include <boost/filesystem.hpp> + +class UpdateException : public std::exception +{ +public: + UpdateException(std::string const& msg) : _msg(msg) { } + ~UpdateException() throw() { } + + char const* what() const throw() override { return _msg.c_str(); } + +private: + std::string const _msg; +}; + +enum BaseLocation +{ + LOCATION_REPOSITORY, + LOCATION_DOWNLOAD +}; + +template <class T> +class DBUpdater +{ +public: + using Path = boost::filesystem::path; + + static std::string GetSourceDirectory(); + + static inline std::string GetConfigEntry(); + + static inline std::string GetTableName(); + + static std::string GetBaseFile(); + + static bool IsEnabled(uint32 const updateMask); + + static BaseLocation GetBaseLocationType(); + + static bool Create(DatabaseWorkerPool<T>& pool); + + static bool Update(DatabaseWorkerPool<T>& pool); + + static bool Populate(DatabaseWorkerPool<T>& pool); + +private: + static std::string GetMySqlCli(); + static bool CheckExecutable(); + + static QueryResult Retrieve(DatabaseWorkerPool<T>& pool, std::string const& query); + static void Apply(DatabaseWorkerPool<T>& pool, std::string const& query); + static void ApplyFile(DatabaseWorkerPool<T>& pool, Path const& path); + static void ApplyFile(DatabaseWorkerPool<T>& pool, std::string const& host, std::string const& user, + std::string const& password, std::string const& port_or_socket, std::string const& database, Path const& path); +}; + +#endif // DBUpdater_h__ diff --git a/src/server/shared/Updater/UpdateFetcher.cpp b/src/server/shared/Updater/UpdateFetcher.cpp new file mode 100644 index 00000000000..b93ca614729 --- /dev/null +++ b/src/server/shared/Updater/UpdateFetcher.cpp @@ -0,0 +1,401 @@ +/* + * Copyright (C) 2008-2015 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 "UpdateFetcher.h" +#include "Log.h" +#include "Util.h" + +#include <fstream> +#include <chrono> +#include <vector> +#include <sstream> +#include <exception> +#include <unordered_map> +#include <openssl/sha.h> + +using namespace boost::filesystem; + +UpdateFetcher::UpdateFetcher(Path const& sourceDirectory, + std::function<void(std::string const&)> const& apply, + std::function<void(Path const& path)> const& applyFile, + std::function<QueryResult(std::string const&)> const& retrieve) : + _sourceDirectory(sourceDirectory), _apply(apply), _applyFile(applyFile), + _retrieve(retrieve) +{ +} + +UpdateFetcher::LocaleFileStorage UpdateFetcher::GetFileList() const +{ + LocaleFileStorage files; + DirectoryStorage directories = ReceiveIncludedDirectories(); + for (auto const& entry : directories) + FillFileListRecursively(entry.path, files, entry.state, 1); + + return files; +} + +void UpdateFetcher::FillFileListRecursively(Path const& path, LocaleFileStorage& storage, State const state, uint32 const depth) const +{ + static uint32 const MAX_DEPTH = 10; + static directory_iterator const end; + + for (directory_iterator itr(path); itr != end; ++itr) + { + if (is_directory(itr->path())) + { + if (depth < MAX_DEPTH) + FillFileListRecursively(itr->path(), storage, state, depth + 1); + } + else if (itr->path().extension() == ".sql") + { + TC_LOG_TRACE("sql.updates", "Added locale file \"%s\".", itr->path().filename().generic_string().c_str()); + + LocaleFileEntry const entry = { itr->path(), state }; + + // Check for doubled filenames + // Since elements are only compared through their filenames this is ok + if (storage.find(entry) != storage.end()) + { + TC_LOG_FATAL("sql.updates", "Duplicated filename occurred \"%s\", since updates are ordered " \ + "through its filename every name needs to be unique!", itr->path().generic_string().c_str()); + + throw UpdateException("Updating failed, see the log for details."); + } + + storage.insert(entry); + } + } +} + +UpdateFetcher::DirectoryStorage UpdateFetcher::ReceiveIncludedDirectories() const +{ + DirectoryStorage directories; + + QueryResult const result = _retrieve("SELECT `path`, `state` FROM `updates_include`"); + if (!result) + return directories; + + do + { + Field* fields = result->Fetch(); + + std::string path = fields[0].GetString(); + if (path.substr(0, 1) == "$") + path = _sourceDirectory.generic_string() + path.substr(1); + + Path const p(path); + + if (!is_directory(p)) + { + TC_LOG_WARN("sql.updates", "DBUpdater: Given update include directory \"%s\" isn't existing, skipped!", p.generic_string().c_str()); + continue; + } + + DirectoryEntry const entry = { p, AppliedFileEntry::StateConvert(fields[1].GetString()) }; + directories.push_back(entry); + + TC_LOG_TRACE("sql.updates", "Added applied file \"%s\" from remote.", p.filename().generic_string().c_str()); + + } while (result->NextRow()); + + return directories; +} + +UpdateFetcher::AppliedFileStorage UpdateFetcher::ReceiveAppliedFiles() const +{ + AppliedFileStorage map; + + QueryResult result = _retrieve("SELECT `name`, `hash`, `state`, UNIX_TIMESTAMP(`timestamp`) FROM `updates` ORDER BY `name` ASC"); + if (!result) + return map; + + do + { + Field* fields = result->Fetch(); + + AppliedFileEntry const entry = { fields[0].GetString(), fields[1].GetString(), + AppliedFileEntry::StateConvert(fields[2].GetString()), fields[3].GetUInt64() }; + + map.insert(std::make_pair(entry.name, entry)); + } + while (result->NextRow()); + + return map; +} + +UpdateFetcher::SQLUpdate UpdateFetcher::ReadSQLUpdate(boost::filesystem::path const& file) const +{ + 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); + + SQLUpdate const update(new std::string(char_count, char{})); + + in.read(&(*update)[0], update->size()); + in.close(); + return update; +} + +uint32 UpdateFetcher::Update(bool const redundancyChecks, bool const allowRehash, bool const archivedRedundancy, int32 const cleanDeadReferencesMaxCount) const +{ + LocaleFileStorage const available = GetFileList(); + AppliedFileStorage applied = ReceiveAppliedFiles(); + + // Fill hash to name cache + HashToFileNameStorage hashToName; + for (auto entry : applied) + hashToName.insert(std::make_pair(entry.second.hash, entry.first)); + + uint32 importedUpdates = 0; + + for (auto const& availableQuery : available) + { + TC_LOG_DEBUG("sql.updates", "Checking update \"%s\"...", availableQuery.first.filename().generic_string().c_str()); + + AppliedFileStorage::const_iterator iter = applied.find(availableQuery.first.filename().string()); + if (iter != applied.end()) + { + // If redundancy is disabled skip it since the update is already applied. + if (!redundancyChecks) + { + TC_LOG_DEBUG("sql.updates", ">> Update is already applied, skipping redundancy checks."); + applied.erase(iter); + continue; + } + + // If the update is in an archived directory and is marked as archived in our database skip redundancy checks (archived updates never change). + if (!archivedRedundancy && (iter->second.state == ARCHIVED) && (availableQuery.second == ARCHIVED)) + { + TC_LOG_DEBUG("sql.updates", ">> Update is archived and marked as archived in database, skipping redundancy checks."); + applied.erase(iter); + continue; + } + } + + // Read update from file + SQLUpdate const update = ReadSQLUpdate(availableQuery.first); + + // Calculate hash + std::string const hash = CalculateHash(update); + + UpdateMode mode = MODE_APPLY; + + // Update is not in our applied list + if (iter == applied.end()) + { + // Catch renames (different filename but same hash) + HashToFileNameStorage::const_iterator const hashIter = hashToName.find(hash); + if (hashIter != hashToName.end()) + { + // Check if the original file was removed if not we've got a problem. + LocaleFileStorage::const_iterator localeIter; + // Push localeIter forward + for (localeIter = available.begin(); (localeIter != available.end()) && + (localeIter->first.filename().string() != hashIter->second); ++localeIter); + + // Conflict! + if (localeIter != available.end()) + { + TC_LOG_WARN("sql.updates", ">> Seems like update \"%s\" \'%s\' was renamed, but the old file is still there! " \ + "Trade it as a new file! (Probably its an unmodified copy of file \"%s\")", + availableQuery.first.filename().string().c_str(), hash.substr(0, 7).c_str(), + localeIter->first.filename().string().c_str()); + } + // Its save to trade the file as renamed here + else + { + TC_LOG_INFO("sql.updates", ">> Renaming update \"%s\" to \"%s\" \'%s\'.", + hashIter->second.c_str(), availableQuery.first.filename().string().c_str(), hash.substr(0, 7).c_str()); + + RenameEntry(hashIter->second, availableQuery.first.filename().string()); + applied.erase(hashIter->second); + continue; + } + } + // Apply the update if it was never seen before. + else + { + TC_LOG_INFO("sql.updates", ">> Applying update \"%s\" \'%s\'...", + availableQuery.first.filename().string().c_str(), hash.substr(0, 7).c_str()); + } + } + // Rehash the update entry if it is contained in our database but with an empty hash. + else if (allowRehash && iter->second.hash.empty()) + { + mode = MODE_REHASH; + + TC_LOG_INFO("sql.updates", ">> Re-hashing update \"%s\" \'%s\'...", availableQuery.first.filename().string().c_str(), + hash.substr(0, 7).c_str()); + } + else + { + // If the hash of the files differs from the one stored in our database reapply the update (because it was changed). + if (iter->second.hash != hash) + { + TC_LOG_INFO("sql.updates", ">> Reapplying update \"%s\" \'%s\' -> \'%s\' (it changed)...", availableQuery.first.filename().string().c_str(), + iter->second.hash.substr(0, 7).c_str(), hash.substr(0, 7).c_str()); + } + else + { + // If the file wasn't changed and just moved update its state if necessary. + if (iter->second.state != availableQuery.second) + { + TC_LOG_DEBUG("sql.updates", ">> Updating state of \"%s\" to \'%s\'...", + availableQuery.first.filename().string().c_str(), AppliedFileEntry::StateConvert(availableQuery.second).c_str()); + + UpdateState(availableQuery.first.filename().string(), availableQuery.second); + } + + TC_LOG_DEBUG("sql.updates", ">> Update is already applied and is matching hash \'%s\'.", hash.substr(0, 7).c_str()); + + applied.erase(iter); + continue; + } + } + + uint32 speed = 0; + AppliedFileEntry const file = { availableQuery.first.filename().string(), hash, availableQuery.second, 0 }; + + switch (mode) + { + case MODE_APPLY: + speed = Apply(availableQuery.first); + /*no break*/ + case MODE_REHASH: + UpdateEntry(file, speed); + break; + } + + if (iter != applied.end()) + applied.erase(iter); + + if (mode == MODE_APPLY) + ++importedUpdates; + } + + // Cleanup up orphaned entries if enabled + if (!applied.empty()) + { + bool const doCleanup = (cleanDeadReferencesMaxCount < 0) || (applied.size() <= static_cast<size_t>(cleanDeadReferencesMaxCount)); + + for (auto const& entry : applied) + { + TC_LOG_WARN("sql.updates", ">> File \'%s\' was applied to the database but is missing in" \ + " your update directory now!", entry.first.c_str()); + + if (doCleanup) + TC_LOG_INFO("sql.updates", "Deleting orphaned entry \'%s\'...", entry.first.c_str()); + } + + if (doCleanup) + CleanUp(applied); + else + { + TC_LOG_ERROR("sql.updates", "Cleanup is disabled! There are %zu dirty files that were applied to your database " \ + "but are now missing in your source directory!", applied.size()); + } + } + + return importedUpdates; +} + +std::string UpdateFetcher::CalculateHash(SQLUpdate const& query) const +{ + // Calculate a Sha1 hash based on query content. + unsigned char digest[SHA_DIGEST_LENGTH]; + SHA1((unsigned char*)query->c_str(), query->length(), (unsigned char*)&digest); + + return ByteArrayToHexStr(digest, SHA_DIGEST_LENGTH); +} + +uint32 UpdateFetcher::Apply(Path const& path) const +{ + using Time = std::chrono::high_resolution_clock; + using ms = std::chrono::milliseconds; + + // Benchmark query speed + auto const begin = Time::now(); + + // Update database + _applyFile(path); + + // Return time the query took to apply + return std::chrono::duration_cast<ms>(Time::now() - begin).count(); +} + +void UpdateFetcher::UpdateEntry(AppliedFileEntry const& entry, uint32 const speed) const +{ + std::string const update = "REPLACE INTO `updates` (`name`, `hash`, `state`, `speed`) VALUES (\"" + + entry.name + "\", \"" + entry.hash + "\", \'" + entry.GetStateAsString() + "\', " + std::to_string(speed) + ")"; + + // Update database + _apply(update); +} + +void UpdateFetcher::RenameEntry(std::string const& from, std::string const& to) const +{ + // Delete target if it exists + { + std::string const update = "DELETE FROM `updates` WHERE `name`=\"" + to + "\""; + + // Update database + _apply(update); + } + + // Rename + { + std::string const update = "UPDATE `updates` SET `name`=\"" + to + "\" WHERE `name`=\"" + from + "\""; + + // Update database + _apply(update); + } +} + +void UpdateFetcher::CleanUp(AppliedFileStorage const& storage) const +{ + if (storage.empty()) + return; + + std::stringstream update; + size_t remaining = storage.size(); + + update << "DELETE FROM `updates` WHERE `name` IN("; + + for (auto const& entry : storage) + { + update << "\"" << entry.first << "\""; + if ((--remaining) > 0) + update << ", "; + } + + update << ")"; + + // Update database + _apply(update.str()); +} + +void UpdateFetcher::UpdateState(std::string const& name, State const state) const +{ + std::string const update = "UPDATE `updates` SET `state`=\'" + AppliedFileEntry::StateConvert(state) + "\' WHERE `name`=\"" + name + "\""; + + // Update database + _apply(update); +} diff --git a/src/server/shared/Updater/UpdateFetcher.h b/src/server/shared/Updater/UpdateFetcher.h new file mode 100644 index 00000000000..fa142547873 --- /dev/null +++ b/src/server/shared/Updater/UpdateFetcher.h @@ -0,0 +1,132 @@ +/* + * Copyright (C) 2008-2015 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 UpdateFetcher_h__ +#define UpdateFetcher_h__ + +#include <DBUpdater.h> + +#include <functional> +#include <string> +#include <memory> +#include <vector> + +class UpdateFetcher +{ + typedef boost::filesystem::path Path; + +public: + UpdateFetcher(Path const& updateDirectory, + std::function<void(std::string const&)> const& apply, + std::function<void(Path const& path)> const& applyFile, + std::function<QueryResult(std::string const&)> const& retrieve); + + uint32 Update(bool const redundancyChecks, bool const allowRehash, + bool const archivedRedundancy, int32 const cleanDeadReferencesMaxCount) const; + +private: + enum UpdateMode + { + MODE_APPLY, + MODE_REHASH + }; + + enum State + { + RELEASED, + ARCHIVED + }; + + struct AppliedFileEntry + { + AppliedFileEntry(std::string const& name_, std::string const& hash_, State state_, uint64 timestamp_) + : name(name_), hash(hash_), state(state_), timestamp(timestamp_) { } + + std::string const name; + + std::string const hash; + + State const state; + + uint64 const timestamp; + + static inline State StateConvert(std::string const& state) + { + return (state == "RELEASED") ? RELEASED : ARCHIVED; + } + + static inline std::string StateConvert(State const state) + { + return (state == RELEASED) ? "RELEASED" : "ARCHIVED"; + } + + std::string GetStateAsString() const + { + return StateConvert(state); + } + }; + + struct DirectoryEntry + { + DirectoryEntry(Path const& path_, State state_) : path(path_), state(state_) { } + + Path const path; + + State const state; + }; + + typedef std::pair<Path, State> LocaleFileEntry; + + struct PathCompare + { + inline bool operator() (LocaleFileEntry const& left, LocaleFileEntry const& right) const + { + return left.first.filename().string() < right.first.filename().string(); + } + }; + + typedef std::set<LocaleFileEntry, PathCompare> LocaleFileStorage; + 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; + + LocaleFileStorage GetFileList() const; + void FillFileListRecursively(Path const& path, LocaleFileStorage& storage, State const state, uint32 const depth) const; + + DirectoryStorage ReceiveIncludedDirectories() const; + AppliedFileStorage ReceiveAppliedFiles() const; + + SQLUpdate ReadSQLUpdate(Path const& file) const; + std::string CalculateHash(SQLUpdate const& query) const; + + uint32 Apply(Path const& path) const; + + void UpdateEntry(AppliedFileEntry const& entry, uint32 const speed = 0) const; + void RenameEntry(std::string const& from, std::string const& to) const; + void CleanUp(AppliedFileStorage const& storage) const; + + void UpdateState(std::string const& name, State const state) const; + + Path const _sourceDirectory; + + std::function<void(std::string const&)> const _apply; + std::function<void(Path const& path)> const _applyFile; + std::function<QueryResult(std::string const&)> const _retrieve; +}; + +#endif // UpdateFetcher_h__ diff --git a/src/server/shared/Utilities/ServiceWin32.cpp b/src/server/shared/Utilities/ServiceWin32.cpp index c73949fc6a3..3e5e416b1a3 100644 --- a/src/server/shared/Utilities/ServiceWin32.cpp +++ b/src/server/shared/Utilities/ServiceWin32.cpp @@ -255,7 +255,7 @@ bool WinServiceRun() if (!StartServiceCtrlDispatcher(serviceTable)) { - TC_LOG_ERROR("server.worldserver", "StartService Failed. Error [%u]", ::GetLastError()); + TC_LOG_ERROR("server.worldserver", "StartService Failed. Error [%u]", uint32(::GetLastError())); return false; } return true; diff --git a/src/server/shared/Utilities/StringFormat.h b/src/server/shared/Utilities/StringFormat.h new file mode 100644 index 00000000000..70d9aefb14d --- /dev/null +++ b/src/server/shared/Utilities/StringFormat.h @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/> + * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/> + * + * 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 TRINITYCORE_STRING_FORMAT_H +#define TRINITYCORE_STRING_FORMAT_H + +#include <format.h> + +namespace Trinity +{ + //! Default TC string format function + template<typename... Args> + inline std::string StringFormat(const char* fmt, Args const&... args) + { + return fmt::sprintf(fmt, args...); + } +} + +#endif diff --git a/src/server/worldserver/CMakeLists.txt b/src/server/worldserver/CMakeLists.txt index d94b5f250aa..63da20df2c7 100644 --- a/src/server/worldserver/CMakeLists.txt +++ b/src/server/worldserver/CMakeLists.txt @@ -47,7 +47,9 @@ include_directories( ${CMAKE_SOURCE_DIR}/dep/gsoap ${CMAKE_SOURCE_DIR}/dep/sockets/include ${CMAKE_SOURCE_DIR}/dep/SFMT + ${CMAKE_SOURCE_DIR}/dep/cppformat ${CMAKE_SOURCE_DIR}/dep/zmqpp + ${CMAKE_SOURCE_DIR}/dep/process ${CMAKE_SOURCE_DIR}/src/server/collision ${CMAKE_SOURCE_DIR}/src/server/collision/Management ${CMAKE_SOURCE_DIR}/src/server/collision/Models @@ -64,6 +66,7 @@ include_directories( ${CMAKE_SOURCE_DIR}/src/server/shared/Networking ${CMAKE_SOURCE_DIR}/src/server/shared/Packets ${CMAKE_SOURCE_DIR}/src/server/shared/Threading + ${CMAKE_SOURCE_DIR}/src/server/shared/Updater ${CMAKE_SOURCE_DIR}/src/server/shared/Utilities ${CMAKE_SOURCE_DIR}/src/server/ipc ${CMAKE_SOURCE_DIR}/src/server/game @@ -175,6 +178,7 @@ target_link_libraries(worldserver gsoap Detour zmqpp + format ${JEMALLOC_LIBRARY} ${READLINE_LIBRARY} ${TERMCAP_LIBRARY} diff --git a/src/server/worldserver/Main.cpp b/src/server/worldserver/Main.cpp index 15d08a903b9..a1e8ba74514 100644 --- a/src/server/worldserver/Main.cpp +++ b/src/server/worldserver/Main.cpp @@ -44,6 +44,7 @@ #include "WorldSocketMgr.h" #include "BattlenetServerManager.h" #include "Realm/Realm.h" +#include "DatabaseLoader.h" #include <openssl/opensslv.h> #include <openssl/crypto.h> #include <boost/asio/io_service.hpp> @@ -324,7 +325,7 @@ void ShutdownCLIThread(std::thread* cliThread) errorBuffer = "Unknown error"; TC_LOG_DEBUG("server.worldserver", "Error cancelling I/O of CliThread, error code %u, detail: %s", - errorCode, errorBuffer); + uint32(errorCode), errorBuffer); LocalFree(errorBuffer); // send keyboard input to safely unblock the CLI thread @@ -520,105 +521,16 @@ bool StartDB() { MySQL::Library_Init(); - std::string dbString; - uint8 asyncThreads, synchThreads; + // Load databases + DatabaseLoader loader("server.worldserver", DatabaseLoader::DATABASE_NONE); + loader + .AddDatabase(HotfixDatabase, "Hotfix") + .AddDatabase(WorldDatabase, "World") + .AddDatabase(CharacterDatabase, "Character") + .AddDatabase(LoginDatabase, "Login"); - dbString = sConfigMgr->GetStringDefault("WorldDatabaseInfo", ""); - if (dbString.empty()) - { - TC_LOG_ERROR("server.worldserver", "World database not specified in configuration file"); - return false; - } - - asyncThreads = uint8(sConfigMgr->GetIntDefault("WorldDatabase.WorkerThreads", 1)); - if (asyncThreads < 1 || asyncThreads > 32) - { - TC_LOG_ERROR("server.worldserver", "World database: invalid number of worker threads specified. " - "Please pick a value between 1 and 32."); - return false; - } - - synchThreads = uint8(sConfigMgr->GetIntDefault("WorldDatabase.SynchThreads", 1)); - ///- Initialize the world database - if (!WorldDatabase.Open(dbString, asyncThreads, synchThreads)) - { - TC_LOG_ERROR("server.worldserver", "Cannot connect to world database %s", dbString.c_str()); - return false; - } - - ///- Get character database info from configuration file - dbString = sConfigMgr->GetStringDefault("CharacterDatabaseInfo", ""); - if (dbString.empty()) - { - TC_LOG_ERROR("server.worldserver", "Character database not specified in configuration file"); - return false; - } - - asyncThreads = uint8(sConfigMgr->GetIntDefault("CharacterDatabase.WorkerThreads", 1)); - if (asyncThreads < 1 || asyncThreads > 32) - { - TC_LOG_ERROR("server.worldserver", "Character database: invalid number of worker threads specified. " - "Please pick a value between 1 and 32."); - return false; - } - - synchThreads = uint8(sConfigMgr->GetIntDefault("CharacterDatabase.SynchThreads", 2)); - - ///- Initialize the Character database - if (!CharacterDatabase.Open(dbString, asyncThreads, synchThreads)) - { - TC_LOG_ERROR("server.worldserver", "Cannot connect to Character database %s", dbString.c_str()); - return false; - } - - ///- Get hotfixes database info from configuration file - dbString = sConfigMgr->GetStringDefault("HotfixDatabaseInfo", ""); - if (dbString.empty()) - { - TC_LOG_ERROR("server.worldserver", "Hotfixes database not specified in configuration file"); - return false; - } - - asyncThreads = uint8(sConfigMgr->GetIntDefault("HotfixDatabase.WorkerThreads", 1)); - if (asyncThreads < 1 || asyncThreads > 32) - { - TC_LOG_ERROR("server.worldserver", "Hotfixes database: invalid number of worker threads specified. " - "Please pick a value between 1 and 32."); - return false; - } - - synchThreads = uint8(sConfigMgr->GetIntDefault("HotfixDatabase.SynchThreads", 2)); - - ///- Initialize the hotfixes database - if (!HotfixDatabase.Open(dbString, asyncThreads, synchThreads)) - { - TC_LOG_ERROR("server.worldserver", "Cannot connect to the hotfix database %s", dbString.c_str()); - return false; - } - - ///- Get login database info from configuration file - dbString = sConfigMgr->GetStringDefault("LoginDatabaseInfo", ""); - if (dbString.empty()) - { - TC_LOG_ERROR("server.worldserver", "Login database not specified in configuration file"); - return false; - } - - asyncThreads = uint8(sConfigMgr->GetIntDefault("LoginDatabase.WorkerThreads", 1)); - if (asyncThreads < 1 || asyncThreads > 32) - { - TC_LOG_ERROR("server.worldserver", "Login database: invalid number of worker threads specified. " - "Please pick a value between 1 and 32."); - return false; - } - - synchThreads = uint8(sConfigMgr->GetIntDefault("LoginDatabase.SynchThreads", 1)); - ///- Initialise the login database - if (!LoginDatabase.Open(dbString, asyncThreads, synchThreads)) - { - TC_LOG_ERROR("server.worldserver", "Cannot connect to login database %s", dbString.c_str()); + if (!loader.Load()) return false; - } ///- Get the realm Id from the configuration file realmHandle.Index = sConfigMgr->GetIntDefault("RealmID", 0); @@ -628,6 +540,7 @@ bool StartDB() return false; } + // Realm Handles QueryResult realmIdQuery = LoginDatabase.PQuery("SELECT `Region`,`Battlegroup` FROM `realmlist` WHERE `id`=%u", realmHandle.Index); if (!realmIdQuery) { diff --git a/src/server/worldserver/RemoteAccess/RASession.h b/src/server/worldserver/RemoteAccess/RASession.h index d272f323c6a..efd2106fdd1 100644 --- a/src/server/worldserver/RemoteAccess/RASession.h +++ b/src/server/worldserver/RemoteAccess/RASession.h @@ -30,8 +30,6 @@ using boost::asio::ip::tcp; const size_t bufferSize = 4096; -#define BUFFER_SIZE 4096 - class RASession : public std::enable_shared_from_this <RASession> { public: diff --git a/src/server/worldserver/worldserver.conf.dist b/src/server/worldserver/worldserver.conf.dist index f0f9adc32ed..ba4bcd765e7 100644 --- a/src/server/worldserver/worldserver.conf.dist +++ b/src/server/worldserver/worldserver.conf.dist @@ -11,6 +11,7 @@ # PERFORMANCE SETTINGS # SERVER LOGGING # SERVER SETTINGS +# UPDATE SETTINGS # WARDEN SETTINGS # PLAYER INTERACTION # CREATURE SETTINGS @@ -1130,6 +1131,93 @@ FeatureSystem.CharacterUndelete.Cooldown = 2592000 ################################################################################################### ################################################################################################### +# UPDATE SETTINGS +# +# Updates.EnableDatabases +# Description: A mask that describes which databases shall be updated. +# +# Following flags are available +# DATABASE_LOGIN = 1, // Auth database +# DATABASE_CHARACTER = 2, // Character database +# DATABASE_WORLD = 4, // World database +# DATABASE_HOTFIX = 8, // Hotfixes database +# +# Default: 0 - (All Disabled) +# 4 - (Enable world only) +# 15 - (All enabled) + +Updates.EnableDatabases = 0 + +# +# Updates.SourcePath +# Description: The path to your TrinityCore source directory. +# If the path is left empty, built-in CMAKE_SOURCE_DIR is used. +# Example: "../TrinityCore" +# Default: "" + +Updates.SourcePath = "" + +# +# Updates.SourcePath +# Description: The path to your mysql cli binary. +# If the path is left empty, built-in path from cmake is used. +# Example: "C:/Program Files/MySQL/MySQL Server 5.6/bin/mysql.exe" +# "mysql.exe" +# "/usr/bin/mysql" +# Default: "" + +Updates.MySqlCLIPath = "" + +# +# Updates.AutoSetup +# Description: Auto populate empty databases. +# Default: 1 - (Enabled) +# 0 - (Disabled) + +Updates.AutoSetup = 1 + +# +# Updates.Redundancy +# Description: Perform data redundancy checks through hashing +# to detect changes on sql updates and reapply it. +# Default: 1 - (Enabled) +# 0 - (Disabled) + +Updates.Redundancy = 1 + +# +# Updates.ArchivedRedundancy +# Description: Check hashes of archived updates (slows down startup). +# Default: 0 - (Disabled) +# 1 - (Enabled) + +Updates.ArchivedRedundancy = 0 + +# +# Updates.AllowRehash +# Description: Inserts the current file hash in the database if it is left empty. +# Useful if you want to mark a file as applied but you don't know its hash. +# Default: 1 - (Enabled) +# 0 - (Disabled) + +Updates.AllowRehash = 1 + +# +# Updates.CleanDeadRefMaxCount +# Description: Cleans dead/ orphaned references that occur if an update was removed or renamed and edited in one step. +# It only starts the clean up if the count of the missing updates is below or equal the Updates.CleanDeadRefMaxCount value. +# This way prevents erasing of the update history due to wrong source directory state (maybe wrong branch or bad revision). +# Disable this if you want to know if the database is in a possible "dirty state". +# Default: 3 - (Enabled) +# 0 - (Disabled) +# -1 - (Enabled - unlimited) + +Updates.CleanDeadRefMaxCount = 3 + +# +################################################################################################### + +################################################################################################### # WARDEN SETTINGS # # Warden.Enabled @@ -3224,6 +3312,7 @@ Logger.root=5,Console Server Logger.server=3,Console Server Logger.commands.gm=3,Console GM Logger.sql.sql=5,Console DBErrors +Logger.sql.updates=3,Console Server #Logger.achievement=3,Console Server #Logger.ahbot=3,Console Server |