aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShauren <shauren.trinity@gmail.com>2014-10-18 17:03:30 +0200
committerShauren <shauren.trinity@gmail.com>2014-10-18 17:03:30 +0200
commit8936723291985d1759a4903901c7a29cc54fdcbf (patch)
tree2ca2331742863ef6318697075aad5ff3f8e76715
parent3ee9961ecce2a745134eeefa45b29109a276e49f (diff)
parent4a0be2bffc21e30624122ec5f36d6c8479f83385 (diff)
Merge branch '4.3.4' of https://github.com/TrinityCore/TrinityCore into 6.x
Conflicts: dep/PackageList.txt src/server/bnetserver/Packets/WoWRealmPackets.cpp src/server/bnetserver/Server/Session.cpp
-rw-r--r--.travis.yml2
-rw-r--r--CMakeLists.txt1
-rw-r--r--README.md4
-rw-r--r--cmake/macros/FindZMQ.cmake76
-rw-r--r--dep/CMakeLists.txt1
-rw-r--r--dep/PackageList.txt5
-rw-r--r--dep/zmqpp/CMakeLists.txt31
-rw-r--r--dep/zmqpp/zmqpp/compatibility.hpp97
-rw-r--r--dep/zmqpp/zmqpp/context.cpp54
-rw-r--r--dep/zmqpp/zmqpp/context.hpp184
-rw-r--r--dep/zmqpp/zmqpp/context_options.hpp26
-rw-r--r--dep/zmqpp/zmqpp/exception.hpp87
-rw-r--r--dep/zmqpp/zmqpp/frame.cpp95
-rw-r--r--dep/zmqpp/zmqpp/frame.hpp58
-rw-r--r--dep/zmqpp/zmqpp/inet.hpp171
-rw-r--r--dep/zmqpp/zmqpp/message.cpp454
-rw-r--r--dep/zmqpp/zmqpp/message.hpp254
-rw-r--r--dep/zmqpp/zmqpp/poller.cpp182
-rw-r--r--dep/zmqpp/zmqpp/poller.hpp186
-rw-r--r--dep/zmqpp/zmqpp/socket.cpp762
-rw-r--r--dep/zmqpp/zmqpp/socket.hpp500
-rw-r--r--dep/zmqpp/zmqpp/socket_options.hpp80
-rw-r--r--dep/zmqpp/zmqpp/socket_types.hpp148
-rw-r--r--dep/zmqpp/zmqpp/zmqpp.cpp30
-rw-r--r--dep/zmqpp/zmqpp/zmqpp.hpp111
-rw-r--r--sql/base/auth_database.sql23
-rw-r--r--sql/updates/auth/2014_10_13_00_auth_434.sql24
-rw-r--r--sql/updates/world/2014_10_04_01_world.sql6
-rw-r--r--sql/updates/world/2014_10_05_00_world.sql86
-rw-r--r--sql/updates/world/2014_10_05_01_world.sql34
-rw-r--r--sql/updates/world/2014_10_05_02_world.sql8
-rw-r--r--sql/updates/world/2014_10_05_03_world.sql5
-rw-r--r--sql/updates/world/2014_10_05_04_world.sql71
-rw-r--r--sql/updates/world/2014_10_05_05_world.sql38
-rw-r--r--sql/updates/world/2014_10_05_06_world.sql6
-rw-r--r--sql/updates/world/2014_10_05_07_world.sql30
-rw-r--r--sql/updates/world/2014_10_06_00_world.sql14
-rw-r--r--sql/updates/world/2014_10_06_01_world.sql38
-rw-r--r--sql/updates/world/2014_10_06_02_world.sql3
-rw-r--r--sql/updates/world/2014_10_06_03_world.sql2
-rw-r--r--sql/updates/world/2014_10_06_04_world.sql66
-rw-r--r--sql/updates/world/2014_10_06_05_world.sql2
-rw-r--r--sql/updates/world/2014_10_06_06_world.sql30
-rw-r--r--sql/updates/world/2014_10_07_00_world.sql21
-rw-r--r--sql/updates/world/2014_10_07_01_world.sql61
-rw-r--r--sql/updates/world/2014_10_08_00_world.sql44
-rw-r--r--sql/updates/world/2014_10_08_01_world.sql10
-rw-r--r--sql/updates/world/2014_10_08_02_world.sql8
-rw-r--r--sql/updates/world/2014_10_09_00_world.sql5
-rw-r--r--sql/updates/world/2014_10_09_01_world.sql7
-rw-r--r--sql/updates/world/2014_10_09_02_world.sql215
-rw-r--r--sql/updates/world/2014_10_10_00_world.sql5
-rw-r--r--sql/updates/world/2014_10_10_01_world_335.sql4
-rw-r--r--sql/updates/world/2014_10_10_02_world.sql2
-rw-r--r--sql/updates/world/2014_10_10_03_world.sql4
-rw-r--r--sql/updates/world/2014_10_10_04_world_335.sql5
-rw-r--r--sql/updates/world/2014_10_10_05_world.sql5
-rw-r--r--sql/updates/world/2014_10_10_06_world.sql12
-rw-r--r--sql/updates/world/2014_10_11_00_world.sql23
-rw-r--r--sql/updates/world/2014_10_11_01_world.sql2
-rw-r--r--sql/updates/world/2014_10_11_02_world.sql117
-rw-r--r--sql/updates/world/2014_10_11_03_world.sql19
-rw-r--r--sql/updates/world/2014_10_11_04_world.sql51
-rw-r--r--sql/updates/world/2014_10_11_05_world.sql7
-rw-r--r--sql/updates/world/2014_10_11_06_world.sql3
-rw-r--r--sql/updates/world/2014_10_11_07_world.sql91
-rw-r--r--sql/updates/world/2014_10_12_00_world.sql294
-rw-r--r--sql/updates/world/2014_10_12_01_world.sql12
-rw-r--r--sql/updates/world/2014_10_12_02_world.sql2
-rw-r--r--sql/updates/world/2014_10_12_03_world.sql2
-rw-r--r--sql/updates/world/2014_10_12_04_world.sql3
-rw-r--r--sql/updates/world/2014_10_12_05_world.sql2
-rw-r--r--sql/updates/world/2014_10_12_06_world.sql8
-rw-r--r--sql/updates/world/2014_10_12_07_world.sql2
-rw-r--r--sql/updates/world/2014_10_13_00_world.sql2
-rw-r--r--sql/updates/world/2014_10_13_01_world.sql423
-rw-r--r--sql/updates/world/2014_10_15_00_world.sql1
-rw-r--r--sql/updates/world/2014_10_16_00_world.sql21
-rw-r--r--sql/updates/world/2014_10_17_00_world.sql117
-rw-r--r--src/server/CMakeLists.txt2
-rw-r--r--src/server/authserver/Authentication/AuthCodes.h57
-rw-r--r--src/server/authserver/CMakeLists.txt1
-rw-r--r--src/server/authserver/Main.cpp13
-rw-r--r--src/server/authserver/PrecompiledHeaders/authPCH.h3
-rw-r--r--src/server/authserver/Realms/RealmList.cpp24
-rw-r--r--src/server/authserver/Realms/RealmList.h10
-rw-r--r--src/server/authserver/Server/BattlenetPackets/ConnectionPackets.h55
-rw-r--r--src/server/authserver/authserver.conf.dist7
-rw-r--r--src/server/bnetserver/Authentication/AuthCodes.cpp55
-rw-r--r--src/server/bnetserver/Authentication/AuthCodes.h128
-rw-r--r--src/server/bnetserver/Authentication/BattlenetPacketCrypt.cpp (renamed from src/server/authserver/Server/BattlenetPacketCrypt.cpp)0
-rw-r--r--src/server/bnetserver/Authentication/BattlenetPacketCrypt.h (renamed from src/server/authserver/Server/BattlenetPacketCrypt.h)6
-rw-r--r--src/server/bnetserver/CMakeLists.txt121
-rw-r--r--src/server/bnetserver/Main.cpp244
-rw-r--r--src/server/bnetserver/Packets/AchievementPackets.h42
-rw-r--r--src/server/bnetserver/Packets/AuthenticationPackets.cpp (renamed from src/server/authserver/Server/BattlenetPackets/AuthenticationPackets.cpp)94
-rw-r--r--src/server/bnetserver/Packets/AuthenticationPackets.h (renamed from src/server/authserver/Server/BattlenetPackets/AuthenticationPackets.h)55
-rw-r--r--src/server/bnetserver/Packets/BitStream.cpp (renamed from src/server/authserver/Server/BattlenetBitStream.cpp)2
-rw-r--r--src/server/bnetserver/Packets/BitStream.h (renamed from src/server/authserver/Server/BattlenetBitStream.h)18
-rw-r--r--src/server/bnetserver/Packets/CachePackets.cpp82
-rw-r--r--src/server/bnetserver/Packets/CachePackets.h79
-rw-r--r--src/server/bnetserver/Packets/ChatPackets.h63
-rw-r--r--src/server/bnetserver/Packets/ConnectionPackets.cpp109
-rw-r--r--src/server/bnetserver/Packets/ConnectionPackets.h153
-rw-r--r--src/server/bnetserver/Packets/FriendsPackets.cpp138
-rw-r--r--src/server/bnetserver/Packets/FriendsPackets.h138
-rw-r--r--src/server/bnetserver/Packets/PacketManager.cpp243
-rw-r--r--src/server/bnetserver/Packets/PacketManager.h105
-rw-r--r--src/server/bnetserver/Packets/Packets.h (renamed from src/server/authserver/Server/BattlenetPackets/BattlenetPackets.h)13
-rw-r--r--src/server/bnetserver/Packets/PacketsBase.cpp (renamed from src/server/authserver/Server/BattlenetPackets/BattlenetPacketsBase.cpp)8
-rw-r--r--src/server/bnetserver/Packets/PacketsBase.h (renamed from src/server/authserver/Server/BattlenetPackets/BattlenetPacketsBase.h)15
-rw-r--r--src/server/bnetserver/Packets/PresencePackets.cpp38
-rw-r--r--src/server/bnetserver/Packets/PresencePackets.h63
-rw-r--r--src/server/bnetserver/Packets/ProfilePackets.h44
-rw-r--r--src/server/bnetserver/Packets/SupportPackets.h (renamed from src/server/authserver/Server/BattlenetPackets/ConnectionPackets.cpp)17
-rw-r--r--src/server/bnetserver/Packets/WoWRealmPackets.cpp (renamed from src/server/authserver/Server/BattlenetPackets/WoWRealmPackets.cpp)90
-rw-r--r--src/server/bnetserver/Packets/WoWRealmPackets.h (renamed from src/server/authserver/Server/BattlenetPackets/WoWRealmPackets.h)69
-rw-r--r--src/server/bnetserver/PrecompiledHeaders/bnetPCH.cpp1
-rw-r--r--src/server/bnetserver/PrecompiledHeaders/bnetPCH.h10
-rw-r--r--src/server/bnetserver/Realms/RealmList.cpp252
-rw-r--r--src/server/bnetserver/Realms/RealmList.h127
-rw-r--r--src/server/bnetserver/Realms/WorldListener.cpp109
-rw-r--r--src/server/bnetserver/Realms/WorldListener.h63
-rw-r--r--src/server/bnetserver/Server/ComponentManager.cpp55
-rw-r--r--src/server/bnetserver/Server/ComponentManager.h61
-rw-r--r--src/server/bnetserver/Server/ModuleManager.cpp (renamed from src/server/authserver/Server/BattlenetManager.cpp)56
-rw-r--r--src/server/bnetserver/Server/ModuleManager.h (renamed from src/server/authserver/Server/BattlenetManager.h)64
-rw-r--r--src/server/bnetserver/Server/Session.cpp (renamed from src/server/authserver/Server/BattlenetSession.cpp)606
-rw-r--r--src/server/bnetserver/Server/Session.h (renamed from src/server/authserver/Server/BattlenetSession.h)46
-rw-r--r--src/server/bnetserver/Server/SessionManager.cpp70
-rw-r--r--src/server/bnetserver/Server/SessionManager.h (renamed from src/server/authserver/Server/BattlenetSessionManager.h)35
-rw-r--r--src/server/bnetserver/bnetserver.conf.dist260
-rw-r--r--src/server/bnetserver/bnetserver.icobin0 -> 136606 bytes
-rw-r--r--src/server/bnetserver/bnetserver.rc94
-rw-r--r--src/server/bnetserver/resource.h15
-rw-r--r--src/server/collision/CMakeLists.txt1
-rw-r--r--src/server/collision/Management/MMapFactory.cpp8
-rw-r--r--src/server/collision/Management/VMapManager2.cpp17
-rw-r--r--src/server/collision/Management/VMapManager2.h17
-rw-r--r--src/server/game/AI/SmartScripts/SmartScript.cpp57
-rw-r--r--src/server/game/AI/SmartScripts/SmartScript.h15
-rw-r--r--src/server/game/AI/SmartScripts/SmartScriptMgr.cpp132
-rw-r--r--src/server/game/AI/SmartScripts/SmartScriptMgr.h38
-rw-r--r--src/server/game/Accounts/AccountMgr.cpp2
-rw-r--r--src/server/game/AuctionHouse/AuctionHouseMgr.cpp14
-rw-r--r--src/server/game/Battlefield/Battlefield.cpp2
-rw-r--r--src/server/game/Battlefield/Zones/BattlefieldWG.cpp28
-rw-r--r--src/server/game/Battlegrounds/Arena.cpp2
-rw-r--r--src/server/game/Battlegrounds/ArenaTeam.cpp16
-rw-r--r--src/server/game/Battlegrounds/Battleground.cpp45
-rw-r--r--src/server/game/Battlegrounds/BattlegroundQueue.cpp18
-rw-r--r--src/server/game/CMakeLists.txt3
-rw-r--r--src/server/game/Calendar/CalendarMgr.cpp18
-rw-r--r--src/server/game/Chat/Channels/Channel.cpp20
-rw-r--r--src/server/game/Chat/Chat.cpp12
-rw-r--r--src/server/game/Conditions/DisableMgr.cpp29
-rw-r--r--src/server/game/Conditions/DisableMgr.h11
-rw-r--r--src/server/game/DungeonFinding/LFGMgr.cpp136
-rw-r--r--src/server/game/DungeonFinding/LFGMgr.h2
-rw-r--r--src/server/game/DungeonFinding/LFGScripts.cpp6
-rw-r--r--src/server/game/Entities/Creature/Creature.cpp15
-rw-r--r--src/server/game/Entities/Creature/Creature.h2
-rw-r--r--src/server/game/Entities/GameObject/GameObject.cpp2
-rw-r--r--src/server/game/Entities/Player/Player.cpp11
-rw-r--r--src/server/game/Entities/Player/SocialMgr.cpp2
-rw-r--r--src/server/game/Entities/Transport/Transport.cpp14
-rw-r--r--src/server/game/Globals/ObjectAccessor.cpp23
-rw-r--r--src/server/game/Globals/ObjectAccessor.h4
-rw-r--r--src/server/game/Globals/ObjectMgr.cpp38
-rw-r--r--src/server/game/Grids/Notifiers/GridNotifiers.cpp2
-rw-r--r--src/server/game/Groups/Group.cpp40
-rw-r--r--src/server/game/Guilds/Guild.cpp10
-rw-r--r--src/server/game/Guilds/Guild.h3
-rw-r--r--src/server/game/Handlers/ArenaTeamHandler.cpp2
-rw-r--r--src/server/game/Handlers/CalendarHandler.cpp2
-rw-r--r--src/server/game/Handlers/CharacterHandler.cpp9
-rw-r--r--src/server/game/Handlers/ChatHandler.cpp4
-rw-r--r--src/server/game/Handlers/GroupHandler.cpp12
-rw-r--r--src/server/game/Handlers/LFGHandler.cpp16
-rw-r--r--src/server/game/Handlers/MailHandler.cpp4
-rw-r--r--src/server/game/Handlers/MiscHandler.cpp11
-rw-r--r--src/server/game/Handlers/PetitionsHandler.cpp8
-rw-r--r--src/server/game/Handlers/QueryHandler.cpp2
-rw-r--r--src/server/game/Instances/InstanceSaveMgr.cpp4
-rw-r--r--src/server/game/Instances/InstanceSaveMgr.h11
-rw-r--r--src/server/game/Loot/LootMgr.cpp25
-rw-r--r--src/server/game/Loot/LootMgr.h3
-rw-r--r--src/server/game/Mails/Mail.cpp2
-rw-r--r--src/server/game/Maps/Map.cpp9
-rw-r--r--src/server/game/Maps/Map.h2
-rw-r--r--src/server/game/Movement/MovementGenerators/RandomMovementGenerator.cpp7
-rw-r--r--src/server/game/Movement/PathGenerator.cpp4
-rw-r--r--src/server/game/Server/BattlenetServerManager.cpp66
-rw-r--r--src/server/game/Server/BattlenetServerManager.h55
-rw-r--r--src/server/game/Server/WorldSession.cpp18
-rw-r--r--src/server/game/Server/WorldSession.h1
-rw-r--r--src/server/game/Server/WorldSocket.cpp20
-rw-r--r--src/server/game/Spells/Spell.cpp5
-rw-r--r--src/server/game/Spells/SpellMgr.cpp10
-rw-r--r--src/server/game/World/World.cpp26
-rw-r--r--src/server/game/World/World.h5
-rw-r--r--src/server/ipc/CMakeLists.txt24
-rw-r--r--src/server/ipc/Commands.cpp81
-rw-r--r--src/server/ipc/Commands.h83
-rw-r--r--src/server/ipc/ZMQTask.cpp93
-rw-r--r--src/server/ipc/ZMQTask.h52
-rw-r--r--src/server/ipc/ZmqContext.cpp52
-rw-r--r--src/server/ipc/ZmqContext.h55
-rw-r--r--src/server/ipc/ZmqListener.cpp69
-rw-r--r--src/server/ipc/ZmqListener.h (renamed from src/server/authserver/Server/BattlenetSessionManager.cpp)44
-rw-r--r--src/server/ipc/ZmqMux.cpp67
-rw-r--r--src/server/ipc/ZmqMux.h47
-rw-r--r--src/server/ipc/ZmqWorker.cpp70
-rw-r--r--src/server/ipc/ZmqWorker.h44
-rw-r--r--src/server/scripts/CMakeLists.txt1
-rw-r--r--src/server/scripts/Commands/cs_ban.cpp2
-rw-r--r--src/server/scripts/Commands/cs_character.cpp2
-rw-r--r--src/server/scripts/Commands/cs_debug.cpp22
-rw-r--r--src/server/scripts/Commands/cs_gm.cpp4
-rw-r--r--src/server/scripts/Commands/cs_group.cpp2
-rw-r--r--src/server/scripts/Commands/cs_message.cpp2
-rw-r--r--src/server/scripts/Commands/cs_misc.cpp13
-rw-r--r--src/server/scripts/Commands/cs_mmaps.cpp3
-rw-r--r--src/server/scripts/Commands/cs_rbac.cpp2
-rw-r--r--src/server/scripts/Commands/cs_reset.cpp2
-rw-r--r--src/server/scripts/Commands/cs_ticket.cpp36
-rw-r--r--src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/instance_culling_of_stratholme.cpp2
-rw-r--r--src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_anubarak_trial.cpp1
-rw-r--r--src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/instance_trial_of_the_crusader.cpp25
-rw-r--r--src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/trial_of_the_crusader.cpp19
-rw-r--r--src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/trial_of_the_crusader.h16
-rw-r--r--src/server/scripts/Northrend/IcecrownCitadel/boss_rotface.cpp2
-rw-r--r--src/server/scripts/Northrend/Ulduar/HallsOfStone/instance_halls_of_stone.cpp4
-rw-r--r--src/server/scripts/Outland/Auchindoun/SethekkHalls/boss_darkweaver_syth.cpp2
-rw-r--r--src/server/scripts/Outland/BlackTemple/boss_reliquary_of_souls.cpp2
-rw-r--r--src/server/scripts/World/go_scripts.cpp20
-rw-r--r--src/server/shared/Database/Implementation/WorldDatabase.cpp2
-rw-r--r--src/server/shared/Database/Implementation/WorldDatabase.h2
-rw-r--r--src/server/shared/Logging/Log.cpp2
-rw-r--r--src/server/shared/Logging/Log.h2
-rw-r--r--src/server/worldserver/CMakeLists.txt6
-rw-r--r--src/server/worldserver/Main.cpp49
-rw-r--r--src/server/worldserver/worldserver.conf.dist47
-rw-r--r--src/tools/mmaps_generator/MapBuilder.cpp8
-rw-r--r--src/tools/mmaps_generator/PathCommon.h2
245 files changed, 10961 insertions, 1305 deletions
diff --git a/.travis.yml b/.travis.yml
index e8ff00f425f..52c15ea5b1b 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -11,7 +11,7 @@ before_install:
- echo "yes" | sudo add-apt-repository ppa:ubuntu-toolchain-r/test
- sudo apt-get -qq update
- sudo apt-get -qq install build-essential libtool gcc-4.8 g++-4.8 make cmake openssl
- - sudo apt-get -qq install libssl-dev libmysqlclient15-dev libmysql++-dev libreadline6-dev zlib1g-dev libbz2-dev
+ - sudo apt-get -qq install libssl-dev libmysqlclient15-dev libmysql++-dev libreadline6-dev zlib1g-dev libbz2-dev libzmq3-dev
- sudo apt-get -qq install libboost1.55-dev libboost-thread1.55-dev libboost-system1.55-dev libboost-program-options1.55-dev
install:
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 5e91c7da4ec..905d92996bf 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -56,6 +56,7 @@ set(OPENSSL_EXPECTED_VERSION 1.0.0)
find_package(PCHSupport)
find_package(OpenSSL REQUIRED)
find_package(Threads REQUIRED)
+find_package(ZMQ REQUIRED)
include(ConfigureBoost)
find_package(MySQL REQUIRED)
diff --git a/README.md b/README.md
index 33fea30e36e..540ce485dca 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,7 @@
# ![logo](http://www.trinitycore.org/f/public/style_images/1_trinitycore.png) TrinityCore
-[![Coverity Scan Build Status](https://scan.coverity.com/projects/435/badge.svg)](https://scan.coverity.com/projects/435)
+[![Coverity Scan Build Status](https://scan.coverity.com/projects/435/badge.svg)](https://scan.coverity.com/projects/435)
+[![Bountysource](https://www.bountysource.com/badge/tracker?tracker_id=1310)](https://www.bountysource.com/trackers/1310-trinity-core?utm_source=1310&utm_medium=shield&utm_campaign=TRACKER_BADGE)
`3.3.5`: [![3.3.5 Build Status](https://travis-ci.org/TrinityCore/TrinityCore.svg?branch=master)](https://travis-ci.org/TrinityCore/TrinityCore)
`4.3.4`: [![4.3.4 Build Status](https://travis-ci.org/TrinityCore/TrinityCore.svg?branch=4.3.4)](https://travis-ci.org/TrinityCore/TrinityCore)
@@ -21,7 +22,6 @@ make pull requests to our [Github repository](https://github.com/TrinityCore/Tri
For further information on the TrinityCore project, please visit our project
website at [TrinityCore.org](http://www.trinitycore.org).
-
## Requirements
+ Platform: Linux, Windows or Mac
diff --git a/cmake/macros/FindZMQ.cmake b/cmake/macros/FindZMQ.cmake
new file mode 100644
index 00000000000..b0d7c56489f
--- /dev/null
+++ b/cmake/macros/FindZMQ.cmake
@@ -0,0 +1,76 @@
+#
+# Find the ZMQ includes and library
+#
+
+# This module defines
+# ZMQ_INCLUDE_DIR, where to find zmq.h
+# ZMQ_LIBRARY, the library needed to use ZMQ
+# ZMQ_FOUND, if false, you cannot build anything that requires ZMQ.
+
+set(ZMQ_FOUND 0)
+
+if (PLATFORM EQUAL 64)
+ set(ZMQ_REGISTRY_PATH
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\ZeroMQ (x64);DisplayIcon]"
+ )
+else()
+ set(ZMQ_REGISTRY_PATH
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\ZeroMQ;DisplayIcon]"
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\ZeroMQ;DisplayIcon]"
+ )
+endif()
+
+find_path(ZMQ_ROOT_DIR
+ NAMES
+ include/zmq.h
+ HINTS
+ ${ZMQ_REGISTRY_PATH}
+ PATHS
+ /usr
+ /usr/local
+)
+
+find_path(ZMQ_INCLUDE_DIR zmq.h ${ZMQ_ROOT_DIR}/include)
+
+if (MSVC)
+ # Read registry key holding version
+ if (PLATFORM EQUAL 64)
+ get_filename_component(ZMQ_NAME "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\ZeroMQ (x64);DisplayVersion]" NAME)
+ else()
+ get_filename_component(ZMQ_NAME "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\ZeroMQ;DisplayVersion]" NAME)
+ if (${ZMQ_NAME} MATCHES "registry") # if key was not found, the string "registry" is returned
+ get_filename_component(ZMQ_NAME "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\ZeroMQ;DisplayVersion]" NAME)
+ endif()
+ endif()
+
+ # Replace dots with underscores
+ string(REGEX REPLACE "\\." "_" ZMQ_NAME ${ZMQ_NAME})
+
+ # Get Visual studio version number
+ string(REGEX REPLACE "Visual Studio ([0-9]+).*" "\\1" ZMQ_VS_VERSION ${CMAKE_GENERATOR})
+
+ # Format ZMQ library file name
+ set(ZMQ_LIBRARY_NAME "libzmq-v${ZMQ_VS_VERSION}0-mt-${ZMQ_NAME}")
+endif()
+
+find_library(ZMQ_LIBRARY
+ NAMES
+ zmq
+ ${ZMQ_LIBRARY_NAME}
+ PATHS
+ /lib
+ /usr/lib
+ /usr/local/lib
+ "${ZMQ_ROOT_DIR}/lib"
+)
+
+if (ZMQ_INCLUDE_DIR AND ZMQ_LIBRARY)
+ set(ZMQ_FOUND 1)
+ message(STATUS "Found ZMQ library: ${ZMQ_LIBRARY}")
+ message(STATUS "Found ZMQ headers: ${ZMQ_INCLUDE_DIR}")
+else()
+ message(FATAL_ERROR "Could not find ZMQ libraries/headers! Please install ZMQ with libraries and headers")
+endif()
+
+# show the ZMQ_INCLUDE_DIR and ZMQ_LIBRARY variables only in the advanced view
+mark_as_advanced(ZMQ_ROOT_DIR ZMQ_INCLUDE_DIR ZMQ_LIBRARY ZMQ_FOUND)
diff --git a/dep/CMakeLists.txt b/dep/CMakeLists.txt
index b469cb694e2..9d186c796f5 100644
--- a/dep/CMakeLists.txt
+++ b/dep/CMakeLists.txt
@@ -36,6 +36,7 @@ endif()
if(SERVERS)
add_subdirectory(gsoap)
+ add_subdirectory(zmqpp)
endif()
if(TOOLS)
diff --git a/dep/PackageList.txt b/dep/PackageList.txt
index d8cad9038b2..12e0de314f7 100644
--- a/dep/PackageList.txt
+++ b/dep/PackageList.txt
@@ -39,3 +39,8 @@ recastnavigation (Recast is state of the art navigation mesh construction toolse
CascLib (An open-source implementation of library for reading CASC storage from Blizzard games since 2014)
https://github.com/ladislav-zezula/CascLib
Version: d3d17de30a1c5678375049f4cf3301a0a7962780
+
+zmqpp (C++ binding for 0mq/zmq is a 'high-level' library that hides most of the c-style interface core 0mq provides.)
+ https://github.com/zeromq/zmqpp
+ Version: 3.2.0 17e9f6afa98f56ecac1e3f3eecbfc112357a6732
+
diff --git a/dep/zmqpp/CMakeLists.txt b/dep/zmqpp/CMakeLists.txt
new file mode 100644
index 00000000000..6b6bd35b6e7
--- /dev/null
+++ b/dep/zmqpp/CMakeLists.txt
@@ -0,0 +1,31 @@
+# Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
+#
+# This file is free software; as a special exception the author gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+file(GLOB_RECURSE sources_zmqpp zmqpp/*.cpp zmqpp/*.hpp zmqpp/*.h)
+
+set(zmqpp_STAT_SRCS
+ ${sources_zmqpp}
+)
+
+include_directories(${ZMQ_INCLUDE_DIR})
+
+add_library(zmqpp STATIC
+ ${zmqpp_STAT_SRCS}
+)
+
+if (WIN32)
+ add_definitions(-DBUILD_VERSION=\\"3.2.0\\")
+else()
+ add_definitions(-DBUILD_VERSION='"3.2.0"')
+endif()
+
+add_definitions(-DBUILD_VERSION_MAJOR=3)
+add_definitions(-DBUILD_VERSION_MINOR=2)
+add_definitions(-DBUILD_VERSION_REVISION=0)
diff --git a/dep/zmqpp/zmqpp/compatibility.hpp b/dep/zmqpp/zmqpp/compatibility.hpp
new file mode 100644
index 00000000000..103b2c82ebd
--- /dev/null
+++ b/dep/zmqpp/zmqpp/compatibility.hpp
@@ -0,0 +1,97 @@
+/**
+ * \file
+ *
+ * \date 10 Sep 2011
+ * \author ron
+ * \author Ben Gray (\@benjamg)
+ *
+ * A fair number of C++0x (or more accurately C++11) features are used in this
+ * library and as this project is used where I work on older compilers this
+ * file was created to help.
+ *
+ * C++ features and their workaround where not supported:
+ * \li lambda functions - disabled, these are only used in the test anyway.
+ * \li typesafe enums - replaced with enum where comparisons needed.
+ * \li nullptr - defined to null.
+ *
+ * As of the port to version 3.1 (libzmqpp version 1.1.0) this file will also
+ * be used to maintain compatablity with multiple versions of 0mq
+ */
+
+#ifndef ZMQPP_COMPATIBILITY_HPP_
+#define ZMQPP_COMPATIBILITY_HPP_
+
+#include <zmq.h>
+#include <cstdint>
+
+// Currently we require at least 0mq version 2.2.x
+#define ZMQPP_REQUIRED_ZMQ_MAJOR 2
+#define ZMQPP_REQUIRED_ZMQ_MINOR 2
+
+#if (ZMQ_VERSION_MAJOR < ZMQPP_REQUIRED_ZMQ_MAJOR) || ((ZMQ_VERSION_MAJOR == ZMQPP_REQUIRED_ZMQ_MAJOR) && (ZMQ_VERSION_MINOR < ZMQPP_REQUIRED_ZMQ_MINOR))
+#error zmqpp requires a later version of 0mq
+#endif
+
+// Experimental feature support
+#if (ZMQ_VERSION_MAJOR == 3) && (ZMQ_VERSION_MINOR == 0)
+#define ZMQ_EXPERIMENTAL_LABELS
+#endif
+
+// Deal with older versions of gcc
+#if defined(__GNUC__) && !defined(__clang__)
+#if __GNUC__ == 4
+
+// Deal with older gcc not supporting C++0x typesafe enum class name {} comparison
+#if __GNUC_MINOR__ < 4
+#define ZMQPP_COMPARABLE_ENUM enum
+#endif
+
+#if __GNUC_MINOR__ == 4
+#if __GNUC_PATCHLEVEL__ < 1
+#undef ZMQPP_COMPARABLE_ENUM
+#define ZMQPP_COMPARABLE_ENUM enum
+#endif // if __GNUC_PATCHLEVEL__ < 1
+#endif // if __GNUC_MINOR__ == 4
+
+// Deal with older gcc not supporting C++0x lambda function
+#if __GNUC_MINOR__ < 5
+#define ZMQPP_IGNORE_LAMBDA_FUNCTION_TESTS
+#define ZMQPP_EXPLICITLY_DELETED
+#endif // if __GNUC_MINOR__ < 5
+
+// Deal with older gcc not supporting C++0x nullptr
+#if __GNUC_MINOR__ < 6
+#define nullptr NULL
+#define NOEXCEPT
+#endif // if __GNUC_MINOR__ < 6
+
+#endif // if __GNUC_ == 4
+#endif // if defined(__GNUC__) && !defined(__clang__)
+
+#if defined(_MSC_VER)
+#define NOEXCEPT throw()
+#if _MSC_VER < 1800
+#define ZMQPP_EXPLICITLY_DELETED
+#endif // if _MSC_VER < 1800
+#if _MSC_VER < 1600
+#define nullptr NULL
+#define ZMQPP_IGNORE_LAMBDA_FUNCTION_TESTS
+#define ZMQPP_COMPARABLE_ENUM enum
+#endif // if _MSC_VER < 1600
+#endif // if defined(_MSC_VER)
+
+// Generic state, assume a modern compiler
+#ifndef ZMQPP_COMPARABLE_ENUM
+#define ZMQPP_COMPARABLE_ENUM enum class
+#endif
+
+#ifndef ZMQPP_EXPLICITLY_DELETED
+#define ZMQPP_EXPLICITLY_DELETED = delete
+#endif
+
+#ifndef NOEXCEPT
+#define NOEXCEPT noexcept
+#endif
+
+#endif /* ZMQPP_COMPATIBILITY_HPP_ */
+
diff --git a/dep/zmqpp/zmqpp/context.cpp b/dep/zmqpp/zmqpp/context.cpp
new file mode 100644
index 00000000000..32c657199dc
--- /dev/null
+++ b/dep/zmqpp/zmqpp/context.cpp
@@ -0,0 +1,54 @@
+/**
+ * \file
+ *
+ * \date 9 Aug 2011
+ * \author Ben Gray (\@benjamg)
+ */
+
+#include "context.hpp"
+
+namespace zmqpp
+{
+
+void context::terminate()
+{
+ int result;
+ do
+ {
+#if (ZMQ_VERSION_MAJOR < 3) || ((ZMQ_VERSION_MAJOR == 3) && (ZMQ_VERSION_MINOR < 2))
+ result = zmq_term(_context);
+#else
+ result = zmq_ctx_destroy(_context);
+#endif
+ } while (result != 0 && zmq_errno() == EINTR);
+ if (result != 0) { throw zmq_internal_exception(); }
+ _context = nullptr;
+}
+
+#if (ZMQ_VERSION_MAJOR > 3) || ((ZMQ_VERSION_MAJOR == 3) && (ZMQ_VERSION_MINOR >= 2))
+void context::set(context_option const option, int const value)
+{
+ if (nullptr == _context) { throw invalid_instance("context is invalid"); }
+
+ if (0 != zmq_ctx_set(_context, static_cast<int>(option), value))
+ {
+ throw zmq_internal_exception();
+ }
+}
+
+int context::get(context_option const option)
+{
+ if (nullptr == _context) { throw invalid_instance("context is invalid"); }
+
+ int result = zmq_ctx_get(_context, static_cast<int>(option));
+
+ if (result < 0)
+ {
+ throw zmq_internal_exception();
+ }
+
+ return result;
+}
+#endif
+
+}
diff --git a/dep/zmqpp/zmqpp/context.hpp b/dep/zmqpp/zmqpp/context.hpp
new file mode 100644
index 00000000000..3ffaf791440
--- /dev/null
+++ b/dep/zmqpp/zmqpp/context.hpp
@@ -0,0 +1,184 @@
+/**
+ * \file
+ *
+ * \date 9 Aug 2011
+ * \author Ben Gray (\@benjamg)
+ */
+
+#ifndef ZMQPP_CONTEXT_HPP_
+#define ZMQPP_CONTEXT_HPP_
+
+#include <cassert>
+
+#include <zmq.h>
+
+#include "compatibility.hpp"
+#include "exception.hpp"
+#if (ZMQ_VERSION_MAJOR > 3) || ((ZMQ_VERSION_MAJOR == 3) && (ZMQ_VERSION_MINOR >= 2))
+#include "context_options.hpp"
+#endif
+
+namespace zmqpp
+{
+
+/*!
+ * The context class represents internal zmq context and io threads.
+ *
+ * By default the context class will create one thread, however this can be
+ * overridden in the constructor.
+ *
+ * The context class is the only object that can be considered thread safe.
+ *
+ * All sockets using endpoints other than inproc require the context to have
+ * at least one thread.
+ *
+ * This class is c++0x move supporting and cannot be copied.
+ */
+class context
+{
+public:
+
+#if (ZMQ_VERSION_MAJOR < 3) || ((ZMQ_VERSION_MAJOR == 3) && (ZMQ_VERSION_MINOR < 2))
+ /*!
+ * Initialise the 0mq context.
+ *
+ * If only inproc is used then the context may be created with zero threads.
+ * Any inproc endpoint using sockets must be created using the same context.
+ *
+ * The context is thread safe an may be used anywhere in your application,
+ * however there is no requirement (other than inproc restrictions) for you
+ * to do this.
+ *
+ * \param threads an integer argument for the number of required threads. Defaults to 1.
+ */
+ context(int const& threads = 1)
+#else
+ /*!
+ * Initialise the 0mq context.
+ *
+ * The context is thread safe an may be used anywhere in your application,
+ * however there is no requirement (other than inproc restrictions) for you
+ * to do this.
+ */
+ context()
+#endif
+ : _context(nullptr)
+ {
+#if (ZMQ_VERSION_MAJOR < 3) || ((ZMQ_VERSION_MAJOR == 3) && (ZMQ_VERSION_MINOR < 2))
+ _context = zmq_init(threads);
+#else
+ _context = zmq_ctx_new();
+#endif
+
+ if (nullptr == _context)
+ {
+ throw zmq_internal_exception();
+ }
+ }
+
+ /*!
+ * Closes the 0mq context.
+ *
+ * Any blocking calls other than a socket close will return with an error.
+ *
+ * If there are open sockets will block while zmq internal buffers are
+ * processed up to a limit specified by that sockets linger option.
+ */
+ ~context() NOEXCEPT
+ {
+ if (nullptr != _context)
+ {
+ terminate();
+ }
+ }
+
+ /*!
+ * Move supporting constructor.
+ *
+ * Allows zero-copy move semantics to be used with this class.
+ *
+ * \param source a rvalue instance of the object who's internals we wish to steal.
+ */
+ context(context&& source) NOEXCEPT
+ : _context(source._context)
+ {
+ source._context = nullptr;
+ }
+
+ /*!
+ * Move supporting operator.
+ *
+ * Allows zero-copy move semantics to be used with this class.
+ *
+ * \param source an rvalue instance of the context who's internals we wish to steal.
+ */
+ context& operator=(context&& source) NOEXCEPT
+ {
+ std::swap( _context, source._context );
+ return *this;
+ }
+
+ /*!
+ * Terminate the current context.
+ *
+ * Any blocking calls other than a socket close will return with an error.
+ *
+ * If there are open sockets will block while zmq internal buffers are
+ * processed up to a limit specified by that sockets linger option.
+ */
+ void terminate();
+
+#if (ZMQ_VERSION_MAJOR > 3) || ((ZMQ_VERSION_MAJOR == 3) && (ZMQ_VERSION_MINOR >= 2))
+ /*!
+ * Set the value of an option in the underlaying zmq context.
+ *
+ * \param option a valid ::context_option
+ * \param value to set the option to
+ */
+ void set(context_option const option, int const value);
+
+ /*!
+ * Get a context option from the underlaying zmq context.
+ *
+ * \param option a valid ::context_option
+ * \return context option value
+ */
+ int get(context_option const option);
+#endif
+
+ /*!
+ * Validity checking of the context
+ *
+ * Checks if the underlying 0mq context for this instance is valid.
+ *
+ * Contexts should always be valid unless people are doing 'fun' things with
+ * std::move.
+ *
+ * \return boolean true if the object is valid.
+ */
+ operator bool() const NOEXCEPT
+ {
+ return nullptr != _context;
+ }
+
+ /*!
+ * Access to the raw 0mq context
+ *
+ * \return void pointer to the underlying 0mq context.
+ */
+ operator void*() const NOEXCEPT
+ {
+ return _context;
+ }
+
+private:
+ void* _context;
+
+ // No copy - private and not implemented
+ context(context const&) ZMQPP_EXPLICITLY_DELETED;
+ context& operator=(context const&) NOEXCEPT ZMQPP_EXPLICITLY_DELETED;
+};
+
+}
+
+#endif /* ZMQPP_CONTEXT_HPP_ */
diff --git a/dep/zmqpp/zmqpp/context_options.hpp b/dep/zmqpp/zmqpp/context_options.hpp
new file mode 100644
index 00000000000..b2e2cf4805f
--- /dev/null
+++ b/dep/zmqpp/zmqpp/context_options.hpp
@@ -0,0 +1,26 @@
+/**
+ * \file
+ *
+ * \date 3 Jul 2013
+ * \author Ben Gray (\@benjamg)
+ */
+
+#ifndef ZMQPP_CONTEXT_OPTIONS_HPP_
+#define ZMQPP_CONTEXT_OPTIONS_HPP_
+
+namespace zmqpp
+{
+
+/** \todo Expand the information on the options to make it actually useful. */
+/*!
+ * \brief possible Context options in zmq
+ */
+
+enum class context_option {
+ io_threads = ZMQ_IO_THREADS, /*!< I/O thread count */
+ max_sockets = ZMQ_MAX_SOCKETS, /*!< Maximum supported sockets */
+};
+
+}
+
+#endif /* ZMQPP_CONTEXT_OPTIONS_HPP_ */
diff --git a/dep/zmqpp/zmqpp/exception.hpp b/dep/zmqpp/zmqpp/exception.hpp
new file mode 100644
index 00000000000..a0b234769ce
--- /dev/null
+++ b/dep/zmqpp/zmqpp/exception.hpp
@@ -0,0 +1,87 @@
+/**
+ * \file
+ *
+ * \date 9 Aug 2011
+ * \author Ben Gray (\@benjamg)
+ */
+
+#ifndef ZMQPP_EXCEPTION_HPP_
+#define ZMQPP_EXCEPTION_HPP_
+
+#include <stdexcept>
+#include <string>
+
+#include <zmq.h>
+
+namespace zmqpp
+{
+
+/** \todo Have a larger variety of exceptions with better state debug information */
+
+/*!
+ * Represents the base zmqpp exception.
+ *
+ * All zmqpp runtime exceptions are children of this class.
+ * The class itself does not provide any special access fields but it only
+ * for convince when catching exceptions.
+ *
+ * The class extends std::runtime_error.
+ *
+ */
+class exception : public std::runtime_error
+{
+public:
+ /*!
+ * Standard exception constructor.
+ *
+ * \param message a string representing the error message.
+ */
+ exception(std::string const& message)
+ : std::runtime_error(message)
+ { }
+};
+
+/*!
+ * Represents an attempt to use an invalid object.
+ *
+ * Objects may be invalid initially or after a shutdown or close.
+ */
+class invalid_instance : public exception
+{
+public:
+ invalid_instance(std::string const& message)
+ : exception(message)
+ { }
+};
+
+/*!
+ * Represents internal zmq errors.
+ *
+ * Any error response from the zmq bindings will be wrapped in this error.
+ *
+ * The class provides access to the zmq error number via zmq_error().
+ */
+class zmq_internal_exception : public exception
+{
+public:
+ /*!
+ * Uses the zmq functions to pull out error messages and numbers.
+ */
+ zmq_internal_exception()
+ : exception(zmq_strerror(zmq_errno()))
+ , _error(zmq_errno())
+ { }
+
+ /*!
+ * Retrieve the zmq error number associated with this exception.
+ * \return zmq error number
+ */
+ int zmq_error() const { return _error; }
+
+private:
+ int _error;
+};
+
+}
+
+#endif /* ZMQPP_EXCEPTION_HPP_ */
diff --git a/dep/zmqpp/zmqpp/frame.cpp b/dep/zmqpp/zmqpp/frame.cpp
new file mode 100644
index 00000000000..4c512ae1010
--- /dev/null
+++ b/dep/zmqpp/zmqpp/frame.cpp
@@ -0,0 +1,95 @@
+/**
+ * \file
+ *
+ * \date 8 Jan 2014
+ * \author Ben Gray (\@benjamg)
+ */
+
+#include <cassert>
+#include <cstring>
+
+#include "exception.hpp"
+#include "frame.hpp"
+
+namespace zmqpp {
+
+frame::frame()
+ : _sent( false )
+{
+ if( 0 != zmq_msg_init( &_msg ) )
+ {
+ throw zmq_internal_exception();
+ }
+}
+
+frame::frame(size_t const size)
+ : _sent( false )
+{
+ if( 0 != zmq_msg_init_size( &_msg, size ) )
+ {
+ throw zmq_internal_exception();
+ }
+}
+
+frame::frame(void const* part, size_t const size)
+ : _sent( false )
+{
+ if( 0 != zmq_msg_init_size( &_msg, size ) )
+ {
+ throw zmq_internal_exception();
+ }
+
+ void* msg_data = zmq_msg_data( &_msg );
+ memcpy( msg_data, part, size );
+}
+
+frame::frame(void* part, size_t const size, zmq_free_fn *ffn, void *hint)
+ : _sent( false )
+{
+ if( 0 != zmq_msg_init_data( &_msg, part, size, ffn, hint ) )
+ {
+ throw zmq_internal_exception();
+ }
+}
+
+frame::~frame()
+{
+#ifndef NDEBUG // unused assert variable in release
+ int result = zmq_msg_close( &_msg );
+ assert(0 == result);
+#else
+ zmq_msg_close( &_msg );
+#endif // NDEBUG
+}
+
+frame::frame(frame&& other)
+ : _sent( other._sent )
+{
+ zmq_msg_init( &_msg );
+ zmq_msg_move( &_msg, &other._msg );
+ other._sent = false;
+}
+
+frame& frame::operator=(frame&& other)
+{
+ zmq_msg_init( &_msg );
+ zmq_msg_move( &_msg, &other._msg );
+ std::swap( _sent, other._sent );
+
+ return *this;
+}
+
+frame frame::copy() const
+{
+ frame other( size() );
+ other._sent = _sent;
+
+ if( 0 != zmq_msg_copy( &other._msg, const_cast<zmq_msg_t*>(&_msg) ) )
+ {
+ throw zmq_internal_exception();
+ }
+
+ return other;
+}
+
+} // namespace zmqpp
diff --git a/dep/zmqpp/zmqpp/frame.hpp b/dep/zmqpp/zmqpp/frame.hpp
new file mode 100644
index 00000000000..c9e4b9b7d82
--- /dev/null
+++ b/dep/zmqpp/zmqpp/frame.hpp
@@ -0,0 +1,58 @@
+/**
+ * \file
+ *
+ * \date 8 Jan 2014
+ * \author Ben Gray (\@benjamg)
+ */
+
+#ifndef ZMQPP_MESSAGE_FRAME_HPP_
+#define ZMQPP_MESSAGE_FRAME_HPP_
+
+#include <zmq.h>
+
+#include "compatibility.hpp"
+
+namespace zmqpp {
+
+/*!
+ * \brief an internal frame wrapper for a single zmq message
+ *
+ * This frame wrapper consists of a zmq message and meta data it is used
+ * by the zmqpp message class to keep track of parts in the internal
+ * queue. It is unlikely you need to use this class.
+ */
+class frame
+{
+public:
+ frame();
+ frame(size_t const size);
+ frame(void const* part, size_t const size);
+ frame(void* part, size_t const size, zmq_free_fn *ffn, void *hint);
+
+ ~frame();
+
+ bool is_sent() const { return _sent; }
+ void const* data() const { return zmq_msg_data( const_cast<zmq_msg_t*>(&_msg) ); }
+ size_t size() const { return zmq_msg_size( const_cast<zmq_msg_t*>(&_msg) ); }
+
+ void mark_sent() { _sent = true; }
+ zmq_msg_t& msg() { return _msg; }
+
+ // Move operators
+ frame(frame&& other);
+ frame& operator=(frame&& other);
+
+ frame copy() const;
+
+private:
+ bool _sent;
+ zmq_msg_t _msg;
+
+ // Disable implicit copy support, code must request a copy to clone
+ frame(frame const&) NOEXCEPT ZMQPP_EXPLICITLY_DELETED;
+ frame& operator=(frame const&) NOEXCEPT ZMQPP_EXPLICITLY_DELETED;
+};
+
+} // namespace zmqpp
+
+#endif /* ZMQPP_MESSAGE_FRAME_HPP_ */
diff --git a/dep/zmqpp/zmqpp/inet.hpp b/dep/zmqpp/zmqpp/inet.hpp
new file mode 100644
index 00000000000..5245aa4143c
--- /dev/null
+++ b/dep/zmqpp/zmqpp/inet.hpp
@@ -0,0 +1,171 @@
+/**
+ * \file
+ *
+ * \date 10 Aug 2011
+ * \author Ben Gray (\@benjamg)
+ */
+
+#ifndef ZMQPP_INET_HPP_
+#define ZMQPP_INET_HPP_
+
+/** \todo cross-platform version of including headers. */
+// We get htons and htonl from here
+#ifdef _WIN32
+#include <WinSock2.h>
+#else
+#include <netinet/in.h>
+#endif
+
+#include "compatibility.hpp"
+
+namespace zmqpp
+{
+
+/*!
+ * \brief Possible byte order types.
+ *
+ * An enumeration of all the known order types, all two of them.
+ * There is also an entry for unknown which is just used as a default.
+ */
+ZMQPP_COMPARABLE_ENUM order {
+ big_endian, /*!< byte order is big endian */
+ little_endian /*!< byte order is little endian */
+};
+
+/*!
+ * Common code for the 64bit versions of htons/htons and ntohs/ntohl
+ *
+ * As htons and ntohs (or htonl and ntohs) always just do the same thing, ie
+ * swap bytes if the host order differs from network order or otherwise don't
+ * do anything, it seemed silly to type the code twice.
+ *
+ * \note This code assumes network order is always big endian. Which it is.
+ * \note The host endian is only checked once and afterwards assumed to remain
+ * the same.
+ *
+ * \param value_to_check unsigned 64 bit integer to swap
+ * \return swapped (or not) unsigned 64 bit integer
+ */
+inline uint64_t swap_if_needed(uint64_t const value_to_check)
+{
+ static order host_order = (htonl(42) == 42) ? order::big_endian : order::little_endian;
+
+ if (order::big_endian == host_order)
+ {
+ return value_to_check;
+ }
+
+ union {
+ uint64_t integer;
+ uint8_t bytes[8];
+ } value { value_to_check };
+
+ std::swap(value.bytes[0], value.bytes[7]);
+ std::swap(value.bytes[1], value.bytes[6]);
+ std::swap(value.bytes[2], value.bytes[5]);
+ std::swap(value.bytes[3], value.bytes[4]);
+
+ return value.integer;
+}
+
+/*!
+ * 64 bit version of the htons/htonl
+ *
+ * I've used the name htonll to try and keep with the htonl naming scheme.
+ *
+ * \param hostlonglong unsigned 64 bit host order integer
+ * \return unsigned 64 bit network order integer
+ */
+inline uint64_t htonll(uint64_t const hostlonglong)
+{
+ return zmqpp::swap_if_needed(hostlonglong);
+}
+
+/*!
+ * 64 bit version of the ntohs/ntohl
+ *
+ * I've used the name htonll to try and keep with the htonl naming scheme.
+ *
+ * \param networklonglong unsigned 64 bit network order integer
+ * \return unsigned 64 bit host order integer
+ */
+inline uint64_t ntohll(uint64_t const networklonglong)
+{
+ return zmqpp::swap_if_needed(networklonglong);
+}
+
+/*!
+ * floating point version of the htons/htonl
+ *
+ * \param value host order floating point
+ * \returns network order floating point
+ */
+inline float htonf(float value)
+{
+ assert(sizeof(float) == sizeof(uint32_t));
+
+ uint32_t temp;
+ memcpy(&temp, &value, sizeof(uint32_t));
+ temp = htonl( temp );
+ memcpy(&value, &temp, sizeof(uint32_t));
+
+ return value;
+}
+
+/*!
+ * floating point version of the ntohs/ntohl
+ *
+ * \param value network order float
+ * \returns host order float
+ */
+inline float ntohf(float value)
+{
+ assert(sizeof(float) == sizeof(uint32_t));
+
+ uint32_t temp;
+ memcpy(&temp, &value, sizeof(uint32_t));
+ temp = ntohl( temp );
+ memcpy(&value, &temp, sizeof(uint32_t));
+
+ return value;
+}
+
+/*!
+ * double precision floating point version of the htons/htonl
+ *
+ * \param value host order double precision floating point
+ * \returns network order double precision floating point
+ */
+inline double htond(double value)
+{
+ assert(sizeof(double) == sizeof(uint64_t));
+
+ uint64_t temp;
+ memcpy(&temp, &value, sizeof(uint64_t));
+ temp = zmqpp::htonll(temp);
+ memcpy(&value, &temp, sizeof(uint64_t));
+
+ return value;
+}
+
+/*!
+ * double precision floating point version of the ntohs/ntohl
+ *
+ * \param value network order double precision floating point
+ * \returns host order double precision floating point
+ */
+inline double ntohd(double value)
+{
+ assert(sizeof(double) == sizeof(uint64_t));
+
+ uint64_t temp;
+ memcpy(&temp, &value, sizeof(uint64_t));
+ temp = zmqpp::ntohll(temp);
+ memcpy(&value, &temp, sizeof(uint64_t));
+
+ return value;
+}
+
+}
+
+#endif /* INET_HPP_ */
diff --git a/dep/zmqpp/zmqpp/message.cpp b/dep/zmqpp/zmqpp/message.cpp
new file mode 100644
index 00000000000..58587307364
--- /dev/null
+++ b/dep/zmqpp/zmqpp/message.cpp
@@ -0,0 +1,454 @@
+/*
+ * Created on: 9 Aug 2011
+ * Author: Ben Gray (@benjamg)
+ */
+
+#include <cassert>
+#include <cstring>
+
+#include "exception.hpp"
+#include "inet.hpp"
+#include "message.hpp"
+
+namespace zmqpp
+{
+
+/*!
+ * \brief internal construct
+ * \internal handles bubbling callback from zmq c style to the c++ functor provided
+ */
+struct callback_releaser
+{
+ message::release_function func;
+};
+
+message::message()
+ : _parts()
+ , _read_cursor(0)
+{
+}
+
+message::~message()
+{
+ _parts.clear();
+}
+
+size_t message::parts() const
+{
+ return _parts.size();
+}
+
+/*
+ * The two const_casts in size and raw_data are a little bit hacky
+ * but neither of these methods called this way actually modify data
+ * so accurately represent the intent of these calls.
+ */
+
+size_t message::size(size_t const part /* = 0 */) const
+{
+ if(part >= _parts.size())
+ {
+ throw exception("attempting to request a message part outside the valid range");
+ }
+
+ return _parts[part].size();
+}
+
+void const* message::raw_data(size_t const part /* = 0 */) const
+{
+ if(part >= _parts.size())
+ {
+ throw exception("attempting to request a message part outside the valid range");
+ }
+
+ return _parts[part].data();
+}
+
+zmq_msg_t& message::raw_msg(size_t const part /* = 0 */)
+{
+ if(part >= _parts.size())
+ {
+ throw exception("attempting to request a message part outside the valid range");
+ }
+
+ return _parts[part].msg();
+}
+
+zmq_msg_t& message::raw_new_msg()
+{
+ _parts.push_back( frame() );
+
+ return _parts.back().msg();
+}
+
+zmq_msg_t& message::raw_new_msg(size_t const reserve_data_size)
+{
+ _parts.push_back( frame(reserve_data_size) );
+
+ return _parts.back().msg();
+}
+
+std::string message::get(size_t const part /* = 0 */) const
+{
+ return std::string(static_cast<char const*>(raw_data(part)), size(part));
+}
+
+
+// Move operators will take ownership of message parts without copying
+void message::move(void* part, size_t const size, release_function const& release)
+{
+ callback_releaser* hint = new callback_releaser();
+ hint->func = release;
+
+ _parts.push_back( frame( part, size, &message::release_callback, hint ) );
+}
+
+// Stream reader style
+void message::reset_read_cursor()
+{
+ _read_cursor = 0;
+}
+
+void message::get(int8_t& integer, size_t const part) const
+{
+ assert(sizeof(int8_t) == size(part));
+
+ int8_t const* byte = static_cast<int8_t const*>(raw_data(part));
+ integer = *byte;
+}
+
+void message::get(int16_t& integer, size_t const part) const
+{
+ assert(sizeof(int16_t) == size(part));
+
+ uint16_t const* network_order = static_cast<uint16_t const*>(raw_data(part));
+ integer = static_cast<int16_t>(ntohs(*network_order));
+}
+
+void message::get(int32_t& integer, size_t const part) const
+{
+ assert(sizeof(int32_t) == size(part));
+
+ uint32_t const* network_order = static_cast<uint32_t const*>(raw_data(part));
+ integer = static_cast<int32_t>(htonl(*network_order));
+}
+
+void message::get(int64_t& integer, size_t const part) const
+{
+ assert(sizeof(int64_t) == size(part));
+
+ uint64_t const* network_order = static_cast<uint64_t const*>(raw_data(part));
+ integer = static_cast<int64_t>(zmqpp::htonll(*network_order));
+}
+
+void message::get(uint8_t& unsigned_integer, size_t const part) const
+{
+ assert(sizeof(uint8_t) == size(part));
+
+ uint8_t const* byte = static_cast<uint8_t const*>(raw_data(part));
+ unsigned_integer = *byte;
+}
+
+void message::get(uint16_t& unsigned_integer, size_t const part) const
+{
+ assert(sizeof(uint16_t) == size(part));
+
+ uint16_t const* network_order = static_cast<uint16_t const*>(raw_data(part));
+ unsigned_integer = ntohs(*network_order);
+}
+
+void message::get(uint32_t& unsigned_integer, size_t const part) const
+{
+ assert(sizeof(uint32_t) == size(part));
+
+ uint32_t const* network_order = static_cast<uint32_t const*>(raw_data(part));
+ unsigned_integer = ntohl(*network_order);
+}
+
+void message::get(uint64_t& unsigned_integer, size_t const part) const
+{
+ assert(sizeof(uint64_t) == size(part));
+
+ uint64_t const* network_order = static_cast<uint64_t const*>(raw_data(part));
+ unsigned_integer = zmqpp::ntohll(*network_order);
+}
+
+void message::get(float& floating_point, size_t const part) const
+{
+ assert(sizeof(float) == size(part));
+
+ float const* network_order = static_cast<float const*>(raw_data(part));
+ floating_point = zmqpp::ntohf(*network_order);
+}
+
+void message::get(double& double_precision, size_t const part) const
+{
+ assert(sizeof(double) == size(part));
+
+ double const* network_order = static_cast<double const*>(raw_data(part));
+ double_precision = zmqpp::ntohd(*network_order);
+}
+
+void message::get(bool& boolean, size_t const part) const
+{
+ assert(sizeof(uint8_t) == size(part));
+
+ uint8_t const* byte = static_cast<uint8_t const*>(raw_data(part));
+ boolean = (*byte != 0);
+}
+
+void message::get(std::string& string, size_t const part) const
+{
+ string.assign( get(part) );
+}
+
+
+// Stream writer style - these all use copy styles
+message& message::operator<<(int8_t const integer)
+{
+ add(reinterpret_cast<void const*>(&integer), sizeof(int8_t));
+ return *this;
+}
+
+message& message::operator<<(int16_t const integer)
+{
+ uint16_t network_order = htons(static_cast<uint16_t>(integer));
+ add(reinterpret_cast<void const*>(&network_order), sizeof(uint16_t));
+
+ return *this;
+}
+
+message& message::operator<<(int32_t const integer)
+{
+ uint32_t network_order = htonl(static_cast<uint32_t>(integer));
+ add(reinterpret_cast<void const*>(&network_order), sizeof(uint32_t));
+
+ return *this;
+}
+
+message& message::operator<<(int64_t const integer)
+{
+ uint64_t network_order = zmqpp::htonll(static_cast<uint64_t>(integer));
+ add(reinterpret_cast<void const*>(&network_order), sizeof(uint64_t));
+
+ return *this;
+}
+
+
+message& message::operator<<(uint8_t const unsigned_integer)
+{
+ add(reinterpret_cast<void const*>(&unsigned_integer), sizeof(uint8_t));
+ return *this;
+}
+
+message& message::operator<<(uint16_t const unsigned_integer)
+{
+ uint16_t network_order = htons(unsigned_integer);
+ add(reinterpret_cast<void const*>(&network_order), sizeof(uint16_t));
+
+ return *this;
+}
+
+message& message::operator<<(uint32_t const unsigned_integer)
+{
+ uint32_t network_order = htonl(unsigned_integer);
+ add(reinterpret_cast<void const*>(&network_order), sizeof(uint32_t));
+
+ return *this;
+}
+
+message& message::operator<<(uint64_t const unsigned_integer)
+{
+ uint64_t network_order = zmqpp::htonll(unsigned_integer);
+ add(reinterpret_cast<void const*>(&network_order), sizeof(uint64_t));
+
+ return *this;
+}
+
+message& message::operator<<(float const floating_point)
+{
+ assert(sizeof(float) == 4);
+
+ float network_order = zmqpp::htonf(floating_point);
+ add(&network_order, sizeof(float));
+
+ return *this;
+}
+
+message& message::operator<<(double const double_precision)
+{
+ assert(sizeof(double) == 8);
+
+ double network_order = zmqpp::htond(double_precision);
+ add(&network_order, sizeof(double));
+
+ return *this;
+}
+
+message& message::operator<<(bool const boolean)
+{
+ uint8_t byte = (boolean) ? 1 : 0;
+ add(reinterpret_cast<void const*>(&byte), sizeof(uint8_t));
+
+ return *this;
+}
+
+message& message::operator<<(char const* c_string)
+{
+ add(reinterpret_cast<void const*>(c_string), strlen(c_string));
+ return *this;
+}
+
+message& message::operator<<(std::string const& string)
+{
+ add(reinterpret_cast<void const*>(string.data()), string.size());
+ return *this;
+}
+
+void message::push_front(void const* part, size_t const size)
+{
+ _parts.emplace( _parts.begin(), part, size );
+}
+
+void message::push_front(int8_t const integer)
+{
+ push_front(&integer, sizeof(int8_t));
+}
+
+void message::push_front(int16_t const integer)
+{
+ uint16_t network_order = htons(static_cast<uint16_t>(integer));
+ push_front(&network_order, sizeof(uint16_t));
+}
+
+void message::push_front(int32_t const integer)
+{
+ uint32_t network_order = htonl(static_cast<uint32_t>(integer));
+ push_front(&network_order, sizeof(uint32_t));
+}
+
+void message::push_front(int64_t const integer)
+{
+ uint64_t network_order = zmqpp::htonll(static_cast<uint64_t>(integer));
+ push_front(&network_order, sizeof(uint64_t));
+}
+
+
+void message::push_front(uint8_t const unsigned_integer)
+{
+ push_front(&unsigned_integer, sizeof(uint8_t));
+}
+
+void message::push_front(uint16_t const unsigned_integer)
+{
+ uint16_t network_order = htons(unsigned_integer);
+ push_front(&network_order, sizeof(uint16_t));
+}
+
+void message::push_front(uint32_t const unsigned_integer)
+{
+ uint32_t network_order = htonl(unsigned_integer);
+ push_front(&network_order, sizeof(uint32_t));
+}
+
+void message::push_front(uint64_t const unsigned_integer)
+{
+ uint64_t network_order = zmqpp::htonll(unsigned_integer);
+ push_front(&network_order, sizeof(uint64_t));
+}
+
+void message::push_front(float const floating_point)
+{
+ assert(sizeof(float) == 4);
+
+ float network_order = zmqpp::htonf(floating_point);
+ push_front(&network_order, sizeof(float));
+}
+
+void message::push_front(double const double_precision)
+{
+ assert(sizeof(double) == 8);
+
+ double network_order = zmqpp::htond(double_precision);
+ push_front(&network_order, sizeof(double));
+}
+
+void message::push_front(bool const boolean)
+{
+ uint8_t byte = (boolean) ? 1 : 0;
+ push_front(&byte, sizeof(uint8_t));
+}
+
+void message::push_front(char const* c_string)
+{
+ push_front(c_string, strlen(c_string));
+}
+
+void message::push_front(std::string const& string)
+{
+ push_front(string.data(), string.size());
+}
+
+void message::pop_front()
+{
+ _parts.erase( _parts.begin() );
+}
+
+void message::pop_back()
+{
+ _parts.pop_back();
+}
+
+message::message(message&& source) NOEXCEPT
+ : _parts()
+ , _read_cursor(0)
+{
+ std::swap(_parts, source._parts);
+}
+
+message& message::operator=(message&& source) NOEXCEPT
+{
+ std::swap(_parts, source._parts);
+ return *this;
+}
+
+message message::copy() const
+{
+ message msg;
+ msg.copy(*this);
+ return msg;
+}
+
+void message::copy(message const& source)
+{
+ _parts.resize( source._parts.size() );
+ for(size_t i = 0; i < source._parts.size(); ++i)
+ {
+ _parts[i] = source._parts[i].copy();
+ }
+
+ // we don't need a copy of the releasers as we did data copies of the internal data,
+ //_releasers = source._releasers;
+ //_strings = source._strings
+}
+
+// Used for internal tracking
+void message::sent(size_t const part)
+{
+ // sanity check
+ assert(!_parts[part].is_sent());
+ _parts[part].mark_sent();
+}
+
+// Note that these releasers are not thread safe, the only safety is provided by
+// the socket class taking ownership so no updates can happen while zmq does it's thing
+// If used in a custom class this has to be dealt with.
+void message::release_callback(void* data, void* hint)
+{
+ callback_releaser* releaser = static_cast<callback_releaser*>(hint);
+ releaser->func(data);
+
+ delete releaser;
+}
+
+}
diff --git a/dep/zmqpp/zmqpp/message.hpp b/dep/zmqpp/zmqpp/message.hpp
new file mode 100644
index 00000000000..2a747bfd1db
--- /dev/null
+++ b/dep/zmqpp/zmqpp/message.hpp
@@ -0,0 +1,254 @@
+/**
+ * \file
+ *
+ * \date 9 Aug 2011
+ * \author Ben Gray (\@benjamg)
+ */
+
+#ifndef ZMQPP_MESSAGE_HPP_
+#define ZMQPP_MESSAGE_HPP_
+
+#include <functional>
+#include <string>
+#include <unordered_map>
+#include <vector>
+#include <utility>
+#include <cassert>
+
+#include <zmq.h>
+
+#include "compatibility.hpp"
+#include "frame.hpp"
+
+namespace zmqpp
+{
+
+/*!
+ * \brief a zmq message with optional multipart support
+ *
+ * A zmq message is made up of one or more parts which are sent together to
+ * the target endpoints. zmq guarantees either the whole message or none
+ * of the message will be delivered.
+ */
+class message
+{
+public:
+ /*!
+ * \brief callback to release user allocated data.
+ *
+ * The release function will be called on any void* moved part.
+ * It must be thread safe to the extent that the callback may occur on
+ * one of the context threads.
+ *
+ * The function called will be passed a single variable which is the
+ * pointer to the memory allocated.
+ */
+ typedef std::function<void (void*)> release_function;
+
+ message();
+ ~message();
+
+ template <typename T, typename ...Args>
+ message(T const &part, Args &&...args)
+ : message()
+ {
+ add(part, std::forward<Args>(args)...);
+ }
+
+ size_t parts() const;
+ size_t size(size_t const part) const;
+ std::string get(size_t const part) const;
+
+ void get(int8_t& integer, size_t const part) const;
+ void get(int16_t& integer, size_t const part) const;
+ void get(int32_t& integer, size_t const part) const;
+ void get(int64_t& integer, size_t const part) const;
+
+ void get(uint8_t& unsigned_integer, size_t const part) const;
+ void get(uint16_t& unsigned_integer, size_t const part) const;
+ void get(uint32_t& unsigned_integer, size_t const part) const;
+ void get(uint64_t& unsigned_integer, size_t const part) const;
+
+ void get(float& floating_point, size_t const part) const;
+ void get(double& double_precision, size_t const part) const;
+ void get(bool& boolean, size_t const part) const;
+
+ void get(std::string& string, size_t const part) const;
+
+ // Warn: If a pointer type is requested the message (well zmq) still 'owns'
+ // the data and will release it when the message object is freed.
+ template<typename Type>
+ Type get(size_t const part)
+ {
+ Type value;
+ get(value, part);
+ return value;
+ }
+
+ template<int part=0, typename T, typename ...Args>
+ void extract(T &nextpart, Args &...args)
+ {
+ assert(part < parts());
+ get(nextpart,part);
+ extract<part+1>(args...);
+ }
+
+ template<int part=0, typename T>
+ void extract(T &nextpart)
+ {
+ assert(part < parts());
+ get(nextpart,part);
+ }
+
+ // Raw get data operations, useful with data structures more than anything else
+ // Warn: The message (well zmq) still 'owns' the data and will release it
+ // when the message object is freed.
+ template<typename Type>
+ void get(Type*& value, size_t const part) const
+ {
+ value = static_cast<Type*>(raw_data(part));
+ }
+
+ // Warn: The message (well zmq) still 'owns' the data and will release it
+ // when the message object is freed.
+ template<typename Type>
+ void get(Type** value, size_t const part) const
+ {
+ *value = static_cast<Type*>(raw_data(part));
+ }
+
+ // Move operators will take ownership of message parts without copying
+ void move(void* part, size_t const size, release_function const& release);
+
+ // Raw move data operation, useful with data structures more than anything else
+ template<typename Object>
+ void move(Object *part)
+ {
+ move(part, sizeof(Object), &deleter_callback<Object>);
+ }
+
+ // Copy operators will take copies of any data
+ template<typename Type>
+ void add(Type *part, size_t const size)
+ {
+ _parts.push_back( frame( part, size ) );
+ }
+
+
+ template<typename Type, typename ...Args>
+ void add(Type const& part, Args &&...args)
+ {
+ *this << part;
+ add(std::forward<Args>(args)...);
+ }
+
+ template<typename Type>
+ void add(Type const part)
+ {
+ *this << part;
+ }
+
+ // Stream reader style
+ void reset_read_cursor();
+
+ template<typename Type>
+ message& operator>>(Type& value)
+ {
+ get(value, _read_cursor++);
+ return *this;
+ }
+
+ // Stream writer style - these all use copy styles
+ message& operator<<(int8_t const integer);
+ message& operator<<(int16_t const integer);
+ message& operator<<(int32_t const integer);
+ message& operator<<(int64_t const integer);
+
+ message& operator<<(uint8_t const unsigned_integer);
+ message& operator<<(uint16_t const unsigned_integer);
+ message& operator<<(uint32_t const unsigned_integer);
+ message& operator<<(uint64_t const unsigned_integer);
+
+ message& operator<<(float const floating_point);
+ message& operator<<(double const double_precision);
+ message& operator<<(bool const boolean);
+
+ message& operator<<(char const* c_string);
+ message& operator<<(std::string const& string);
+
+ // Queue manipulation
+ void push_front(void const* part, size_t const size);
+
+ // TODO: unify conversion of types with the stream operators
+ void push_front(int8_t const integer);
+ void push_front(int16_t const integer);
+ void push_front(int32_t const integer);
+ void push_front(int64_t const integer);
+
+ void push_front(uint8_t const unsigned_integer);
+ void push_front(uint16_t const unsigned_integer);
+ void push_front(uint32_t const unsigned_integer);
+ void push_front(uint64_t const unsigned_integer);
+
+ void push_front(float const floating_point);
+ void push_front(double const double_precision);
+ void push_front(bool const boolean);
+
+ void push_front(char const* c_string);
+ void push_front(std::string const& string);
+
+ void pop_front();
+
+ void push_back(void const* part, size_t const size)
+ {
+ add( part, size );
+ }
+
+ template<typename Type>
+ void push_back(Type const part)
+ {
+ *this << part;
+ }
+
+ void pop_back();
+
+ void remove(size_t const part);
+
+ // Move supporting
+ message(message&& source) NOEXCEPT;
+ message& operator=(message&& source) NOEXCEPT;
+
+ // Copy support
+ message copy() const;
+ void copy(message const& source);
+
+ // Used for internal tracking
+ void sent(size_t const part);
+
+ // Access to raw zmq details
+ void const* raw_data(size_t const part = 0) const;
+ zmq_msg_t& raw_msg(size_t const part = 0);
+ zmq_msg_t& raw_new_msg();
+ zmq_msg_t& raw_new_msg(size_t const reserve_data_size);
+
+private:
+ typedef std::vector<frame> parts_type;
+ parts_type _parts;
+ size_t _read_cursor;
+
+ // Disable implicit copy support, code must request a copy to clone
+ message(message const&) NOEXCEPT ZMQPP_EXPLICITLY_DELETED;
+ message& operator=(message const&) NOEXCEPT ZMQPP_EXPLICITLY_DELETED;
+
+ static void release_callback(void* data, void* hint);
+
+ template<typename Object>
+ static void deleter_callback(void* data)
+ {
+ delete static_cast<Object*>(data);
+ }
+};
+
+}
+
+#endif /* ZMQPP_MESSAGE_HPP_ */
diff --git a/dep/zmqpp/zmqpp/poller.cpp b/dep/zmqpp/zmqpp/poller.cpp
new file mode 100644
index 00000000000..a6340c9bd61
--- /dev/null
+++ b/dep/zmqpp/zmqpp/poller.cpp
@@ -0,0 +1,182 @@
+/*
+ * Created on: 16 Aug 2011
+ * Author: Ben Gray (@benjamg)
+ */
+
+#include "exception.hpp"
+#include "socket.hpp"
+#include "poller.hpp"
+
+#include <zmq.h>
+
+namespace zmqpp
+{
+
+const long poller::wait_forever = -1;
+const short poller::poll_none = 0;
+const short poller::poll_in = ZMQ_POLLIN;
+const short poller::poll_out = ZMQ_POLLOUT;
+const short poller::poll_error = ZMQ_POLLERR;
+
+poller::poller()
+ : _items()
+ , _index()
+ , _fdindex()
+{
+
+}
+
+poller::~poller()
+{
+ _items.clear();
+ _index.clear();
+ _fdindex.clear();
+}
+
+void poller::add(socket& socket, short const event /* = POLL_IN */)
+{
+ zmq_pollitem_t item { socket, 0, event, 0 };
+
+ size_t index = _items.size();
+ _items.push_back(item);
+ _index[socket] = index;
+}
+
+void poller::add(int const descriptor, short const event /* = POLL_IN */)
+{
+ zmq_pollitem_t item { nullptr, descriptor, event, 0 };
+
+ size_t index = _items.size();
+ _items.push_back(item);
+ _fdindex[descriptor] = index;
+}
+
+bool poller::has(socket_t const& socket)
+{
+ return _index.find(socket) != _index.end();
+}
+
+bool poller::has(int const descriptor)
+{
+ return _fdindex.find(descriptor) != _fdindex.end();
+}
+
+void poller::reindex(size_t const index)
+{
+ if ( nullptr != _items[index].socket )
+ {
+ auto found = _index.find( _items[index].socket );
+ if (_index.end() == found) { throw exception("unable to reindex socket in poller"); }
+ found->second = index;
+ }
+ else
+ {
+ auto found = _fdindex.find( _items[index].fd );
+ if (_fdindex.end() == found) { throw exception("unable to reindex file descriptor in poller"); }
+ found->second = index;
+ }
+}
+
+void poller::remove(socket_t const& socket)
+{
+ auto found = _index.find(socket);
+ if (_index.end() == found) { return; }
+
+ if ( _items.size() - 1 == found->second )
+ {
+ _items.pop_back();
+ _index.erase(found);
+ return;
+ }
+
+ std::swap(_items[found->second], _items.back());
+ _items.pop_back();
+
+ auto index = found->second;
+ _index.erase(found);
+
+ reindex( index );
+}
+
+void poller::remove(int const descriptor)
+{
+ auto found = _fdindex.find(descriptor);
+ if (_fdindex.end() == found) { return; }
+
+ if ( _items.size() - 1 == found->second )
+ {
+ _items.pop_back();
+ _fdindex.erase(found);
+ return;
+ }
+
+ std::swap(_items[found->second], _items.back());
+ _items.pop_back();
+
+ auto index = found->second;
+ _fdindex.erase(found);
+
+ reindex( index );
+}
+
+void poller::check_for(socket const& socket, short const event)
+{
+ auto found = _index.find(socket);
+ if (_index.end() == found)
+ {
+ throw exception("this socket is not represented within this poller");
+ }
+
+ _items[found->second].events = event;
+}
+
+void poller::check_for(int const descriptor, short const event)
+{
+ auto found = _fdindex.find(descriptor);
+ if (_fdindex.end() == found)
+ {
+ throw exception("this socket is not represented within this poller");
+ }
+
+ _items[found->second].events = event;
+}
+
+bool poller::poll(long timeout /* = WAIT_FOREVER */)
+{
+ int result = zmq_poll(_items.data(), _items.size(), timeout);
+ if (result < 0)
+ {
+ if(EINTR == zmq_errno())
+ {
+ return false;
+ }
+
+ throw zmq_internal_exception();
+ }
+
+ return (result > 0);
+}
+
+short poller::events(socket const& socket) const
+{
+ auto found = _index.find(socket);
+ if (_index.end() == found)
+ {
+ throw exception("this socket is not represented within this poller");
+ }
+
+ return _items[found->second].revents;
+}
+
+short poller::events(int const descriptor) const
+{
+ auto found = _fdindex.find(descriptor);
+ if (_fdindex.end() == found)
+ {
+ throw exception("this file descriptor is not represented within this poller");
+ }
+
+ return _items[found->second].revents;
+}
+
+}
diff --git a/dep/zmqpp/zmqpp/poller.hpp b/dep/zmqpp/zmqpp/poller.hpp
new file mode 100644
index 00000000000..a19063a091d
--- /dev/null
+++ b/dep/zmqpp/zmqpp/poller.hpp
@@ -0,0 +1,186 @@
+/**
+ * \file
+ *
+ * \date 9 Aug 2011
+ * \author Ben Gray (\@benjamg)
+ */
+
+#ifndef ZMQPP_POLLER_HPP_
+#define ZMQPP_POLLER_HPP_
+
+#include <unordered_map>
+#include <vector>
+
+#include "compatibility.hpp"
+
+namespace zmqpp
+{
+
+class socket;
+typedef socket socket_t;
+
+/*!
+ * Polling wrapper.
+ *
+ * Allows access to polling for any number of sockets or file descriptors.
+ */
+class poller
+{
+public:
+ static const long wait_forever; /*!< Block forever flag, default setting. */
+
+ static const short poll_none; /*!< No polling flags set. */
+ static const short poll_in; /*!< Monitor inbound flag. */
+ static const short poll_out; /*!< Monitor output flag. */
+ static const short poll_error; /*!< Monitor error flag.\n Only for file descriptors. */
+
+ /*!
+ * Construct an empty polling model.
+ */
+ poller();
+
+ /*!
+ * Cleanup poller.
+ *
+ * Any sockets will need to be closed separately.
+ */
+ ~poller();
+
+ /*!
+ * Add a socket to the polling model and set which events to monitor.
+ *
+ * \param socket the socket to monitor.
+ * \param event the event flags to monitor on the socket.
+ */
+ void add(socket_t& socket, short const event = poll_in);
+
+ /*!
+ * Add a file descriptor to the polling model and set which events to monitor.
+ *
+ * \param descriptor the file descriptor to monitor.
+ * \param event the event flags to monitor.
+ */
+ void add(int const descriptor, short const event = poll_in | poll_error);
+
+ /*!
+ * Check if we are monitoring a given socket with this poller.
+ *
+ * \param socket the socket to check.
+ * \return true if it is there.
+ */
+ bool has(socket_t const& socket);
+
+ /*!
+ * Check if we are monitoring a given file descriptor with this poller.
+ *
+ * \param descriptor the file descriptor to check.
+ * \return true if it is there.
+ */
+ bool has(int const descriptor);
+
+ /*!
+ * Stop monitoring a socket.
+ *
+ * \param socket the socket to stop monitoring.
+ */
+ void remove(socket_t const& socket);
+
+ /*!
+ * Stop monitoring a file descriptor.
+ *
+ * \param descriptor the file descriptor to stop monitoring.
+ */
+ void remove(int const descriptor);
+
+ /*!
+ * Update the monitored event flags for a given socket.
+ *
+ * \param socket the socket to update event flags.
+ * \param event the event flags to monitor on the socket.
+ */
+ void check_for(socket_t const& socket, short const event);
+
+ /*!
+ * Update the monitored event flags for a given file descriptor.
+ *
+ * \param descriptor the file descriptor to update event flags.
+ * \param event the event flags to monitor on the socket.
+ */
+ void check_for(int const descriptor, short const event);
+
+ /*!
+ * Poll for monitored events.
+ *
+ * By default this method will block forever or until at least one of the monitored
+ * sockets or file descriptors has events.
+ *
+ * If a timeout is set and was reached then this function returns false.
+ *
+ * \param timeout milliseconds to timeout.
+ * \return true if there is an event..
+ */
+ bool poll(long timeout = wait_forever);
+
+ /*!
+ * Get the event flags triggered for a socket.
+ *
+ * \param socket the socket to get triggered event flags for.
+ * \return the event flags.
+ */
+ short events(socket_t const& socket) const;
+
+ /*!
+ * Get the event flags triggered for a file descriptor.
+ *
+ * \param descriptor the file descriptor to get triggered event flags for.
+ * \return the event flags.
+ */
+ short events(int const descriptor) const;
+
+ /*!
+ * Check either a file descriptor or socket for input events.
+ *
+ * Templated helper method that calls through to event and checks for a given flag
+ *
+ * \param watchable either a file descriptor or socket known to the poller.
+ * \return true if there is input.
+ */
+ template<typename Watched>
+ bool has_input(Watched const& watchable) const { return events(watchable) & poll_in; }
+
+ /*!
+ * Check either a file descriptor or socket for output events.
+ *
+ * Templated helper method that calls through to event and checks for a given flag
+ *
+ * \param watchable either a file descriptor or socket known to the poller.
+ * \return true if there is output.
+ */
+ template<typename Watched>
+ bool has_output(Watched const& watchable) const { return events(watchable) & poll_out; }
+
+ /*!
+ * Check a file descriptor.
+ *
+ * Templated helper method that calls through to event and checks for a given flag
+ *
+ * Technically this template works for sockets as well but the error flag is never set for
+ * sockets so I have no idea why someone would call it.
+ *
+ * \param watchable a file descriptor know to the poller.
+ * \return true if there is an error.
+ */
+ template<typename Watched>
+ bool has_error(Watched const& watchable) const { return events(watchable) & poll_error; }
+
+private:
+ std::vector<zmq_pollitem_t> _items;
+ std::unordered_map<void *, size_t> _index;
+ std::unordered_map<int, size_t> _fdindex;
+
+ void reindex(size_t const index);
+};
+
+}
+
+#endif /* ZMQPP_POLLER_HPP_ */
diff --git a/dep/zmqpp/zmqpp/socket.cpp b/dep/zmqpp/zmqpp/socket.cpp
new file mode 100644
index 00000000000..8b4efe4f1d2
--- /dev/null
+++ b/dep/zmqpp/zmqpp/socket.cpp
@@ -0,0 +1,762 @@
+/*
+ * Created on: 9 Aug 2011
+ * Author: Ben Gray (@benjamg)
+ */
+
+#include <array>
+#include <cassert>
+#include <cstring>
+#include <functional>
+
+#include "context.hpp"
+#include "exception.hpp"
+#include "message.hpp"
+#include "socket.hpp"
+
+namespace zmqpp
+{
+
+const int socket::normal = 0;
+#if (ZMQ_VERSION_MAJOR == 2)
+const int socket::dont_wait = ZMQ_NOBLOCK;
+#else
+const int socket::dont_wait = ZMQ_DONTWAIT;
+#endif
+const int socket::send_more = ZMQ_SNDMORE;
+#ifdef ZMQ_EXPERIMENTAL_LABELS
+const int socket::send_label = ZMQ_SNDLABEL;
+#endif
+
+const int max_socket_option_buffer_size = 256;
+const int max_stream_buffer_size = 4096;
+
+socket::socket(const context& context, socket_type const type)
+ : _socket(nullptr)
+ , _type(type)
+ , _recv_buffer()
+{
+ _socket = zmq_socket(context, static_cast<int>(type));
+ if(nullptr == _socket)
+ {
+ throw zmq_internal_exception();
+ }
+
+ zmq_msg_init(&_recv_buffer);
+}
+
+socket::~socket()
+{
+ zmq_msg_close(&_recv_buffer);
+
+ if (nullptr != _socket)
+ {
+
+#ifndef NDEBUG // unused assert variable in release
+ int result = zmq_close(_socket);
+ assert(0 == result);
+#else
+ zmq_close(_socket);
+#endif // NDEBUG
+
+ _socket = nullptr;
+ }
+}
+
+void socket::bind(endpoint_t const& endpoint)
+{
+ int result = zmq_bind(_socket, endpoint.c_str());
+
+ if (0 != result)
+ {
+ throw zmq_internal_exception();
+ }
+}
+
+void socket::unbind(endpoint_t const& endpoint)
+{
+#if (ZMQ_VERSION_MAJOR > 3 || (ZMQ_VERSION_MAJOR == 3 && ZMQ_VERSION_MINOR >= 2))
+ int result = zmq_unbind(_socket, endpoint.c_str());
+
+ if (0 != result)
+ {
+ throw zmq_internal_exception();
+ }
+#endif
+}
+
+void socket::connect(endpoint_t const& endpoint)
+{
+ int result = zmq_connect(_socket, endpoint.c_str());
+
+ if (0 != result)
+ {
+ throw zmq_internal_exception();
+ }
+}
+
+void socket::disconnect(endpoint_t const& endpoint)
+{
+#if (ZMQ_VERSION_MAJOR > 3 || (ZMQ_VERSION_MAJOR == 3 && ZMQ_VERSION_MINOR >= 2))
+ int result = zmq_disconnect(_socket, endpoint.c_str());
+
+ if (0 != result)
+ {
+ throw zmq_internal_exception();
+ }
+#endif
+}
+
+void socket::close()
+{
+ int result = zmq_close(_socket);
+
+ if (0 != result)
+ {
+ throw zmq_internal_exception();
+ }
+
+ _socket = nullptr;
+}
+
+bool socket::send(message& message, bool const dont_block /* = false */)
+{
+ size_t parts = message.parts();
+ if (parts == 0)
+ {
+ throw std::invalid_argument("sending requires messages have at least one part");
+ }
+
+ bool dont_wait = dont_block;
+ for(size_t i = 0; i < parts; ++i)
+ {
+ int flag = socket::normal;
+ if(dont_wait) { flag |= socket::dont_wait; }
+ if(i < (parts - 1)) { flag |= socket::send_more; }
+
+#if (ZMQ_VERSION_MAJOR == 2)
+ int result = zmq_send( _socket, &message.raw_msg(i), flag );
+#elif (ZMQ_VERSION_MAJOR < 3) || ((ZMQ_VERSION_MAJOR == 3) && (ZMQ_VERSION_MINOR < 2))
+ int result = zmq_sendmsg( _socket, &message.raw_msg(i), flag );
+#else
+ int result = zmq_msg_send( &message.raw_msg(i), _socket, flag );
+#endif
+
+ if (result < 0)
+ {
+ // the zmq framework should not block if the first part is accepted
+ // so we should only ever get this error on the first part
+ if((0 == i) && (EAGAIN == zmq_errno()))
+ {
+ return false;
+ }
+
+ if(EINTR == zmq_errno())
+ {
+ if (0 == message.parts())
+ {
+ return false;
+ }
+
+ // If we have an interrupt but it's not on the first part then we
+ // know we can safely send out the rest of the message as we can
+ // enforce that it won't wait on a blocking action
+ dont_wait = true;
+ continue;
+ }
+
+ // sanity checking
+ assert(EAGAIN != zmq_errno());
+
+ throw zmq_internal_exception();
+ }
+
+ message.sent(i);
+ }
+
+ // Leave message reference in a stable state
+ zmqpp::message local;
+ std::swap(local, message);
+ return true;
+}
+
+bool socket::receive(message& message, bool const dont_block /* = false */)
+{
+ if (message.parts() > 0)
+ {
+ // swap and discard old message
+ zmqpp::message local;
+ std::swap(local, message);
+ }
+
+ int flags = (dont_block) ? socket::dont_wait : socket::normal;
+ bool more = true;
+
+ while(more)
+ {
+#if (ZMQ_VERSION_MAJOR == 2)
+ int result = zmq_recv( _socket, &_recv_buffer, flags );
+#elif (ZMQ_VERSION_MAJOR < 3) || ((ZMQ_VERSION_MAJOR == 3) && (ZMQ_VERSION_MINOR < 2))
+ int result = zmq_recvmsg( _socket, &_recv_buffer, flags );
+#else
+ int result = zmq_msg_recv( &_recv_buffer, _socket, flags );
+#endif
+
+ if(result < 0)
+ {
+ if ((0 == message.parts()) && (EAGAIN == zmq_errno()))
+ {
+ return false;
+ }
+
+ if(EINTR == zmq_errno())
+ {
+ if (0 == message.parts())
+ {
+ return false;
+ }
+
+ // If we have an interrupt but it's not on the first part then we
+ // know we can safely pull out the rest of the message as it will
+ // not be blocking
+ continue;
+ }
+
+ assert(EAGAIN != zmq_errno());
+
+ throw zmq_internal_exception();
+ }
+
+ zmq_msg_t& dest = message.raw_new_msg();
+ zmq_msg_move(&dest, &_recv_buffer);
+
+ get(socket_option::receive_more, more);
+ }
+
+ return true;
+}
+
+
+bool socket::send(std::string const& string, int const flags /* = NORMAL */)
+{
+ return send_raw(string.data(), string.size(), flags);
+}
+
+bool socket::receive(std::string& string, int const flags /* = NORMAL */)
+{
+#if (ZMQ_VERSION_MAJOR == 2)
+ int result = zmq_recv( _socket, &_recv_buffer, flags );
+#elif (ZMQ_VERSION_MAJOR < 3) || ((ZMQ_VERSION_MAJOR == 3) && (ZMQ_VERSION_MINOR < 2))
+ int result = zmq_recvmsg( _socket, &_recv_buffer, flags );
+#else
+ int result = zmq_msg_recv( &_recv_buffer, _socket, flags );
+#endif
+
+ if(result >= 0)
+ {
+ string.reserve(zmq_msg_size(&_recv_buffer));
+ string.assign(static_cast<char*>(zmq_msg_data(&_recv_buffer)), zmq_msg_size(&_recv_buffer));
+
+ return true;
+ }
+
+ if (EAGAIN == zmq_errno() || EINTR == zmq_errno())
+ {
+ return false;
+ }
+
+ throw zmq_internal_exception();
+}
+
+
+bool socket::send_raw(char const* buffer, int const length, int const flags /* = NORMAL */)
+{
+#if (ZMQ_VERSION_MAJOR == 2)
+ zmq_msg_t msg;
+ int result = zmq_msg_init_size(&msg, length);
+ if (result != 0)
+ {
+ zmq_internal_exception();
+ }
+
+ memcpy(zmq_msg_data(&msg), buffer, length);
+ result = zmq_send(_socket, &msg, flags);
+#else
+ int result = zmq_send(_socket, buffer, length, flags);
+#endif
+ if(result >= 0)
+ {
+ return true;
+ }
+
+#if (ZMQ_VERSION_MAJOR == 2)
+ // only actually need to close this on error
+ zmq_msg_close(&msg);
+#endif
+
+ if (EAGAIN == zmq_errno() || EINTR == zmq_errno())
+ {
+ return false;
+ }
+
+ throw zmq_internal_exception();
+}
+
+bool socket::receive_raw(char* buffer, int& length, int const flags /* = NORMAL */)
+{
+#if (ZMQ_VERSION_MAJOR == 2)
+ int result = zmq_recv( _socket, &_recv_buffer, flags );
+#elif (ZMQ_VERSION_MAJOR < 3) || ((ZMQ_VERSION_MAJOR == 3) && (ZMQ_VERSION_MINOR < 2))
+ int result = zmq_recvmsg( _socket, &_recv_buffer, flags );
+#else
+ int result = zmq_msg_recv( &_recv_buffer, _socket, flags );
+#endif
+
+ if(result >= 0)
+ {
+ length = zmq_msg_size(&_recv_buffer);
+ memcpy(buffer, zmq_msg_data(&_recv_buffer), length);
+
+ return true;
+ }
+
+ if (EAGAIN == zmq_errno() || EINTR == zmq_errno())
+ {
+ return false;
+ }
+
+ throw zmq_internal_exception();
+}
+
+
+// Helper
+void socket::subscribe(std::string const& topic)
+{
+ set(socket_option::subscribe, topic);
+}
+
+void socket::unsubscribe(std::string const& topic)
+{
+ set(socket_option::unsubscribe, topic);
+}
+
+bool socket::has_more_parts() const
+{
+ return get<bool>(socket_option::receive_more);
+}
+
+
+// Set socket options for different types of option
+void socket::set(socket_option const option, int const value)
+{
+ switch(option)
+ {
+ // unsigned 64bit Integers
+#if (ZMQ_VERSION_MAJOR == 2)
+ case socket_option::high_water_mark:
+ case socket_option::send_buffer_size:
+ case socket_option::receive_buffer_size:
+#endif
+ case socket_option::affinity:
+ if (value < 0) { throw exception("attempting to set an unsigned 64 bit integer option with a negative integer"); }
+ set(option, static_cast<uint64_t>(value));
+ break;
+
+ // 64bit Integers
+#if (ZMQ_VERSION_MAJOR == 2)
+ case socket_option::rate:
+ case socket_option::recovery_interval:
+ case socket_option::recovery_interval_seconds:
+ case socket_option::swap_size:
+#else
+ case socket_option::max_messsage_size:
+#endif
+ set(option, static_cast<int64_t>(value));
+ break;
+
+ // Boolean
+#if (ZMQ_VERSION_MAJOR > 3) || ((ZMQ_VERSION_MAJOR == 3) && (ZMQ_VERSION_MINOR >= 1))
+ case socket_option::ipv4_only:
+#endif
+#if (ZMQ_VERSION_MAJOR == 2)
+ case socket_option::multicast_loopback:
+#endif
+#if (ZMQ_VERSION_MAJOR > 3) || ((ZMQ_VERSION_MAJOR == 3) && (ZMQ_VERSION_MINOR >= 2))
+#if (ZMQ_VERSION_MINOR == 2)
+ case socket_option::delay_attach_on_connect:
+#else
+ case socket_option::immediate:
+#endif
+ case socket_option::router_mandatory:
+ case socket_option::xpub_verbose:
+#endif
+ if (value == 0) { set(option, false); }
+ else if (value == 1) { set(option, true); }
+ else { throw exception("attempting to set a boolean option with a non 0 or 1 integer"); }
+ break;
+
+ // Default or Boolean
+#if (ZMQ_VERSION_MAJOR > 3) || ((ZMQ_VERSION_MAJOR == 3) && (ZMQ_VERSION_MINOR >= 2))
+ case socket_option::tcp_keepalive:
+ if (value < -1 || value > 1) { throw exception("attempting to set a default or boolean option with a non -1, 0 or 1 integer"); }
+ if (0 != zmq_setsockopt(_socket, static_cast<int>(option), &value, sizeof(value)))
+ {
+ throw zmq_internal_exception();
+ }
+ break;
+#endif
+
+ // Integers that require +ve numbers
+#if (ZMQ_VERSION_MAJOR == 2)
+ case socket_option::reconnect_interval_max:
+#else
+ case socket_option::reconnect_interval_max:
+ case socket_option::send_buffer_size:
+ case socket_option::recovery_interval:
+ case socket_option::receive_buffer_size:
+ case socket_option::send_high_water_mark:
+ case socket_option::receive_high_water_mark:
+ case socket_option::multicast_hops:
+ case socket_option::rate:
+#endif
+ case socket_option::backlog:
+ if (value < 0) { throw exception("attempting to set a positive only integer option with a negative integer"); }
+ // Integers
+ case socket_option::reconnect_interval:
+ case socket_option::linger:
+ case socket_option::receive_timeout:
+ case socket_option::send_timeout:
+#if (ZMQ_VERSION_MAJOR > 3) || ((ZMQ_VERSION_MAJOR == 3) && (ZMQ_VERSION_MINOR >= 2))
+ case socket_option::tcp_keepalive_idle:
+ case socket_option::tcp_keepalive_count:
+ case socket_option::tcp_keepalive_interval:
+#endif
+ if (0 != zmq_setsockopt(_socket, static_cast<int>(option), &value, sizeof(value)))
+ {
+ throw zmq_internal_exception();
+ }
+ break;
+ default:
+ throw exception("attempting to set a non signed integer option with a signed integer value");
+ }
+}
+
+void socket::set(socket_option const option, bool const value)
+{
+ switch(option)
+ {
+#if (ZMQ_VERSION_MAJOR == 2)
+ case socket_option::multicast_loopback:
+#endif
+#if (ZMQ_VERSION_MAJOR > 3) || ((ZMQ_VERSION_MAJOR == 3) && (ZMQ_VERSION_MINOR >= 1))
+ case socket_option::ipv4_only:
+#endif
+#if (ZMQ_VERSION_MAJOR > 3) || ((ZMQ_VERSION_MAJOR == 3) && (ZMQ_VERSION_MINOR >= 2))
+#if (ZMQ_VERSION_MINOR == 2)
+ case socket_option::delay_attach_on_connect:
+#else
+ case socket_option::immediate:
+#endif
+ case socket_option::router_mandatory:
+ case socket_option::xpub_verbose:
+#endif
+ {
+ int ivalue = value ? 1 : 0;
+ if (0 != zmq_setsockopt(_socket, static_cast<int>(option), &ivalue, sizeof(ivalue)))
+ {
+ throw zmq_internal_exception();
+ }
+ break;
+ }
+ default:
+ throw exception("attempting to set a non boolean option with a boolean value");
+ }
+}
+
+void socket::set(socket_option const option, uint64_t const value)
+{
+ switch(option)
+ {
+#if (ZMQ_VERSION_MAJOR == 2)
+ // unsigned 64bit Integers
+ case socket_option::high_water_mark:
+ case socket_option::send_buffer_size:
+ case socket_option::receive_buffer_size:
+#endif
+ case socket_option::affinity:
+ if (0 != zmq_setsockopt(_socket, static_cast<int>(option), &value, sizeof(value)))
+ {
+ throw zmq_internal_exception();
+ }
+ break;
+ default:
+ throw exception("attempting to set a non unsigned 64 bit integer option with a unsigned 64 bit integer value");
+ }
+}
+
+void socket::set(socket_option const option, int64_t const value)
+{
+ switch(option)
+ {
+#if (ZMQ_VERSION_MAJOR == 2)
+ case socket_option::rate:
+ case socket_option::recovery_interval:
+ case socket_option::recovery_interval_seconds:
+ case socket_option::swap_size:
+#else
+ case socket_option::max_messsage_size:
+#endif
+ // zmq only allowed +ve int64_t options
+ if (value < 0) { throw exception("attempting to set a positive only 64 bit integer option with a negative 64bit integer"); }
+ if (0 != zmq_setsockopt(_socket, static_cast<int>(option), &value, sizeof(value)))
+ {
+ throw zmq_internal_exception();
+ }
+ break;
+ default:
+ throw exception("attempting to set a non 64 bit integer option with a 64 bit integer value");
+ }
+}
+
+void socket::set(socket_option const option, char const* value, size_t const length)
+{
+ switch(option)
+ {
+ case socket_option::identity:
+ case socket_option::subscribe:
+ case socket_option::unsubscribe:
+#if (ZMQ_VERSION_MAJOR > 3) || ((ZMQ_VERSION_MAJOR == 3) && (ZMQ_VERSION_MINOR >= 2))
+ case socket_option::tcp_accept_filter:
+#endif
+ if (0 != zmq_setsockopt(_socket, static_cast<int>(option), value, length))
+ {
+ throw zmq_internal_exception();
+ }
+ break;
+ default:
+ throw exception("attempting to set a non string option with a string value");
+ }
+}
+
+// Get socket options, multiple versions for easy of use
+void socket::get(socket_option const option, int& value) const
+{
+ size_t value_size = sizeof(int);
+
+ switch(option)
+ {
+#if (ZMQ_VERSION_MAJOR == 2)
+ case socket_option::receive_more:
+ case socket_option::multicast_loopback:
+ value = static_cast<int>(get<int64_t>(option));
+ break;
+#endif
+ case socket_option::type:
+ case socket_option::linger:
+ case socket_option::backlog:
+ case socket_option::reconnect_interval:
+ case socket_option::reconnect_interval_max:
+ case socket_option::receive_timeout:
+ case socket_option::send_timeout:
+ case socket_option::file_descriptor:
+ case socket_option::events:
+#if (ZMQ_VERSION_MAJOR > 2)
+ case socket_option::receive_more:
+ case socket_option::send_buffer_size:
+ case socket_option::receive_buffer_size:
+ case socket_option::rate:
+ case socket_option::recovery_interval:
+ case socket_option::send_high_water_mark:
+ case socket_option::receive_high_water_mark:
+ case socket_option::multicast_hops:
+#endif
+#if (ZMQ_VERSION_MAJOR > 3) || ((ZMQ_VERSION_MAJOR == 3) && (ZMQ_VERSION_MINOR >= 1))
+ case socket_option::ipv4_only:
+#endif
+#if (ZMQ_VERSION_MAJOR > 3) || ((ZMQ_VERSION_MAJOR == 3) && (ZMQ_VERSION_MINOR >= 2))
+#if (ZMQ_VERSION_MINOR == 2)
+ case socket_option::delay_attach_on_connect:
+#else
+ case socket_option::immediate:
+#endif
+ case socket_option::tcp_keepalive:
+ case socket_option::tcp_keepalive_idle:
+ case socket_option::tcp_keepalive_count:
+ case socket_option::tcp_keepalive_interval:
+#endif
+#ifdef ZMQ_EXPERIMENTAL_LABELS
+ case socket_option::receive_label:
+#endif
+ if (0 != zmq_getsockopt(_socket, static_cast<int>(option), &value, &value_size))
+ {
+ throw zmq_internal_exception();
+ }
+
+ // sanity check
+ assert(value_size <= sizeof(int));
+ break;
+ default:
+ throw exception("attempting to get a non integer option with an integer value");
+ }
+}
+
+void socket::get(socket_option const option, bool& value) const
+{
+#if (ZMQ_VERSION_MAJOR == 2)
+ int64_t int_value = 0;
+ size_t value_size = sizeof(int64_t);
+#else
+ int int_value = 0;
+ size_t value_size = sizeof(int);
+#endif
+
+ switch(option)
+ {
+ case socket_option::receive_more:
+#if (ZMQ_VERSION_MAJOR == 2)
+ case socket_option::multicast_loopback:
+#endif
+#if (ZMQ_VERSION_MAJOR > 3) || ((ZMQ_VERSION_MAJOR == 3) && (ZMQ_VERSION_MINOR >= 1))
+ case socket_option::ipv4_only:
+#endif
+#if (ZMQ_VERSION_MAJOR > 3) || ((ZMQ_VERSION_MAJOR == 3) && (ZMQ_VERSION_MINOR >= 2))
+#if (ZMQ_VERSION_MINOR == 2)
+ case socket_option::delay_attach_on_connect:
+#else
+ case socket_option::immediate:
+#endif
+#endif
+#ifdef ZMQ_EXPERIMENTAL_LABELS
+ case socket_option::receive_label:
+#endif
+ if (0 != zmq_getsockopt(_socket, static_cast<int>(option), &int_value, &value_size))
+ {
+ throw zmq_internal_exception();
+ }
+
+ value = (int_value == 1) ? true : false;
+ break;
+ default:
+ throw exception("attempting to get a non boolean option with a boolean value");
+ }
+}
+
+void socket::get(socket_option const option, uint64_t& value) const
+{
+ size_t value_size = sizeof(uint64_t);
+
+ switch(option)
+ {
+#if (ZMQ_VERSION_MAJOR == 2)
+ case socket_option::high_water_mark:
+ case socket_option::send_buffer_size:
+ case socket_option::receive_buffer_size:
+#endif
+ case socket_option::affinity:
+ if(0 != zmq_getsockopt(_socket, static_cast<int>(option), &value, &value_size))
+ {
+ throw zmq_internal_exception();
+ }
+ break;
+ default:
+ throw exception("attempting to get a non unsigned 64 bit integer option with an unsigned 64 bit integer value");
+ }
+}
+
+void socket::get(socket_option const option, int64_t& value) const
+{
+ size_t value_size = sizeof(int64_t);
+
+ switch(option)
+ {
+#if (ZMQ_VERSION_MAJOR == 2)
+ case socket_option::rate:
+ case socket_option::recovery_interval:
+ case socket_option::recovery_interval_seconds:
+ case socket_option::swap_size:
+ case socket_option::receive_more:
+ case socket_option::multicast_loopback:
+#else
+ case socket_option::max_messsage_size:
+#endif
+ if(0 != zmq_getsockopt(_socket, static_cast<int>(option), &value, &value_size))
+ {
+ throw zmq_internal_exception();
+ }
+ break;
+ default:
+ throw exception("attempting to get a non 64 bit integer option with an 64 bit integer value");
+ }
+}
+
+void socket::get(socket_option const option, std::string& value) const
+{
+ static std::array<char, max_socket_option_buffer_size> buffer;
+ size_t size = max_socket_option_buffer_size;
+
+ switch(option)
+ {
+ case socket_option::identity:
+#if (ZMQ_VERSION_MAJOR > 3) || ((ZMQ_VERSION_MAJOR == 3) && (ZMQ_VERSION_MINOR >= 2))
+ case socket_option::last_endpoint:
+#endif
+ if(0 != zmq_getsockopt(_socket, static_cast<int>(option), buffer.data(), &size))
+ {
+ throw zmq_internal_exception();
+ }
+
+ value.assign(buffer.data(), size);
+ break;
+ default:
+ throw exception("attempting to get a non string option with a string value");
+ }
+}
+
+socket::socket(socket&& source) NOEXCEPT
+ : _socket(source._socket)
+ , _type(source._type)
+ , _recv_buffer()
+{
+ // we steal the zmq_msg_t from the valid socket, we only init our own because it's cheap
+ // and zmq_msg_move does a valid check
+ zmq_msg_init(&_recv_buffer);
+ zmq_msg_move(&_recv_buffer, &source._recv_buffer);
+
+ // Clean up source a little, we will handle the deinit, it doesn't need to
+ source._socket = nullptr;
+}
+
+socket& socket::operator=(socket&& source) NOEXCEPT
+{
+ std::swap(_socket, source._socket);
+
+ _type = source._type; // just clone?
+
+ // we steal the zmq_msg_t from the valid socket, we only init our own because it's cheap
+ // and zmq_msg_move does a valid check
+ zmq_msg_init(&_recv_buffer);
+ zmq_msg_move(&_recv_buffer, &source._recv_buffer);
+
+ return *this;
+}
+
+
+socket::operator bool() const
+{
+ return nullptr != _socket;
+}
+
+
+socket::operator void*() const
+{
+ return _socket;
+}
+
+void socket::track_message(message const& /* message */, uint32_t const parts, bool& should_delete)
+{
+ if (parts == 0)
+ {
+ should_delete = true;
+ }
+}
+
+}
diff --git a/dep/zmqpp/zmqpp/socket.hpp b/dep/zmqpp/zmqpp/socket.hpp
new file mode 100644
index 00000000000..279bf801f77
--- /dev/null
+++ b/dep/zmqpp/zmqpp/socket.hpp
@@ -0,0 +1,500 @@
+/**
+ * \file
+ *
+ * \date 9 Aug 2011
+ * \author Ben Gray (\@benjamg)
+ */
+
+#ifndef ZMQPP_SOCKET_HPP_
+#define ZMQPP_SOCKET_HPP_
+
+#include <cstring>
+#include <string>
+#include <list>
+
+#include <zmq.h>
+
+#include "compatibility.hpp"
+
+#include "socket_types.hpp"
+#include "socket_options.hpp"
+
+namespace zmqpp
+{
+
+class context;
+class message;
+
+typedef std::string endpoint_t;
+typedef context context_t;
+typedef message message_t;
+
+/*!
+ * The socket class represents the zmq sockets.
+ *
+ * A socket can be bound and/or connected to as many endpoints as required
+ * with the sole exception of a ::pair socket.
+ *
+ * The routing is handled by zmq based on the type set.
+ *
+ * The bound side of an inproc connection must occur first and inproc can only
+ * connect to other inproc sockets of the same context.
+ *
+ * This class is c++0x move supporting and cannot be copied.
+ */
+class socket
+{
+public:
+ static const int normal; /*!< /brief default send type, no flags set */
+#if (ZMQ_VERSION_MAJOR == 2)
+ static const int dont_wait; /*!< /brief don't block if sending is not currently possible */
+#else
+ static const int dont_wait; /*!< /brief don't block if sending is not currently possible */
+#endif
+ static const int send_more; /*!< /brief more parts will follow this one */
+#ifdef ZMQ_EXPERIMENTAL_LABELS
+ static const int send_label; /*!< /brief this message part is an internal zmq label */
+#endif
+
+ /*!
+ * Create a socket for a given type.
+ *
+ * \param context the zmq context under which the socket will live
+ * \param type a valid ::socket_type for the socket
+ */
+ socket(context_t const& context, socket_type const type);
+
+ /*!
+ * This will close any socket still open before returning
+ */
+ ~socket();
+
+ /*!
+ * Get the type of the socket, this works on zmqpp types and not the zmq internal types.
+ * Use the socket::get method if you wish to intergoate the zmq internal ones.
+ *
+ * \return the type of the socket
+ */
+ socket_type type() const { return _type; }
+
+ /*!
+ * Asynchronously binds to an endpoint.
+ *
+ * \param endpoint the zmq endpoint to bind to
+ */
+ void bind(endpoint_t const& endpoint);
+
+ /*!
+ * Unbinds from a previously bound endpoint.
+ *
+ * \param endpoint the zmq endpoint to bind to
+ */
+ void unbind(endpoint_t const& endpoint);
+
+ /*!
+ * Asynchronously connects to an endpoint.
+ * If the endpoint is not inproc then zmq will happily keep trying
+ * to connect until there is something there.
+ *
+ * Inproc sockets must have a valid target already bound before connection
+ * will work.
+ *
+ * \param endpoint the zmq endpoint to connect to
+ */
+ void connect(endpoint_t const& endpoint);
+
+ /*!
+ * Asynchronously connects to multiple endpoints.
+ * If the endpoint is not inproc then zmq will happily keep trying
+ * to connect until there is something there.
+ *
+ * Inproc sockets must have a valid target already bound before connection
+ * will work.
+ *
+ * This is a helper function that wraps the single item connect in a loop
+ *
+ * \param connections_begin the starting iterator for zmq endpoints.
+ * \param connections_end the final iterator for zmq endpoints.
+ */
+ template<typename InputIterator>
+ void connect(InputIterator const& connections_begin, InputIterator const& connections_end)
+ {
+ for(InputIterator it = connections_begin; it != connections_end; ++it)
+ {
+ connect(*it);
+ }
+ }
+
+
+ /*!
+ * Disconnects a previously connected endpoint.
+ *
+ * \param endpoint the zmq endpoint to disconnect from
+ */
+ void disconnect(endpoint_t const& endpoint);
+
+ /*!
+ * Disconnects from multiple previously connected endpoints.
+ *
+ * This is a helper function that wraps the single item disconnect in a loop
+ *
+ * \param disconnections_begin the starting iterator for zmq endpoints.
+ * \param disconnections_end the final iterator for zmq endpoints.
+ */
+ template<typename InputIterator>
+ void disconnect(InputIterator const& disconnections_begin, InputIterator const& disconnections_end)
+ {
+ for(InputIterator it = disconnections_begin; it != disconnections_end; ++it)
+ {
+ disconnect(*it);
+ }
+ }
+
+ /*!
+ * Closes the internal zmq socket and marks this instance
+ * as invalid.
+ */
+ void close();
+
+ /*!
+ * Sends the message over the connection, this may be a multipart message.
+ *
+ * If dont_block is true and we are unable to add a new message then this
+ * function will return false.
+ *
+ * \param message message to send
+ * \param dont_block boolean to dictate if we wait while sending.
+ * \return true if message sent, false if it would have blocked
+ */
+ bool send(message_t& message, bool const dont_block = false);
+
+ /*!
+ * Gets a message from the connection, this may be a multipart message.
+ *
+ * If dont_block is true and we are unable to get a message then this
+ * function will return false.
+ *
+ * \param message reference to fill with received data
+ * \param dont_block boolean to dictate if we wait for data.
+ * \return true if message sent, false if it would have blocked
+ */
+ bool receive(message_t& message, bool const dont_block = false);
+
+ /*!
+ * Sends the byte data held by the string as the next message part.
+ *
+ * If the socket::DONT_WAIT flag and we are unable to add a new message to
+ * socket then this function will return false.
+ *
+ * \param string message part to send
+ * \param flags message send flags
+ * \return true if message part sent, false if it would have blocked
+ */
+ bool send(std::string const& string, int const flags = normal);
+
+ /*!
+ * If there is a message ready then get the next part as a string
+ *
+ * If the socket::DONT_WAIT flag and there is no message ready to receive
+ * then this function will return false.
+ *
+ * \param string message part to receive into
+ * \param flags message receive flags
+ * \return true if message part received, false if it would have blocked
+ */
+ bool receive(std::string& string, int const flags = normal);
+
+ /*!
+ * Sends the byte data pointed to by buffer as the next part of the message.
+ *
+ * If the socket::DONT_WAIT flag and we are unable to add a new message to
+ * socket then this function will return false.
+ *
+ * \param buffer byte buffer pointer to start writing from
+ * \param length max length of the buffer
+ * \param flags message send flags
+ * \return true if message part sent, false if it would have blocked
+ */
+ bool send_raw(char const* buffer, int const length, int const flags = normal);
+
+ /*!
+ * \warning If the buffer is not large enough for the message part then the
+ * data will be truncated. The rest of the part is lost forever.
+ *
+ * If there is a message ready then get the next part of it as a raw
+ * byte buffer.
+ *
+ * If the socket::DONT_WAIT flag and there is no message ready to receive
+ * then this function will return false.
+ *
+ * \param buffer byte buffer pointer to start writing to
+ * \param length max length of the buffer
+ * \param flags message receive flags
+ * \return true if message part received, false if it would have blocked
+ */
+ bool receive_raw(char* buffer, int& length, int const flags = normal);
+
+ /*!
+ *
+ * Subscribe to a topic
+ *
+ * Helper function that is equivalent of calling
+ * \code
+ * set(zmqpp::socket_option::subscribe, topic);
+ * \endcode
+ *
+ * This method is only useful for subscribe type sockets.
+ *
+ * \param topic the topic to subscribe to.
+ */
+ void subscribe(std::string const& topic);
+
+ /*!
+ * Subscribe to a topic
+ *
+ * Helper function that is equivalent of a loop calling
+ * \code
+ * set(zmqpp::socket_option::subscribe, topic);
+ * \endcode
+ *
+ * This method is only useful for subscribe type sockets.
+ *
+ * Generally this will be used with stl collections using begin() and
+ * end() functions to get the iterators.
+ * For this reason the end loop runs until the end iterator, not inclusive
+ * of it.
+ *
+ * \param topics_begin the starting iterator for topics.
+ * \param topics_end the final iterator for topics.
+ */
+ template<typename InputIterator>
+ void subscribe(InputIterator const& topics_begin, InputIterator const& topics_end)
+ {
+ for(InputIterator it = topics_begin; it != topics_end; ++it)
+ {
+ subscribe(*it);
+ }
+ }
+
+ /*!
+ * Unsubscribe from a topic
+ *
+ * Helper function that is equivalent of calling
+ * \code
+ * set(zmqpp::socket_option::unsubscribe, topic);
+ * \endcode
+ *
+ * This method is only useful for subscribe type sockets.
+ *
+ * \param topic the topic to unsubscribe from.
+ */
+ void unsubscribe(std::string const& topic);
+
+ /*!
+ * Unsubscribe from a topic
+ *
+ * Helper function that is equivalent of a loop calling
+ * \code
+ * set(zmqpp::socket_option::unsubscribe, topic);
+ * \endcode
+ *
+ * This method is only useful for subscribe type sockets.
+ *
+ * Generally this will be used with stl collections using begin() and
+ * end() functions to get the iterators.
+ * For this reason the end loop runs until the end iterator, not inclusive
+ * of it.
+ *
+ * \param topics_begin the starting iterator for topics.
+ * \param topics_end the final iterator for topics.
+ */
+ template<typename InputIterator>
+ void unsubscribe(InputIterator const& topics_begin, InputIterator const& topics_end)
+ {
+ for(InputIterator it = topics_begin; it != topics_end; ++it)
+ {
+ unsubscribe(*it);
+ }
+ }
+
+ /*!
+ * If the last receive part call to the socket resulted
+ * in a label or a non-terminating part of a multipart
+ * message this will return true.
+ *
+ * \return true if there are more parts
+ */
+ bool has_more_parts() const;
+
+ /*!
+ * Set the value of an option in the underlaying zmq socket.
+ *
+ * \param option a valid ::socket_option
+ * \param value to set the option to
+ */
+ void set(socket_option const option, int const value);
+
+ /*!
+ * Set the value of an option in the underlaying zmq socket.
+ *
+ * \since 2.0.0 (built against 0mq version 3.1.x or later)
+ *
+ * \param option a valid ::socket_option
+ * \param value to set the option to
+ */
+ void set(socket_option const option, bool const value);
+
+ /*!
+ * Set the value of an option in the underlaying zmq socket.
+ *
+ * \param option a valid ::socket_option
+ * \param value to set the option to
+ */
+ void set(socket_option const option, uint64_t const value);
+
+ /*!
+ * Set the value of an option in the underlaying zmq socket.
+ *
+ * \param option a valid ::socket_option
+ * \param value to set the option to
+ */
+ void set(socket_option const option, int64_t const value);
+
+ /*!
+ * Set the value of an option in the underlaying zmq socket.
+ *
+ * \param option a valid ::socket_option
+ * \param pointer to raw byte value to set the option to
+ * \param length the size of the raw byte value
+ */
+ void set(socket_option const option, char const* value, size_t const length);
+
+ /*!
+ * Set the value of an option in the underlaying zmq socket.
+ *
+ * \param option a valid ::socket_option
+ * \param pointer to null terminated cstring value to set the option to
+ */
+ inline void set(socket_option const option, char const* value) { set(option, value, strlen(value)); }
+
+ /*!
+ * Set the value of an option in the underlaying zmq socket.
+ *
+ * \param option a valid ::socket_option
+ * \param value to set the option to
+ */
+ inline void set(socket_option const option, std::string const value) { set(option, value.c_str(), value.length()); }
+
+ /*!
+ * Get a socket option from the underlaying zmq socket.
+ *
+ * \param option a valid ::socket_option
+ * \param value referenced int to return value in
+ */
+ void get(socket_option const option, int& value) const;
+
+ /*!
+ * Get a socket option from the underlaying zmq socket.
+ *
+ * \param option a valid ::socket_option
+ * \param value referenced bool to return value in
+ */
+ void get(socket_option const option, bool& value) const;
+
+ /*!
+ * Get a socket option from the underlaying zmq socket.
+ *
+ * \param option a valid ::socket_option
+ * \param value referenced uint64_t to return value in
+ */
+ void get(socket_option const option, uint64_t& value) const;
+
+ /*!
+ * Get a socket option from the underlaying zmq socket.
+ *
+ * \param option a valid ::socket_option
+ * \param value referenced uint64_t to return value in
+ */
+ void get(socket_option const option, int64_t& value) const;
+
+ /*!
+ * Get a socket option from the underlaying zmq socket.
+ *
+ * \param option a valid ::socket_option
+ * \param value referenced std::string to return value in
+ */
+ void get(socket_option const option, std::string& value) const;
+
+ /*!
+ * For those that don't want to get into a referenced value this templated method
+ * will return the value instead.
+ *
+ * \param option a valid ::socket_option
+ * \return socket option value
+ */
+ template<typename Type>
+ Type get(socket_option const option) const
+ {
+ Type value = Type();
+ get(option, value);
+ return value;
+ }
+
+ /*!
+ * Move constructor
+ *
+ * Moves the internals of source to this object, there is no guarantee
+ * that source will be left in a valid state.
+ *
+ * This constructor is noexcept and so will not throw exceptions
+ *
+ * \param source target socket to steal internals from
+ */
+ socket(socket&& source) NOEXCEPT;
+
+ /*!
+ * Move operator
+ *
+ * Moves the internals of source to this object, there is no guarantee
+ * that source will be left in a valid state.
+ *
+ * This function is noexcept and so will not throw exceptions
+ *
+ * \param source target socket to steal internals from
+ * \return socket reference to this
+ */
+ socket& operator=(socket&& source) NOEXCEPT;
+
+ /*!
+ * Check the socket is still valid
+ *
+ * This tests the internal state of the socket.
+ * If creation failed for some reason or if the move functions were used
+ * to move the socket internals to another instance this will return false.
+ *
+ * \return true if the socket is valid
+ */
+ operator bool() const;
+
+ /*!
+ * Access to the raw 0mq context
+ *
+ * \return void pointer to the underlying 0mq socket
+ */
+ operator void*() const;
+
+private:
+ void* _socket;
+ socket_type _type;
+ zmq_msg_t _recv_buffer;
+
+ // No copy
+ socket(socket const&) NOEXCEPT ZMQPP_EXPLICITLY_DELETED;
+ socket& operator=(socket const&) NOEXCEPT ZMQPP_EXPLICITLY_DELETED;
+
+ void track_message(message_t const&, uint32_t const, bool&);
+};
+
+}
+
+#endif /* ZMQPP_SOCKET_HPP_ */
diff --git a/dep/zmqpp/zmqpp/socket_options.hpp b/dep/zmqpp/zmqpp/socket_options.hpp
new file mode 100644
index 00000000000..c5c8586cbc7
--- /dev/null
+++ b/dep/zmqpp/zmqpp/socket_options.hpp
@@ -0,0 +1,80 @@
+/**
+ * \file
+ *
+ * \date 23 Sep 2011
+ * \author Ben Gray (\@benjamg)
+ */
+
+#ifndef ZMQPP_SOCKET_OPTIONS_HPP_
+#define ZMQPP_SOCKET_OPTIONS_HPP_
+
+namespace zmqpp
+{
+
+/** \todo Expand the information on the options to make it actually useful. */
+/*!
+ * \brief possible Socket options in zmq
+ */
+
+enum class socket_option {
+ affinity = ZMQ_AFFINITY, /*!< I/O thread affinity */
+ identity = ZMQ_IDENTITY, /*!< Socket identity */
+ subscribe = ZMQ_SUBSCRIBE, /*!< Add topic subscription - set only */
+ unsubscribe = ZMQ_UNSUBSCRIBE, /*!< Remove topic subscription - set only */
+ rate = ZMQ_RATE, /*!< Multicast data rate */
+ send_buffer_size = ZMQ_SNDBUF, /*!< Kernel transmission buffer size */
+ receive_buffer_size = ZMQ_RCVBUF, /*!< Kernel receive buffer size */
+ receive_more = ZMQ_RCVMORE, /*!< Can receive more parts - get only */
+ file_descriptor = ZMQ_FD, /*!< Socket file descriptor - get only */
+ events = ZMQ_EVENTS, /*!< Socket event flags - get only */
+ type = ZMQ_TYPE, /*!< Socket type - get only */
+ linger = ZMQ_LINGER, /*!< Socket linger timeout */
+ backlog = ZMQ_BACKLOG, /*!< Maximum length of outstanding connections - get only */
+#if (ZMQ_VERSION_MAJOR == 2)
+ // Note that this is inverse of the zmq names for version 2.x
+ recovery_interval_seconds = ZMQ_RECOVERY_IVL, /*!< Multicast recovery interval in seconds */
+ recovery_interval = ZMQ_RECOVERY_IVL_MSEC, /*!< Multicast recovery interval in milliseconds */
+#else
+ recovery_interval = ZMQ_RECOVERY_IVL, /*!< Multicast recovery interval in milliseconds */
+#endif
+ reconnect_interval = ZMQ_RECONNECT_IVL, /*!< Reconnection interval */
+ reconnect_interval_max = ZMQ_RECONNECT_IVL_MAX, /*!< Maximum reconnection interval */
+ receive_timeout = ZMQ_RCVTIMEO, /*!< Maximum inbound block timeout */
+ send_timeout = ZMQ_SNDTIMEO, /*!< Maximum outbound block timeout */
+#if (ZMQ_VERSION_MAJOR == 2)
+ high_water_mark = ZMQ_HWM, /*!< High-water mark for all messages */
+ swap_size = ZMQ_SWAP, /*!< Maximum socket swap size in bytes */
+ multicast_loopback = ZMQ_MCAST_LOOP, /*!< Allow multicast packet loopback */
+#else
+ max_messsage_size = ZMQ_MAXMSGSIZE, /*!< Maximum inbound message size */
+ send_high_water_mark = ZMQ_SNDHWM, /*!< High-water mark for outbound messages */
+ receive_high_water_mark = ZMQ_RCVHWM, /*!< High-water mark for inbound messages */
+ multicast_hops = ZMQ_MULTICAST_HOPS, /*!< Maximum number of multicast hops */
+#endif
+#if (ZMQ_VERSION_MAJOR > 3) || ((ZMQ_VERSION_MAJOR == 3) && (ZMQ_VERSION_MINOR >= 1))
+ ipv4_only = ZMQ_IPV4ONLY,
+#endif
+#if (ZMQ_VERSION_MAJOR > 3) || ((ZMQ_VERSION_MAJOR == 3) && (ZMQ_VERSION_MINOR >= 2))
+#if (ZMQ_VERSION_MINOR == 2)
+ delay_attach_on_connect = ZMQ_DELAY_ATTACH_ON_CONNECT, /*!< Delay buffer attachment until connect complete */
+#else
+ // ZMQ_DELAY_ATTACH_ON_CONNECT is renamed in ZeroMQ starting 3.3.x
+ immediate = ZMQ_IMMEDIATE, /*!< Block message sending until connect complete */
+#endif
+ last_endpoint = ZMQ_LAST_ENDPOINT, /*!< Last bound endpoint - get only */
+ router_mandatory = ZMQ_ROUTER_MANDATORY, /*!< Require routable messages - set only */
+ xpub_verbose = ZMQ_XPUB_VERBOSE, /*!< Pass on existing subscriptions - set only */
+ tcp_keepalive = ZMQ_TCP_KEEPALIVE, /*!< Enable TCP keepalives */
+ tcp_keepalive_idle = ZMQ_TCP_KEEPALIVE_IDLE, /*!< TCP keepalive idle count (generally retry count) */
+ tcp_keepalive_count = ZMQ_TCP_KEEPALIVE_CNT, /*!< TCP keepalive retry count */
+ tcp_keepalive_interval = ZMQ_TCP_KEEPALIVE_INTVL, /*!< TCP keepalive interval */
+ tcp_accept_filter = ZMQ_TCP_ACCEPT_FILTER, /*!< Filter inbound connections - set only */
+#endif
+#ifdef ZMQ_EXPERIMENTAL_LABELS
+ receive_label = ZMQ_RCVLABEL, /*!< Received label part - get only */
+#endif
+};
+
+}
+
+#endif /* ZMQPP_SOCKET_OPTIONS_HPP_ */
diff --git a/dep/zmqpp/zmqpp/socket_types.hpp b/dep/zmqpp/zmqpp/socket_types.hpp
new file mode 100644
index 00000000000..e59e71ca0e1
--- /dev/null
+++ b/dep/zmqpp/zmqpp/socket_types.hpp
@@ -0,0 +1,148 @@
+/**
+ * \file
+ *
+ * \date 23 Sep 2011
+ * \author Ben Gray (\@benjamg)
+ */
+
+#ifndef ZMQPP_SOCKET_TYPES_HPP_
+#define ZMQPP_SOCKET_TYPES_HPP_
+
+namespace zmqpp
+{
+
+/*!
+ * \brief Socket types allowed by zmq
+ *
+ * The socket type choose at creation must be one of these types.
+ *
+ * Each is designed for a different use and has different limitations.
+ */
+enum class socket_type {
+ /*!
+ * One to one - two way connection.\n
+ * Connect to ::pair.\n
+ * A \c pair socket has to be connected only one other pair socket and allows
+ * two way communication between them.
+ */
+ pair = ZMQ_PAIR,
+
+ /*!
+ * One to many - fan out.\n
+ * Connect to ::subscribe or ::xsubscribe.\n
+ * Socket is send only.\n
+ * Socket will drop messages and not block.\n
+ * \c publish sockets allow sending of the same message to many subscribers
+ * each subscriber can limit what is sent through the socket_option::subscribe
+ * settings.
+ */
+ publish = ZMQ_PUB,
+
+ /*!
+ * \note It seems doxygen can't work out which data is for the socket type and
+ * which is for the socket option so both get listed for both.
+ *
+ * One to many - fair-queued.\n
+ * Connect to ::publish or ::xpublish.\n
+ * Socket is receive only.\n
+ * The \c subscribe socket can connection to any number of publishers and will
+ * fairly pull messages from each. The socket_option::subscribe settings can
+ * be use to limit which messages are received and by default none are.
+ */
+ subscribe = ZMQ_SUB,
+
+ /*!
+ * One to many - fair-queued.\n
+ * Connect to ::push.\n
+ * Socket is receive only.\n
+ * The \c pull socket fairly pulls messages from all pushers it is connected
+ * to.
+ */
+ pull = ZMQ_PULL,
+
+ /*!
+ * One to many - load-balanced.\n
+ * Connect to ::pull.\n
+ * Socket is send only.\n
+ * Socket will block if unable to send.\n
+ * The \c push socket fairly distributes messages between any connected
+ * puller sockets.
+ */
+ push = ZMQ_PUSH,
+
+ /*!
+ * One to many - fair-queued outgoing, last peer incoming.\n
+ * Connect to ::reply or ::xreply.\n
+ * Socket flips between send and receive only.\n
+ * Socket will block if unable to send.\n
+ * The \c request socket will fairly balance requests sent out to a
+ * replier and then can only be used to receive until that replier
+ * sends a reply.
+ */
+ request = ZMQ_REQ,
+
+ /*!
+ * One to many - load-balanced incoming, last peer outgoing.\n
+ * Connect to ::request or ::xrequest.\n
+ * Socket flips between send and receive only.\n
+ * Socket will drop messages and not block.\n
+ * The \c reply socket can only receive until it pulls a message from a
+ * requester at which point it can only send until the reply is sent.
+ */
+ reply = ZMQ_REP,
+
+ /*!
+ * One to many - fan out.\n
+ * Connect to ::subscribe or ::xsubscribe.\n
+ * Socket is send only with the exception of special subscription messages.\n
+ * Socket will drop messages and not block.\n
+ * \c xpublish act the same as ::publish sockets however also allow special
+ * subscription messages to be received from subscribers.
+ */
+ xpublish = ZMQ_XPUB,
+
+ /*!
+ * One to many - fair-queued.\n
+ * Connect to ::publish or ::xpublish.\n
+ * Socket is receive only with the exception of special subscription messages\n
+ * \c xsubscribe act the same as ::subscribe sockets however also allow special
+ * subscription messages to be send to connected publishers.
+ */
+ xsubscribe = ZMQ_XSUB,
+
+ /*!
+ * One to many - fair-queued incoming, load-balanced outgoing.\n
+ * Connect to ::reply or ::xreply.\n
+ * Socket will block if unable to send.\n
+ * An \c xrequest socket balances requests between repliers and pulls replies
+ * back in a fair manner. Each request is expected to have exactly one reply.
+ */
+ xrequest = ZMQ_XREQ,
+
+ /*!
+ * One to many - fair-queued incoming, targeted outgoing.\n
+ * Connect to ::request or ::xrequest.\n
+ * Socket will drop messages and not block.\n
+ * An \c xreply socket fairly pulls in requests from requesters and will
+ * label requests so it can return replies back to the correct target.
+ */
+ xreply = ZMQ_XREP,
+
+ // To match for people who prefer the shorter versions
+ pub = ZMQ_PUB, /*!< version of ::publish to match zmq name convention */
+ sub = ZMQ_SUB, /*!< version of ::subscribe to match zmq name convention */
+ req = ZMQ_REQ, /*!< version of ::request to match zmq name convention */
+ rep = ZMQ_REP, /*!< version of ::reply to match zmq name convention */
+ xpub = ZMQ_XPUB, /*!< version of ::xpublish to match zmq name convention */
+ xsub = ZMQ_XSUB, /*!< version of ::xsubscribe to match zmq name convention */
+ xreq = ZMQ_XREQ, /*!< version of ::xrequest to match zmq name convention */
+ xrep = ZMQ_XREP, /*!< version of ::xreply to match zmq name convention */
+
+ // For completion
+ router = ZMQ_ROUTER, /*!< \deprecated Matches zmq 2.x xrep functionality. */
+ dealer = ZMQ_DEALER /*!< \deprecated Matches zmq 2.x xreq functionality. */
+};
+
+}
+
+#endif /* ZMQPP_SOCKET_TYPES_HPP_ */
diff --git a/dep/zmqpp/zmqpp/zmqpp.cpp b/dep/zmqpp/zmqpp/zmqpp.cpp
new file mode 100644
index 00000000000..216948e73e7
--- /dev/null
+++ b/dep/zmqpp/zmqpp/zmqpp.cpp
@@ -0,0 +1,30 @@
+/*
+ * Created on: 18 Aug 2011
+ * Author: Ben Gray (@benjamg)
+ */
+
+#include "zmqpp.hpp"
+
+namespace zmqpp
+{
+
+std::string version()
+{
+ return BUILD_VERSION;
+}
+
+void version(uint8_t& major, uint8_t& minor, uint8_t& revision)
+{
+ major = ZMQPP_VERSION_MAJOR;
+ minor = ZMQPP_VERSION_MINOR;
+ revision = ZMQPP_VERSION_REVISION;
+}
+
+void zmq_version(uint8_t& major, uint8_t& minor, uint8_t& patch)
+{
+ major = ZMQ_VERSION_MAJOR;
+ minor = ZMQ_VERSION_MINOR;
+ patch = ZMQ_VERSION_PATCH;
+}
+
+}
diff --git a/dep/zmqpp/zmqpp/zmqpp.hpp b/dep/zmqpp/zmqpp/zmqpp.hpp
new file mode 100644
index 00000000000..92a47ce38bf
--- /dev/null
+++ b/dep/zmqpp/zmqpp/zmqpp.hpp
@@ -0,0 +1,111 @@
+/**
+ * \file
+ *
+ * \date 9 Aug 2011
+ * \author Ben Gray (\@benjamg)
+ *
+ * License: http://www.opensource.org/licenses/MIT
+ *
+ * Copyright (C) 2011 by Ben Gray
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef ZMQPP_ZMQPP_HPP_
+#define ZMQPP_ZMQPP_HPP_
+
+/**
+ * \def ZMQPP_VERSION_MAJOR
+ * zmqpp major version number, generated at compile time
+ */
+#define ZMQPP_VERSION_MAJOR BUILD_VERSION_MAJOR
+
+/**
+ * \def ZMQPP_VERSION_MINOR
+ * zmqpp minor version number, generated at compile time
+ */
+#define ZMQPP_VERSION_MINOR BUILD_VERSION_MINOR
+
+/**
+ * \def ZMQPP_VERSION_REVISION
+ * zmqpp version revision number, generated at compile time
+ */
+#define ZMQPP_VERSION_REVISION BUILD_VERSION_REVISION
+
+#include <zmq.h>
+
+#include "compatibility.hpp"
+#include "context.hpp"
+#include "exception.hpp"
+#include "message.hpp"
+#include "poller.hpp"
+#include "socket.hpp"
+
+/*!
+ * \brief C++ wrapper around zmq
+ *
+ * All zmq++ / zmqpp functions, constants and classes live within this namespace,
+ */
+namespace zmqpp
+{
+
+/*!
+ * Returns the current major.minor.revision version number as a string.
+ *
+ * \return string version number.
+ */
+std::string version();
+
+/*!
+ * Retrieve the parts of the zmqpp version number.
+ *
+ * Set the three parameters to values representing the zmqpp version number.
+ * These values are generated at library compile time.
+ *
+ * \param major an unsigned 8 bit reference to set to the major version.
+ * \param minor an unsigned 8 bit reference to set to the minor version.
+ * \param revision an unsigned 8 bit reference to set the current revision.
+ */
+void version(uint8_t& major, uint8_t& minor, uint8_t& revision);
+
+/*!
+ * Retrieve the parts of the 0mq version this library was built against.
+ *
+ * Because sections of the library are optionally compiled in or ignored
+ * depending on the version of 0mq it was compiled against this method is
+ * provided to allow sanity checking for usage.
+ *
+ * Set the three parameters to values representing the 0mq version number.
+ * These values are generated at library compile time.
+ *
+ * \param major an unsigned 8 bit reference to set to the major version.
+ * \param minor an unsigned 8 bit reference to set to the minor version.
+ * \param revision an unsigned 8 bit reference to set the current revision.
+ */
+void zmq_version(uint8_t& major, uint8_t& minor, uint8_t& patch);
+
+typedef context context_t; /*!< \brief context type */
+typedef std::string endpoint_t; /*!< \brief endpoint type */
+typedef message message_t; /*!< \brief message type */
+typedef poller poller_t; /*!< \brief poller type */
+typedef socket socket_t; /*!< \brief socket type */
+
+}
+
+#endif /* ZMQPP_ZMQPP_HPP_ */
diff --git a/sql/base/auth_database.sql b/sql/base/auth_database.sql
index d743e393618..ed2112c04c5 100644
--- a/sql/base/auth_database.sql
+++ b/sql/base/auth_database.sql
@@ -237,7 +237,7 @@ CREATE TABLE `battlenet_modules` (
`Type` varchar(8) NOT NULL,
`System` varchar(8) NOT NULL,
`Data` text,
- PRIMARY KEY (`Hash`),
+ PRIMARY KEY (`Name`,`System`),
UNIQUE KEY `uk_name_type_system` (`Name`,`Type`,`System`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;
@@ -272,7 +272,26 @@ INSERT INTO `battlenet_modules` VALUES
('bfe4ceb47700aa872e815e007e27df955d4cd4bc1fe731039ee6498ce209f368','Resume','auth','Win',NULL),
('00ffd88a437afbb88d7d4b74be2e3b43601605ee229151aa9f4bebb29ef66280','Resume','auth','Mac',NULL),
('898166926805f897804bdbbf40662c9d768590a51a0b26c40dbcdf332ba11974','Resume','auth','Wn64',NULL),
-('304627d437c38500c0b5ca0c6220eeade91390e52a2b005ff3f7754afa1f93cd','Resume','auth','Mc64',NULL);
+('304627d437c38500c0b5ca0c6220eeade91390e52a2b005ff3f7754afa1f93cd','Resume','auth','Mc64',NULL),
+('cc654428261322763f4cada5b7f4b3b67660e85639bea916986b3f366fe8adc2','ERRS','xml','enGB','AA6C50D3'),
+('2753d31092f1978bdd78ebd4fae2d189364ad7108ceb22fbf1413be1f43bef04','PFTY','pfty','zhCN','DF6C50D3'),
+('5813f318f7e40a07a7cdfeeec9827942e6fdc5ccee0d4171148443e429ad0ead','PFTY','pfty','ruRU','DF6C50D3'),
+('83663d54444eadad40d43725e59bde8eda10276e76fc3c4e6f2ca56332ee8f03','PFTY','pfty','enSG','DF6C50D3'),
+('870f53d10b4e1b09d6b622cd5671ba4ff1ad69512dfa2c676072c52e45c7f0f9','PFTY','pfty','esES','DF6C50D3'),
+('305bbdab1953e65974a249e276867e13ad2c3cabca3668983cb5ed406251bb7b','PFTY','pfty','frFR','DF6C50D3'),
+('83663d54444eadad40d43725e59bde8eda10276e76fc3c4e6f2ca56332ee8f03','PFTY','pfty','enGB','DF6C50D3'),
+('a2ec4b41148214037a2e89a2e557af716d085241b81f5244494bdc77a891ca38','PFTY','pfty','csCZ','DF6C50D3'),
+('a8c77051991b1a6c5dfe412e9f46d8f584349996fbde37c4f2a527c192163502','PFTY','pfty','plPL','DF6C50D3'),
+('83663d54444eadad40d43725e59bde8eda10276e76fc3c4e6f2ca56332ee8f03','PFTY','pfty','enUS','DF6C50D3'),
+('7466b2db3f03768aa2527535d4b3c6c9ef9e8fb07c6db88b1019f3d25a2942e8','PFTY','pfty','koKR','DF6C50D3'),
+('a2ec4b41148214037a2e89a2e557af716d085241b81f5244494bdc77a891ca38','PFTY','pfty','jaJP','DF6C50D3'),
+('3e381d4f83201f4e3c482eb74da12e5ff9dd924da2413d8fb33f5eea9a02c2c2','PFTY','pfty','zhTW','DF6C50D3'),
+('83663d54444eadad40d43725e59bde8eda10276e76fc3c4e6f2ca56332ee8f03','PFTY','pfty','enTH','DF6C50D3'),
+('b72e65b6b34d8f859e79b5f28952e26553a796d5e1d75c2b5930bc0daeaa728c','PFTY','pfty','itIT','DF6C50D3'),
+('e8b82becbe0a0a1bbb5561df69320edbd770897a8deaab23caa6736255e0dc33','PFTY','pfty','esMX','DF6C50D3'),
+('83663d54444eadad40d43725e59bde8eda10276e76fc3c4e6f2ca56332ee8f03','PFTY','pfty','enAU','DF6C50D3'),
+('0a3f6f3f0535ea21dbe620085192afc796203047e270e0e1b76f15a739fe1797','PFTY','pfty','ptBR','DF6C50D3'),
+('047329d08d433da2622e9fc2ee96c8dd8f35e7770699d07cf74855b9c8ea9125','PFTY','pfty','deDE','DF6C50D3');
/*!40000 ALTER TABLE `battlenet_modules` ENABLE KEYS */;
UNLOCK TABLES;
diff --git a/sql/updates/auth/2014_10_13_00_auth_434.sql b/sql/updates/auth/2014_10_13_00_auth_434.sql
new file mode 100644
index 00000000000..e7c984d70f6
--- /dev/null
+++ b/sql/updates/auth/2014_10_13_00_auth_434.sql
@@ -0,0 +1,24 @@
+ALTER TABLE `battlenet_modules`
+ DROP PRIMARY KEY,
+ ADD PRIMARY KEY (`Name`, `System`);
+DELETE FROM `battlenet_modules` WHERE `Name` IN ('ERRS','PFTY');
+INSERT INTO `battlenet_modules` (`Hash`,`Name`,`Type`,`System`,`Data`) VALUES
+('cc654428261322763f4cada5b7f4b3b67660e85639bea916986b3f366fe8adc2', 'ERRS', 'xml', 'enGB', 'AA6C50D3'),
+('2753d31092f1978bdd78ebd4fae2d189364ad7108ceb22fbf1413be1f43bef04', 'PFTY', 'pfty', 'zhCN', 'DF6C50D3'),
+('5813f318f7e40a07a7cdfeeec9827942e6fdc5ccee0d4171148443e429ad0ead', 'PFTY', 'pfty', 'ruRU', 'DF6C50D3'),
+('83663d54444eadad40d43725e59bde8eda10276e76fc3c4e6f2ca56332ee8f03', 'PFTY', 'pfty', 'enSG', 'DF6C50D3'),
+('870f53d10b4e1b09d6b622cd5671ba4ff1ad69512dfa2c676072c52e45c7f0f9', 'PFTY', 'pfty', 'esES', 'DF6C50D3'),
+('305bbdab1953e65974a249e276867e13ad2c3cabca3668983cb5ed406251bb7b', 'PFTY', 'pfty', 'frFR', 'DF6C50D3'),
+('83663d54444eadad40d43725e59bde8eda10276e76fc3c4e6f2ca56332ee8f03', 'PFTY', 'pfty', 'enGB', 'DF6C50D3'),
+('a2ec4b41148214037a2e89a2e557af716d085241b81f5244494bdc77a891ca38', 'PFTY', 'pfty', 'csCZ', 'DF6C50D3'),
+('a8c77051991b1a6c5dfe412e9f46d8f584349996fbde37c4f2a527c192163502', 'PFTY', 'pfty', 'plPL', 'DF6C50D3'),
+('83663d54444eadad40d43725e59bde8eda10276e76fc3c4e6f2ca56332ee8f03', 'PFTY', 'pfty', 'enUS', 'DF6C50D3'),
+('7466b2db3f03768aa2527535d4b3c6c9ef9e8fb07c6db88b1019f3d25a2942e8', 'PFTY', 'pfty', 'koKR', 'DF6C50D3'),
+('a2ec4b41148214037a2e89a2e557af716d085241b81f5244494bdc77a891ca38', 'PFTY', 'pfty', 'jaJP', 'DF6C50D3'),
+('3e381d4f83201f4e3c482eb74da12e5ff9dd924da2413d8fb33f5eea9a02c2c2', 'PFTY', 'pfty', 'zhTW', 'DF6C50D3'),
+('83663d54444eadad40d43725e59bde8eda10276e76fc3c4e6f2ca56332ee8f03', 'PFTY', 'pfty', 'enTH', 'DF6C50D3'),
+('b72e65b6b34d8f859e79b5f28952e26553a796d5e1d75c2b5930bc0daeaa728c', 'PFTY', 'pfty', 'itIT', 'DF6C50D3'),
+('e8b82becbe0a0a1bbb5561df69320edbd770897a8deaab23caa6736255e0dc33', 'PFTY', 'pfty', 'esMX', 'DF6C50D3'),
+('83663d54444eadad40d43725e59bde8eda10276e76fc3c4e6f2ca56332ee8f03', 'PFTY', 'pfty', 'enAU', 'DF6C50D3'),
+('0a3f6f3f0535ea21dbe620085192afc796203047e270e0e1b76f15a739fe1797', 'PFTY', 'pfty', 'ptBR', 'DF6C50D3'),
+('047329d08d433da2622e9fc2ee96c8dd8f35e7770699d07cf74855b9c8ea9125', 'PFTY', 'pfty', 'deDE', 'DF6C50D3');
diff --git a/sql/updates/world/2014_10_04_01_world.sql b/sql/updates/world/2014_10_04_01_world.sql
new file mode 100644
index 00000000000..fa7f662ca82
--- /dev/null
+++ b/sql/updates/world/2014_10_04_01_world.sql
@@ -0,0 +1,6 @@
+UPDATE `gameobject_template` SET `AIName`="SmartGameObjectAI" WHERE `entry` IN(164885,164886,164887,164888,171939,171942,173284,173324,173327,174594,174595,174596,174597,174598,174599,174600,174601,174602,174603,174604,174605,174606,174607,174608,174684,174686,174708,174709,174712,174713,191124);
+UPDATE `creature_template` SET `AIName`="SmartAI" WHERE `entry` IN(29525,29863,24198,23698,21611,21503);
+UPDATE `smart_scripts` SET `link`=0 WHERE `entryorguid` IN(8978,2706) AND `source_type`=0 AND `id`=0;
+UPDATE `smart_scripts` SET `event_type`=61 WHERE `entryorguid` IN(4675,28156) AND `source_type`=0 AND `id`=1;
+UPDATE `smart_scripts` SET `link`=0 WHERE `entryorguid`=21057 AND `source_type`=0 AND `id`=9;
+UPDATE `smart_scripts` SET `link`=0 WHERE `entryorguid`=25806 AND `source_type`=0 AND `id`=2;
diff --git a/sql/updates/world/2014_10_05_00_world.sql b/sql/updates/world/2014_10_05_00_world.sql
new file mode 100644
index 00000000000..7d055e72f9f
--- /dev/null
+++ b/sql/updates/world/2014_10_05_00_world.sql
@@ -0,0 +1,86 @@
+--
+UPDATE `gossip_menu_option` SET `OptionBroadcastTextID`=11038 WHERE `menu_id`=21278 AND `id`=0;
+
+-- BroadcastTextID0
+UPDATE `npc_text` SET `BroadcastTextID0`=3989 WHERE `ID`=1643;
+UPDATE `npc_text` SET `BroadcastTextID0`=3991 WHERE `ID`=1644;
+UPDATE `npc_text` SET `BroadcastTextID0`=3992 WHERE `ID`=1647;
+UPDATE `npc_text` SET `BroadcastTextID0`=3993 WHERE `ID`=1648;
+UPDATE `npc_text` SET `BroadcastTextID0`=3994 WHERE `ID`=1649;
+UPDATE `npc_text` SET `BroadcastTextID0`=3996 WHERE `ID`=1650;
+UPDATE `npc_text` SET `BroadcastTextID0`=4002 WHERE `ID`=1651;
+UPDATE `npc_text` SET `BroadcastTextID0`=4004 WHERE `ID`=1652;
+UPDATE `npc_text` SET `BroadcastTextID0`=4009 WHERE `ID`=1655;
+UPDATE `npc_text` SET `BroadcastTextID0`=4011 WHERE `ID`=1656;
+UPDATE `npc_text` SET `BroadcastTextID0`=4012 WHERE `ID`=1657;
+UPDATE `npc_text` SET `BroadcastTextID0`=4083 WHERE `ID`=1693;
+UPDATE `npc_text` SET `BroadcastTextID0`=4170 WHERE `ID`=1753;
+UPDATE `npc_text` SET `BroadcastTextID0`=4171 WHERE `ID`=1754;
+UPDATE `npc_text` SET `BroadcastTextID0`=4172 WHERE `ID`=1755;
+UPDATE `npc_text` SET `BroadcastTextID0`=4173 WHERE `ID`=1756;
+UPDATE `npc_text` SET `BroadcastTextID0`=4182 WHERE `ID`=1758;
+UPDATE `npc_text` SET `BroadcastTextID0`=4184 WHERE `ID`=1759;
+
+-- BroadcastTextID1
+UPDATE `npc_text` SET `BroadcastTextID1`=2880 WHERE `ID`=882;
+UPDATE `npc_text` SET `BroadcastTextID1`=6319 WHERE `ID`=905;
+UPDATE `npc_text` SET `BroadcastTextID1`=6312 WHERE `ID`=922;
+UPDATE `npc_text` SET `BroadcastTextID1`=6313 WHERE `ID`=923;
+UPDATE `npc_text` SET `BroadcastTextID1`=6324 WHERE `ID`=928;
+UPDATE `npc_text` SET `BroadcastTextID1`=5085 WHERE `ID`=2762;
+UPDATE `npc_text` SET `BroadcastTextID1`=6343 WHERE `ID`=2769;
+UPDATE `npc_text` SET `BroadcastTextID1`=5107 WHERE `ID`=2774;
+UPDATE `npc_text` SET `BroadcastTextID1`=6349 WHERE `ID`=2775;
+UPDATE `npc_text` SET `BroadcastTextID1`=6350 WHERE `ID`=2776;
+UPDATE `npc_text` SET `BroadcastTextID1`=5116 WHERE `ID`=2794;
+UPDATE `npc_text` SET `BroadcastTextID1`=6335 WHERE `ID`=2795;
+UPDATE `npc_text` SET `BroadcastTextID1`=5365 WHERE `ID`=2797;
+UPDATE `npc_text` SET `BroadcastTextID1`=6337 WHERE `ID`=2798;
+UPDATE `npc_text` SET `BroadcastTextID1`=5132 WHERE `ID`=2801;
+UPDATE `npc_text` SET `BroadcastTextID1`=6344 WHERE `ID`=2804;
+UPDATE `npc_text` SET `BroadcastTextID1`=6347 WHERE `ID`=2807;
+UPDATE `npc_text` SET `BroadcastTextID1`=5346 WHERE `ID`=3025;
+UPDATE `npc_text` SET `BroadcastTextID1`=5358 WHERE `ID`=3036;
+UPDATE `npc_text` SET `BroadcastTextID1`=5373 WHERE `ID`=3040;
+UPDATE `npc_text` SET `BroadcastTextID1`=6361 WHERE `ID`=3042;
+UPDATE `npc_text` SET `BroadcastTextID1`=6334 WHERE `ID`=3814;
+UPDATE `npc_text` SET `BroadcastTextID1`=7053 WHERE `ID`=4310;
+UPDATE `npc_text` SET `BroadcastTextID1`=10134 WHERE `ID`=7387;
+UPDATE `npc_text` SET `BroadcastTextID1`=10367 WHERE `ID`=7484;
+UPDATE `npc_text` SET `BroadcastTextID1`=10413 WHERE `ID`=7498;
+UPDATE `npc_text` SET `BroadcastTextID1`=10418 WHERE `ID`=7500;
+UPDATE `npc_text` SET `BroadcastTextID1`=10420 WHERE `ID`=7501;
+UPDATE `npc_text` SET `BroadcastTextID1`=10391 WHERE `ID`=7502;
+UPDATE `npc_text` SET `BroadcastTextID1`=10396 WHERE `ID`=7505;
+UPDATE `npc_text` SET `BroadcastTextID1`=10399 WHERE `ID`=7506;
+UPDATE `npc_text` SET `BroadcastTextID1`=10405 WHERE `ID`=7508;
+UPDATE `npc_text` SET `BroadcastTextID1`=10407 WHERE `ID`=7509;
+UPDATE `npc_text` SET `BroadcastTextID1`=10766 WHERE `ID`=15296;
+UPDATE `npc_text` SET `BroadcastTextID1`=18268 WHERE `ID`=20551;
+UPDATE `npc_text` SET `BroadcastTextID1`=18269 WHERE `ID`=20564;
+UPDATE `npc_text` SET `BroadcastTextID1`=22227 WHERE `ID`=11256;
+UPDATE `npc_text` SET `BroadcastTextID1`=45371 WHERE `ID`=16783;
+UPDATE `npc_text` SET `BroadcastTextID1`=6111 WHERE `ID`=3668;
+UPDATE `npc_text` SET `BroadcastTextID1`=10386 WHERE `ID`=7496;
+
+-- BroadcastTextID2
+UPDATE `npc_text` SET `BroadcastTextID2`=22228 WHERE `ID`=11256;
+UPDATE `npc_text` SET `BroadcastTextID2`=18282 WHERE `ID`=20551;
+UPDATE `npc_text` SET `BroadcastTextID2`=2909 WHERE `ID`=900;
+UPDATE `npc_text` SET `BroadcastTextID2`=13816 WHERE `ID`=8893;
+
+-- BroadcastTextID3
+UPDATE `npc_text` SET `BroadcastTextID3`=2878 WHERE `ID`=879;
+
+-- BroadcastTextID4
+UPDATE `npc_text` SET `BroadcastTextID5`=13345 WHERE `ID`=8760;
+
+-- Misc
+UPDATE `npc_text` SET `text7_0`='' WHERE `ID`=3297;
+UPDATE `npc_text` SET `text7_0`='' WHERE `ID`=7530;
+UPDATE `npc_text` SET `text7_0`='' WHERE `ID`=7635;
+UPDATE `npc_text` SET `text7_0`='' WHERE `ID`=7669;
+UPDATE `npc_text` SET `text7_0`='' WHERE `ID`=8061;
+UPDATE `npc_text` SET `text7_0`='' WHERE `ID`=8480;
+UPDATE `npc_text` SET `text7_0`='' WHERE `ID`=8484;
+UPDATE `npc_text` SET `text7_0`='' WHERE `ID`=8934;
diff --git a/sql/updates/world/2014_10_05_01_world.sql b/sql/updates/world/2014_10_05_01_world.sql
new file mode 100644
index 00000000000..3e8b699dedc
--- /dev/null
+++ b/sql/updates/world/2014_10_05_01_world.sql
@@ -0,0 +1,34 @@
+--
+SET @Linda :=32687;
+SET @Alec :=32692;
+
+UPDATE creature_template SET `AIName`='SmartAI' WHERE entry IN (@Linda, @Alec);
+
+DELETE FROM `smart_scripts` WHERE `entryorguid` = @Linda AND `source_type` = 0;
+DELETE FROM `smart_scripts` WHERE `entryorguid` = @Linda*100 AND `source_type` = 9;
+DELETE FROM `smart_scripts` WHERE `entryorguid` = @Linda*100+1 AND `source_type` = 9;
+INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES
+(@Linda, 0, 0, 0, 10, 0, 100, 0, 1, 10, 300000, 300000, 87, @Linda*100, @Linda*100+1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Linda - OOC_LOS - RANDOM_TIMED_ACTIONLIST'),
+(@Linda*100,9,0,0,0,0,100,0,0,0,0,0,1,0,0,0,0,0,0,7,0,0,0,0,0,0,0,'Linda - RANDOM_TIMED_ACTIONLIST - talk'),
+(@Linda*100+1,9,0,0,0,0,100,0,0,0,0,0,1,0,0,0,0,0,0,19,@Alec,5,0,0,0,0,0,'Linda - RANDOM_TIMED_ACTIONLIST - talk');
+
+DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=22 AND `SourceGroup`=1 AND `SourceEntry`=@Linda;
+INSERT INTO `conditions` (`SourceTypeOrReferenceId`,`SourceGroup`,`SourceEntry`,`ElseGroup`,`ConditionTypeOrReference`,`ConditionValue1`,`ConditionValue2`,`ConditionValue3`, `ErrorTextId`,`ScriptName`,`Comment`) VALUES
+(22,1,@Linda,0,5,1090,128,0,0,'','event require Kirin Tor Exalted');
+
+
+DELETE FROM creature_text WHERE entry IN (@Linda, @Alec);
+INSERT INTO `creature_text` (`entry`, `groupid`, `id`, `text`, `type`, `language`, `probability`, `emote`, `duration`, `sound`, `comment`, `BroadcastTextID`) VALUES
+(@Linda, 0, 0, 'There goes the finest $c I have the honor of knowing.', 12, 0, 100, 0, 0, 0, 'Linda Ann Kastinglow', 32866),
+(@Linda, 0, 1, '$n, you''re an inspiration.', 12, 0, 100, 0, 0, 0, 'Linda Ann Kastinglow', 32867),
+(@Linda, 0, 2, 'A fine example of a $g man:woman;, that $n.', 12, 0, 100, 0, 0, 0, 'Linda Ann Kastinglow', 32868),
+(@Linda, 0, 3, 'You couldn''t ask for a finer person than $n, I say.', 12, 0, 100, 0, 0, 0, 'Linda Ann Kastinglow', 32869),
+(@Linda, 0, 4, '$n, wonderful to see you. Wonderful.', 12, 0, 100, 0, 0, 0, 'Linda Ann Kastinglow', 32870),
+(@Linda, 0, 5, '$n! Ah, fantastic to see you out and about. Busy as always, hm?', 12, 0, 100, 0, 0, 0, 'Linda Ann Kastinglow', 32871),
+
+(@Alec, 0, 0, 'There goes the finest $c I have the honor of knowing.', 12, 0, 100, 0, 0, 0, 'Arcanist Alec', 32866),
+(@Alec, 0, 1, '$n, you''re an inspiration.', 12, 0, 100, 0, 0, 0, 'Arcanist Alec', 32867),
+(@Alec, 0, 2, 'A fine example of a $g man:woman;, that $n.', 12, 0, 100, 0, 0, 0, 'Arcanist Alec', 32868),
+(@Alec, 0, 3, 'You couldn''t ask for a finer person than $n, I say.', 12, 0, 100, 0, 0, 0, 'Arcanist Alec', 32869),
+(@Alec, 0, 4, '$n, wonderful to see you. Wonderful.', 12, 0, 100, 0, 0, 0, 'Arcanist Alec', 32870),
+(@Alec, 0, 5, '$n! Ah, fantastic to see you out and about. Busy as always, hm?', 12, 0, 100, 0, 0, 0, 'Arcanist Alec', 32871);
diff --git a/sql/updates/world/2014_10_05_02_world.sql b/sql/updates/world/2014_10_05_02_world.sql
new file mode 100644
index 00000000000..09a8fc24895
--- /dev/null
+++ b/sql/updates/world/2014_10_05_02_world.sql
@@ -0,0 +1,8 @@
+--
+SET @ENTRY := 29483;
+SET @SPELL_ENERGY_SURGE := 54559;
+UPDATE `creature` SET `spawndist`=0, `MovementType`=0 WHERE `id` =@ENTRY;
+UPDATE `creature_template` SET `unit_flags`=`unit_flags`|4|33554432, `AIName`='SmartAI' WHERE `entry`=@ENTRY;
+DELETE FROM `smart_scripts` WHERE `entryorguid`=@ENTRY AND `source_type`=0;
+INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES
+(@ENTRY, 0, 0, 0, 9, 0, 100, 0, 1, 20, 1000, 1000, 11, @SPELL_ENERGY_SURGE, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 'K3 Perimeter Turret - Within 1-20 Range - Cast ''Energy Surge''');
diff --git a/sql/updates/world/2014_10_05_03_world.sql b/sql/updates/world/2014_10_05_03_world.sql
new file mode 100644
index 00000000000..30603214312
--- /dev/null
+++ b/sql/updates/world/2014_10_05_03_world.sql
@@ -0,0 +1,5 @@
+ALTER TABLE `creature` ADD `zoneId` SMALLINT(5) UNSIGNED NOT NULL DEFAULT '0' COMMENT 'Zone Identifier' AFTER `map`;
+ALTER TABLE `creature` ADD `areaId` SMALLINT(5) UNSIGNED NOT NULL DEFAULT '0' COMMENT 'Area Identifier' AFTER `zoneId`;
+
+ALTER TABLE `gameobject` ADD `zoneId` SMALLINT(5) UNSIGNED NOT NULL DEFAULT '0' COMMENT 'Zone Identifier' AFTER `map`;
+ALTER TABLE `gameobject` ADD `areaId` SMALLINT(5) UNSIGNED NOT NULL DEFAULT '0' COMMENT 'Area Identifier' AFTER `zoneId`;
diff --git a/sql/updates/world/2014_10_05_04_world.sql b/sql/updates/world/2014_10_05_04_world.sql
new file mode 100644
index 00000000000..ed32e268a87
--- /dev/null
+++ b/sql/updates/world/2014_10_05_04_world.sql
@@ -0,0 +1,71 @@
+SET @CGUID :=74960;
+SET @OGUID :=21104;
+
+DELETE FROM `creature` WHERE `guid` BETWEEN @CGUID+0 AND @CGUID+12;
+INSERT INTO `creature` (`guid`, `id`, `map`, `spawnMask`, `phaseMask`, `position_x`, `position_y`, `position_z`, `orientation`, `spawntimesecs`, `spawndist`, `MovementType`) VALUES
+(@CGUID+0 , 24545, 530, 1, 1, -1882.759, 5575.42, -12.3448, 4.677482, 120, 0, 0), -- Thunderbrew "Apprentice" (Area: Shattrath City)
+(@CGUID+1 , 24484, 530, 1, 1, -1872.835, 5560.321, -12.3448, 2.748216, 120, 0, 0), -- Brewfest Reveler (Area: Shattrath City) (Auras: 43910 - Brewfest Reveler - Gnome)
+(@CGUID+2 , 24484, 530, 1, 1, -1878.838, 5562.812, -12.3448, 5.889809, 120, 0, 0), -- Brewfest Reveler (Area: Shattrath City) (Auras: 43909 - Brewfest Reveler - Dwarf)
+(@CGUID+3 , 24484, 530, 1, 1, -1878.618, 5556.088, -12.3448, 3.259485, 120, 0, 0), -- Brewfest Reveler (Area: Shattrath City) (Auras: 43910 - Brewfest Reveler - Gnome)
+(@CGUID+4 , 24484, 530, 1, 1, -1897.398, 5558.127, -12.3448, 1.710423, 120, 0, 0), -- Brewfest Reveler (Area: Shattrath City) (Auras: 44004 - Brewfest Reveler - Goblin - Female)
+(@CGUID+5 , 24484, 530, 1, 1, -1899.819, 5560.333, -12.3448, 0.3665192, 120, 0, 0), -- Brewfest Reveler (Area: Shattrath City) (Auras: 44003 - Brewfest Reveler - Goblin - Male)
+(@CGUID+6 , 24484, 530, 1, 1, -1921.889, 5554.328, -12.34481, 0.04066804, 120, 0, 0), -- Brewfest Reveler (Area: Shattrath City) (Auras: 43916 - Brewfest Reveler - Troll)
+(@CGUID+7 , 24484, 530, 1, 1, -1916.578, 5551.592, -12.34481, 2.666002, 120, 0, 0), -- Brewfest Reveler (Area: Shattrath City) (Auras: 43917 - Brewfest Reveler - Undead)
+(@CGUID+8 , 24484, 530, 1, 1, -1924.595, 5549.645, -12.3448, 1.046868, 120, 0, 0), -- Brewfest Reveler (Area: Shattrath City) (Auras: 43914 - Brewfest Reveler - Orc)
+(@CGUID+9 , 24484, 530, 1, 1, -1897.494, 5562.316, -12.3448, 4.433136, 120, 0, 0), -- Brewfest Reveler (Area: Shattrath City) (Auras: 44003 - Brewfest Reveler - Goblin - Male)
+(@CGUID+10, 24501, 530, 1, 1, -1926.787, 5562.968, -12.3448, 5.061455, 120, 0, 0), -- Drohn's Distillery Apprentice (Area: Shattrath City)
+(@CGUID+11, 24484, 530, 1, 1, -1895.234, 5560.195, -12.34481, 2.80998, 120, 0, 0), -- Brewfest Reveler (Area: Shattrath City) (Auras: 44003 - Brewfest Reveler - Goblin - Male)
+(@CGUID+12, 23511, 530, 1, 1, -1906.297, 5569.852, -12.3448, 4.974188, 120, 0, 0); -- Gordok Brew Apprentice (Area: Shattrath City)
+
+DELETE FROM `creature_addon` WHERE `guid` BETWEEN @CGUID+0 AND @CGUID+12;
+INSERT INTO `creature_addon` (`guid`, `mount`, `bytes1`, `bytes2`, `auras`) VALUES
+(@CGUID+1 , 0, 0x0, 0x101, '43910'), -- Brewfest Reveler - 43910 - Brewfest Reveler - Gnome
+(@CGUID+2 , 0, 0x0, 0x101, '43909'), -- Brewfest Reveler - 43909 - Brewfest Reveler - Dwarf
+(@CGUID+3 , 0, 0x0, 0x101, '43910'), -- Brewfest Reveler - 43910 - Brewfest Reveler - Gnome
+(@CGUID+4 , 0, 0x0, 0x101, '44004'), -- Brewfest Reveler - 44004 - Brewfest Reveler - Goblin - Female
+(@CGUID+5 , 0, 0x0, 0x101, '44003'), -- Brewfest Reveler - 44003 - Brewfest Reveler - Goblin - Male
+(@CGUID+6 , 0, 0x0, 0x101, '43916'), -- Brewfest Reveler - 43916 - Brewfest Reveler - Troll
+(@CGUID+7 , 0, 0x0, 0x101, '43917'), -- Brewfest Reveler - 43917 - Brewfest Reveler - Undead
+(@CGUID+8 , 0, 0x0, 0x101, '43914'), -- Brewfest Reveler - 43914 - Brewfest Reveler - Orc
+(@CGUID+9 , 0, 0x0, 0x101, '44003'), -- Brewfest Reveler - 44003 - Brewfest Reveler - Goblin - Male
+(@CGUID+11, 0, 0x0, 0x101, '44003'); -- Brewfest Reveler - 44003 - Brewfest Reveler - Goblin - Male
+
+DELETE FROM `gameobject` WHERE `guid` BETWEEN @OGUID+0 AND @OGUID+8;
+INSERT INTO `gameobject` (`guid`, `id`, `map`, `spawnMask`, `phaseMask`, `position_x`, `position_y`, `position_z`, `orientation`, `rotation0`, `rotation1`, `rotation2`, `rotation3`, `spawntimesecs`, `animprogress`, `state`) VALUES
+(@OGUID+0, 186259, 530, 1, 1, -1875.389, 5579.114, -12.42814, 1.605702, 0, 0, 0, 1, 120, 255, 1), -- Thunderbrew Festive Wagon (Area: Shattrath City)
+(@OGUID+1, 180037, 530, 1, 1, -1909.218, 5569.716, -12.42814, 4.97419, 0, 0, 0, 1, 120, 255, 1), -- Haybail 01 (Area: Shattrath City)
+(@OGUID+2, 180037, 530, 1, 1, -1906.963, 5573.009, -12.42814, 3.47321, 0, 0, 0, 1, 120, 255, 1), -- Haybail 01 (Area: Shattrath City)
+(@OGUID+3, 178666, 530, 1, 1, -1882.575, 5582.089, -12.42814, 3.141593, 0, 0, 0, 1, 120, 255, 1), -- Gypsy Wagon (Area: Shattrath City)
+(@OGUID+4, 178666, 530, 1, 1, -1928.171, 5567.508, -12.42814, 3.38594, 0, 0, 0, 1, 120, 255, 1), -- Gypsy Wagon (Area: Shattrath City)
+(@OGUID+5, 186255, 530, 1, 1, -1920.9, 5568.442, -12.42814, 1.884953, 0, 0, 0, 1, 120, 255, 1), -- Drohn's Distillery Festive Wagon (Area: Shattrath City)
+(@OGUID+6, 186257, 530, 1, 1, -1900.552, 5575.883, -12.42814, 1.937312, 0, 0, 0, 1, 120, 255, 1), -- Gordok Festive Wagon (Area: Shattrath City)
+(@OGUID+7, 180037, 530, 1, 1, -1893.456, 5576.866, -12.42814, 4.223697, 0, 0, 0, 1, 120, 255, 1), -- Haybail 01 (Area: Shattrath City)
+(@OGUID+8, 180037, 530, 1, 1, -1904.326, 5571.048, -12.42814, 1.902409, 0, 0, 0, 1, 120, 255, 1); -- Haybail 01 (Area: Shattrath City)
+
+DELETE FROM `game_event_creature` WHERE `eventEntry`=24 AND `guid` BETWEEN @CGUID+0 AND @CGUID+12;
+INSERT INTO `game_event_creature` (`eventEntry`, `guid`) VALUES
+(24, @CGUID+0),
+(24, @CGUID+1),
+(24, @CGUID+2),
+(24, @CGUID+3),
+(24, @CGUID+4),
+(24, @CGUID+5),
+(24, @CGUID+6),
+(24, @CGUID+7),
+(24, @CGUID+8),
+(24, @CGUID+9),
+(24, @CGUID+10),
+(24, @CGUID+11),
+(24, @CGUID+12);
+
+DELETE FROM `game_event_gameobject` WHERE `eventEntry`=24 AND `guid` BETWEEN @OGUID+0 AND @OGUID+8;
+INSERT INTO `game_event_gameobject` (`eventEntry`, `guid`) VALUES
+(24, @OGUID+0),
+(24, @OGUID+1),
+(24, @OGUID+2),
+(24, @OGUID+3),
+(24, @OGUID+4),
+(24, @OGUID+5),
+(24, @OGUID+6),
+(24, @OGUID+7),
+(24, @OGUID+8);
diff --git a/sql/updates/world/2014_10_05_05_world.sql b/sql/updates/world/2014_10_05_05_world.sql
new file mode 100644
index 00000000000..35775eaac70
--- /dev/null
+++ b/sql/updates/world/2014_10_05_05_world.sql
@@ -0,0 +1,38 @@
+--
+UPDATE `npc_text` SET `BroadcastTextID0`=5793 WHERE `ID`=3464;
+UPDATE `npc_text` SET `BroadcastTextID0`=10046 WHERE `ID`=7339;
+UPDATE `npc_text` SET `BroadcastTextID0`=10048 WHERE `ID`=7340;
+UPDATE `npc_text` SET `BroadcastTextID0`=10053 WHERE `ID`=7341;
+UPDATE `npc_text` SET `BroadcastTextID0`=10062 WHERE `ID`=7355;
+UPDATE `npc_text` SET `BroadcastTextID0`=10065 WHERE `ID`=7356;
+UPDATE `npc_text` SET `BroadcastTextID0`=10082 WHERE `ID`=7362;
+UPDATE `npc_text` SET `BroadcastTextID0`=10086 WHERE `ID`=7363;
+UPDATE `npc_text` SET `BroadcastTextID0`=10092 WHERE `ID`=7365;
+UPDATE `npc_text` SET `BroadcastTextID0`=10210 WHERE `ID`=7437;
+UPDATE `npc_text` SET `BroadcastTextID0`=10366 WHERE `ID`=7484;
+UPDATE `npc_text` SET `BroadcastTextID0`=10412 WHERE `ID`=7498;
+UPDATE `npc_text` SET `BroadcastTextID0`=10417 WHERE `ID`=7500;
+UPDATE `npc_text` SET `BroadcastTextID0`=10419 WHERE `ID`=7501;
+UPDATE `npc_text` SET `BroadcastTextID0`=10390 WHERE `ID`=7502;
+UPDATE `npc_text` SET `BroadcastTextID0`=10395 WHERE `ID`=7505;
+UPDATE `npc_text` SET `BroadcastTextID0`=10404 WHERE `ID`=7508;
+UPDATE `npc_text` SET `BroadcastTextID0`=10406 WHERE `ID`=7509;
+UPDATE `npc_text` SET `BroadcastTextID0`=10466 WHERE `ID`=7596;
+UPDATE `npc_text` SET `BroadcastTextID0`=10468 WHERE `ID`=7597;
+UPDATE `npc_text` SET `BroadcastTextID0`=10470 WHERE `ID`=7598;
+UPDATE `npc_text` SET `BroadcastTextID0`=10475 WHERE `ID`=7614;
+UPDATE `npc_text` SET `BroadcastTextID0`=10493 WHERE `ID`=7641;
+UPDATE `npc_text` SET `BroadcastTextID0`=10543 WHERE `ID`=7674;
+UPDATE `npc_text` SET `BroadcastTextID0`=10547 WHERE `ID`=7676;
+UPDATE `npc_text` SET `BroadcastTextID0`=10548 WHERE `ID`=7677;
+UPDATE `npc_text` SET `BroadcastTextID0`=10557 WHERE `ID`=7683;
+UPDATE `npc_text` SET `BroadcastTextID0`=17814 WHERE `ID`=20201;
+UPDATE `npc_text` SET `BroadcastTextID0`=27613 WHERE `ID`=13100;
+UPDATE `npc_text` SET `BroadcastTextID0`=9499 WHERE `ID`=6938;
+UPDATE `npc_text` SET `BroadcastTextID0`=6016 WHERE `ID`=447;
+UPDATE `npc_text` SET `BroadcastTextID0`=20391 WHERE `ID`=10412;
+UPDATE `npc_text` SET `BroadcastTextID0`=19868 WHERE `ID`=10616;
+UPDATE `npc_text` SET `BroadcastTextID0`=14430 WHERE `ID`=9080;
+UPDATE `npc_text` SET `BroadcastTextID0`=10567 WHERE `ID`=7692;
+UPDATE `npc_text` SET `BroadcastTextID0`=6001 WHERE `ID`=3579;
+UPDATE `npc_text` SET `BroadcastTextID0`=5035 WHERE `ID`=2725;
diff --git a/sql/updates/world/2014_10_05_06_world.sql b/sql/updates/world/2014_10_05_06_world.sql
new file mode 100644
index 00000000000..fa28f871d64
--- /dev/null
+++ b/sql/updates/world/2014_10_05_06_world.sql
@@ -0,0 +1,6 @@
+--
+UPDATE `creature` SET `map`=571 WHERE `guid`=101828 AND `id`=25434;
+UPDATE `creature` SET `position_y`=-6381.79 WHERE `guid`=82822 AND `id`=16303;
+UPDATE `creature` SET `position_y`=-6395.32 WHERE `guid`=82826 AND `id`=16303;
+UPDATE `creature` SET `position_y`=-6343.51 WHERE `guid`=82827 AND `id`=16303;
+UPDATE `creature` SET `map`=1 WHERE `guid`=40251 AND `id`=29346;
diff --git a/sql/updates/world/2014_10_05_07_world.sql b/sql/updates/world/2014_10_05_07_world.sql
new file mode 100644
index 00000000000..4e2e84def5a
--- /dev/null
+++ b/sql/updates/world/2014_10_05_07_world.sql
@@ -0,0 +1,30 @@
+UPDATE `creature_template` SET `AIName`='SmartAI' WHERE `entry` IN(25285,31033);
+DELETE FROM `smart_scripts` WHERE `entryorguid` IN(25285,31033) AND `source_type`=0;
+DELETE FROM `smart_scripts` WHERE `entryorguid` =2528500 AND `source_type`=9;
+
+INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES
+(25285, 0, 0, 0, 10, 0, 100, 0, 1, 50, 120000, 300000, 80, 2528500, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Harbinger Vurenn - OOC LOS - Run Script'),
+(31033, 0, 0, 0, 10, 0, 100, 0, 1, 20, 600000, 900000, 1, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 'Crusader of Virtue - OOC LOS - Say Line'),
+(2528500, 9, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Harbinger Vurenn - Script - Say Line 0'),
+(2528500, 9, 1, 0, 0, 0, 100, 0, 8000, 8000, 0, 0, 1, 0, 0, 0, 0, 0, 0, 19, 25301, 0, 0, 0, 0, 0, 0, 'Harbinger Vurenn - Script - Say Line 0 (Counselor Talbot)'),
+(2528500, 9, 2, 0, 0, 0, 100, 0, 7000, 7000, 0, 0, 1, 2, 0, 0, 0, 0, 0, 19, 25250, 0, 0, 0, 0, 0, 0, 'Harbinger Vurenn - Script - Say Line 2 (General Arlos)'),
+(2528500, 9, 3, 0, 0, 0, 100, 0, 12000, 12000, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Harbinger Vurenn - Script - Say Line 1');
+
+DELETE FROM `creature_text` WHERE `entry` IN(25301,25285,31033);
+DELETE FROM `creature_text` WHERE `entry` =25250 AND `groupid`=2;
+
+INSERT INTO `creature_text` (`entry`, `groupid`, `id`, `text`, `type`, `language`, `probability`, `emote`, `duration`, `sound`, `comment`,`BroadcastTextID`) VALUES
+(25250, 2, 0, 'Your offer will be carefully considered, harbinger. In the meantime we will make use of your delegation in an advisory role.', 12, 7, 100, 1, 0, 0, 'General Arlos',24790),
+(25301, 0, 0, 'Our troops, general, consist mostly of villagers and peasants. Good men, but not quite rid of the prejudices and superstitions of their upbringing. They''re not ready to fight alongside our more exotic allies.', 12, 7, 100, 1, 0, 0, 'Counselor Talbot',24789),
+(25285, 0, 0, 'Give the word, general. I will have two regiments at your disposal in a month''s time.', 12, 7, 100, 0, 0, 0, 'Harbinger Vurenn',24787),
+(25285, 1, 0, 'Very well, general. Should you change your mind, my people will be more than willing to provide military assistance.', 12, 7, 100, 0, 0, 0, 'Harbinger Vurenn',24788),
+(31033, 0, 0, 'There goes the hero of the Vanguard!', 12, 0, 100, 66, 0, 0, 'Crusader of Virtue',31385),
+(31033, 0, 1, '%s cheers at you.', 16, 1, 100, 71, 0, 0, 'Crusader of Virtue',25275),
+(31033, 0, 2, 'We couldn''t have done it without you, $g sir:ma''am;.', 12, 0, 100, 66, 0, 0, 'Crusader of Virtue',31384),
+(31033, 0, 3, 'You honor us with your presence, $n.', 12, 0, 100, 66, 0, 0, 'Crusader of Virtue',31386),
+(31033, 0, 4, 'Thank you, $n. From the bottom of my heart. Thank you.', 12, 0, 100, 66, 0, 0, 'Crusader of Virtue',31388),
+(31033, 0, 5, 'Call on me anytime, $n.', 12, 0, 100, 66, 0, 0, 'Crusader of Virtue',31389);
+
+DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=22 AND `SourceEntry`=31033;
+INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES
+(22, 1, 31033, 0, 0, 8, 0, 13157, 0, 0, 0, 0, 0, '', 'Crusader of Virtue - Only run SAI if player is rewarded for quest 13157');
diff --git a/sql/updates/world/2014_10_06_00_world.sql b/sql/updates/world/2014_10_06_00_world.sql
new file mode 100644
index 00000000000..5ef37298264
--- /dev/null
+++ b/sql/updates/world/2014_10_06_00_world.sql
@@ -0,0 +1,14 @@
+--
+UPDATE `creature_text` SET `BroadcastTextId`=9633 WHERE `entry`=14467 AND `groupid`=0 AND `id`=0;
+UPDATE `creature_text` SET `BroadcastTextId`=7798 WHERE `entry`=701 AND `groupid`=0 AND `id`=0;
+UPDATE `creature_text` SET `BroadcastTextId`=8355 WHERE `entry`=12923 AND `groupid`=0 AND `id`=0;
+UPDATE `creature_text` SET `BroadcastTextId`=8355 WHERE `entry`=12924 AND `groupid`=0 AND `id`=0;
+UPDATE `creature_text` SET `BroadcastTextId`=8355 WHERE `entry`=12925 AND `groupid`=0 AND `id`=0;
+UPDATE `creature_text` SET `BroadcastTextId`=10601 WHERE `entry`=11380 AND `groupid`=0 AND `id`=0;
+UPDATE `creature_text` SET `BroadcastTextId`=23175 WHERE `entry`=23863 AND `groupid`=2 AND `id`=0;
+UPDATE `creature_text` SET `BroadcastTextId`=23176 WHERE `entry`=23863 AND `groupid`=3 AND `id`=0;
+UPDATE `creature_text` SET `BroadcastTextId`=23178 WHERE `entry`=23863 AND `groupid`=5 AND `id`=0;
+UPDATE `creature_text` SET `BroadcastTextId`=23179 WHERE `entry`=23863 AND `groupid`=6 AND `id`=0;
+UPDATE `creature_text` SET `BroadcastTextId`=23181 WHERE `entry`=23863 AND `groupid`=8 AND `id`=0;
+UPDATE `creature_text` SET `BroadcastTextId`=23182 WHERE `entry`=23863 AND `groupid`=8 AND `id`=1;
+UPDATE `creature_text` SET `BroadcastTextId`=23183 WHERE `entry`=23863 AND `groupid`=9 AND `id`=0;
diff --git a/sql/updates/world/2014_10_06_01_world.sql b/sql/updates/world/2014_10_06_01_world.sql
new file mode 100644
index 00000000000..841f5bc117b
--- /dev/null
+++ b/sql/updates/world/2014_10_06_01_world.sql
@@ -0,0 +1,38 @@
+-- BroadcastTextID0
+UPDATE `npc_text` SET `BroadcastTextID0`=3962 WHERE `ID`=1620;
+UPDATE `npc_text` SET `BroadcastTextID0`=3963 WHERE `ID`=1621;
+UPDATE `npc_text` SET `BroadcastTextID0`=8806 WHERE `ID`=6789;
+UPDATE `npc_text` SET `BroadcastTextID0`=9168 WHERE `ID`=6789;
+UPDATE `npc_text` SET `BroadcastTextID0`=9626 WHERE `ID`=7002;
+UPDATE `npc_text` SET `BroadcastTextID0`=9628 WHERE `ID`=7003;
+UPDATE `npc_text` SET `BroadcastTextID0`=9630 WHERE `ID`=7004;
+UPDATE `npc_text` SET `BroadcastTextID0`=9632 WHERE `ID`=7005;
+UPDATE `npc_text` SET `BroadcastTextID0`=11275 WHERE `ID`=8060;
+UPDATE `npc_text` SET `BroadcastTextID0`=11892 WHERE `ID`=8326;
+UPDATE `npc_text` SET `BroadcastTextID0`=11894 WHERE `ID`=8327;
+UPDATE `npc_text` SET `BroadcastTextID0`=12100 WHERE `ID`=8426;
+UPDATE `npc_text` SET `BroadcastTextID0`=12280 WHERE `ID`=8516;
+UPDATE `npc_text` SET `BroadcastTextID0`=14071 WHERE `ID`=8975;
+UPDATE `npc_text` SET `BroadcastTextID0`=14386 WHERE `ID`=9064;
+UPDATE `npc_text` SET `BroadcastTextID0`=17555 WHERE `ID`=9949;
+UPDATE `npc_text` SET `BroadcastTextID0`=19019 WHERE `ID`=10339;
+UPDATE `npc_text` SET `BroadcastTextID0`=19431 WHERE `ID`=10454;
+UPDATE `npc_text` SET `BroadcastTextID0`=20459 WHERE `ID`=10733;
+UPDATE `npc_text` SET `BroadcastTextID0`=20643 WHERE `ID`=10798;
+UPDATE `npc_text` SET `BroadcastTextID0`=20883 WHERE `ID`=10830;
+UPDATE `npc_text` SET `BroadcastTextID0`=21404 WHERE `ID`=10926;
+UPDATE `npc_text` SET `BroadcastTextID0`=21535 WHERE `ID`=10967;
+UPDATE `npc_text` SET `BroadcastTextID0`=21542 WHERE `ID`=10976;
+UPDATE `npc_text` SET `BroadcastTextID0`=21610 WHERE `ID`=11026;
+UPDATE `npc_text` SET `BroadcastTextID0`=21618 WHERE `ID`=11029;
+UPDATE `npc_text` SET `BroadcastTextID0`=21814 WHERE `ID`=11059;
+
+-- npc_text
+UPDATE `npc_text` SET `BroadcastTextID0`=10796 WHERE `ID`=7804;
+UPDATE `npc_text` SET `BroadcastTextID0`=2545 WHERE `ID`=6491;
+UPDATE `npc_text` SET `BroadcastTextID0`=6877 WHERE `ID`=4194;
+
+-- creature_text
+UPDATE `creature_text` SET `BroadcastTextId`=6198 WHERE `entry`=3977 AND `groupid`=1 AND `id`=0;
+UPDATE `creature_text` SET `BroadcastTextId`=35523 WHERE `entry`=35320 AND `groupid`=0 AND `id`=0;
+UPDATE `creature_text` SET `BroadcastTextId`=35529 WHERE `entry`=35320 AND `groupid`=1 AND `id`=0;
diff --git a/sql/updates/world/2014_10_06_02_world.sql b/sql/updates/world/2014_10_06_02_world.sql
new file mode 100644
index 00000000000..56929a9b5db
--- /dev/null
+++ b/sql/updates/world/2014_10_06_02_world.sql
@@ -0,0 +1,3 @@
+--
+UPDATE `creature_template` SET `faction`=834 WHERE `entry`=14435;
+UPDATE `creature_template` SET `faction`=90 WHERE `entry`=6268;
diff --git a/sql/updates/world/2014_10_06_03_world.sql b/sql/updates/world/2014_10_06_03_world.sql
new file mode 100644
index 00000000000..b0335d78834
--- /dev/null
+++ b/sql/updates/world/2014_10_06_03_world.sql
@@ -0,0 +1,2 @@
+--
+UPDATE `creature_template` SET `AIName`='' WHERE `entry`=21611;
diff --git a/sql/updates/world/2014_10_06_04_world.sql b/sql/updates/world/2014_10_06_04_world.sql
new file mode 100644
index 00000000000..41e18bcbb9e
--- /dev/null
+++ b/sql/updates/world/2014_10_06_04_world.sql
@@ -0,0 +1,66 @@
+DELETE FROM `waypoint_data` WHERE `id`=1131170;
+UPDATE `creature_addon` SET `path_id`=0 WHERE `guid`=113117;
+UPDATE `creature` SET `MovementType`=0 WHERE `guid`=113117;
+
+DELETE FROM `waypoints` WHERE `entry`=23734;
+
+INSERT INTO `waypoints` (`entry`, `pointid`, `position_x`, `position_y`, `position_z`, `point_comment`) VALUES
+(23734, 1, 629.388, -5021.37, 3.04091, 'Anchorite Yazmina <First Aid Trainer>'),
+(23734, 2, 630.836, -5011.95, 3.8314, 'Anchorite Yazmina <First Aid Trainer>'),
+(23734, 3, 630.836, -5011.95, 3.8314, 'Anchorite Yazmina <First Aid Trainer>'),
+(23734, 4, 624.458, -5003.92, 3.59241, 'Anchorite Yazmina <First Aid Trainer>'),
+(23734, 5, 614.28, -5005.49, 3.06355, 'Anchorite Yazmina <First Aid Trainer>'),
+(23734, 6, 607.946, -5014.89, 3.10032, 'Anchorite Yazmina <First Aid Trainer>'),
+(23734, 7, 612.983, -5025.49, 2.03711, 'Anchorite Yazmina <First Aid Trainer>'),
+(23734, 8, 625.177, -5026.14, 2.32847, 'Anchorite Yazmina <First Aid Trainer>');
+
+UPDATE `creature_template` SET `AIName`='SmartAI' WHERE `entry` IN(23734,23728);
+DELETE FROM `smart_scripts` WHERE `entryorguid` IN(23734,23728) AND `source_type`=0;
+DELETE FROM `smart_scripts` WHERE `entryorguid` IN(2373400,2373401,2373402,2373403,237404,2372800) AND `source_type`=9;
+
+INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES
+(23734, 0, 0, 0, 11, 0, 100, 0, 0, 0, 0, 0, 53, 0, 23734, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Anchorite Yazmina <First Aid Trainer> - On Spawn - Start WP'),
+(23734, 0, 1, 0, 40, 0, 5, 0, 0, 0, 0, 0, 87, 2373400,2373401,2373402,2373403,0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Anchorite Yazmina <First Aid Trainer> - On Reached WP - Run Random Script'),
+(23728, 0, 0, 0, 10, 0, 100, 0, 1, 50, 120000, 300000, 80, 2372800, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Guard Captain Zorek - OOC LOS - Run Script'),
+(2372800, 9, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Guard Captain Zorek - Script - Say Line 0'),
+(2372800, 9, 1, 0, 0, 0, 100, 0, 1000, 1000, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Guard Captain Zorek - Script - Say Line 1'),
+(2372800, 9, 2, 0, 0, 0, 100, 0, 5000, 5000, 0, 0, 1, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Guard Captain Zorek - Script - Say Line 2'),
+(2372800, 9, 3, 0, 0, 0, 100, 0, 11000, 11000, 0, 0, 1, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Guard Captain Zorek - Script - Say Line 3'),
+(2373400, 9, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 54, 10000, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Anchorite Yazmina <First Aid Trainer> - Script 1 - Pause WP'),
+(2373401, 9, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 54, 15000, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Anchorite Yazmina <First Aid Trainer> - Script 2 - Pause WP'),
+(2373401, 9, 1, 0, 0, 0, 100, 0, 0, 0, 0, 0, 66, 0, 0, 0, 0, 0, 0, 19, 23783, 0, 0, 0, 0, 0, 0, 'Anchorite Yazmina <First Aid Trainer> - Script 2 - Face Injured Defender'),
+(2373401, 9, 2, 0, 0, 0, 100, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Anchorite Yazmina <First Aid Trainer> - Script 2 - Say Line 1'),
+(2373401, 9, 3, 0, 0, 0, 100, 0, 5000, 5000, 0, 0, 90, 8, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Anchorite Yazmina <First Aid Trainer> - Script 2 - Set Bytes 1'),
+(2373401, 9, 4, 0, 0, 0, 100, 0, 1000, 1000, 0, 0, 17, 69, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Anchorite Yazmina <First Aid Trainer> - Script 2 - Set Emote State 69'),
+(2373401, 9, 5, 0, 0, 0, 100, 0, 6000, 6000, 0, 0, 17, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Anchorite Yazmina <First Aid Trainer> - Script 2 - Set Emote State 0'),
+(2373401, 9, 6, 0, 0, 0, 100, 0, 2000, 2000, 0, 0, 1, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Anchorite Yazmina <First Aid Trainer> - Script 2 - Say Line 2'),
+(2373401, 9, 7, 0, 0, 0, 100, 0, 1000, 1000, 0, 0, 91, 8, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Anchorite Yazmina <First Aid Trainer> - Script 2 - Remove Bytes 1'),
+(2373402, 9, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 54, 15000, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Anchorite Yazmina <First Aid Trainer> - Script 3 - Pause WP'),
+(2373402, 9, 1, 0, 0, 0, 100, 0, 0, 0, 0, 0, 66, 0, 0, 0, 0, 0, 0, 19, 23783, 0, 0, 0, 0, 0, 0, 'Anchorite Yazmina <First Aid Trainer> - Script 3 - Face Injured Defender'),
+(2373402, 9, 2, 0, 0, 0, 100, 0, 0, 0, 0, 0, 1, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Anchorite Yazmina <First Aid Trainer> - Script 3 - Say Line 3'),
+(2373402, 9, 3, 0, 0, 0, 100, 0, 4000, 4000, 0, 0, 90, 8, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Anchorite Yazmina <First Aid Trainer> - Script 3 - Set Bytes 1'),
+(2373402, 9, 4, 0, 0, 0, 100, 0, 2000, 2000, 0, 0, 17, 69, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Anchorite Yazmina <First Aid Trainer> - Script 3 - Set Emote State 69'),
+(2373402, 9, 5, 0, 0, 0, 100, 0, 6000, 6000, 0, 0, 17, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Anchorite Yazmina <First Aid Trainer> - Script 3 - Set Emote State 0'),
+(2373402, 9, 6, 0, 0, 0, 100, 0, 2000, 2000, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Anchorite Yazmina <First Aid Trainer> - Script 3 - Say Line 0'),
+(2373402, 9, 7, 0, 0, 0, 100, 0, 1000, 1000, 0, 0, 91, 8, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Anchorite Yazmina <First Aid Trainer> - Script 3 - Remove Bytes 1'),
+(2373403, 9, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 54, 15000, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Anchorite Yazmina <First Aid Trainer> - Script 4 - Pause WP'),
+(2373403, 9, 1, 0, 0, 0, 100, 0, 0, 0, 0, 0, 66, 0, 0, 0, 0, 0, 0, 19, 23783, 0, 0, 0, 0, 0, 0, 'Anchorite Yazmina <First Aid Trainer> - Script 4 - Face Injured Defender'),
+(2373403, 9, 2, 0, 0, 0, 100, 0, 0, 0, 0, 0, 1, 4, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Anchorite Yazmina <First Aid Trainer> - Script 4 - Say Line 4'),
+(2373403, 9, 3, 0, 0, 0, 100, 0, 4000, 4000, 0, 0, 90, 8, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Anchorite Yazmina <First Aid Trainer> - Script 4 - Set Bytes 1'),
+(2373403, 9, 4, 0, 0, 0, 100, 0, 2000, 2000, 0, 0, 17, 69, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Anchorite Yazmina <First Aid Trainer> - Script 4 - Set Emote State 69'),
+(2373403, 9, 5, 0, 0, 0, 100, 0, 6000, 6000, 0, 0, 17, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Anchorite Yazmina <First Aid Trainer> - Script 4 - Set Emote State 0'),
+(2373403, 9, 6, 0, 0, 0, 100, 0, 2000, 2000, 0, 0, 1, 5, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Anchorite Yazmina <First Aid Trainer> - Script 4 - Say Line 5'),
+(2373403, 9, 7, 0, 0, 0, 100, 0, 1000, 1000, 0, 0, 91, 8, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Anchorite Yazmina <First Aid Trainer> - Script 4 - Remove Bytes 1');
+
+DELETE FROM `creature_text` WHERE `entry` IN(23734,23728);
+INSERT INTO `creature_text` (`entry`, `groupid`, `id`, `text`, `type`, `language`, `probability`, `emote`, `duration`, `sound`, `comment`,`BroadcastTextID`) VALUES
+(23734, 0, 0, 'That should slow the infection down a little.', 12, 7, 100, 1, 0, 0, 'Anchorite Yazmina',22251),
+(23734, 1, 0, 'I can only hope the treatment will work.', 12, 7, 100, 1, 0, 0, 'Anchorite Yazmina',22828),
+(23734, 2, 0, 'I just don''t have the medical supplies I need to properly treat all of you.', 12, 7, 100, 1, 0, 5495, 'Anchorite Yazmina',22829),
+(23734, 3, 0, 'Oh my, let me change those bandages!', 12, 7, 100, 5, 0, 0, 'Anchorite Yazmina',22250),
+(23734, 4, 0, 'Don''t worry, soldier. Yazmina is going to take care of you.', 12, 7, 100, 1, 0, 0, 'Anchorite Yazmina',22830),
+(23734, 5, 0, '%s shakes her head.', 16, 7, 100, 274, 0, 0, 'Anchorite Yazmina',22831),
+(23728, 0, 0, '%s clears his throat.', 16, 7, 100, 0, 0, 0, 'Guard Captain Zorek',22737),
+(23728, 1, 0, 'I look across this base and all I see is fear... Are you gonna be scared when the Lich King''s armies are sittin'' pretty in Stormwind? Ironforge? NO! You''re not. And do you know why? Because you''ll be dead, that''s why.', 12, 7, 100, 1, 0, 0, 'Guard Captain Zorek',22738),
+(23728, 2, 0, 'So when you''re feeling that tinglin'' sensation at the base of your spine and you''re ''bout ready to wet your pants, embrace it. Let it enrage you. That fear is the only thing that''s gonna keep you breathin''.', 12, 7, 100, 25, 0, 0, 'Guard Captain Zorek',22739),
+(23728, 3, 0, 'Am I clear? Do you understand what I''m sayin''? I don''t wanna have to send any more coffins or letters home.', 12, 7, 100, 6, 0, 0, 'Guard Captain Zorek',22740);
diff --git a/sql/updates/world/2014_10_06_05_world.sql b/sql/updates/world/2014_10_06_05_world.sql
new file mode 100644
index 00000000000..8f9a4e67b33
--- /dev/null
+++ b/sql/updates/world/2014_10_06_05_world.sql
@@ -0,0 +1,2 @@
+--
+UPDATE `smart_scripts` SET `entryorguid`='21661' WHERE `entryorguid`=21611;
diff --git a/sql/updates/world/2014_10_06_06_world.sql b/sql/updates/world/2014_10_06_06_world.sql
new file mode 100644
index 00000000000..fde8bd4550a
--- /dev/null
+++ b/sql/updates/world/2014_10_06_06_world.sql
@@ -0,0 +1,30 @@
+DELETE FROM `gameobject_template` WHERE `entry` IN (184718,184722);
+INSERT INTO `gameobject_template` (`entry`, `type`, `displayId`, `name`, `data0`, `data1`, `data2`, `data3`, `size`, `VerifiedBuild`) VALUES
+(184718, 6, 327, 'Cauldron Summoner', 0, 0, 0, 36549, 1, -18019),
+(184722, 6, 327, 'Cauldron Bug Summoner', 0, 0, 0, 36552, 1, -18019);
+
+DELETE FROM `gameobject` WHERE `guid` IN(25566,25567) AND `id` IN(184721,184717,184722,184718);
+
+INSERT INTO `gameobject` (`guid`, `id`, `map`, `spawnMask`, `phaseMask`, `position_x`, `position_y`, `position_z`, `orientation`, `rotation0`, `rotation1`, `rotation2`, `rotation3`, `spawntimesecs`, `animprogress`, `state`, `VerifiedBuild`) VALUES
+(25566, 184718, 530, 1, 1, -970.813, 2172, 15.5428, -2.33874, 0, 0, 0.920505, -0.390731, 0, 100, 1, 0),
+(25567, 184722, 530, 1, 1, -970.813, 2172, 15.5428, -2.33874, 0, 0, 0.920505, -0.390731, 0, 100, 1, 0);
+
+DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=13 AND `SourceEntry`=36546;
+INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES
+(13, 1, 36546, 0, 0, 31, 0, 5, 184715, 0, 0, 0, 0, '', 'Boil Bleeding Hollow Blood - Cursed Cauldron'),
+(13, 2, 36546, 0, 0, 31, 0, 5, 184722, 0, 0, 0, 0, '', 'Boil Bleeding Hollow Blood - Cauldron Bug Summoner');
+
+UPDATE `creature_template` SET `AIName`='SmartAI' WHERE `entry` IN(21308,21306);
+DELETE FROM `smart_scripts` WHERE `entryorguid` IN(21308,21306) AND `source_type`=0;
+
+INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES
+(21308, 0, 0, 0, 11, 0, 100, 0, 0, 0, 0, 0, 11, 36555, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Cursed Scarab Summoner - On Spawn - Cast Summon Cursed Scarabs'),
+(21306, 0, 0, 1, 11, 0, 100, 0, 0, 0, 0, 0, 89, 20, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Cursed Scarab - On Spawn - Set Random Movement'),
+(21306, 0, 1, 2, 61, 0, 100, 0, 0, 0, 0, 0, 59, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Cursed Scarab - On Spawn - Set Run On'),
+(21306, 0, 2, 3, 61, 0, 100, 0, 0, 0, 0, 0, 11, 36556, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Cursed Scarab - On Spawn - Cast Cursed Scarab Periodic'),
+(21306, 0, 3, 4, 61, 0, 100, 0, 0, 0, 0, 0, 11, 36559, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Cursed Scarab - On Spawn - Cast Cursed Scarab Despawn Timer'),
+(21306, 0, 4, 0, 61, 0, 100, 0, 0, 0, 0, 0, 11, 31309, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Cursed Scarab - On Spawn - Cast Spirit Particles (red, big)'),
+(21306, 0, 5, 0, 8, 0, 100, 0, 36560, 0, 0, 0, 41, 40000, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Cursed Scarab - On Spellhit (Cursed Scarab Despawn Periodic Trigger) - Despawn'),
+(21306, 0, 6, 7, 1, 0, 100, 1, 5000, 90000, 0, 0, 2, 14, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Cursed Scarab - OOC - Set faction'),
+(21306, 0, 7, 8, 61, 0, 100, 1, 0, 0, 0, 0, 8, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Cursed Scarab - OOC - Set Hostile'),
+(21306, 0, 8, 0, 61, 0, 100, 1, 0, 0, 0, 0, 49, 0, 0, 0, 0, 0, 0, 21, 100, 0, 0, 0, 0, 0, 0, 'Cursed Scarab - OOC - Attack Sumoner');
diff --git a/sql/updates/world/2014_10_07_00_world.sql b/sql/updates/world/2014_10_07_00_world.sql
new file mode 100644
index 00000000000..85962032e03
--- /dev/null
+++ b/sql/updates/world/2014_10_07_00_world.sql
@@ -0,0 +1,21 @@
+-- npc_text
+UPDATE `npc_text` SET `BroadcastTextID0`=5195 WHERE `ID`=2838;
+UPDATE `npc_text` SET `BroadcastTextID0`=11738 WHERE `ID`=8296;
+UPDATE `npc_text` SET `BroadcastTextID0`=11790 WHERE `ID`=8282;
+UPDATE `npc_text` SET `BroadcastTextID0`=11797 WHERE `ID`=8298;
+UPDATE `npc_text` SET `BroadcastTextID0`=20625 WHERE `ID`=10787;
+UPDATE `npc_text` SET `BroadcastTextID0`=37804 WHERE `ID`=15240;
+UPDATE `npc_text` SET `BroadcastTextID0`=11736 WHERE `ID`=8244;
+UPDATE `npc_text` SET `BroadcastTextID0`=11799 WHERE `ID`=8291;
+UPDATE `npc_text` SET `BroadcastTextID0`=12770 WHERE `ID`=8663;
+UPDATE `npc_text` SET `BroadcastTextID0`=14410 WHERE `ID`=9072;
+UPDATE `npc_text` SET `BroadcastTextID0`=14546 WHERE `ID`=9110;
+UPDATE `npc_text` SET `BroadcastTextID0`=17748 WHERE `ID`=9984;
+UPDATE `npc_text` SET `BroadcastTextID0`=21971 WHERE `ID`=11093;
+UPDATE `npc_text` SET `BroadcastTextID0`=27167 WHERE `ID`=12978;
+UPDATE `npc_text` SET `BroadcastTextID0`=32577 WHERE `ID`=14089;
+UPDATE `npc_text` SET `BroadcastTextID0`=37148 WHERE `ID`=15155;
+UPDATE `npc_text` SET `BroadcastTextID0`=38655 WHERE `ID`=15412;
+UPDATE `npc_text` SET `BroadcastTextID0`=40449 WHERE `ID`=15866;
+UPDATE `npc_text` SET `BroadcastTextID0`=40471 WHERE `ID`=15873;
+UPDATE `npc_text` SET `BroadcastTextID0`=40482 WHERE `ID`=15877;
diff --git a/sql/updates/world/2014_10_07_01_world.sql b/sql/updates/world/2014_10_07_01_world.sql
new file mode 100644
index 00000000000..6d9940f7666
--- /dev/null
+++ b/sql/updates/world/2014_10_07_01_world.sql
@@ -0,0 +1,61 @@
+-- Fix Quest 11501 "News From the East"
+
+SET @WALT := 24807;
+SET @CONSTRUCT := 24852;
+
+UPDATE `creature_template` SET `npcflag`=`npcflag`|1 WHERE `entry`=@WALT;
+UPDATE `creature_template` SET `speed_run`=4.285714, `VehicleId`=87, `InhabitType`=4 WHERE `entry`=@CONSTRUCT;
+
+UPDATE `creature_template` SET `AIName`='SmartAI' WHERE `entry` IN (@WALT,@CONSTRUCT);
+DELETE FROM `smart_scripts` WHERE `entryorguid` IN (@WALT,@CONSTRUCT) AND `source_type`=0;
+DELETE FROM `smart_scripts` WHERE `entryorguid`=@CONSTRUCT*100 AND `source_type`=9;
+INSERT INTO `smart_scripts` (`entryorguid`,`source_type`,`id`,`link`,`event_type`,`event_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action_type`,`action_param1`,`action_param2`,`action_param3`,`action_param4`,`action_param5`,`action_param6`,`target_type`,`target_param1`,`target_param2`,`target_param3`,`target_x`,`target_y`,`target_z`,`target_o`,`comment`) VALUES
+(@WALT,0,0,1,62,0,100,0,9022,0,0,0,11,49975,0,0,0,0,0,7,0,0,0,0,0,0,0, 'Walt <Explorers'' League> - On gossip option select - Spellcast Iron Rune Construct Taxi'),
+(@WALT,0,1,0,61,0,100,0,0,0,0,0,72,0,0,0,0,0,0,7,0,0,0,0,0,0,0, 'Walt <Explorers'' League> - On gossip option select - Close gossip'),
+(@CONSTRUCT,0,0,0,54,0,100,0,0,0,0,0,80,@CONSTRUCT*100,2,0,0,0,0,1,0,0,0,0,0,0,0, 'Iron Rune Construct - Just summoned - Run script'),
+(@CONSTRUCT,0,1,2,40,0,100,1,18,@CONSTRUCT,0,0,1,1,2000,0,0,0,0,1,0,0,0,0,0,0,0, 'Iron Rune Construct - On WP 18 reached - Say line'),
+(@CONSTRUCT,0,2,0,61,0,100,0,0,0,0,0,28,44687,0,0,0,0,0,1,0,0,0,0,0,0,0, 'Iron Rune Construct - On WP 18 reached - Remove aura Rocket Jump'),
+(@CONSTRUCT,0,3,0,52,0,100,0,1,@CONSTRUCT,0,0,11,44688,0,0,0,0,0,1,0,0,0,0,0,0,0, 'Iron Rune Construct - On text over - Spellcast System Failure'),
+
+(@CONSTRUCT*100,9,0,0,0,0,100,0,4000,4000,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0, 'Iron Rune Construct script - Say line'),
+(@CONSTRUCT*100,9,1,0,0,0,100,0,0,0,0,0,11,44687,0,0,0,0,0,1,0,0,0,0,0,0,0, 'Iron Rune Construct script - Spellcast Rocket Jump'),
+(@CONSTRUCT*100,9,2,0,0,0,100,0,2000,2000,0,0,53,1,@CONSTRUCT,0,0,0,0,1,0,0,0,0,0,0,0, 'Iron Rune Construct script - Start WP movement');
+
+DELETE FROM `gossip_menu_option` WHERE `menu_id`=9022 AND `id`=0;
+INSERT INTO `gossip_menu_option` (`menu_id`,`id`,`option_icon`,`option_text`,`OptionBroadcastTextID`,`option_id`,`npc_option_npcflag`,`action_menu_id`,`action_poi_id`,`box_coded`,`box_money`,`box_text`) VALUES
+(9022,0,0,'I''m ready to go, Walt.',23929,1,1,0,0,0,0,'');
+
+DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=15 AND `SourceGroup`=9022;
+INSERT INTO `conditions` (`SourceTypeOrReferenceId`,`SourceGroup`,`SourceEntry`,`ElseGroup`,`ConditionTypeOrReference`,`ConditionValue1`,`ConditionValue2`,`ConditionValue3`,`ErrorTextId`,`ScriptName`,`Comment`) VALUES
+(15,9022,0,0,28,11501,0,0,0,'','Walt <Explorers'' League> - Show gossip option only if player has completed but not rewarded quest News From the East');
+
+DELETE FROM `creature_text` WHERE `entry`=@CONSTRUCT;
+INSERT INTO `creature_text` (`entry`,`groupid`,`id`,`text`,`type`,`language`,`probability`,`emote`,`duration`,`sound`,`comment`,`BroadcastTextID`) VALUES
+(@CONSTRUCT,0,0,'Launching.',12,0,100,0,0,0,'Iron Rune Construct',23860),
+(@CONSTRUCT,1,0,'System failure in 3... 2...',12,0,100,0,0,0,'Iron Rune Construct',23930);
+
+DELETE FROM `waypoints` WHERE `entry`=@CONSTRUCT;
+INSERT INTO `waypoints` (`entry`,`pointid`,`position_x`,`position_y`,`position_z`,`point_comment`) VALUES
+(@CONSTRUCT,1,479.0616,-5941.539,316.96,'Iron Rune Construct'),
+(@CONSTRUCT,2,479.2529,-5941.489,365.9878,'Iron Rune Construct'),
+(@CONSTRUCT,3,517.0134,-5825.359,365.9878,'Iron Rune Construct'),
+(@CONSTRUCT,4,527.9034,-5659.926,365.9878,'Iron Rune Construct'),
+(@CONSTRUCT,5,715.0627,-5351.074,365.9878,'Iron Rune Construct'),
+(@CONSTRUCT,6,768.4551,-5018.862,365.9878,'Iron Rune Construct'),
+(@CONSTRUCT,7,840.6277,-4827.729,365.9878,'Iron Rune Construct'),
+(@CONSTRUCT,8,864.8306,-4741.804,365.9878,'Iron Rune Construct'),
+(@CONSTRUCT,9,966.0306,-4488.406,365.9878,'Iron Rune Construct'),
+(@CONSTRUCT,10,1030.845,-4374.208,346.4599,'Iron Rune Construct'),
+(@CONSTRUCT,11,1063.375,-4205.252,346.4599,'Iron Rune Construct'),
+(@CONSTRUCT,12,1066.279,-4072.605,289.821,'Iron Rune Construct'),
+(@CONSTRUCT,13,1066.46,-3833.815,282.9599,'Iron Rune Construct'),
+(@CONSTRUCT,14,1236.65,-3685.513,282.9599,'Iron Rune Construct'),
+(@CONSTRUCT,15,1357.56,-3430.121,217.8767,'Iron Rune Construct'),
+(@CONSTRUCT,16,1382.808,-3290.728,217.8767,'Iron Rune Construct'),
+(@CONSTRUCT,17,1388.928,-3261.844,203.7378,'Iron Rune Construct'),
+(@CONSTRUCT,18,1390.475,-3262.215,161.9602,'Iron Rune Construct');
+
+DELETE FROM `spell_scripts` WHERE `id`=44688 AND `command`=14;
+INSERT INTO `spell_scripts` (`id`,`effIndex`,`delay`,`command`,`datalong`,`datalong2`,`dataint`,`x`,`y`,`z`,`o`) VALUES
+(44688,0,0,14,46598,0,0,0,0,0,0),
+(44688,0,0,15,44741,1,0,0,0,0,0);
diff --git a/sql/updates/world/2014_10_08_00_world.sql b/sql/updates/world/2014_10_08_00_world.sql
new file mode 100644
index 00000000000..baacc085323
--- /dev/null
+++ b/sql/updates/world/2014_10_08_00_world.sql
@@ -0,0 +1,44 @@
+--
+SET @Hira :=31238;
+
+UPDATE creature_template SET ScriptName='', `AIName`='SmartAI', InhabitType=4 WHERE entry=@Hira;
+DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=15 AND `SourceGroup`=10723;
+INSERT INTO `conditions` (`SourceTypeOrReferenceId`,`SourceGroup`,`SourceEntry`,`ElseGroup`,`ConditionTypeOrReference`,`ConditionValue1`,`ConditionValue2`,`ConditionValue3`, `ErrorTextId`,`ScriptName`,`Comment`) VALUES
+(15,10723,1,0,27,80,3,0,0,'','Show gossip menu if player''s level 80 or higher'),
+(15,10723,1,0,25,54197,0,0,0,'','Show gossip menu if player has lerned 54197');
+
+DELETE FROM `smart_scripts` WHERE `entryorguid` = @Hira AND `source_type` = 0;
+DELETE FROM `smart_scripts` WHERE `entryorguid` = @Hira*100 AND `source_type` = 9;
+DELETE FROM `smart_scripts` WHERE `entryorguid` = @Hira*100+1 AND `source_type` = 9;
+INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES
+(@Hira, 0, 0, 0, 1, 0, 100, 0, 600000, 600000, 600000, 600000, 80, @Hira*100, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Hira - OOC - actionlist'),
+(@Hira*100, 9, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Hira - actionlist - talk (emote)'),
+(@Hira*100, 9, 1, 0, 0, 0, 100, 0, 5000, 5000, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Hira - actionlist - talk'),
+(@Hira*100, 9, 2, 0, 0, 0, 100, 0, 0, 0, 0, 0, 18, 33554432, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Hira - actionlist - set UNIT_FLAG_NOT_SELECTABLE'),
+(@Hira*100, 9, 3, 0, 0, 0, 100, 0, 0, 0, 0, 0, 53, 1, @Hira, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Hira - actionlist - start wp'),
+(@Hira,0 ,1 ,0 ,40 ,0 ,100 ,0, 11, 0, 0, 0 ,80, @Hira*100+1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Ruul the Darkener - way point reached - Re action list'),
+(@Hira*100+1, 9, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 66, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 5815.272, 473.4902, 658.7961, 4.660029, 'Hira - actionlist - SET Orientation'),
+(@Hira*100+1, 9, 1, 0, 0, 0, 100, 0, 0, 0, 0, 0, 19, 33554432, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Hira - actionlist - remove UNIT_FLAG_NOT_SELECTABLE');
+
+DELETE FROM `waypoints` WHERE `entry`=@Hira;
+INSERT INTO `waypoints` (`entry`,`pointid`,`position_x`,`position_y`,`position_z`,`point_comment`) VALUES
+(@Hira,1,5806.834, 475.4562, 661.3664, 'Hira Snowdawn WP'),
+(@Hira,2,5792.614, 466.3004, 662.0329, 'Hira Snowdawn WP'),
+(@Hira,3,5786.764, 450.582, 662.5331, 'Hira Snowdawn WP'),
+(@Hira,4,5791.111, 434.2068, 665.3663, 'Hira Snowdawn WP'),
+(@Hira,5,5804.108, 423.6482, 665.6719, 'Hira Snowdawn WP'),
+(@Hira,6,5821.129, 422.7363, 665.1718, 'Hira Snowdawn WP'),
+(@Hira,7,5835.191, 431.9838, 663.9774, 'Hira Snowdawn WP'),
+(@Hira,8,5841.177, 447.7776, 662.783, 'Hira Snowdawn WP'),
+(@Hira,9,5836.82, 464.0104, 661.894, 'Hira Snowdawn WP'),
+(@Hira,10,5823.853, 474.5901, 661.3664, 'Hira Snowdawn WP'),
+(@Hira,11,5815.272, 473.4902, 658.7961, 'Hira Snowdawn WP');
+
+DELETE FROM `creature_text` WHERE `entry` IN (@Hira);
+INSERT INTO `creature_text` (`entry`, `groupid`, `id`, `text`, `type`, `language`, `probability`, `emote`, `duration`, `sound`, `comment`, `BroadcastTextID`) VALUES
+(@Hira, 0, 0, 'Come, Cloudwing. Let''s do a lap.', 12, 0, 100, 0, 0, 0, 'Hira Snowdawn', 32247),
+(@Hira, 0, 1, 'Feeling as restless as I am, Cloudwing? Then let us fly!', 12, 0, 100, 0, 0, 0, 'Hira Snowdawn', 32252),
+(@Hira, 0, 2, 'I''m bored, Cloudwing. Go, go!', 12, 0, 100, 0, 0, 0, 'Hira Snowdawn', 32251),
+(@Hira, 1, 0, '%s sighs softly and rolls her shoulders.', 16, 0, 100, 0, 0, 0, 'Hira Snowdawn', 32249),
+(@Hira, 1, 1, '%s looks around Krasus'' Landing, bored.', 16, 0, 100, 0, 0, 0, 'Hira Snowdawn', 32244),
+(@Hira, 1, 2, '%s yawns quietly into the palm of her hand.', 16, 0, 100, 0, 0, 0, 'Hira Snowdawn', 32245);
diff --git a/sql/updates/world/2014_10_08_01_world.sql b/sql/updates/world/2014_10_08_01_world.sql
new file mode 100644
index 00000000000..f7fb328965b
--- /dev/null
+++ b/sql/updates/world/2014_10_08_01_world.sql
@@ -0,0 +1,10 @@
+--
+UPDATE `creature_text` SET `BroadcastTextId`=0 WHERE `entry`=3977 AND `groupid`=1;
+UPDATE `creature_text` SET `BroadcastTextId`=0 WHERE `entry`=11380 AND `groupid`=0;
+UPDATE `creature_text` SET `BroadcastTextId`=0 WHERE `entry`=23863 AND `groupid`=2;
+UPDATE `creature_text` SET `BroadcastTextId`=0 WHERE `entry`=23863 AND `groupid`=3;
+UPDATE `creature_text` SET `BroadcastTextId`=0 WHERE `entry`=23863 AND `groupid`=4;
+UPDATE `creature_text` SET `BroadcastTextId`=0 WHERE `entry`=23863 AND `groupid`=5;
+UPDATE `creature_text` SET `BroadcastTextId`=0 WHERE `entry`=23863 AND `groupid`=6;
+UPDATE `creature_text` SET `BroadcastTextId`=0 WHERE `entry`=23863 AND `groupid`=8;
+UPDATE `creature_text` SET `BroadcastTextId`=0 WHERE `entry`=23863 AND `groupid`=9;
diff --git a/sql/updates/world/2014_10_08_02_world.sql b/sql/updates/world/2014_10_08_02_world.sql
new file mode 100644
index 00000000000..b53cf736b62
--- /dev/null
+++ b/sql/updates/world/2014_10_08_02_world.sql
@@ -0,0 +1,8 @@
+DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=17 AND `SourceEntry`=48046;
+INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES
+(17, 0, 48046, 0, 0, 31, 1, 3, 26408, 0, 0, 0, 0, '', "Use Camera targets Iron Rune-Smith"),
+(17, 0, 48046, 0, 0, 36, 1, 0, 0, 0, 1, 0, 0, '', "Target must be dead"),
+(17, 0, 48046, 0, 1, 31, 1, 3, 26414, 0, 0, 0, 0, '', "Use Camera targets Runic Lightning Gunner"),
+(17, 0, 48046, 0, 1, 36, 1, 0, 0, 0, 1, 0, 0, '', "Target must be dead"),
+(17, 0, 48046, 0, 2, 31, 1, 3, 27177, 0, 0, 0, 0, '', "Use Camera targets Iron Rune Overseer"),
+(17, 0, 48046, 0, 2, 36, 1, 0, 0, 0, 1, 0, 0, '', "Target must be dead");
diff --git a/sql/updates/world/2014_10_09_00_world.sql b/sql/updates/world/2014_10_09_00_world.sql
new file mode 100644
index 00000000000..00d70229bea
--- /dev/null
+++ b/sql/updates/world/2014_10_09_00_world.sql
@@ -0,0 +1,5 @@
+--
+DELETE FROM `spell_target_position` WHERE `id` IN (28444,72613);
+INSERT INTO `spell_target_position` (`id`, `effIndex`, `target_map`, `target_position_x`, `target_position_y`, `target_position_z`, `target_orientation`, `VerifiedBuild`) VALUES
+(72613, 0, 533, 3005.509277, -3434.641113, 304.195, 5.81041, 0),
+(28444, 0, 533, 3005.509277, -3434.641113, 304.195, 5.81041, 0);
diff --git a/sql/updates/world/2014_10_09_01_world.sql b/sql/updates/world/2014_10_09_01_world.sql
new file mode 100644
index 00000000000..5ffe056a8c9
--- /dev/null
+++ b/sql/updates/world/2014_10_09_01_world.sql
@@ -0,0 +1,7 @@
+--
+DELETE FROM `spell_linked_spell` WHERE `spell_trigger`=47435;
+INSERT INTO `spell_linked_spell` (`spell_trigger`, `spell_effect`, `type`, `comment`) VALUES
+(47435, -47447, 0, 'remove debuff');
+DELETE FROM `conditions` WHERE `sourcetypeorreferenceid`=17 AND `sourceentry`=47435;
+INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES
+(17,0,47435,0,0,1,0,47447,1,0,0,0,0,'','Cast ''Scrape Corrosive Spit'' only if player has ''Corrosive Spit''');
diff --git a/sql/updates/world/2014_10_09_02_world.sql b/sql/updates/world/2014_10_09_02_world.sql
new file mode 100644
index 00000000000..32b79006de6
--- /dev/null
+++ b/sql/updates/world/2014_10_09_02_world.sql
@@ -0,0 +1,215 @@
+SET @Guid := 74522;
+SET @Entry := 19610;
+
+DELETE FROM `creature_text` WHERE `entry` in(19610,19217);
+INSERT INTO `creature_text` (`entry`, `groupid`, `id`, `text`, `type`, `language`, `probability`, `emote`, `duration`, `sound`, `comment`,`BroadcastTextID`) VALUES
+(19610, 0, 0, 'A skunk! Eeeeeeeeeeeeeeeeeew! Don''t touch me!', 12, 0, 100, 0, 0, 0, 'Irradiated Worker',17857),
+(19610, 1, 0, 'Get it away from me!', 12, 0, 100, 0, 0, 0, 'Irradiated Worker',17858),
+(19610, 2, 0, 'Show us a trick, Ravandwyr!', 12, 0, 100, 0, 0, 0, 'Irradiated Worker',17852),
+(19610, 3, 0, 'Let me outta here! Guys... guys?', 12, 0, 100, 0, 0, 0, 'Irradiated Worker',17874),
+(19610, 4, 0, 'Oh man, he got you good!', 12, 0, 100, 0, 0, 0, 'Irradiated Worker',17875),
+(19610, 5, 0, 'Remember how you''re always telling us to chill?', 12, 0, 100, 11, 0, 0, 'Irradiated Worker',17876),
+(19610, 6, 0, 'That was the best trick ever! Ok, boys, let''s go get a drink.', 12, 0, 100, 4, 0, 0, 'Irradiated Worker',17853),
+(19610, 7, 0, 'My eyebrows! You singed my eyebrows!', 12, 0, 100, 22, 0, 0, 'Irradiated Worker',20285),
+(19610, 8, 0, 'Don''t worry. It''s an improvement!', 12, 0, 100, 11, 0, 0, 'Irradiated Worker',20286),
+(19217, 0, 0, 'Oh, another show already? Very well then...', 12, 0, 100, 1, 0, 0, 'Ravandwyr',17848),
+(19217, 1, 0, '%s sighs audibly and glances at Sagan.', 16, 0, 100, 0, 0, 0, 'Ravandwyr',17849),
+(19217, 2, 0, 'I shall transform my familiar, Sagan, into something truly wondrous!', 12, 0, 100, 25, 0, 0, 'Ravandwyr',17855),
+(19217, 3, 0, 'And, for my next trick...', 12, 0, 100, 1, 0, 0, 'Ravandwyr',17850),
+(19217, 4, 0, 'A simple practical joke.', 12, 0, 100, 25, 0, 0, 'Ravandwyr',17877),
+(19217, 5, 0, 'Thank you for watching, everyone! If you''d be so kind as to bring your non-irradiated currency to tomorrow''s performance, I''d appreciate it.', 12, 0, 100, 2, 0, 0, 'Ravandwyr',17856),
+(19217, 6, 0, 'I shall breathe fire!', 12, 0, 100, 25, 0, 0, 'Ravandwyr',17854);
+
+UPDATE `creature_template` SET `ainame`='SmartAI', `scriptname`='' WHERE `entry` IN(19610,19217,19482);
+DELETE FROM `smart_scripts` WHERE `entryorguid` IN(19610,19217,-@Guid-0,-@Guid-1,-@Guid-2,19482) AND `source_type`=0;
+DELETE FROM `smart_scripts` WHERE `entryorguid` IN(1921700,1921701,1921702) AND `source_type`=9;
+
+INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES
+(1921700, 9, 0, 0, 0, 0, 100, 0, 4000, 4000, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Ravandwyr - Script 1 - Say Line 0'),
+(1921700, 9, 1, 0, 0, 0, 100, 0, 4000, 4000, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Ravandwyr - Script 1 - Say Line 1'),
+(1921700, 9, 2, 0, 0, 0, 100, 0, 2000, 2000, 0, 0, 1, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Ravandwyr - Script 1 - Say Line 3'),
+(1921700, 9, 3, 0, 0, 0, 100, 0, 2000, 2000, 0, 0, 1, 4, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Ravandwyr - Script 1 - Say Line 4'),
+(1921700, 9, 4, 0, 0, 0, 100, 0, 2000, 2000, 0, 0, 11, 34326, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Ravandwyr - Script 1 - Cast Frost Nova'),
+(1921700, 9, 5, 0, 0, 0, 100, 0, 2000, 2000, 0, 0, 45, 3, 3, 0, 0, 0, 0, 10, @Guid+1, 19610, 0, 0, 0, 0, 0, 'Ravandwyr - Script 1 - Set Data Irradiated Worker'),
+(1921700, 9, 6, 0, 0, 0, 100, 0, 3000, 3000, 0, 0, 1, 3, 0, 0, 0, 0, 0, 10, @Guid+1, 19610, 0, 0, 0, 0, 0, 'Ravandwyr - Script 1 - Say Line 3 on Irradiated Worker'),
+(1921700, 9, 7, 0, 0, 0, 100, 0, 1000, 1000, 0, 0, 5, 11, 0, 0, 0, 0, 0, 9, 19610, 0, 20, 0, 0, 0, 0, 'Ravandwyr - Script 1 - Play Emote OneShotLaugh'),
+(1921700, 9, 8, 0, 0, 0, 100, 0, 3000, 3000, 0, 0, 1, 4, 0, 0, 0, 0, 0, 10, @Guid+2, 19610, 0, 0, 0, 0, 0, 'Ravandwyr - Script 1 - Say Line 4 on Irradiated Worker'),
+(1921700, 9, 9, 0, 0, 0, 100, 0, 4000, 4000, 0, 0, 5, 11, 0, 0, 0, 0, 0, 9, 19610, 0, 20, 0, 0, 0, 0, 'Ravandwyr - Script 1 - Play Emote OneShotLaugh'),
+(1921700, 9, 10, 0, 0, 0, 100, 0, 1000, 1000, 0, 0, 1, 5, 0, 0, 0, 0, 0, 10, @Guid+0, 19610, 0, 0, 0, 0, 0, 'Ravandwyr - Script 1 - Say Line 5 on Irradiated Worker'),
+(1921700, 9, 11, 0, 0, 0, 100, 0, 2000, 2000, 0, 0, 1, 5, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Ravandwyr - Script 1 - Say Line 5'),
+(1921700, 9, 12, 0, 0, 0, 100, 0, 3000, 3000, 0, 0, 5, 4, 0, 0, 0, 0, 0, 9, 19610, 0, 20, 0, 0, 0, 0, 'Ravandwyr - Script 1 - Play Emote OneShotCheer'),
+(1921700, 9, 13, 0, 0, 0, 100, 0, 3000, 3000, 0, 0, 1, 6, 0, 0, 0, 0, 0, 10, @Guid+2, 19610, 0, 0, 0, 0, 0, 'Ravandwyr - Script 1 - Say Line 6'),
+(1921700, 9, 14, 0, 0, 0, 100, 0, 4000, 4000, 0, 0, 45, 2, 2, 0, 0, 0, 0, 9, 19610, 0, 100, 0, 0, 0, 0, 'Ravandwyr - Script 1 - Set Data on Irradiated Worker'),
+(1921701, 9, 0, 0, 0, 0, 100, 0, 4000, 4000, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Ravandwyr - Script 2 - Say Line 0'),
+(1921701, 9, 1, 0, 0, 0, 100, 0, 4000, 4000, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Ravandwyr - Script 2 - Say Line 1'),
+(1921701, 9, 2, 0, 0, 0, 100, 0, 2000, 2000, 0, 0, 1, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Ravandwyr - Script 2 - Say Line 3'),
+(1921701, 9, 3, 0, 0, 0, 100, 0, 2000, 2000, 0, 0, 1, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Ravandwyr - Script 2 - Say Line 2'),
+(1921701, 9, 4, 0, 0, 0, 100, 0, 4000, 4000, 0, 0, 11, 34656, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Ravandwyr - Script 2 - Cast Arcane Explosion (Cosmetic)'),
+(1921701, 9, 5, 0, 0, 0, 100, 0, 1000, 1000, 0, 0, 45, 1, 1, 0, 0, 0, 0, 19, 19482, 0, 0, 0, 0, 0, 0, 'Ravandwyr - Script 2 - Set Data Sagan'),
+(1921701, 9, 6, 0, 0, 0, 100, 0, 3000, 3000, 0, 0, 1, 0, 0, 0, 0, 0, 0, 10, @Guid+2, 19610, 0, 0, 0, 0, 0, 'Ravandwyr - Script 2 - Say Line 0 on Irradiated Worker'),
+(1921701, 9, 7, 0, 0, 0, 100, 0, 5000, 5000, 0, 0, 1, 1, 0, 0, 0, 0, 0, 10, @Guid+1, 19610, 0, 0, 0, 0, 0, 'Ravandwyr - Script 2 - Say Line 1 on Irradiated Worker'),
+(1921701, 9, 8, 0, 0, 0, 100, 0, 5000, 5000, 0, 0, 45, 2, 2, 0, 0, 0, 0, 19, 19482, 0, 0, 0, 0, 0, 0, 'Ravandwyr - Script 2 - Set Data Sagan'),
+(1921701, 9, 9, 0, 0, 0, 100, 0, 2000, 2000, 0, 0, 1, 5, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Ravandwyr - Script 2 - Say Line 5'),
+(1921701, 9, 10, 0, 0, 0, 100, 0, 3000, 3000, 0, 0, 5, 4, 0, 0, 0, 0, 0, 9, 19610, 0, 20, 0, 0, 0, 0, 'Ravandwyr - Script 2 - Play Emote OneShotCheer'),
+(1921701, 9, 11, 0, 0, 0, 100, 0, 3000, 3000, 0, 0, 1, 6, 0, 0, 0, 0, 0, 10, @Guid+2, 19610, 0, 0, 0, 0, 0, 'Ravandwyr - Script 2 - Say Line 6'),
+(1921701, 9, 12, 0, 0, 0, 100, 0, 4000, 4000, 0, 0, 45, 2, 2, 0, 0, 0, 0, 9, 19610, 0, 100, 0, 0, 0, 0, 'Ravandwyr - Script 2 - Set Data on Irradiated Worker'),
+(1921702, 9, 0, 0, 0, 0, 100, 0, 4000, 4000, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Ravandwyr - Script 3 - Say Line 0'),
+(1921702, 9, 1, 0, 0, 0, 100, 0, 4000, 4000, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Ravandwyr - Script 3 - Say Line 1'),
+(1921702, 9, 2, 0, 0, 0, 100, 0, 2000, 2000, 0, 0, 1, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Ravandwyr - Script 3 - Say Line 3'),
+(1921702, 9, 3, 0, 0, 0, 100, 0, 2000, 2000, 0, 0, 1, 6, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Ravandwyr - Script 3 - Say Line 6'),
+(1921702, 9, 4, 0, 0, 0, 100, 0, 4000, 4000, 0, 0, 11, 29389, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Ravandwyr - Script 3 - Cast Firebreathing'),
+(1921702, 9, 5, 0, 0, 0, 100, 0, 2000, 2000, 0, 0, 1, 7, 0, 0, 0, 0, 0, 10, @Guid+1, 19610, 0, 0, 0, 0, 0, 'Ravandwyr - Script 3 - Say Line 7 on Irradiated Worker'),
+(1921702, 9, 6, 0, 0, 0, 100, 0, 5000, 5000, 0, 0, 1, 8, 0, 0, 0, 0, 0, 10, @Guid+2, 19610, 0, 0, 0, 0, 0, 'Ravandwyr - Script 3 - Say Line 8 on Irradiated Worker'),
+(1921702, 9, 7, 0, 0, 0, 100, 0, 2000, 2000, 0, 0, 1, 5, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Ravandwyr - Script 3 - Say Line 5'),
+(1921702, 9, 8, 0, 0, 0, 100, 0, 3000, 3000, 0, 0, 5, 4, 0, 0, 0, 0, 0, 9, 19610, 0, 20, 0, 0, 0, 0, 'Ravandwyr - Script 3 - Play Emote OneShotCheer'),
+(1921702, 9, 9, 0, 0, 0, 100, 0, 3000, 3000, 0, 0, 1, 6, 0, 0, 0, 0, 0, 10, @Guid+2, 19610, 0, 0, 0, 0, 0, 'Ravandwyr - Script 3 - Say Line 6'),
+(1921702, 9, 10, 0, 0, 0, 100, 0, 4000, 4000, 0, 0, 45, 2, 2, 0, 0, 0, 0, 9, 19610, 0, 100, 0, 0, 0, 0, 'Ravandwyr - Script 3 - Set Data on Irradiated Worker'),
+(19217, 0, 0, 0, 38, 0, 100, 0, 1, 1, 0, 0, 87, 1921700, 1921701, 1921702, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Ravandwyr - On Data Set - Run Script'),
+(19217, 0, 1, 2, 1, 0, 100, 0, 420000, 600000, 420000, 600000, 45, 1, 1, 0, 0, 0, 0, 10, @Guid+0, 19610, 0, 0, 0, 0, 0, 'Ravandwyr - OOC - Set Data'),
+(19217, 0, 2, 3, 61, 0, 100, 0, 0, 0, 0, 0, 45, 1, 1, 0, 0, 0, 0, 10, @Guid+1, 19610, 0, 0, 0, 0, 0, 'Ravandwyr - OOC - Set Data'),
+(19217, 0, 3, 0, 61, 0, 100, 0, 0, 0, 0, 0, 45, 1, 1, 0, 0, 0, 0, 10, @Guid+2, 19610, 0, 0, 0, 0, 0, 'Ravandwyr - OOC - Set Data'),
+(19217, 0, 4, 5, 38, 0, 100, 0, 2, 2, 0, 0, 45, 1, 1, 0, 0, 0, 0, 10, @Guid+0, 19610, 0, 0, 0, 0, 0, 'Ravandwyr - On Data Set - Set Data'),
+(19217, 0, 5, 6, 61, 0, 100, 0, 0, 0, 0, 0, 45, 1, 1, 0, 0, 0, 0, 10, @Guid+1, 19610, 0, 0, 0, 0, 0, 'Ravandwyr - On Data Set - Set Data'),
+(19217, 0, 6, 0, 61, 0, 100, 0, 0, 0, 0, 0, 45, 1, 1, 0, 0, 0, 0, 10, @Guid+2, 19610, 0, 0, 0, 0, 0, 'Ravandwyr - On Data Set - Set Data'),
+(19217, 0, 7, 8, 62, 0, 100, 0, 7981, 0, 0, 0, 85, 35378, 2, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 'Ravandwyr - On Gossip Option 0 Selected - Invoker Cast Summon Archmages Staff'),
+(19217, 0, 8, 0, 61, 0, 100, 0, 0, 0, 0, 0, 72, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 'Ravandwyr - On Gossip Option 0 Selected - Close Gossip'),
+(19482, 0, 0, 1, 38, 0, 100, 0, 1, 1, 0, 0, 11, 34718, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Sagan <Ravandwyrs Familiar> - On Data Set - Cast Transform Sagan (Skunk)'),
+(19482, 0, 1, 0, 61, 0, 100, 0, 0, 0, 0, 0, 53, 0, 19482, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Sagan <Ravandwyrs Familiar> - On Data Set - Start WP'),
+(19482, 0, 2, 0, 38, 0, 100, 0, 2, 2, 0, 0, 28, 34718, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Sagan <Ravandwyrs Familiar> - On Data Set - Remove Aura Transform Sagan (Skunk)'),
+(-@Guid-0, 0, 0, 7, 38, 0, 100, 1, 1, 1, 0, 0, 53, 0, (@Entry*100)+0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Irradiated Worker - On Data Set Start WP'),
+(-@Guid-1, 0, 0, 7, 38, 0, 100, 1, 1, 1, 0, 0, 53, 0, (@Entry*100)+1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Irradiated Worker - On Data Set Start WP'),
+(-@Guid-2, 0, 0, 7, 38, 0, 100, 1, 1, 1, 0, 0, 53, 0, (@Entry*100)+2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Irradiated Worker - On Data Set Start WP'),
+(-@Guid-0, 0, 1, 0, 38, 0, 100, 1, 2, 2, 0, 0, 53, 0, (@Entry*100)+3, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Irradiated Worker - On Data Set Start WP'),
+(-@Guid-1, 0, 1, 0, 38, 0, 100, 1, 2, 2, 0, 0, 53, 0, (@Entry*100)+3, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Irradiated Worker - On Data Set Start WP'),
+(-@Guid-2, 0, 1, 0, 38, 0, 100, 1, 2, 2, 0, 0, 53, 0, (@Entry*100)+3, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Irradiated Worker - On Data Set Start WP'),
+(-@Guid-0, 0, 2, 3, 40, 0, 100, 1, 15, (@Entry*100)+0, 0, 0, 1, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Irradiated Worker - On Reached WP15 - Say Line'),
+(-@Guid-0, 0, 3, 8, 61, 0, 100, 1, 0, 0, 0, 0, 45, 1, 1, 0, 0, 0, 0, 19, 19217, 0, 0, 0, 0, 0, 0, 'Irradiated Worker - On Reached WP15 - Set Data Ravandwyr'),
+(-@Guid-1, 0, 2, 0, 38, 0, 100, 1, 3, 3, 0, 0, 11, 34973, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Irradiated Worker - On Data Set - Cast Ravandwyrs Ice Block'),
+(-@Guid-0, 0, 4, 0, 40, 0, 100, 1, 39, (@Entry*100)+3, 0, 0, 41, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Irradiated Worker - On Reached WP52 - Despawn'),
+(-@Guid-1, 0, 4, 0, 40, 0, 100, 1, 39, (@Entry*100)+3, 0, 0, 41, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Irradiated Worker - On Reached WP52 - Despawn'),
+(-@Guid-2, 0, 4, 0, 40, 0, 100, 1, 39, (@Entry*100)+3, 0, 0, 41, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Irradiated Worker - On Reached WP52 - Despawn'),
+(-@Guid-0, 0, 5, 6, 11, 0, 100, 0, 0, 0, 0, 0, 47, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Irradiated Worker - On Spawn - Set Invisible'),
+(-@Guid-1, 0, 5, 6, 11, 0, 100, 0, 0, 0, 0, 0, 47, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Irradiated Worker - On Spawn - Set Invisible'),
+(-@Guid-2, 0, 5, 6, 11, 0, 100, 0, 0, 0, 0, 0, 47, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Irradiated Worker - On Spawn - Set Invisible'),
+(-@Guid-0, 0, 6, 0, 61, 0, 100, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Irradiated Worker - On Spawn - Set Emote State None'),
+(-@Guid-1, 0, 6, 0, 61, 0, 100, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Irradiated Worker - On Spawn - Set Emote State None'),
+(-@Guid-2, 0, 6, 0, 61, 0, 100, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Irradiated Worker - On Spawn - Set Emote State None'),
+(-@Guid-0, 0, 7, 0, 61, 0, 100, 0, 0, 0, 0, 0, 47, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Irradiated Worker - On Data Set - Set Visible'),
+(-@Guid-1, 0, 7, 0, 61, 0, 100, 0, 0, 0, 0, 0, 47, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Irradiated Worker - On Data Set - Set Visible'),
+(-@Guid-2, 0, 7, 0, 61, 0, 100, 0, 0, 0, 0, 0, 47, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Irradiated Worker - On Data Set - Set Visible'),
+(-@Guid-0, 0, 8, 0, 61, 0, 100, 0, 0, 0, 0, 0, 66, 0, 0, 0, 0, 0, 0, 19, 19217, 0, 0, 0, 0, 0, 0, 'Irradiated Worker - Reached WP - Set Orientation'),
+(-@Guid-1, 0, 8, 0, 40, 0, 100, 0, 15, (@Entry*100)+1, 0, 0, 66, 0, 0, 0, 0, 0, 0, 19, 19217, 0, 0, 0, 0, 0, 0, 'Irradiated Worker - On Reached WP - Set Orientation'),
+(-@Guid-2, 0, 8, 0, 40, 0, 100, 0, 4, (@Entry*100)+2, 0, 0, 66, 0, 0, 0, 0, 0, 0, 19, 19217, 0, 0, 0, 0, 0, 0, 'Irradiated Worker - On Reached WP - Set Orientation');
+
+DELETE FROM `creature` WHERE `guid` In(@Guid,@Guid+1,@Guid+2);
+INSERT INTO `creature` (`guid`, `id`, `map`, `spawnMask`, `phaseMask`, `modelid`, `equipment_id`, `position_x`, `position_y`, `position_z`, `orientation`, `spawntimesecs`, `spawndist`, `currentwaypoint`, `curhealth`, `curmana`, `MovementType`, `npcflag`, `unit_flags`, `dynamicflags`, `VerifiedBuild`) VALUES
+-- GUID: Full: 0xF1304C9A00055BAB Type: Unit Entry: 19610 Low: 351147
+(@Guid+0, 19610, 530, 1, 1, 0, 1, 2987.086, 3693.867, 142.8286, 1.888375, 300, 0, 0, 0, 0, 0, 0, 0, 0, 0),
+-- GUID: Full: 0xF1304C9A00055BAA Type: Unit Entry: 19610 Low: 351146
+(@Guid+1, 19610, 530, 1, 1, 0, 1, 2985.687, 3696.518, 142.7822, 1.968468, 300, 0, 0, 0, 0, 0, 0, 0, 0, 0),
+-- GUID: Full: 0xF1304C9A00055BA9 Type: Unit Entry: 19610 Low: 351145
+(@Guid+2, 19610, 530, 1, 1, 0, 1, 2984.306, 3699.182, 142.6974, 2.028504, 300, 0, 0, 0, 0, 0, 0, 0, 0, 0);
+
+DELETE FROM `waypoints` WHERE `entry` BETWEEN (@Entry*100)+0 AND (@Entry*100)+3;
+DELETE FROM `waypoints` WHERE `entry` =19482;
+
+INSERT INTO `waypoints` (`entry`, `pointid`, `position_x`, `position_y`, `position_z`, `point_comment`) VALUES
+-- Entry: Full: 0xF1304C9A00055BAB Type: Unit Entry: 19610 Low: 351147
+((@Entry*100)+0, 1, 2984.458, 3699.44, 142.6468, 'Irradiated Worker'),
+((@Entry*100)+0, 2, 2982.822, 3701.982, 142.6412, 'Irradiated Worker'),
+((@Entry*100)+0, 3, 2980.689, 3704.22, 142.5162, 'Irradiated Worker'),
+((@Entry*100)+0, 4, 2979.411, 3706.947, 142.5162, 'Irradiated Worker'),
+((@Entry*100)+0, 5, 2972.232, 3710.486, 142.5704, 'Irradiated Worker'),
+((@Entry*100)+0, 6, 2975.728, 3712.639, 142.3912, 'Irradiated Worker'),
+((@Entry*100)+0, 7, 2978.256, 3714.196, 142.3912, 'Irradiated Worker'),
+((@Entry*100)+0, 8, 2980.499, 3716.544, 142.3912, 'Irradiated Worker'),
+((@Entry*100)+0, 9, 2983.385, 3717.424, 142.46, 'Irradiated Worker'),
+((@Entry*100)+0, 10, 2988.857, 3715.101, 143.0921, 'Irradiated Worker'),
+((@Entry*100)+0, 11, 2990.199, 3717.815, 143.0774, 'Irradiated Worker'),
+((@Entry*100)+0, 12, 2991.541, 3720.528, 143.1886, 'Irradiated Worker'),
+((@Entry*100)+0, 13, 2992.891, 3723.256, 143.4944, 'Irradiated Worker'),
+((@Entry*100)+0, 14, 2993.456, 3724.4, 143.6318, 'Irradiated Worker'),
+((@Entry*100)+0, 15, 2997.077, 3726.937, 143.8528, 'Irradiated Worker'),
+-- Entry: Full: 0xF1304C9A00055BAA Type: Unit Entry: 19610 Low: 351146
+((@Entry*100)+1, 1, 2982.834, 3701.963, 142.6412, 'Irradiated Worker'),
+((@Entry*100)+1, 2, 2981.199, 3704.505, 142.5162, 'Irradiated Worker'),
+((@Entry*100)+1, 3, 2979.416, 3706.937, 142.5162, 'Irradiated Worker'),
+((@Entry*100)+1, 4, 2978.139, 3709.664, 142.3633, 'Irradiated Worker'),
+((@Entry*100)+1, 5, 2974.786, 3712.059, 142.2566, 'Irradiated Worker'),
+((@Entry*100)+1, 6, 2978.282, 3714.212, 142.3912, 'Irradiated Worker'),
+((@Entry*100)+1, 7, 2980.81, 3715.77, 142.3912, 'Irradiated Worker'),
+((@Entry*100)+1, 8, 2983.369, 3717.418, 142.4579, 'Irradiated Worker'),
+((@Entry*100)+1, 9, 2986.255, 3718.298, 142.6792, 'Irradiated Worker'),
+((@Entry*100)+1, 10, 2990.187, 3717.79, 143.0789, 'Irradiated Worker'),
+((@Entry*100)+1, 11, 2991.529, 3720.504, 143.1872, 'Irradiated Worker'),
+((@Entry*100)+1, 12, 2992.871, 3723.217, 143.4897, 'Irradiated Worker'),
+((@Entry*100)+1, 13, 2994.22, 3725.945, 143.6921, 'Irradiated Worker'),
+((@Entry*100)+1, 14, 2994.786, 3727.09, 143.8295, 'Irradiated Worker'),
+((@Entry*100)+1, 15, 2993.273, 3728.817, 144.0368, 'Irradiated Worker'),
+-- Entry: Full: 0xF1304C9A00055BA9 Type: Unit Entry: 19610 Low: 351145
+((@Entry*100)+2, 1, 2976.518, 3713.125, 142.3912, 'Irradiated Worker'),
+((@Entry*100)+2, 2, 2976.683, 3713.479, 142.6767, 'Irradiated Worker'),
+((@Entry*100)+2, 3, 2991.181, 3719.8, 143.1453, 'Irradiated Worker'),
+((@Entry*100)+2, 4, 2996.115, 3729.779, 143.9875, 'Irradiated Worker'),
+-- End WP
+((@Entry*100)+3, 1, 2995.449, 3728.861, 144.042, 'Irradiated Worker'),
+((@Entry*100)+3, 2, 2993.671, 3726.411, 143.748, 'Irradiated Worker'),
+((@Entry*100)+3, 3, 2992.502, 3723.404, 143.5121, 'Irradiated Worker'),
+((@Entry*100)+3, 4, 2990.972, 3722.039, 143.2026, 'Irradiated Worker'),
+((@Entry*100)+3, 5, 2987.993, 3719.381, 142.7629, 'Irradiated Worker'),
+((@Entry*100)+3, 6, 2983.944, 3718.579, 142.5269, 'Irradiated Worker'),
+((@Entry*100)+3, 7, 2982.988, 3715.74, 142.4609, 'Irradiated Worker'),
+((@Entry*100)+3, 8, 2980.014, 3713.131, 142.628, 'Irradiated Worker'),
+((@Entry*100)+3, 9, 2980.164, 3711.079, 142.6879, 'Irradiated Worker'),
+((@Entry*100)+3, 10, 2980.455, 3707.102, 142.523, 'Irradiated Worker'),
+((@Entry*100)+3, 11, 2980.064, 3704.01, 142.2676, 'Irradiated Worker'),
+((@Entry*100)+3, 12, 2980.808, 3701.123, 142.6412, 'Irradiated Worker'),
+((@Entry*100)+3, 13, 2983.227, 3692.621, 143.0479, 'Irradiated Worker'),
+((@Entry*100)+3, 14, 2986.019, 3691.538, 142.9493, 'Irradiated Worker'),
+((@Entry*100)+3, 15, 2988.529, 3688.696, 142.8852, 'Irradiated Worker'),
+((@Entry*100)+3, 16, 2994.542, 3689.015, 143.4549, 'Irradiated Worker'),
+((@Entry*100)+3, 17, 2997.563, 3689.176, 143.6308, 'Irradiated Worker'),
+((@Entry*100)+3, 18, 3000.586, 3689.337, 143.6308, 'Irradiated Worker'),
+((@Entry*100)+3, 19, 3003.604, 3689.804, 143.6307, 'Irradiated Worker'),
+((@Entry*100)+3, 20, 3006.637, 3689.782, 143.6307, 'Irradiated Worker'),
+((@Entry*100)+3, 21, 3009.671, 3689.76, 143.6307, 'Irradiated Worker'),
+((@Entry*100)+3, 22, 3012.702, 3689.738, 143.6307, 'Irradiated Worker'),
+((@Entry*100)+3, 23, 3015.754, 3690.37, 143.6307, 'Irradiated Worker'),
+((@Entry*100)+3, 24, 3018.766, 3690.016, 143.6306, 'Irradiated Worker'),
+((@Entry*100)+3, 25, 3021.777, 3689.662, 143.6306, 'Irradiated Worker'),
+((@Entry*100)+3, 26, 3024.792, 3689.307, 143.6306, 'Irradiated Worker'),
+((@Entry*100)+3, 27, 3027.821, 3689.124, 143.6306, 'Irradiated Worker'),
+((@Entry*100)+3, 28, 3030.809, 3688.724, 143.2758, 'Irradiated Worker'),
+((@Entry*100)+3, 29, 3033.767, 3688.14, 143.0482, 'Irradiated Worker'),
+((@Entry*100)+3, 30, 3036.724, 3687.555, 142.9637, 'Irradiated Worker'),
+((@Entry*100)+3, 31, 3039.848, 3684.927, 142.7658, 'Irradiated Worker'),
+((@Entry*100)+3, 32, 3042.658, 3686.022, 142.7131, 'Irradiated Worker'),
+((@Entry*100)+3, 33, 3045.463, 3687.116, 142.6446, 'Irradiated Worker'),
+((@Entry*100)+3, 34, 3048.52, 3687.687, 142.3446, 'Irradiated Worker'),
+((@Entry*100)+3, 35, 3051.203, 3689.113, 142.5257, 'Irradiated Worker'),
+((@Entry*100)+3, 36, 3053.872, 3690.532, 140.5028, 'Irradiated Worker'),
+((@Entry*100)+3, 37, 3056.601, 3691.824, 142.8937, 'Irradiated Worker'),
+((@Entry*100)+3, 38, 3058.226, 3692.761, 143.2548, 'Irradiated Worker'),
+((@Entry*100)+3, 39, 3058.292, 3692.803, 143.258, 'Irradiated Worker'),
+-- Sagan
+(19482, 1, 2996.497, 3734.341, 144.3418, 'Sagan <Ravandwyrs Familiar>'),
+(19482, 2, 2993.747, 3734.091, 144.0918, 'Sagan <Ravandwyrs Familiar>'),
+(19482, 3, 2991.747, 3732.591, 144.0918, 'Sagan <Ravandwyrs Familiar>'),
+(19482, 4, 2990.747, 3730.341, 144.0918, 'Sagan <Ravandwyrs Familiar>'),
+(19482, 5, 2991.247, 3727.591, 144.0918, 'Sagan <Ravandwyrs Familiar>'),
+(19482, 6, 2993.497, 3725.591, 144.0918, 'Sagan <Ravandwyrs Familiar>'),
+(19482, 7, 2996.747, 3724.341, 144.0918, 'Sagan <Ravandwyrs Familiar>'),
+(19482, 8, 2999.997, 3725.841, 144.0918, 'Sagan <Ravandwyrs Familiar>'),
+(19482, 9, 3001.247, 3730.091, 144.0918, 'Sagan <Ravandwyrs Familiar>');
+
+DELETE FROM `gossip_menu_option` WHERE `menu_id`=7981;
+INSERT INTO `gossip_menu_option` (`menu_id`, `id`, `option_icon`, `option_text`, `OptionBroadcastTextID`, `option_id`, `npc_option_npcflag`, `action_menu_id`, `action_poi_id`, `box_coded`, `box_money`, `box_text`, `BoxBroadcastTextID`) VALUES
+(7981, 0, 0, 'I''ve lost Archmage Vargoth''s Staff. Can you replace it?', 18546, 1, 1, 0, 0, 0, 0, '', 0);
+
+DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=15 AND `SourceGroup`=7981;
+INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES
+(15, 7981, 0, 0, 0, 2, 0, 28455, 1, 0, 1, 0, 0, '', 'Gossip Option requires Player does not have Archmage Vargoths Staff'),
+(15, 7981, 0, 0, 0, 8, 0, 10174, 0, 0, 0, 0, 0, '', 'Gossip Option requires Curse of the Violet Tower rewarded'),
+(15, 7981, 0, 0, 0, 8, 0, 10209, 0, 0, 1, 0, 0, '', 'Gossip Option requires Player is not rewarded for Summoner Kanthins Prize');
+
+UPDATE `creature_text` SET `probability`=20 WHERE `entry`=19541;
diff --git a/sql/updates/world/2014_10_10_00_world.sql b/sql/updates/world/2014_10_10_00_world.sql
new file mode 100644
index 00000000000..3ac4e678fec
--- /dev/null
+++ b/sql/updates/world/2014_10_10_00_world.sql
@@ -0,0 +1,5 @@
+UPDATE `creature_template` SET `unit_flags`=320, `flags_extra`=2 WHERE `entry` IN(36065,36066);
+DELETE FROM `creature_template_addon` WHERE `entry` IN(36066, 36065);
+INSERT INTO `creature_template_addon` (`entry`, `mount`, `bytes1`, `bytes2`, `auras`) VALUES
+(36066, 0, 0x2000000, 0x1, ''),
+(36065, 0, 0x2000000, 0x1, '');
diff --git a/sql/updates/world/2014_10_10_01_world_335.sql b/sql/updates/world/2014_10_10_01_world_335.sql
new file mode 100644
index 00000000000..624286e6910
--- /dev/null
+++ b/sql/updates/world/2014_10_10_01_world_335.sql
@@ -0,0 +1,4 @@
+--
+DELETE FROM `gameobject_template` WHERE `entry` = 180671;
+INSERT INTO `gameobject_template` (`entry`, `type`, `displayId`, `name`, `data0`, `data1`, `VerifiedBuild`) VALUES
+(180671,3,644,'Xandivious\' Demon Bag',43,17516,-18019);
diff --git a/sql/updates/world/2014_10_10_02_world.sql b/sql/updates/world/2014_10_10_02_world.sql
new file mode 100644
index 00000000000..8f971f8ad1e
--- /dev/null
+++ b/sql/updates/world/2014_10_10_02_world.sql
@@ -0,0 +1,2 @@
+--
+UPDATE `creature_loot_template` SET `item`=49426 WHERE `entry`=38433 AND `item`=47241;
diff --git a/sql/updates/world/2014_10_10_03_world.sql b/sql/updates/world/2014_10_10_03_world.sql
new file mode 100644
index 00000000000..2d21cb6d010
--- /dev/null
+++ b/sql/updates/world/2014_10_10_03_world.sql
@@ -0,0 +1,4 @@
+--
+DELETE FROM `gameobject_loot_template` WHERE `Entry` = 17516;
+INSERT INTO `gameobject_loot_template` (`Entry`,`Item`,`Chance`,`QuestRequired`) VALUES
+(17516,21145,100,1);
diff --git a/sql/updates/world/2014_10_10_04_world_335.sql b/sql/updates/world/2014_10_10_04_world_335.sql
new file mode 100644
index 00000000000..c32f68fb400
--- /dev/null
+++ b/sql/updates/world/2014_10_10_04_world_335.sql
@@ -0,0 +1,5 @@
+--
+DELETE FROM `gameobject_template` WHERE `entry` IN (202947,202948);
+INSERT INTO `gameobject_template` (`entry`, `type`, `displayId`, `name`, `data0`, `data1`, `VerifiedBuild`) VALUES
+(202947,3,9467,'Cologne Neutralizer',93,28677,15211),
+(202948,3,9468,'Perfume Neutralizer',93,28678,15211);
diff --git a/sql/updates/world/2014_10_10_05_world.sql b/sql/updates/world/2014_10_10_05_world.sql
new file mode 100644
index 00000000000..0a93850972e
--- /dev/null
+++ b/sql/updates/world/2014_10_10_05_world.sql
@@ -0,0 +1,5 @@
+--
+DELETE FROM `gameobject_loot_template` WHERE `Entry` IN (28677,28678);
+INSERT INTO `gameobject_loot_template` (`Entry`,`Item`,`Chance`,`QuestRequired`) VALUES
+(28677,49352,100,1),
+(28678,49351,100,1);
diff --git a/sql/updates/world/2014_10_10_06_world.sql b/sql/updates/world/2014_10_10_06_world.sql
new file mode 100644
index 00000000000..c3fbca838b2
--- /dev/null
+++ b/sql/updates/world/2014_10_10_06_world.sql
@@ -0,0 +1,12 @@
+UPDATE `smart_scripts` SET `link`=0 WHERE `entryorguid`=30945 AND `source_type`=0 AND `id`=3;
+UPDATE `smart_scripts` SET `link`=28 WHERE `entryorguid`=28659 AND `source_type`=0 AND `id`=26;
+UPDATE `smart_scripts` SET `link`=4 WHERE `entryorguid`=27788 AND `source_type`=0 AND `id`=3;
+UPDATE `smart_scripts` SET `link`=1 WHERE `entryorguid`=26434 AND `source_type`=0 AND `id`=0;
+UPDATE `smart_scripts` SET `link`=0 WHERE `entryorguid`=25979 AND `source_type`=0 AND `id`=1;
+UPDATE `smart_scripts` SET `event_type`=61 WHERE `entryorguid`=23859 AND `source_type`=0 AND `id`=3;
+UPDATE `smart_scripts` SET `link`=6 WHERE `entryorguid` IN (34965,19643) AND `source_type`=0 AND `id`=5;
+UPDATE `smart_scripts` SET `link`=0 WHERE `entryorguid` BETWEEN -23715 AND -23712 AND `source_type`=0 AND `id`=0;
+UPDATE `smart_scripts` SET `link`=0 WHERE `entryorguid`=12996 AND `source_type`=0 AND `id`=8;
+UPDATE `smart_scripts` SET `link`=8 WHERE `entryorguid`=18171 AND `source_type`=0 AND `id`=7;
+UPDATE `smart_scripts` SET `link`=5 WHERE `entryorguid`=19657 AND `source_type`=0 AND `id`=4;
+UPDATE `smart_scripts` SET `id`=21, `link`=0, `comment`="The Leaper - In Combat - Cast Hunger For Blood" WHERE `entryorguid`=29840 AND `source_type`=0 AND `id`=7 AND `link`=21;
diff --git a/sql/updates/world/2014_10_11_00_world.sql b/sql/updates/world/2014_10_11_00_world.sql
new file mode 100644
index 00000000000..dcfb679e7e7
--- /dev/null
+++ b/sql/updates/world/2014_10_11_00_world.sql
@@ -0,0 +1,23 @@
+-- Scourge Cage
+UPDATE `gameobject_template` SET `data2`=120000, AIName='SmartGameObjectAI', ScriptName='', `VerifiedBuild`=-18019 WHERE `entry` IN (
+187854,
+187855,
+187856,
+187857,
+187858,
+187859,
+187860,
+187861,
+187862,
+187863,
+187864,
+187865,
+187866,
+187867,
+187868,
+187870,
+187871,
+187872,
+187873,
+187874
+);
diff --git a/sql/updates/world/2014_10_11_01_world.sql b/sql/updates/world/2014_10_11_01_world.sql
new file mode 100644
index 00000000000..b1fe0b91826
--- /dev/null
+++ b/sql/updates/world/2014_10_11_01_world.sql
@@ -0,0 +1,2 @@
+--
+UPDATE `creature` SET `position_x`=1875.67, `position_y`=1303.86, `position_z`=90.4382 WHERE `guid`=29809 and `id`=1506;
diff --git a/sql/updates/world/2014_10_11_02_world.sql b/sql/updates/world/2014_10_11_02_world.sql
new file mode 100644
index 00000000000..3256fa15c45
--- /dev/null
+++ b/sql/updates/world/2014_10_11_02_world.sql
@@ -0,0 +1,117 @@
+-- On Ruby Wings (12498)
+
+SET @QUEST := 12498;
+SET @NPC_WYRMREST_VANQUISHER := 27996; -- Wyrmrest Vanquisher
+SET @NPC_THIASSI_THE_LIGHNTNING_BRINGER := 28018; -- Thiassi the Lightning Bringer
+SET @NPC_GRAND_NECROLORD_ANTIOK := 28006; -- Grand Necrolord Antiok
+SET @NPC_WASTES_SCAVENGER := 28005; -- Wastes Scavenger
+SET @SPELL_DEVOUR_GHOUL := 50430; -- Devour Ghoul
+SET @SPELL_ENGULFING_FIREBALL := 55987; -- Engulfing Fireball
+SET @SPELL_FLAME_FURY := 50348; -- Flame Fury
+SET @SPELL_MOUNT := 50343; -- Controlling Wyrmrest Vanquisher
+SET @ITEM_SCYTHE_OF_ANTIOK := 38305; -- Item Scythe of Antiok
+
+UPDATE `creature_template` SET npcflag=16777216, `spell1`=@SPELL_FLAME_FURY, `spell2`=@SPELL_ENGULFING_FIREBALL, `spell3`=@SPELL_DEVOUR_GHOUL, `InhabitType`=4 WHERE `entry`=@NPC_WYRMREST_VANQUISHER;
+
+DELETE FROM `npc_spellclick_spells` WHERE npc_entry IN (@NPC_WYRMREST_VANQUISHER);
+INSERT INTO `npc_spellclick_spells` VALUES (@NPC_WYRMREST_VANQUISHER, @SPELL_MOUNT, 1, 0);
+
+DELETE FROM `creature_template_addon` WHERE `entry` in (@NPC_WYRMREST_VANQUISHER, @NPC_GRAND_NECROLORD_ANTIOK);
+INSERT INTO `creature_template_addon` (`entry`,`path_id`,`mount`,`bytes1`,`bytes2`,`emote`,`auras`) VALUES
+(@NPC_WYRMREST_VANQUISHER,0,0,50331648,0,0,'50345'),
+(@NPC_GRAND_NECROLORD_ANTIOK,0,0,0,0,0,'50494');
+
+UPDATE vehicle_template_accessory set minion=0,`summontype`=1 where entry=@NPC_THIASSI_THE_LIGHNTNING_BRINGER;
+
+Delete from creature_loot_template where entry =@NPC_GRAND_NECROLORD_ANTIOK and item=@ITEM_SCYTHE_OF_ANTIOK;
+
+DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=13 AND `SourceEntry`=@SPELL_FLAME_FURY;
+INSERT INTO `conditions` (`SourceTypeOrReferenceId`,`SourceGroup`,`SourceEntry`,`SourceId`,`ElseGroup`,`ConditionTypeOrReference`,`ConditionTarget`,`ConditionValue1`,`ConditionValue2`,`ConditionValue3`,`NegativeCondition`,`ErrorType`,`ErrorTextId`,`ScriptName`,`Comment`) VALUES
+(13,1,@SPELL_FLAME_FURY,0,1,31,0,3,@NPC_WASTES_SCAVENGER,0,0,0,0,'','Flame Fury can only Hit Wastes Scavenger');
+
+DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=13 AND `SourceEntry`=55988;
+INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES
+(13, 1, 55988, 0, 2, 31, 0, 3, 26493, 0, 0, 0, 0, '', 'Engulfing Fireball targets Wastes Task Manager'),
+(13, 1, 55988, 0, 1, 31, 0, 3, 26492, 0, 0, 0, 0, '', 'Engulfing Fireball targets Wastes Digger'),
+(13, 1, 55988, 0, 0, 31, 0, 3, 28005, 0, 0, 0, 0, '', 'Engulfing Fireball targets Wastes Scavenger'),
+(13, 2, 55988, 0, 0, 31, 0, 3, 27270, 0, 0, 0, 0, '', 'Engulfing Fireball targets Rotting Storm Giant'),
+(13, 2, 55988, 0, 1, 31, 0, 3, 28018, 0, 0, 0, 0, '', 'Engulfing Fireball targets Thiassi');
+
+DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=13 AND `SourceEntry` IN (50430,50443);
+INSERT INTO `conditions` (`SourceTypeOrReferenceId`,`SourceGroup`,`SourceEntry`,`SourceId`,`ElseGroup`,`ConditionTypeOrReference`,`ConditionTarget`,`ConditionValue1`,`ConditionValue2`,`ConditionValue3`,`NegativeCondition`,`ErrorType`,`ErrorTextId`,`ScriptName`,`Comment`) VALUES
+(13,1,50430,0,0,31,0,3,28005,0,0,0,0,'','Devour Ghoul targets Wastes Scavenger'),
+(13,3,50443,0,0,31,0,3,27996,0,0,0,0,'','Nourishment targets Wyrmrest Vanquisher');
+
+DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`in (16,17) AND `SourceEntry` IN (27996,50426);
+INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES
+(16, 0, 27996, 0, 0, 23, 0, 4161, 0, 0, 0, 0, 0, '', 'Wyrmrest Vanquisher allowed in Wyrmrest Temple'),
+(16, 0, 27996, 0, 4, 23, 0, 4184, 0, 0, 0, 0, 0, '', 'Wyrmrest Vanquisher allowed in Path of the Titans'),
+(16, 0, 27996, 0, 3, 23, 0, 4174, 0, 0, 0, 0, 0, '', 'Wyrmrest Vanquisher allowed in The Wicked Coil'),
+(16, 0, 27996, 0, 2, 23, 0, 4173, 0, 0, 0, 0, 0, '', 'Wyrmrest Vanquisher allowed in Galakronds Rest'),
+(16, 0, 27996, 0, 1, 23, 0, 4254, 0, 0, 0, 0, 0, '', 'Wyrmrest Vanquisher allowed in The Dragon Wastes'),
+(17, 0, 50426, 0, 3, 23, 0, 4174, 0, 0, 0, 0, 0, '', 'Wyrmrest Vanquisher can be summoned in The Wicked Coil'),
+(17, 0, 50426, 0, 2, 23, 0, 4173, 0, 0, 0, 0, 0, '', 'Wyrmrest Vanquisher can be summoned in Galakronds Rest'),
+(17, 0, 50426, 0, 1, 23, 0, 4254, 0, 0, 0, 0, 0, '', 'Wyrmrest Vanquisher can be summoned in The Dragon Wastes'),
+(17, 0, 50426, 0, 0, 23, 0, 4161, 0, 0, 0, 0, 0, '', 'Wyrmrest Vanquisher can be summoned in Wyrmrest Temple');
+
+DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=22 AND `SourceGroup`=5 and `SourceEntry`=@NPC_WYRMREST_VANQUISHER;
+INSERT INTO `conditions` (`SourceTypeOrReferenceId`,`SourceGroup`,`SourceEntry`,`ElseGroup`,`ConditionTypeOrReference`,`ConditionValue1`,`ConditionValue2`,`ConditionValue3`, `ErrorTextId`,`ScriptName`,`Comment`) VALUES
+(22,5,@NPC_WYRMREST_VANQUISHER,0,9,12498,0,0,0,'','event require quest taken to prevent despawn when the spell devour ghoul is casted'),
+(22,5,@NPC_WYRMREST_VANQUISHER,1,28,12498,0,0,0,'','event require quest complete to prevent despawn when the spell devour ghoul is casted');
+
+UPDATE creature_template SET AIName='SmartAI' WHERE entry IN (@NPC_GRAND_NECROLORD_ANTIOK, @NPC_THIASSI_THE_LIGHNTNING_BRINGER, @NPC_WYRMREST_VANQUISHER);
+DELETE FROM smart_scripts WHERE entryorguid = @NPC_GRAND_NECROLORD_ANTIOK and source_type=0;
+DELETE FROM smart_scripts WHERE entryorguid = @NPC_THIASSI_THE_LIGHNTNING_BRINGER and source_type=0;
+DELETE FROM smart_scripts WHERE entryorguid = @NPC_WYRMREST_VANQUISHER and source_type=0;
+DELETE FROM smart_scripts WHERE entryorguid = @NPC_WYRMREST_VANQUISHER*100 and source_type=9;
+DELETE FROM `smart_scripts` WHERE `entryorguid` = 28005 and source_type=0 and id=14; -- (there is already a script for this npc id=0 to id=13)
+DELETE FROM `smart_scripts` WHERE `entryorguid` = 28005*100 and source_type=9;
+
+INSERT INTO `smart_scripts` (`entryorguid`,`source_type`,`id`,`link`,`event_type`,`event_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action_type`,`action_param1`,`action_param2`,`action_param3`,`action_param4`,`action_param5`,`action_param6`,`target_type`,`target_param1`,`target_param2`,`target_param3`,`target_x`,`target_y`,`target_z`,`target_o`,`comment`) VALUES
+
+(@NPC_GRAND_NECROLORD_ANTIOK, 0, 0, 0, 0, 0, 100, 0, 7000, 7000, 18000, 18000, 11, 32863, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 'Nekrolord Antiok - IC - Cast Demon Seed'),
+(@NPC_GRAND_NECROLORD_ANTIOK, 0, 1, 0, 0, 0, 100, 0, 1100, 1100, 20000, 20000, 11, 50455, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 'Nekrolord Antiok - IC - Cast Shadow Bolt'),
+(@NPC_GRAND_NECROLORD_ANTIOK, 0, 2, 0, 1, 0, 100, 0, 10000, 10000, 40000, 40000, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Nekrolord Antiok - OOC - Random Yell'),
+(@NPC_GRAND_NECROLORD_ANTIOK, 0, 3, 0, 2, 0, 100, 1, 0, 25, 0, 0, 11, 50497, 1, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 'Nekrolord Antiok - HP under 25% - Cast Scream of Chaos'),
+(@NPC_GRAND_NECROLORD_ANTIOK, 0, 4, 0, 6, 0, 100, 0, 0, 0, 0, 0, 11, 50472, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Nekrolord Antiok - On Death - Cast Drop Scythe of Antiok'),
+(@NPC_GRAND_NECROLORD_ANTIOK, 0, 5, 7, 4, 0, 100, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Nekrolord Antiok - On Aggro - Yell'),
+(@NPC_GRAND_NECROLORD_ANTIOK, 0, 6, 0, 61, 0, 100, 0, 0, 0, 0, 0, 11, 55984, 1, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 'Nekrolord Antiok - On Aggro - Cast Shadow Bolt'),
+(@NPC_GRAND_NECROLORD_ANTIOK, 0, 7, 8, 4, 0, 100, 0, 0, 0, 0, 0, 51, 0, 0, 0, 0, 0, 0, 19, @NPC_WYRMREST_VANQUISHER, 20, 0, 0, 0, 0, 0, 'Nekrolord Antiok - On Aggro - kill WYRMREST'),
+(@NPC_GRAND_NECROLORD_ANTIOK, 0, 8, 0, 61, 0, 100, 0, 0, 0, 0, 0, 28, 50494, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Nekrolord Antiok - On Aggro - remove aura'),
+
+(@NPC_THIASSI_THE_LIGHNTNING_BRINGER, 0, 0, 0, 0, 0, 100, 0, 5000, 5000, 12000, 14000, 11, 50456, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 'Thiassi the Lightning Bringer - IC - Cast Thiassi''s Stormbolt'),
+(@NPC_THIASSI_THE_LIGHNTNING_BRINGER, 0, 1, 0, 0, 0, 100, 0, 9000, 9000, 15000, 19000, 11, 15593, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Thiassi the Lightning Bringer - IC - Cast War Stomp'),
+(@NPC_THIASSI_THE_LIGHNTNING_BRINGER, 0, 2, 0, 6, 0, 100, 0, 0, 0, 0, 0, 19, 2146959359, 0, 0, 0, 0, 0, 19, @NPC_GRAND_NECROLORD_ANTIOK, 10, 0, 0, 0, 0, 0, 'Thiassi the Lightning Bringer - On Death - remove unitflag from target'),
+
+(@NPC_WYRMREST_VANQUISHER, 0, 0, 0, 1, 0, 100, 0, 9000, 9000, 30000, 30000, 1, 0, 0, 0, 0, 0, 0, 21, 10, 0, 0, 0, 0, 0, 0, 'WYRMREST VANQUISHER - OOC - Random talk'),
+(@NPC_WYRMREST_VANQUISHER, 0, 1, 0, 2, 0, 100, 1, 0, 33, 0, 0, 1, 1, 0, 0, 0, 0, 0, 21, 10, 0, 0, 0, 0, 0, 0, 'WYRMREST VANQUISHER - HP under 33% - talk'),
+(@NPC_WYRMREST_VANQUISHER, 0, 3, 0, 54, 0, 100, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'WYRMREST VANQUISHER - Just summoned - react passif'),
+(@NPC_WYRMREST_VANQUISHER, 0, 4, 0, 28, 0, 100, 0, 0, 0, 0, 0, 80, @NPC_WYRMREST_VANQUISHER*100, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'WYRMREST VANQUISHER - PASSENGER_REMOVED - Actionlist'),
+(@NPC_WYRMREST_VANQUISHER*100, 9, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 0, 21, 10, 0, 0, 0, 0, 0, 0, 'WYRMREST VANQUISHER - ActionList - talk'),
+(@NPC_WYRMREST_VANQUISHER*100, 9, 1, 0, 0, 0, 100, 0, 1000, 1000, 0, 0, 41, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'WYRMREST VANQUISHER - ActionList - despawn'),
+
+
+(28005, 0, 14, 0, 8, 0, 100, 0, 50430, 0, 0, 0, 80, 28005*100, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Wastes Scavenger - On spellhit Devour Ghoul - Run script'),
+(28005*100, 9, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 11, 50437, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 'Wastes Scavenger script - Spellcast Devour Ghoul'),
+(28005*100, 9, 1, 0, 0, 0, 100, 0, 4000, 4000, 0, 0, 11, 50443, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 'Wastes Scavenger script - Spellcast Nourishment'),
+(28005*100, 9, 2, 0, 0, 0, 100, 0, 0, 0, 0, 0, 41, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Wastes Scavenger script - Despawn');
+
+DELETE FROM creature_text WHERE entry in (@NPC_GRAND_NECROLORD_ANTIOK, @NPC_WYRMREST_VANQUISHER);
+INSERT INTO `creature_text` (`entry`, `groupid`, `id`, `text`, `type`, `language`, `probability`, `emote`, `duration`, `sound`, `comment`, `BroadcastTextID`) VALUES
+(@NPC_GRAND_NECROLORD_ANTIOK,0,0,'You think you''ve won, mortal? Face the unbridled power of Antiok!',14,0,100,0,0,0,'Antiok Yell1',27415),
+(@NPC_GRAND_NECROLORD_ANTIOK,0,1,'Behold! The Scythe of Antiok!',14,0,100,0,0,0,'Antiok Yell2', 27416),
+(@NPC_GRAND_NECROLORD_ANTIOK,1,0,'Soon, the bones of Galakrond will rise from their eternal slumber and wreak havoc upon this world!',14,0,100,0,0,0,'Antiok Yell3', 27406),
+(@NPC_GRAND_NECROLORD_ANTIOK,1,1,'The Lich King demands more frost wyrms be sent to Angrathar! Meet his demands or face my wrath!',14,0,100,0,0,0,'Antiok Yell4', 27408),
+(@NPC_GRAND_NECROLORD_ANTIOK,1,2,'Faster, dogs! We mustn''t relent in our assault against the interlopers!',14,0,100,0,0,0,'Antiok Yell5', 27405),
+(@NPC_GRAND_NECROLORD_ANTIOK,1,3,'Attackers are upon us! Let none through to this ancient grave!',14,0,100,0,0,0,'Antiok Yell6', 27409),
+(@NPC_GRAND_NECROLORD_ANTIOK,1,4,'Hear me, minions! Hear your lord, Antiok! Double your efforts or pay the consequences of failure!',14,0,100,0,0,0,'Antiok Yell7', 27407),
+(@NPC_WYRMREST_VANQUISHER,0,1,'Across this vast expanse rest the bones of my ancestors. Their spirits have ascended to the Chamber of the Aspects.',12,0,100,0,0,0,'WYRMREST VANQUISHER', 27394),
+(@NPC_WYRMREST_VANQUISHER,0,2,'Galakrond was the progenitor of dragonkind. It was from Galakrond that the Titans shaped the five Aspects.',12,0,100,0,0,0,'WYRMREST VANQUISHER', 27396),
+(@NPC_WYRMREST_VANQUISHER,0,3,'It truly is a shame that the blue dragonflight has chosen such a heartless, cold path. It pains me greatly to do battle with Malygos''s children.',12,0,100,0,0,0,'WYRMREST VANQUISHER', 27400),
+(@NPC_WYRMREST_VANQUISHER,0,4,'The queen and her council have been speaking lately of a disaster at Ulduar. Something has happened in Storm Peaks!',12,0,100,0,0,0,'WYRMREST VANQUISHER', 27399),
+(@NPC_WYRMREST_VANQUISHER,0,5,'Today is a good day, friend. Long has it been since I have left Wyrmrest Temple, free to fly across the great Dragonblight.',12,0,100,0,0,0,'WYRMREST VANQUISHER', 27398),
+(@NPC_WYRMREST_VANQUISHER,0,6,'What the Scourge has done here will reverberate throughout our world. The aberrations must be stopped!',12,0,100,0,0,0,'WYRMREST VANQUISHER', 27395),
+(@NPC_WYRMREST_VANQUISHER,1,0,'You must remember that I have yet to mature into an elder wyrm. I must eat to renew my strength!',12,0,100,0,0,0,'WYRMREST VANQUISHER', 27397),
+(@NPC_WYRMREST_VANQUISHER,2,0,'I have been called back to Wyrmrest, ally. Farewell!',12,0,100,0,0,0,'WYRMREST VANQUISHER', 27404);
+
+UPDATE `creature` SET `equipment_id`=0 WHERE `guid` IN(74522,74523,74524);
diff --git a/sql/updates/world/2014_10_11_03_world.sql b/sql/updates/world/2014_10_11_03_world.sql
new file mode 100644
index 00000000000..a6edf333508
--- /dev/null
+++ b/sql/updates/world/2014_10_11_03_world.sql
@@ -0,0 +1,19 @@
+DELETE FROM gameobject WHERE guid=99998;
+INSERT INTO `gameobject` (guid, id, map, spawnMask, phaseMask, position_x, position_y, position_z, spawntimesecs, State) VALUES
+(99998, 180673, 1, 1, 1, 6723.67, -5271.68, 778, 180, 1);
+
+set @Xandivious:=15623;
+
+Delete from creature_loot_template where entry =@Xandivious and item=21145;
+
+Update creature_template set `AIName`='SmartAI' where entry in (@Xandivious);
+
+DELETE FROM `smart_scripts` WHERE `entryorguid` = @Xandivious AND `source_type` = 0;
+Insert into `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) values
+
+(@Xandivious, 0, 0, 0, 25, 0, 100, 0, 0, 0, 0, 0, 11, 25818, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, ' Xandivious - On reset - cast Aura of Rot'),
+(@Xandivious, 0, 1, 0, 0, 0, 100, 0, 3000, 3000, 15000, 15000, 11, 11980, 1, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 'Xandivious - IC - cast Curse of Weakness'),
+(@Xandivious, 0, 2, 0, 0, 0, 100, 0, 5000, 5000, 15000, 15000, 11, 11639, 1, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 'Xandivious - IC - cast Shadow Word: Pain'),
+(@Xandivious, 0, 3, 0, 0, 0, 100, 0, 7000, 7000, 10000, 10000, 11, 16046, 1, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 'Xandivious - IC - cast Blast Wave'),
+(@Xandivious, 0, 4, 0, 2, 0, 100, 1, 0, 50, 0, 0, 11, 8599, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Xandivious - HP under 50% - Enrage'),
+(@Xandivious, 0, 5, 0, 6, 0, 100, 0, 0, 0, 0, 0, 85, 25791, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Xandivious - On Death - invoker_Cast Xandivious Demon Bag');
diff --git a/sql/updates/world/2014_10_11_04_world.sql b/sql/updates/world/2014_10_11_04_world.sql
new file mode 100644
index 00000000000..5b1eca19278
--- /dev/null
+++ b/sql/updates/world/2014_10_11_04_world.sql
@@ -0,0 +1,51 @@
+-- Schematic: Field Repair Bot 74A
+
+Update npc_text set BroadcastTextID0=9486 where `ID`=6931;
+Delete from gossip_menu where `entry`=5749 and `text_id`=6931;
+insert into gossip_menu (`entry`, `text_id`) values (5749, 6931);
+
+Update npc_text set BroadcastTextID0=9484 where `ID`=6930;
+Delete from gossip_menu where `entry`=5749 and `text_id`=6930;
+insert into gossip_menu (`entry`, `text_id`) values (5749, 6930);
+
+Update npc_text set BroadcastTextID0=9483 where `ID`=6929;
+Delete from gossip_menu where `entry`=5749 and `text_id`=6929;
+insert into gossip_menu (`entry`, `text_id`) values (5749, 6929);
+
+Update npc_text set BroadcastTextID0=9487 where `ID`=6932;
+Delete from gossip_menu where `entry`=5749 and `text_id`=6932;
+insert into gossip_menu (`entry`, `text_id`) values (5749, 6932);
+
+DELETE FROM `gossip_menu_option` WHERE `menu_id` = 5749;
+INSERT INTO `gossip_menu_option` (`menu_id`, id, option_icon, `option_text`, `OptionBroadcastTextID`, `option_id`, `npc_option_npcflag`)
+VALUES (5749, 0, 0, '<Copy the schematic into your engineering notebook.>', 9485, 1, 3);
+
+DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId` =15 AND `SourceGroup`=5749;
+INSERT INTO `conditions` (`SourceTypeOrReferenceId`,`SourceGroup`,`SourceEntry`,`ElseGroup`,`ConditionTypeOrReference`,`ConditionValue1`,`ConditionValue2`,`ConditionValue3`, `NegativeCondition`, `ErrorTextId`,`ScriptName`,`Comment`) VALUES
+(15,5749,0,0,7,202,300,0,0,0,'','Show gossip menu if player have 300 or more in Engineering'),
+(15,5749,0,0,25,22704,0,0,1,0,'','Show gossip menu if player doesn''t learned the spell');
+
+DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=14 AND `SourceGroup`=5749 and `SourceEntry`= 6931;
+INSERT INTO `conditions` (`SourceTypeOrReferenceId`,`SourceGroup`,`SourceEntry`,`ElseGroup`,`ConditionTypeOrReference`,`ConditionValue1`,`ConditionValue2`,`ConditionValue3`, `NegativeCondition`, `ErrorTextId`,`ScriptName`,`Comment`) VALUES
+(14,5749,6931,0,7,202,300,0,1,0,'','Show gossip menu if player is an Engineer but have less than 300'),
+(14,5749,6931,0,25,4036,0,0,0,0,'','Show gossip menu if player is an Engineer');
+
+DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=14 AND `SourceGroup`=5749 and `SourceEntry`= 6930;
+INSERT INTO `conditions` (`SourceTypeOrReferenceId`,`SourceGroup`,`SourceEntry`,`ElseGroup`,`ConditionTypeOrReference`,`ConditionValue1`,`ConditionValue2`,`ConditionValue3`, `ErrorTextId`,`ScriptName`,`Comment`) VALUES
+(14,5749,6930,0,7,202,300,0,0,'','Show gossip menu if player have 300 or more in Engineering');
+
+DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=14 AND `SourceGroup`=5749 and `SourceEntry`= 6929;
+INSERT INTO `conditions` (`SourceTypeOrReferenceId`,`SourceGroup`,`SourceEntry`,`ElseGroup`,`ConditionTypeOrReference`,`ConditionValue1`,`ConditionValue2`,`ConditionValue3`, `NegativeCondition`, `ErrorTextId`,`ScriptName`,`Comment`) VALUES
+(14,5749,6929,0,25,4036,0,0,1,0,'','Show gossip menu if player is not an Engineer');
+
+DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=14 AND `SourceGroup`=5749 and `SourceEntry`= 6932;
+INSERT INTO `conditions` (`SourceTypeOrReferenceId`,`SourceGroup`,`SourceEntry`,`ElseGroup`,`ConditionTypeOrReference`,`ConditionValue1`,`ConditionValue2`,`ConditionValue3`, `ErrorTextId`,`ScriptName`,`Comment`) VALUES
+(14,5749,6932,0,25,22704,0,0,0,'','Show gossip menu if player learned the spell');
+
+UPDATE `gameobject_template` SET `AIName`='SmartGameObjectAI', ScriptName='' WHERE `entry`=179552;
+DELETE FROM `smart_scripts` WHERE `entryorguid` = 179552 AND `source_type` = 1;
+
+INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES
+
+(179552, 1, 0, 0, 62, 0, 100, 0, 5749, 0, 0, 0, 85, 22864, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, '179552 - On Gossip Select - InvokerCast'),
+(179552, 1, 1, 0, 62, 0, 100, 0, 5749, 0, 0, 0, 72, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, '179552 - On Gossip Select - CloseGossip');
diff --git a/sql/updates/world/2014_10_11_05_world.sql b/sql/updates/world/2014_10_11_05_world.sql
new file mode 100644
index 00000000000..5a087f3c0d4
--- /dev/null
+++ b/sql/updates/world/2014_10_11_05_world.sql
@@ -0,0 +1,7 @@
+UPDATE `smart_scripts` SET `action_type`=86, `action_param2`=2, `action_param3`=18, `action_param4`=35, `target_type`=1, `target_param1`=0 WHERE `entryorguid`=23689 AND `source_type`=0 AND `id`=2;
+UPDATE `smart_scripts` SET `action_type`=86, `action_param2`=2, `action_param3`=18, `action_param4`=35, `target_type`=1, `target_param1`=0 WHERE `entryorguid`=24170 AND `source_type`=0 AND `id`=1;
+UPDATE `smart_scripts` SET `action_type`=86, `action_param2`=2, `action_param3`=21, `action_param4`=20, `target_type`=1, `target_param1`=0 WHERE `entryorguid`=24439 AND `source_type`=0 AND `id`=3;
+UPDATE `smart_scripts` SET `action_type`=86, `action_param2`=2, `action_param3`=21, `action_param4`=10, `target_type`=1, `target_param1`=0 WHERE `entryorguid`=27409 AND `source_type`=0 AND `id`=5;
+UPDATE `smart_scripts` SET `action_type`=86, `action_param2`=2, `action_param3`=23, `action_param4`=0, `target_type`=1, `target_param1`=0 WHERE `entryorguid`=31048 AND `source_type`=0 AND `id`=2;
+UPDATE `smart_scripts` SET `action_type`=85, `action_param2`=2, `target_type`=1 WHERE `entryorguid`=24439 AND `source_type`=0 AND `id`=4;
+UPDATE `smart_scripts` SET `action_type`=85, `action_param2`=2, `target_type`=1 WHERE `entryorguid`=27202 AND `source_type`=0 AND `id`=11;
diff --git a/sql/updates/world/2014_10_11_06_world.sql b/sql/updates/world/2014_10_11_06_world.sql
new file mode 100644
index 00000000000..875d71d4ac0
--- /dev/null
+++ b/sql/updates/world/2014_10_11_06_world.sql
@@ -0,0 +1,3 @@
+--
+UPDATE `creature_template` SET `gossip_menu_id`=10949, `npcflag`=4225 WHERE `entry`=37904;
+UPDATE `gossip_menu_option` SET `option_id`=3, `npc_option_npcflag`=128 WHERE `menu_id`=10949 AND `id`=0;
diff --git a/sql/updates/world/2014_10_11_07_world.sql b/sql/updates/world/2014_10_11_07_world.sql
new file mode 100644
index 00000000000..385f46baa2f
--- /dev/null
+++ b/sql/updates/world/2014_10_11_07_world.sql
@@ -0,0 +1,91 @@
+UPDATE `creature` SET `MovementType`=0,`spawndist`=0 WHERE `guid` IN(121055,121049);
+
+DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=13 AND `SourceEntry` IN(58108,58118);
+INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES
+(13, 1, 58108, 0, 0, 31, 0, 3, 30995, 0, 0, 0, 0, '', 'Patches Chain targets Patches Chain Target'),
+(13, 1, 58118, 0, 0, 31, 0, 3, 30992, 0, 0, 0, 0, '', 'Patches Revenge targets Doctor Sabnok');
+
+UPDATE `gameobject_template` SET `AIName`='SmartGameObjectAI', `ScriptName`='' WHERE `entry`=193025;
+UPDATE `creature_template` SET `AIName`= 'SmartAI' WHERE `entry` IN(30992,30993,30995);
+DELETE FROM `smart_scripts` WHERE `entryorguid` IN(30992,30993,30995) and `source_type`=0;
+DELETE FROM `smart_scripts` WHERE `entryorguid` IN(3099200,3099300) and `source_type`=9;
+DELETE FROM `smart_scripts` WHERE `source_type`=1 AND `entryorguid`=193025;
+
+INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES
+(193025, 1, 0 ,1, 70, 0, 100, 0, 2, 0, 0,0,45,1,1,0,0,0,0,19,30993,0,0,0, 0, 0, 0, 'Metal Stake - On State Changed - Set Data 1 1 on "Patches"'),
+(193025, 1, 1 ,0, 61, 0, 100, 0, 0, 0, 0,0,104,1,0,0,0,0,0,1,0,0,0,0, 0, 0, 0, 'Metal Stake - On State Changed - Set Flag In Use"'),
+(193025, 1, 2 ,0, 38, 0, 100, 0, 2, 2, 0,0,104,4,0,0,0,0,0,1,0,0,0,0, 0, 0, 0, 'Metal Stake - On Data Set - Remove Flag In Use"'),
+(30992, 0, 0, 0, 6, 0, 100, 0, 0, 0, 0, 0, 45, 3 , 3, 0, 0, 0, 0, 19, 30993, 0, 0, 0, 0, 0, 0, 'Doctor Sabnok - On Death - Set Data 3 3 on "Patches"'),
+(30992, 0, 1, 0,54, 0, 100, 0, 0, 0, 0, 0, 53, 0 , 30992, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Doctor Sabnok - On Just Summoned - Start WP'),
+(30992, 0, 2, 0,40, 0, 100, 0, 10, 30992, 0, 0, 45, 2 , 2, 0, 0, 0, 0, 19, 30993, 0, 0, 0, 0, 0, 0, 'Doctor Sabnok - Reached WP10 - Set Data 2 2 on "Patches"'),
+(30992, 0, 3, 4,40, 0, 100, 0, 14, 30992, 0, 0, 101, 0 , 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Doctor Sabnok - Reached WP14 - Set Home Position'),
+(30992, 0, 4, 5,61, 0, 100, 0, 0, 0, 0, 0, 8, 2 , 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Doctor Sabnok - Reached WP14 - Set Hostile'),
+(30992, 0, 5, 7,61, 0, 100, 0, 0, 0, 0, 0, 80, 3099200 , 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Doctor Sabnok - Reached WP14 - Run Script'),
+(30992, 0, 6, 0,11, 0, 100, 0, 0, 0, 0, 0, 18, 256 , 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Doctor Sabnok - On Spawn - Set Unit Flags'),
+(30992, 0, 7, 0,61, 0, 100, 0, 0, 0, 0, 0, 45, 5 , 5, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Doctor Sabnok - On Reached WP14 - Set Data 5 5 on "Patches"'),
+(30993, 0, 0, 0, 11, 0, 100, 0, 0, 0, 0, 0, 22, 2 , 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, '"Patches" - On Respawn - Set Phase 2'),
+(30993, 0, 1, 0, 1, 2, 100, 0, 0, 0, 3000, 3000, 11, 58108 , 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, '"Patches" - OOC (Phase 2) - Cast Patches Chain'),
+(30993, 0, 2, 3, 38, 0, 100, 0, 1, 1, 300000, 300000, 22, 0 , 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, '"Patches" - On Data Set 1 1 - Set Phase 1'),
+(30993, 0, 3, 4, 61, 0, 100, 0, 0, 0, 0, 0, 28, 58108 , 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, '"Patches" - On Data Set 1 1 - Remove Aura Patches Chain'),
+(30993, 0, 4, 5,61, 0, 100, 0, 0, 0, 0, 0, 45, 1 , 1, 0, 0, 0, 0, 19, 30995, 0, 0, 0, 0, 0, 0, '"Patches" - On Data Set 1 1 - Set Data 1 1 on Patches chain target'),
+(30993, 0, 5, 6, 61, 0, 100, 0, 0, 0, 0, 0, 12, 30992 , 2, 300000, 0, 0, 0, 8, 0, 0, 0, 6630.52, 3167.312, 659.3602, 2.740049, '"Patches" - On Data Set 1 1 - Summon Doctor Sabnok'),
+(30993, 0, 6, 7, 61, 0, 100, 0, 0, 0, 0, 0, 1, 1 , 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, '"Patches" - On Data Set 1 1 - Say Line 1'),
+(30993, 0, 7, 0, 61, 0, 100, 0, 0, 0, 0, 0, 2, 2036 , 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, '"Patches" - On Data Set 1 1 - Set Faction'),
+(30993, 0, 8, 9, 38, 0, 100, 0, 3, 3, 0, 0, 11, 59115 , 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Patches" - On Data Set 3 3 - Cast Patches Credit'),
+(30993, 0, 9, 0, 61, 0, 100, 0, 0, 0, 0, 0, 41, 5000 , 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Patches" - On Data Set 3 3 - Despawn'),
+(30993, 0, 10, 15, 38, 0, 100, 0, 5, 5, 0, 0, 89, 0 , 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Patches" - On On Data Set 5 5 - Turn Random Move Off'),
+(30993, 0, 11, 0, 38, 0, 100, 0, 4, 4, 0, 0, 80, 3099300 , 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Patches" - On Data Set 4 4 - Run Script'),
+(30993, 0, 12, 13, 11, 0, 100, 0, 0, 0, 0, 0, 45, 1 , 1, 0, 0, 0, 0, 14, 62005, 193025, 0, 0, 0, 0, 0, 'Patches" - On Respawn - Set Data 1 1 on Metal Stake'),
+(30993, 0, 13, 14, 61, 0, 100, 0, 0, 0, 0, 0, 89, 5 , 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Patches" - On Respawn - Set Random Movement'),
+(30993, 0, 14, 0, 61, 0, 100, 0, 0, 0, 0, 0, 18, 768 , 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Patches" - On Respawn - Set Unit Flags'),
+(30993, 0, 15, 0, 61, 0, 100, 0, 0, 0, 0, 0, 66, 0 , 0, 0, 0, 0, 0, 19, 30992, 0, 0, 0, 0, 0, 0, 'Patches" - On On Data Set 5 5 - Face Doctor Sabnok'),
+(30995, 0, 0, 0, 38, 0, 100, 0, 1, 1, 0, 0, 28, 58108 , 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Patches Chain Target - On Data Set 1 1 - Remove Aura Patches Chain'),
+(3099200, 9, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 66, 0 , 0, 0, 0, 0, 0, 21, 50, 0, 0, 0, 0, 0, 0, 'Doctor Sabnok - Script - Face Player'),
+(3099200, 9, 1, 0, 0, 0, 100, 0, 0, 0, 0, 0, 5, 21 , 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Doctor Sabnok - Script - Play Emote OneShotApplaud'),
+(3099200, 9, 2, 0, 0, 0, 100, 0, 1000, 1000, 0, 0, 1, 1 , 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Doctor Sabnok - Script - Say Line 1'),
+(3099200, 9, 3, 0, 0, 0, 100, 0, 6000, 6000, 0, 0, 1, 2 , 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Doctor Sabnok - Script - Say Line 2'),
+(3099200, 9, 4, 0, 0, 0, 100, 0, 6000, 6000, 0, 0, 1, 3 , 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Doctor Sabnok - Script - Say Line 3'),
+(3099200, 9, 5, 0, 0, 0, 100, 0, 4000, 4000, 0, 0, 5, 11 , 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Doctor Sabnok - Script - Play Emote OneShotLaugh'),
+(3099200, 9, 6, 0, 0, 0, 100, 0, 0, 0, 0, 0, 45, 4 , 4, 0, 0, 0, 0, 19, 30993, 0, 0, 0, 0, 0, 0, 'Doctor Sabnok - Set Data 4 4 on "Patches"'),
+(3099200, 9, 7, 0, 0, 0, 100, 0, 0, 0, 0, 0, 19, 256 , 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Doctor Sabnok - Set Unit Flags"'),
+(3099300, 9, 0, 0, 0, 0, 100, 0, 3000, 3000, 0, 0, 8, 2 , 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, '"Patches" - Script - Set Hostile'),
+(3099300, 9, 1, 0, 0, 0, 100, 0, 0, 0, 0, 0, 19, 768 , 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, '"Patches" - Script - Set Unit Flags'),
+(3099300, 9, 2, 0, 0, 0, 100, 0, 0, 0, 0, 0, 49, 0 , 0, 0, 0, 0, 0, 19, 30992, 0, 0, 0, 0, 0, 0, '"Patches" - Script - Start Attack'),
+(3099300, 9, 3, 0, 0, 0, 100, 0, 0, 0, 0, 0, 1, 2 , 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, '"Patches" - Script - Say Line 2'),
+(3099300, 9, 4, 0, 0, 0, 100, 0, 4000, 4000, 0, 0, 11, 58118 , 0, 0, 0, 0, 0, 19, 30992, 0, 0, 0, 0, 0, 0, '"Patches" - Script - Cast Patches Revenge');
+
+DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=22 AND `SourceEntry`=30993;
+
+DELETE FROM `creature_text` WHERE `entry` IN(30992,30993);
+INSERT INTO `creature_text` (`entry`, `groupid`, `id`, `text`, `type`, `language`, `probability`, `emote`, `duration`, `sound`, `comment`, `BroadcastTextID`) VALUES
+(30992, 1, 0, 'Oh, bravo. Do you feel proud of yourself now that you''ve unleashed this terrible mistake?', 12, 0, 100, 21, 0, 0, 'Doctor Sabnok',31550),
+(30992, 2, 0, 'I already had him scheduled for disposal, but I suppose we can speed up the process a bit.', 12, 0, 100, 1, 0, 0, 'Doctor Sabnok',31551),
+(30992, 3, 0, 'It''s a pity so many fine, and reusable, parts will go to waste... ', 12, 0, 100, 11, 0, 0, 'Doctor Sabnok',31553),
+(30993, 1, 0, 'Patches get revenge on Doctor Sabnok!', 12, 0, 100, 51, 0, 0, '\"Patches\"',31556),
+(30993, 2, 0, 'Patches not going to be cut open or sewn up no more!', 12, 0, 100, 1, 0, 0, '\"Patches\"',31554);
+
+DELETE FROM `creature` WHERE `id` =30992;
+
+UPDATE `creature_template` SET `faction`=974, `speed_run`=1.142857, `unit_flags`=0 WHERE `entry`=30992;
+UPDATE `creature_template` SET `unit_flags`=0 WHERE `entry` =30993;
+
+DELETE FROM `waypoints` WHERE `entry` IN(30992,30993);
+INSERT INTO `waypoints` (`entry`, `pointid`, `position_x`, `position_y`, `position_z`, `point_comment`) VALUES
+(30992, 1, 6631.495, 3167.087, 659.3602, 'Doctor Sabnok'),
+(30992, 2, 6630.52, 3167.312, 659.3602, 'Doctor Sabnok'),
+(30992, 3, 6626.219, 3169.138, 658.8849, 'Doctor Sabnok'),
+(30992, 4, 6625.229, 3169.558, 658.8132, 'Doctor Sabnok'),
+(30992, 5, 6619.998, 3171.78, 656.6917, 'Doctor Sabnok'),
+(30992, 6, 6618.303, 3172.5, 655.796, 'Doctor Sabnok'),
+(30992, 7, 6618.303, 3172.5, 655.796, 'Doctor Sabnok'),
+(30992, 8, 6618.216, 3172.712, 655.967, 'Doctor Sabnok'),
+(30992, 9, 6614.216, 3176.462, 654.217, 'Doctor Sabnok'),
+(30992, 10, 6613.862, 3176.668, 653.9982, 'Doctor Sabnok'),
+(30992, 11, 6612.862, 3177.668, 653.7482, 'Doctor Sabnok'),
+(30992, 12, 6606.399, 3184.294, 649.7903, 'Doctor Sabnok'),
+(30992, 13, 6606.399, 3185.794, 649.2903, 'Doctor Sabnok'),
+(30992, 14, 6606.149, 3189.544, 648.5403, 'Doctor Sabnok');
+
+DELETE FROM `creature_template_addon` WHERE `entry` IN (30993);
+INSERT INTO `creature_template_addon` (`entry`, `mount`, `bytes1`, `bytes2`, `auras`) VALUES
+(30993, 0, 0x0, 0x1, '54262'); -- 30993 - 54262
diff --git a/sql/updates/world/2014_10_12_00_world.sql b/sql/updates/world/2014_10_12_00_world.sql
new file mode 100644
index 00000000000..ca1a062f437
--- /dev/null
+++ b/sql/updates/world/2014_10_12_00_world.sql
@@ -0,0 +1,294 @@
+-- Spectral Stable Hand SAI
+SET @ENTRY := 15551;
+UPDATE `smart_scripts` SET `event_chance`=50 WHERE `entryorguid`=@ENTRY AND `id`=4;
+DELETE FROM `smart_scripts` WHERE `entryorguid`=@ENTRY AND `id`=5;
+INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES
+(@ENTRY, 0, 5, 0, 4, 0, 50, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Spectral Stable Hand - On Aggro - Talk');
+
+-- Spectral Apprentice SAI
+SET @ENTRY := 16389;
+UPDATE `creature_template` SET `AIName`='SmartAI' WHERE `entry`=@ENTRY;
+DELETE FROM `smart_scripts` WHERE `entryorguid`=@ENTRY AND `id` IN (0, 1);
+INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES
+(@ENTRY, 0, 0, 0, 4, 0, 50, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Spectral Apprentice - On Aggro - Talk'),
+(@ENTRY, 0, 1, 0, 6, 0, 50, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Spectral Apprentice - On Death - Talk');
+
+-- Phantom Attendant SAI
+SET @ENTRY := 16406;
+UPDATE `smart_scripts` SET `event_chance`=100, `event_flags`=0 WHERE `entryorguid`=@ENTRY AND `id`=0;
+DELETE FROM `smart_scripts` WHERE `entryorguid`=@ENTRY AND `id` IN (4, 5);
+INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES
+(@ENTRY, 0, 4, 0, 4, 0, 10, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Phantom Attendant - On Aggro - Talk'),
+(@ENTRY, 0, 5, 0, 6, 0, 10, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Phantom Attendant - On Death - Talk');
+
+-- Spectral Servant SAI
+SET @ENTRY := 16407;
+UPDATE `smart_scripts` SET `event_chance`=50 WHERE `entryorguid`=@ENTRY AND `id`=2;
+DELETE FROM `smart_scripts` WHERE `entryorguid`=@ENTRY AND `id`=3;
+INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES
+(@ENTRY, 0, 3, 0, 4, 0, 50, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Spectral Servant - On Aggro - Talk');
+
+-- Phantom Valet SAI
+SET @ENTRY := 16408;
+UPDATE `smart_scripts` SET `event_chance`=50 WHERE `entryorguid`=@ENTRY AND `id`=1;
+DELETE FROM `smart_scripts` WHERE `entryorguid`=@ENTRY AND `id`=2;
+INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES
+(@ENTRY, 0, 2, 0, 4, 0, 50, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Phantom Valet - On Aggro - Talk');
+
+-- Phantom Guest SAI
+SET @ENTRY := 16409;
+UPDATE `smart_scripts` SET `event_chance`=10, `event_flags`=0 WHERE `entryorguid`=@ENTRY AND `id`=6;
+DELETE FROM `smart_scripts` WHERE `entryorguid`=@ENTRY AND `id`=7;
+INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES
+(@ENTRY, 0, 7, 0, 4, 0, 10, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Phantom Guest - On Aggro - Talk');
+
+-- Spectral Retainer SAI
+SET @ENTRY := 16410;
+UPDATE `creature_template` SET `AIName`='SmartAI' WHERE `entry`=@ENTRY;
+DELETE FROM `smart_scripts` WHERE `entryorguid`=@ENTRY AND `id` IN (0, 1);
+INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES
+(@ENTRY, 0, 0, 0, 4, 0, 50, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Spectral Retainer - On Aggro - Talk'),
+(@ENTRY, 0, 1, 0, 6, 0, 50, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Spectral Retainer - On Death - Talk');
+
+-- Spectral Chef SAI
+SET @ENTRY := 16411;
+DELETE FROM `smart_scripts` WHERE `entryorguid`=@ENTRY AND `id` IN (2, 3);
+INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES
+(@ENTRY, 0, 2, 0, 4, 0, 50, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Spectral Chef - On Aggro - Talk'),
+(@ENTRY, 0, 3, 0, 6, 0, 50, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Spectral Chef - On Death - Talk');
+
+-- Ghostly Baker SAI
+SET @ENTRY := 16412;
+UPDATE `creature_template` SET `AIName`='SmartAI' WHERE `entry`=@ENTRY;
+DELETE FROM `smart_scripts` WHERE `entryorguid`=@ENTRY AND `id` IN (0, 1);
+INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES
+(@ENTRY, 0, 0, 0, 4, 0, 50, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Ghostly Baker - On Aggro - Talk'),
+(@ENTRY, 0, 1, 0, 6, 0, 50, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Ghostly Baker - On Death - Talk');
+
+-- Spectral Sentry SAI
+SET @ENTRY := 16424;
+DELETE FROM `smart_scripts` WHERE `entryorguid`=@ENTRY AND `id` IN (1, 2);
+INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES
+(@ENTRY, 0, 1, 0, 4, 0, 50, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Spectral Sentry - On Aggro - Talk'),
+(@ENTRY, 0, 2, 0, 6, 0, 50, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Spectral Sentry - On Death - Talk');
+
+-- Phantom Guardsman SAI
+SET @ENTRY := 16425;
+DELETE FROM `smart_scripts` WHERE `entryorguid`=@ENTRY AND `id` IN (2, 3);
+INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES
+(@ENTRY, 0, 2, 0, 4, 0, 50, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Phantom Guardsman - On Aggro - Talk'),
+(@ENTRY, 0, 3, 0, 6, 0, 50, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Phantom Guardsman - On Death - Talk');
+
+-- Wanton Hostess SAI
+SET @ENTRY := 16459;
+UPDATE `smart_scripts` SET `event_flags`=1 WHERE `entryorguid`=@ENTRY AND `id`=2;
+DELETE FROM `smart_scripts` WHERE `entryorguid`=@ENTRY AND `id` IN (5, 6, 7, 8);
+INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES
+(@ENTRY, 0, 5, 0, 4, 0, 50, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Wanton Hostess - On Aggro - Talk'),
+(@ENTRY, 0, 6, 0, 6, 0, 50, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Wanton Hostess - On Death - Talk'),
+(@ENTRY, 0, 7, 0, 2, 0, 100, 1, 0, 50, 0, 0, 1, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Wanton Hostess - On Transform - Talk'),
+(@ENTRY, 0, 8, 0, 1, 0, 50, 0, 0, 40000, 45000, 120000, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Wanton Hostess - Out of Combat - Talk');
+
+-- Night Mistress SAI
+SET @ENTRY := 16460;
+DELETE FROM `smart_scripts` WHERE `entryorguid`=@ENTRY AND `id` IN (4, 5, 6, 7);
+INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES
+(@ENTRY, 0, 4, 0, 4, 0, 50, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Night Mistress - On Aggro - Talk'),
+(@ENTRY, 0, 5, 0, 6, 0, 50, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Night Mistress - On Death - Talk'),
+(@ENTRY, 0, 6, 0, 2, 0, 100, 1, 0, 50, 0, 0, 1, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Night Mistress - On Transform - Talk'),
+(@ENTRY, 0, 7, 0, 1, 0, 50, 0, 0, 40000, 45000, 120000, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Night Mistress - Out of Combat - Talk');
+
+-- Concubine SAI
+SET @ENTRY := 16461;
+UPDATE `smart_scripts` SET `action_param1`=2, `comment`='Concubine - Death - Talk' WHERE `entryorguid`=@ENTRY AND `id`=3;
+UPDATE `smart_scripts` SET `event_flags`=0, `event_param2`=40000, `event_param3`=45000, `event_param4`=120000, `action_param1`=0, `comment`='Concubine - Out of Combat - Talk' WHERE `entryorguid`=@ENTRY AND `id`=4;
+DELETE FROM `smart_scripts` WHERE `entryorguid`=@ENTRY AND `id` IN (6, 7);
+INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES
+(@ENTRY, 0, 6, 0, 4, 0, 50, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Concubine - On Aggro - Talk'),
+(@ENTRY, 0, 7, 0, 2, 0, 100, 1, 0, 50, 0, 0, 1, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Concubine - On Transform - Talk');
+
+-- Spectral Patron SAI
+SET @ENTRY := 16468;
+UPDATE `smart_scripts` SET `event_chance`=10 WHERE `entryorguid`=@ENTRY AND `id`=2; -- comment tbh
+DELETE FROM `smart_scripts` WHERE `entryorguid`=@ENTRY AND `id`=3;
+INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES
+(@ENTRY, 0, 3, 0, 4, 0, 10, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Spectral Patron - On Aggro - Talk');
+
+-- Ghostly Philanthropist SAI
+SET @ENTRY := 16470;
+UPDATE `smart_scripts` SET `event_chance`=50 WHERE `entryorguid`=@ENTRY AND `id`=2;
+DELETE FROM `smart_scripts` WHERE `entryorguid`=@ENTRY AND `id`=3;
+INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES
+(@ENTRY, 0, 3, 0, 4, 0, 50, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Ghostly Philanthropist - On Aggro - Talk');
+
+-- Skeletal Usher SAI
+SET @ENTRY := 16471;
+DELETE FROM `smart_scripts` WHERE `entryorguid`=@ENTRY AND `id` IN (3, 4);
+INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES
+(@ENTRY, 0, 3, 0, 4, 0, 50, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Skeletal Usher - On Aggro - Talk'),
+(@ENTRY, 0, 4, 0, 6, 0, 50, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Skeletal Usher - On Death - Talk');
+
+-- Phantom Stagehand SAI
+SET @ENTRY := 16472;
+DELETE FROM `smart_scripts` WHERE `entryorguid`=@ENTRY AND `id` IN (3, 4);
+INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES
+(@ENTRY, 0, 3, 0, 4, 0, 50, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Phantom Stagehand - On Aggro - Talk'),
+(@ENTRY, 0, 4, 0, 6, 0, 50, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Phantom Stagehand - On Death - Talk');
+
+-- Phantom Guardsman SAI
+SET @ENTRY := 16473;
+DELETE FROM `smart_scripts` WHERE `entryorguid`=@ENTRY AND `id` IN (3, 4);
+INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES
+(@ENTRY, 0, 3, 0, 4, 0, 50, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Spectral Performer - On Aggro - Talk'),
+(@ENTRY, 0, 4, 0, 6, 0, 50, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Spectral Performer - On Death - Talk');
+
+-- Ghastly Haunt SAI
+SET @ENTRY := 16481;
+UPDATE `smart_scripts` SET `event_chance`=50 WHERE `entryorguid`=@ENTRY AND `id`=2;
+DELETE FROM `smart_scripts` WHERE `entryorguid`=@ENTRY AND `id`=3;
+INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES
+(@ENTRY, 0, 3, 0, 4, 0, 50, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Ghastly Haunt - On Aggro - Talk');
+
+-- Trapped Soul SAI
+SET @ENTRY := 16482;
+UPDATE `smart_scripts` SET `event_chance`=50 WHERE `entryorguid`=@ENTRY AND `id`=2;
+DELETE FROM `smart_scripts` WHERE `entryorguid`=@ENTRY AND `id`=3;
+INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES
+(@ENTRY, 0, 3, 0, 4, 0, 50, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Trapped Soul - On Aggro - Talk');
+
+
+UPDATE `creature_text` SET `type`=12 WHERE `entry`=16414 AND `groupid`=0 AND `id`=2; -- Ghostly Steward
+UPDATE `creature_text` SET `type`=12 WHERE `entry`=16470 AND `groupid`=0 AND `id`=1; -- Ghostly Philanthropist
+
+DELETE FROM `creature_text` WHERE (`entry`=15551 AND `groupid`=1 AND `id`=0) OR (`entry`=15551 AND `groupid`=1 AND `id`=1) OR (`entry`=16389 AND `groupid`=0 AND `id`=0) OR (`entry`=16389 AND `groupid`=0 AND `id`=1) OR (`entry`=16389 AND `groupid`=1 AND `id`=0) OR (`entry`=16389 AND `groupid`=1 AND `id`=1) OR (`entry`=16406 AND `groupid`=0 AND `id`=2) OR (`entry`=16406 AND `groupid`=1 AND `id`=0) OR (`entry`=16406 AND `groupid`=1 AND `id`=1) OR (`entry`=16406 AND `groupid`=1 AND `id`=2) OR (`entry`=16407 AND `groupid`=1 AND `id`=0) OR (`entry`=16407 AND `groupid`=1 AND `id`=1) OR (`entry`=16407 AND `groupid`=1 AND `id`=2) OR (`entry`=16408 AND `groupid`=0 AND `id`=1) OR (`entry`=16408 AND `groupid`=0 AND `id`=2) OR (`entry`=16408 AND `groupid`=1 AND `id`=0) OR (`entry`=16408 AND `groupid`=1 AND `id`=1) OR (`entry`=16408 AND `groupid`=1 AND `id`=2) OR (`entry`=16408 AND `groupid`=1 AND `id`=3) OR (`entry`=16408 AND `groupid`=1 AND `id`=4) OR (`entry`=16409 AND `groupid`=0 AND `id`=1) OR (`entry`=16409 AND `groupid`=0 AND `id`=2) OR (`entry`=16409 AND `groupid`=1 AND `id`=0) OR (`entry`=16409 AND `groupid`=1 AND `id`=1) OR (`entry`=16409 AND `groupid`=1 AND `id`=2) OR (`entry`=16410 AND `groupid`=0 AND `id`=0) OR (`entry`=16410 AND `groupid`=0 AND `id`=1) OR (`entry`=16410 AND `groupid`=0 AND `id`=2) OR (`entry`=16410 AND `groupid`=1 AND `id`=0) OR (`entry`=16410 AND `groupid`=1 AND `id`=1) OR (`entry`=16410 AND `groupid`=1 AND `id`=2) OR (`entry`=16411 AND `groupid`=0 AND `id`=0) OR (`entry`=16411 AND `groupid`=0 AND `id`=1) OR (`entry`=16411 AND `groupid`=0 AND `id`=2) OR (`entry`=16411 AND `groupid`=1 AND `id`=0) OR (`entry`=16411 AND `groupid`=1 AND `id`=1) OR (`entry`=16411 AND `groupid`=1 AND `id`=2) OR (`entry`=16412 AND `groupid`=0 AND `id`=0) OR (`entry`=16412 AND `groupid`=0 AND `id`=1) OR (`entry`=16412 AND `groupid`=0 AND `id`=2) OR (`entry`=16412 AND `groupid`=1 AND `id`=0) OR (`entry`=16412 AND `groupid`=1 AND `id`=1) OR (`entry`=16412 AND `groupid`=1 AND `id`=2) OR (`entry`=16414 AND `groupid`=0 AND `id`=3) OR (`entry`=16414 AND `groupid`=1 AND `id`=0) OR (`entry`=16414 AND `groupid`=1 AND `id`=1) OR (`entry`=16414 AND `groupid`=1 AND `id`=2) OR (`entry`=16424 AND `groupid`=0 AND `id`=0) OR (`entry`=16424 AND `groupid`=0 AND `id`=1) OR (`entry`=16424 AND `groupid`=0 AND `id`=2) OR (`entry`=16424 AND `groupid`=1 AND `id`=0) OR (`entry`=16424 AND `groupid`=1 AND `id`=1) OR (`entry`=16424 AND `groupid`=1 AND `id`=2) OR (`entry`=16425 AND `groupid`=0 AND `id`=0) OR (`entry`=16425 AND `groupid`=0 AND `id`=1) OR (`entry`=16425 AND `groupid`=0 AND `id`=2) OR (`entry`=16425 AND `groupid`=1 AND `id`=0) OR (`entry`=16425 AND `groupid`=1 AND `id`=1) OR (`entry`=16425 AND `groupid`=1 AND `id`=2) OR (`entry`=16459 AND `groupid`=0 AND `id`=0) OR (`entry`=16459 AND `groupid`=0 AND `id`=1) OR (`entry`=16459 AND `groupid`=0 AND `id`=2) OR (`entry`=16459 AND `groupid`=0 AND `id`=3) OR (`entry`=16459 AND `groupid`=1 AND `id`=0) OR (`entry`=16459 AND `groupid`=1 AND `id`=1) OR (`entry`=16459 AND `groupid`=1 AND `id`=2) OR (`entry`=16459 AND `groupid`=2 AND `id`=0) OR (`entry`=16459 AND `groupid`=2 AND `id`=1) OR (`entry`=16459 AND `groupid`=2 AND `id`=2) OR (`entry`=16459 AND `groupid`=2 AND `id`=3) OR (`entry`=16459 AND `groupid`=2 AND `id`=4) OR (`entry`=16459 AND `groupid`=3 AND `id`=0) OR (`entry`=16459 AND `groupid`=3 AND `id`=1) OR (`entry`=16459 AND `groupid`=3 AND `id`=2) OR (`entry`=16459 AND `groupid`=3 AND `id`=3) OR (`entry`=16459 AND `groupid`=3 AND `id`=4) OR (`entry`=16459 AND `groupid`=3 AND `id`=5) OR (`entry`=16459 AND `groupid`=3 AND `id`=6) OR (`entry`=16460 AND `groupid`=0 AND `id`=3) OR (`entry`=16460 AND `groupid`=1 AND `id`=0) OR (`entry`=16460 AND `groupid`=1 AND `id`=1) OR (`entry`=16460 AND `groupid`=1 AND `id`=2) OR (`entry`=16460 AND `groupid`=2 AND `id`=0) OR (`entry`=16460 AND `groupid`=2 AND `id`=1) OR (`entry`=16460 AND `groupid`=2 AND `id`=2) OR (`entry`=16460 AND `groupid`=2 AND `id`=3) OR (`entry`=16460 AND `groupid`=2 AND `id`=4) OR (`entry`=16460 AND `groupid`=3 AND `id`=0) OR (`entry`=16460 AND `groupid`=3 AND `id`=1) OR (`entry`=16460 AND `groupid`=3 AND `id`=2) OR (`entry`=16460 AND `groupid`=3 AND `id`=3) OR (`entry`=16460 AND `groupid`=3 AND `id`=4) OR (`entry`=16460 AND `groupid`=3 AND `id`=5) OR (`entry`=16460 AND `groupid`=3 AND `id`=6) OR (`entry`=16461 AND `groupid`=0 AND `id`=0) OR (`entry`=16461 AND `groupid`=0 AND `id`=1) OR (`entry`=16461 AND `groupid`=0 AND `id`=2) OR (`entry`=16461 AND `groupid`=0 AND `id`=3) OR (`entry`=16461 AND `groupid`=1 AND `id`=0) OR (`entry`=16461 AND `groupid`=1 AND `id`=1) OR (`entry`=16461 AND `groupid`=1 AND `id`=2) OR (`entry`=16461 AND `groupid`=2 AND `id`=0) OR (`entry`=16461 AND `groupid`=2 AND `id`=1) OR (`entry`=16461 AND `groupid`=2 AND `id`=2) OR (`entry`=16461 AND `groupid`=2 AND `id`=3) OR (`entry`=16461 AND `groupid`=2 AND `id`=4) OR (`entry`=16461 AND `groupid`=3 AND `id`=0) OR (`entry`=16461 AND `groupid`=3 AND `id`=1) OR (`entry`=16461 AND `groupid`=3 AND `id`=2) OR (`entry`=16461 AND `groupid`=3 AND `id`=3) OR (`entry`=16461 AND `groupid`=3 AND `id`=4) OR (`entry`=16461 AND `groupid`=3 AND `id`=5) OR (`entry`=16461 AND `groupid`=3 AND `id`=6) OR (`entry`=16468 AND `groupid`=1 AND `id`=0) OR (`entry`=16468 AND `groupid`=1 AND `id`=1) OR (`entry`=16470 AND `groupid`=1 AND `id`=0) OR (`entry`=16470 AND `groupid`=1 AND `id`=1) OR (`entry`=16471 AND `groupid`=0 AND `id`=0) OR (`entry`=16471 AND `groupid`=0 AND `id`=1) OR (`entry`=16471 AND `groupid`=0 AND `id`=2) OR (`entry`=16471 AND `groupid`=0 AND `id`=3) OR (`entry`=16471 AND `groupid`=0 AND `id`=4) OR (`entry`=16471 AND `groupid`=1 AND `id`=0) OR (`entry`=16471 AND `groupid`=1 AND `id`=1) OR (`entry`=16472 AND `groupid`=0 AND `id`=0) OR (`entry`=16472 AND `groupid`=0 AND `id`=1) OR (`entry`=16472 AND `groupid`=1 AND `id`=0) OR (`entry`=16472 AND `groupid`=1 AND `id`=1) OR (`entry`=16473 AND `groupid`=0 AND `id`=0) OR (`entry`=16473 AND `groupid`=0 AND `id`=1) OR (`entry`=16473 AND `groupid`=1 AND `id`=0) OR (`entry`=16473 AND `groupid`=1 AND `id`=1) OR (`entry`=16481 AND `groupid`=1 AND `id`=0) OR (`entry`=16481 AND `groupid`=1 AND `id`=1) OR (`entry`=16482 AND `groupid`=1 AND `id`=0) OR (`entry`=16482 AND `groupid`=1 AND `id`=1);
+INSERT INTO `creature_text` (`entry`, `groupid`, `id`, `text`, `type`, `probability`, `sound`, `BroadcastTextId`, `comment`) VALUES
+(15551, 1, 0, 'Intruder!', 12, 100, 0, 13773, 'Spectral Stable Hand - On Aggro'),
+(15551, 1, 1, 'You are not welcome here!', 12, 100, 0, 13774, 'Spectral Stable Hand - On Aggro'),
+(16389, 0, 0, 'You are not welcome here!', 12, 100, 0, 13774, 'Spectral Apprentice - On Aggro'),
+(16389, 0, 1, 'You, hold there!', 12, 100, 0, 13798, 'Spectral Apprentice - On Aggro'),
+(16389, 1, 0, 'I am lost...', 12, 100, 0, 13801, 'Spectral Apprentice - On Death'),
+(16389, 1, 1, 'Why...?', 12, 100, 0, 13802, 'Spectral Apprentice - On Death'),
+(16406, 0, 2, 'I mustn''t be afraid....', 12, 100, 0, 13849, 'Phantom Attendant - On Death'),
+(16406, 1, 0, 'You''ll ruin everything!', 12, 100, 0, 13844, 'Phantom Attendant - On Aggro'),
+(16406, 1, 1, 'Off with you!', 12, 100, 0, 13845, 'Phantom Attendant - On Aggro'),
+(16406, 1, 2, 'We do not wish to be disturbed!', 12, 100, 0, 13846, 'Phantom Attendant - On Aggro'),
+(16407, 1, 0, 'What is this?', 12, 100, 0, 13820, 'Spectral Servant - On Aggro'),
+(16407, 1, 1, 'Invaders in the tower!', 12, 100, 0, 13821, 'Spectral Servant - On Aggro'),
+(16407, 1, 2, 'Stop them!', 12, 100, 0, 13822, 'Spectral Servant - On Aggro'),
+(16408, 0, 1, 'My time is done.', 12, 100, 0, 13857, 'Phantom Valet - On Death'),
+(16408, 0, 2, 'No, not now! Not like this!', 12, 100, 0, 13858, 'Phantom Valet - On Death'),
+(16408, 1, 0, 'Hey! Where do you think you are going, sneaking around like that?', 12, 100, 0, 13398, 'Phantom Valet - On Aggro'),
+(16408, 1, 1, 'Excuse me, are you trying to sneak by without an invitation?', 12, 100, 0, 13399, 'Phantom Valet - On Aggro'),
+(16408, 1, 2, 'Begone, outsider!', 12, 100, 0, 13851, 'Phantom Valet - On Aggro'),
+(16408, 1, 3, 'You''ll not ruin the celebration!', 12, 100, 0, 13852, 'Phantom Valet - On Aggro'),
+(16408, 1, 4, 'We are besieged!', 12, 100, 0, 13853, 'Phantom Valet - On Aggro'),
+(16409, 0, 1, 'It''s not my time, not yet!', 12, 100, 0, 13842, 'Phantom Guest - On Death'),
+(16409, 0, 2, 'All good things must come to an end.', 12, 100, 0, 13843, 'Phantom Guest - On Death'),
+(16409, 1, 0, 'How dare you interfere?!', 12, 100, 0, 13838, 'Phantom Guest - On Aggro'),
+(16409, 1, 1, 'You do not belong here!', 12, 100, 0, 13839, 'Phantom Guest - On Aggro'),
+(16409, 1, 2, 'Leave us alone! Let us be!', 12, 100, 0, 13840, 'Phantom Guest - On Aggro'),
+(16410, 0, 0, 'You''ll ruin everything!', 12, 100, 0, 13844, 'Spectral Retainer - On Aggro'),
+(16410, 0, 1, 'Off with you!', 12, 100, 0, 13845, 'Spectral Retainer - On Aggro'),
+(16410, 0, 2, 'We do not wish to be disturbed!', 12, 100, 0, 13846, 'Spectral Retainer - On Aggro'),
+(16410, 1, 0, 'Where am I? What--', 12, 100, 0, 13847, 'Spectral Retainer - On Death'),
+(16410, 1, 1, 'What is happening?', 12, 100, 0, 13848, 'Spectral Retainer - On Death'),
+(16410, 1, 2, 'I mustn''t be afraid....', 12, 100, 0, 13849, 'Spectral Retainer - On Death'),
+(16411, 0, 0, 'I''ll chop you into minced meat!', 12, 100, 0, 13861, 'Spectral Chef - On Aggro'),
+(16411, 0, 1, 'I''ll gut you like a fish!', 12, 100, 0, 13862, 'Spectral Chef - On Aggro'),
+(16411, 0, 2, 'I''ll carve the meat from your bones!', 12, 100, 0, 13863, 'Spectral Chef - On Aggro'),
+(16411, 1, 0, 'I have served to the last....', 12, 100, 0, 13864, 'Spectral Chef - On Death'),
+(16411, 1, 1, 'This isn''t the end; it can''t be!', 12, 100, 0, 13865, 'Spectral Chef - On Death'),
+(16411, 1, 2, 'I tried, master. I tried.', 12, 100, 0, 13866, 'Spectral Chef - On Death'),
+(16412, 0, 0, 'I''ll chop you into minced meat!', 12, 100, 0, 13861, 'Ghostly Baker - On Aggro'),
+(16412, 0, 1, 'I''ll gut you like a fish!', 12, 100, 0, 13862, 'Ghostly Baker - On Aggro'),
+(16412, 0, 2, 'I''ll carve the meat from your bones!', 12, 100, 0, 13863, 'Ghostly Baker - On Aggro'),
+(16412, 1, 0, 'I have served to the last....', 12, 100, 0, 13864, 'Ghostly Baker - On Death'),
+(16412, 1, 1, 'This isn''t the end; it can''t be!', 12, 100, 0, 13865, 'Ghostly Baker - On Death'),
+(16412, 1, 2, 'I tried, master. I tried.', 12, 100, 0, 13866, 'Ghostly Baker - On Death'),
+(16414, 0, 3, 'How dare you spill the master''s wine!', 12, 100, 0, 13435, 'Ghostly Steward - On Death'),
+(16414, 1, 0, 'Impudent outsiders!', 12, 100, 0, 13876, 'Ghostly Steward - On Aggro'),
+(16414, 1, 1, 'Meddling fools! You will pay with your lives!', 12, 100, 0, 13877, 'Ghostly Steward - On Aggro'),
+(16414, 1, 2, 'You''ll never make it out alive....', 12, 100, 0, 13879, 'Ghostly Steward - On Aggro'),
+(16424, 0, 0, 'What is this?', 12, 100, 0, 13820, 'Spectral Sentry - On Aggro'),
+(16424, 0, 1, 'Invaders in the tower!', 12, 100, 0, 13821, 'Spectral Sentry - On Aggro'),
+(16424, 0, 2, 'Stop them!', 12, 100, 0, 13822, 'Spectral Sentry - On Aggro'),
+(16424, 1, 0, 'You will be punished!', 12, 100, 0, 13835, 'Spectral Sentry - On Death'),
+(16424, 1, 1, 'You... will... pay.', 12, 100, 0, 13836, 'Spectral Sentry - On Death'),
+(16424, 1, 2, 'I have failed....', 12, 100, 0, 13834, 'Spectral Sentry - On Death'),
+(16425, 0, 0, 'To arms!', 12, 100, 0, 13829, 'Phantom Guardsman - On Aggro'),
+(16425, 0, 1, 'Protect the tower!', 12, 100, 0, 13830, 'Phantom Guardsman - On Aggro'),
+(16425, 0, 2, 'Have at them!', 12, 100, 0, 13831, 'Phantom Guardsman - On Aggro'),
+(16425, 1, 0, 'You will be punished!', 12, 100, 0, 13835, 'Phantom Guardsman - On Death'),
+(16425, 1, 1, 'You... will... pay.', 12, 100, 0, 13836, 'Phantom Guardsman - On Death'),
+(16425, 1, 2, 'I have failed....', 12, 100, 0, 13834, 'Phantom Guardsman - On Death'),
+(16459, 0, 0, 'So I said, "Yeah, but that''ll cost you extra."', 12, 100, 0, 13883, 'Wanton Hostess - Out of Combat'),
+(16459, 0, 1, 'Five seconds. I''m not kidding!', 12, 100, 0, 13884, 'Wanton Hostess - Out of Combat'),
+(16459, 0, 2, 'He asked if the imp could join in--can you believe it? Actually, it wasn''t half bad....', 12, 100, 0, 13885, 'Wanton Hostess - Out of Combat'),
+(16459, 0, 3, 'They fall asleep after. Me, I fall asleep during....', 12, 100, 0, 13886, 'Wanton Hostess - Out of Combat'),
+(16459, 1, 0, 'Come play with me!', 12, 100, 0, 13880, 'Wanton Hostess - On Aggro'),
+(16459, 1, 1, 'You WILL be mine.', 12, 100, 0, 13881, 'Wanton Hostess - On Aggro'),
+(16459, 1, 2, 'Come here, pretty. You have what I need!', 12, 100, 0, 13882, 'Wanton Hostess - On Aggro'),
+(16459, 2, 0, 'It was fun while it lasted....', 12, 100, 0, 13889, 'Wanton Hostess - On Death'),
+(16459, 2, 1, '<sigh> It''s always over too soon.', 12, 100, 0, 13890, 'Wanton Hostess - On Death'),
+(16459, 2, 2, 'Just when things were getting interesting.', 12, 100, 0, 13897, 'Wanton Hostess - On Death'),
+(16459, 2, 3, 'We could have had so much fun!', 12, 100, 0, 13898, 'Wanton Hostess - On Death'),
+(16459, 3, 0, 'Come any closer, and I''ll scream.', 12, 100, 0, 13887, 'Wanton Hostess - On Transform'),
+(16459, 3, 1, 'I want to show you a different side of me....', 12, 100, 0, 13888, 'Wanton Hostess - On Transform'),
+(16459, 3, 2, 'I want you to be with me... forever and ever.', 12, 100, 0, 13891, 'Wanton Hostess - On Transform'),
+(16459, 3, 3, 'Shhh... I have a little secret I''ve been keeping.\n', 12, 100, 0, 13892, 'Wanton Hostess - On Transform'),
+(16459, 3, 4, 'I''ve been very, very naughty....', 12, 100, 0, 13895, 'Wanton Hostess - On Transform'),
+(16459, 3, 5, 'Enough foreplay. Let''s get down to business.', 12, 100, 0, 13896, 'Wanton Hostess - On Transform'),
+(16460, 0, 3, 'They fall asleep after. Me, I fall asleep during....', 12, 100, 0, 13886, 'Night Mistress - Out of Combat'),
+(16460, 1, 0, 'Come play with me!', 12, 100, 0, 13880, 'Night Mistress - On Aggro'),
+(16460, 1, 1, 'You WILL be mine.', 12, 100, 0, 13881, 'Night Mistress - On Aggro'),
+(16460, 1, 2, 'Come here, pretty. You have what I need!', 12, 100, 0, 13882, 'Night Mistress - On Aggro'),
+(16460, 2, 0, 'It was fun while it lasted....', 12, 100, 0, 13889, 'Night Mistress - On Death'),
+(16460, 2, 1, '<sigh> It''s always over too soon.', 12, 100, 0, 13890, 'Night Mistress - On Death'),
+(16460, 2, 2, 'Just when things were getting interesting.', 12, 100, 0, 13897, 'Night Mistress - On Death'),
+(16460, 2, 3, 'We could have had so much fun!', 12, 100, 0, 13898, 'Night Mistress - On Death'),
+(16460, 3, 0, 'Come any closer, and I''ll scream.', 12, 100, 0, 13887, 'Night Mistress - On Transform'),
+(16460, 3, 1, 'I want to show you a different side of me....', 12, 100, 0, 13888, 'Night Mistress - On Transform'),
+(16460, 3, 2, 'I want you to be with me... forever and ever.', 12, 100, 0, 13891, 'Night Mistress - On Transform'),
+(16460, 3, 3, 'Shhh... I have a little secret I''ve been keeping.\n', 12, 100, 0, 13892, 'Night Mistress - On Transform'),
+(16460, 3, 4, 'I''ve been very, very naughty....', 12, 100, 0, 13895, 'Night Mistress - On Transform'),
+(16460, 3, 5, 'Enough foreplay. Let''s get down to business.', 12, 100, 0, 13896, 'Night Mistress - On Transform'),
+(16461, 0, 0, 'So I said, "Yeah, but that''ll cost you extra."', 12, 100, 0, 13883, 'Concubine - Out of Combat'),
+(16461, 0, 1, 'Five seconds. I''m not kidding!', 12, 100, 0, 13884, 'Concubine - Out of Combat'),
+(16461, 0, 2, 'He asked if the imp could join in--can you believe it? Actually, it wasn''t half bad....', 12, 100, 0, 13885, 'Concubine - Out of Combat'),
+(16461, 0, 3, 'They fall asleep after. Me, I fall asleep during....', 12, 100, 0, 13886, 'Concubine - Out of Combat'),
+(16461, 1, 0, 'Come play with me!', 12, 100, 0, 13880, 'Concubine - On Aggro'),
+(16461, 1, 1, 'You WILL be mine.', 12, 100, 0, 13881, 'Concubine - On Aggro'),
+(16461, 1, 2, 'Come here, pretty. You have what I need!', 12, 100, 0, 13882, 'Concubine - On Aggro'),
+(16461, 2, 0, 'It was fun while it lasted....', 12, 100, 0, 13889, 'Concubine - On Death'),
+(16461, 2, 1, '<sigh> It''s always over too soon.', 12, 100, 0, 13890, 'Concubine - On Death'),
+(16461, 2, 2, 'Just when things were getting interesting.', 12, 100, 0, 13897, 'Concubine - On Death'),
+(16461, 2, 3, 'We could have had so much fun!', 12, 100, 0, 13898, 'Concubine - On Death'),
+(16461, 3, 0, 'Come any closer, and I''ll scream.', 12, 100, 0, 13887, 'Concubine - On Transform'),
+(16461, 3, 1, 'I want to show you a different side of me....', 12, 100, 0, 13888, 'Concubine - On Transform'),
+(16461, 3, 2, 'I want you to be with me... forever and ever.', 12, 100, 0, 13891, 'Concubine - On Transform'),
+(16461, 3, 3, 'Shhh... I have a little secret I''ve been keeping.\n', 12, 100, 0, 13892, 'Concubine - On Transform'),
+(16461, 3, 4, 'I''ve been very, very naughty....', 12, 100, 0, 13895, 'Concubine - On Transform'),
+(16461, 3, 5, 'Enough foreplay. Let''s get down to business.', 12, 100, 0, 13896, 'Concubine - On Transform'),
+(16468, 1, 0, 'You must not interfere!', 12, 100, 0, 13916, 'Spectral Patron - On Aggro'),
+(16468, 1, 1, 'What are you doing? Be off!', 12, 100, 0, 13917, 'Spectral Patron - On Aggro'),
+(16470, 1, 0, 'You were not invited!', 12, 100, 0, 13943, 'Ghostly Philanthropist - On Aggro'),
+(16470, 1, 1, 'Your insolence will not be tolerated!', 12, 100, 0, 13942, 'Ghostly Philanthropist - On Aggro'),
+(16471, 0, 0, 'Clear the area!', 12, 100, 0, 13920, 'Skeletal Usher - On Aggro'),
+(16471, 0, 1, 'Where''s your ticket?', 12, 100, 0, 13921, 'Skeletal Usher - On Aggro'),
+(16471, 0, 2, 'The show is for guests only!', 12, 100, 0, 13922, 'Skeletal Usher - On Aggro'),
+(16471, 0, 3, 'You should not have come here!', 12, 100, 0, 13923, 'Skeletal Usher - On Aggro'),
+(16471, 0, 4, 'You''ll be joining the other guests now....', 12, 100, 0, 13924, 'Skeletal Usher - On Aggro'),
+(16471, 1, 0, 'You cannot stop us all!', 12, 100, 0, 13925, 'Skeletal Usher - On Death'),
+(16471, 1, 1, 'Your death will soon follow....', 12, 100, 0, 13926, 'Skeletal Usher - On Death'),
+(16472, 0, 0, 'You''re not allowed here!', 12, 100, 0, 13928, 'Phantom Stagehand - On Aggro'),
+(16472, 0, 1, 'You''re not a guest!', 12, 100, 0, 13929, 'Phantom Stagehand - On Aggro'),
+(16472, 1, 0, 'Am I released from my duties?', 12, 100, 0, 13930, 'Phantom Stagehand - On Death'),
+(16472, 1, 1, 'At last, my work is done.', 12, 100, 0, 13931, 'Phantom Stagehand - On Death'),
+(16473, 0, 0, 'I will not be upstaged by amateurs!', 12, 100, 0, 13938, 'Spectral Performer - On Aggro'),
+(16473, 0, 1, 'The show must go on!', 12, 100, 0, 13939, 'Spectral Performer - On Aggro'),
+(16473, 1, 0, 'It''s so cold, so dark.... I''m not overacting, am I?', 12, 100, 0, 13940, 'Spectral Performer - On Death'),
+(16473, 1, 1, 'Make sure my name is spelled correctly on the tombst--', 12, 100, 0, 13941, 'Spectral Performer - On Death'),
+(16481, 1, 0, 'You will find no reward here, only death!', 12, 100, 0, 13946, 'Ghastly Haunt - On Aggro'),
+(16481, 1, 1, 'Visitors are forbidden!', 12, 100, 0, 13947, 'Ghastly Haunt - On Aggro'),
+(16482, 1, 0, 'You will find no reward here, only death!', 12, 100, 0, 13946, 'Trapped Soul - On Aggro'),
+(16482, 1, 1, 'Visitors are forbidden!', 12, 100, 0, 13947, 'Trapped Soul - On Aggro');
diff --git a/sql/updates/world/2014_10_12_01_world.sql b/sql/updates/world/2014_10_12_01_world.sql
new file mode 100644
index 00000000000..d34ce5b4dbf
--- /dev/null
+++ b/sql/updates/world/2014_10_12_01_world.sql
@@ -0,0 +1,12 @@
+-- Insert "Brazie's Black Book of Secrets" into Brazie Getz's vendor table
+DELETE FROM `npc_vendor` WHERE `entry`=37904 AND `item`=49926;
+INSERT INTO `npc_vendor` (`entry`, `item`, `maxcount`, `incrtime`, `ExtendedCost`, `VerifiedBuild`) VALUES
+(37904, 49926, 0, 0, 0, 0);
+-- Add various Brazie's "guides" inside "Brazie's Black Book of Secrets"
+DELETE FROM `item_loot_template` WHERE `Entry`=49926 AND `Item` IN (49918, 49922, 49923, 49924, 49925);
+INSERT INTO `item_loot_template` (`Entry`, `Item`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`) VALUES
+(49926, 49918, 100, 0, 1, 0, 1, 1), -- Brazie's Guide to Getting Good with Gnomish Girls
+(49926, 49922, 100, 0, 1, 0, 1, 1), -- Brazie's Dictionary of Devilish Draenei Damsels
+(49926, 49923, 100, 0, 1, 0, 1, 1), -- Brazie's Document on Dwarven Dates in Dun Morogh
+(49926, 49924, 100, 0, 1, 0, 1, 1), -- Brazie's Notes on Naughty Night Elves
+(49926, 49925, 100, 0, 1, 0, 1, 1); -- Brazie's Handbook to Handling Human Hunnies
diff --git a/sql/updates/world/2014_10_12_02_world.sql b/sql/updates/world/2014_10_12_02_world.sql
new file mode 100644
index 00000000000..42417c4602a
--- /dev/null
+++ b/sql/updates/world/2014_10_12_02_world.sql
@@ -0,0 +1,2 @@
+--
+DELETE FROM `spell_dbc` WHERE `Id` = 100001;
diff --git a/sql/updates/world/2014_10_12_03_world.sql b/sql/updates/world/2014_10_12_03_world.sql
new file mode 100644
index 00000000000..7f6649cd271
--- /dev/null
+++ b/sql/updates/world/2014_10_12_03_world.sql
@@ -0,0 +1,2 @@
+--
+UPDATE `spell_dbc` SET `AttributesEx3` = 0 WHERE `Id` = 65142;
diff --git a/sql/updates/world/2014_10_12_04_world.sql b/sql/updates/world/2014_10_12_04_world.sql
new file mode 100644
index 00000000000..b522b5fc927
--- /dev/null
+++ b/sql/updates/world/2014_10_12_04_world.sql
@@ -0,0 +1,3 @@
+UPDATE `smart_scripts` SET `link`=12 WHERE `entryorguid`=11680 AND `source_type`=0 AND `id`=11;
+UPDATE `smart_scripts` SET `link`=2 WHERE `entryorguid`=18855 AND `source_type`=0 AND `id`=1;
+UPDATE `smart_scripts` SET `link`=18 WHERE `entryorguid`=26670 AND `source_type`=0 AND `id`=18;
diff --git a/sql/updates/world/2014_10_12_05_world.sql b/sql/updates/world/2014_10_12_05_world.sql
new file mode 100644
index 00000000000..8ea7ba0aea1
--- /dev/null
+++ b/sql/updates/world/2014_10_12_05_world.sql
@@ -0,0 +1,2 @@
+--
+UPDATE `spell_dbc` SET `AttributesEx3` = 128 WHERE `Id` = 65142;
diff --git a/sql/updates/world/2014_10_12_06_world.sql b/sql/updates/world/2014_10_12_06_world.sql
new file mode 100644
index 00000000000..c448e6cbd98
--- /dev/null
+++ b/sql/updates/world/2014_10_12_06_world.sql
@@ -0,0 +1,8 @@
+DELETE FROM `creature_loot_template` WHERE `Entry`=15623;
+INSERT INTO `creature_loot_template`(`Entry`,`Item`,`Chance`,`MinCount`,`MaxCount`) VALUES
+(15623,14047,19,1,4),
+(15623,14256,3,1,1),
+(15623,8952,2,1,1),
+(15623,13446,1.3,1,1),
+(15623,13443,0.3,1,1),
+(15623,14283,0.11,1,1);
diff --git a/sql/updates/world/2014_10_12_07_world.sql b/sql/updates/world/2014_10_12_07_world.sql
new file mode 100644
index 00000000000..1bd0e4d9352
--- /dev/null
+++ b/sql/updates/world/2014_10_12_07_world.sql
@@ -0,0 +1,2 @@
+DELETE FROM `creature_loot_template` WHERE `Entry`=15623 AND `Item`=12002;
+INSERT INTO `creature_loot_template`(`Entry`,`Item`,`Chance`,`MinCount`,`MaxCount`) VALUE (15623,12002,0.13,1,1);
diff --git a/sql/updates/world/2014_10_13_00_world.sql b/sql/updates/world/2014_10_13_00_world.sql
new file mode 100644
index 00000000000..1af4567bfae
--- /dev/null
+++ b/sql/updates/world/2014_10_13_00_world.sql
@@ -0,0 +1,2 @@
+UPDATE `smart_scripts` SET `link`=18 WHERE `entryorguid`=26670 AND `source_type`=0 AND `id`=17;
+UPDATE `smart_scripts` SET `link`=20 WHERE `entryorguid`=26670 AND `source_type`=0 AND `id`=19;
diff --git a/sql/updates/world/2014_10_13_01_world.sql b/sql/updates/world/2014_10_13_01_world.sql
new file mode 100644
index 00000000000..33ab4d3ecda
--- /dev/null
+++ b/sql/updates/world/2014_10_13_01_world.sql
@@ -0,0 +1,423 @@
+DELETE FROM `creature_text` WHERE (`entry`=315 AND `groupid`=0 AND `id`=2) OR (`entry`=706 AND `groupid`=0 AND `id`=3) OR (`entry`=1398 AND `groupid`=0 AND `id`=3) OR (`entry`=1398 AND `groupid`=0 AND `id`=4) OR (`entry`=1398 AND `groupid`=0 AND `id`=5) OR (`entry`=1399 AND `groupid`=0 AND `id`=3) OR (`entry`=1399 AND `groupid`=0 AND `id`=4) OR (`entry`=1399 AND `groupid`=0 AND `id`=5) OR (`entry`=1410 AND `groupid`=0 AND `id`=2) OR (`entry`=1410 AND `groupid`=0 AND `id`=3) OR (`entry`=1410 AND `groupid`=0 AND `id`=4) OR (`entry`=1410 AND `groupid`=0 AND `id`=5) OR (`entry`=1493 AND `groupid`=0 AND `id`=0) OR (`entry`=1493 AND `groupid`=0 AND `id`=6) OR (`entry`=1493 AND `groupid`=0 AND `id`=7) OR (`entry`=1719 AND `groupid`=0 AND `id`=3) OR (`entry`=1719 AND `groupid`=0 AND `id`=4) OR (`entry`=1976 AND `groupid`=0 AND `id`=3) OR (`entry`=1976 AND `groupid`=0 AND `id`=4) OR (`entry`=1976 AND `groupid`=0 AND `id`=5) OR (`entry`=1976 AND `groupid`=0 AND `id`=6) OR (`entry`=1976 AND `groupid`=0 AND `id`=7) OR (`entry`=2044 AND `groupid`=0 AND `id`=2) OR (`entry`=2396 AND `groupid`=0 AND `id`=2) OR (`entry`=2922 AND `groupid`=0 AND `id`=3) OR (`entry`=2922 AND `groupid`=0 AND `id`=4) OR (`entry`=3218 AND `groupid`=0 AND `id`=3) OR (`entry`=3218 AND `groupid`=0 AND `id`=4) OR (`entry`=3218 AND `groupid`=0 AND `id`=5) OR (`entry`=3218 AND `groupid`=0 AND `id`=6) OR (`entry`=3218 AND `groupid`=0 AND `id`=7) OR (`entry`=3296 AND `groupid`=0 AND `id`=3) OR (`entry`=3296 AND `groupid`=0 AND `id`=4) OR (`entry`=3296 AND `groupid`=0 AND `id`=5) OR (`entry`=3296 AND `groupid`=0 AND `id`=6) OR (`entry`=3296 AND `groupid`=0 AND `id`=7) OR (`entry`=3502 AND `groupid`=0 AND `id`=3) OR (`entry`=3502 AND `groupid`=0 AND `id`=4) OR (`entry`=3502 AND `groupid`=0 AND `id`=5) OR (`entry`=3502 AND `groupid`=0 AND `id`=6) OR (`entry`=3502 AND `groupid`=0 AND `id`=7) OR (`entry`=3504 AND `groupid`=0 AND `id`=3) OR (`entry`=3504 AND `groupid`=1 AND `id`=3) OR (`entry`=3518 AND `groupid`=0 AND `id`=2) OR (`entry`=3518 AND `groupid`=0 AND `id`=3) OR (`entry`=3520 AND `groupid`=0 AND `id`=3) OR (`entry`=3520 AND `groupid`=1 AND `id`=3) OR (`entry`=4624 AND `groupid`=0 AND `id`=3) OR (`entry`=4624 AND `groupid`=0 AND `id`=4) OR (`entry`=4624 AND `groupid`=0 AND `id`=5) OR (`entry`=4624 AND `groupid`=0 AND `id`=6) OR (`entry`=4624 AND `groupid`=0 AND `id`=7) OR (`entry`=4979 AND `groupid`=2 AND `id`=3) OR (`entry`=5355 AND `groupid`=0 AND `id`=0) OR (`entry`=5355 AND `groupid`=0 AND `id`=1) OR (`entry`=5355 AND `groupid`=0 AND `id`=4) OR (`entry`=5355 AND `groupid`=0 AND `id`=5) OR (`entry`=5391 AND `groupid`=0 AND `id`=1) OR (`entry`=5391 AND `groupid`=2 AND `id`=2) OR (`entry`=5662 AND `groupid`=0 AND `id`=8) OR (`entry`=5698 AND `groupid`=0 AND `id`=8) OR (`entry`=5699 AND `groupid`=0 AND `id`=5) OR (`entry`=5955 AND `groupid`=0 AND `id`=2) OR (`entry`=5955 AND `groupid`=0 AND `id`=3) OR (`entry`=5955 AND `groupid`=0 AND `id`=4) OR (`entry`=5955 AND `groupid`=0 AND `id`=5) OR (`entry`=5955 AND `groupid`=0 AND `id`=6) OR (`entry`=5955 AND `groupid`=0 AND `id`=7) OR (`entry`=10541 AND `groupid`=0 AND `id`=3) OR (`entry`=10541 AND `groupid`=1 AND `id`=3) OR (`entry`=10541 AND `groupid`=1 AND `id`=4) OR (`entry`=10541 AND `groupid`=1 AND `id`=5) OR (`entry`=10541 AND `groupid`=1 AND `id`=6) OR (`entry`=10799 AND `groupid`=0 AND `id`=3) OR (`entry`=11136 AND `groupid`=0 AND `id`=2) OR (`entry`=11136 AND `groupid`=0 AND `id`=3) OR (`entry`=11136 AND `groupid`=0 AND `id`=4) OR (`entry`=11190 AND `groupid`=0 AND `id`=3) OR (`entry`=11190 AND `groupid`=0 AND `id`=4) OR (`entry`=11190 AND `groupid`=0 AND `id`=5) OR (`entry`=11190 AND `groupid`=0 AND `id`=6) OR (`entry`=11190 AND `groupid`=0 AND `id`=7) OR (`entry`=11582 AND `groupid`=0 AND `id`=3) OR (`entry`=11582 AND `groupid`=0 AND `id`=4) OR (`entry`=12337 AND `groupid`=0 AND `id`=3) OR (`entry`=15184 AND `groupid`=0 AND `id`=3) OR (`entry`=15184 AND `groupid`=0 AND `id`=4) OR (`entry`=15184 AND `groupid`=0 AND `id`=5) OR (`entry`=15184 AND `groupid`=0 AND `id`=6) OR (`entry`=15184 AND `groupid`=0 AND `id`=7) OR (`entry`=17259 AND `groupid`=0 AND `id`=3) OR (`entry`=17259 AND `groupid`=0 AND `id`=4) OR (`entry`=17259 AND `groupid`=0 AND `id`=5) OR (`entry`=17259 AND `groupid`=0 AND `id`=6) OR (`entry`=17271 AND `groupid`=0 AND `id`=3) OR (`entry`=17271 AND `groupid`=0 AND `id`=4) OR (`entry`=17271 AND `groupid`=0 AND `id`=5) OR (`entry`=17271 AND `groupid`=0 AND `id`=6) OR (`entry`=17491 AND `groupid`=0 AND `id`=2) OR (`entry`=17491 AND `groupid`=0 AND `id`=3) OR (`entry`=17491 AND `groupid`=0 AND `id`=4) OR (`entry`=17491 AND `groupid`=0 AND `id`=5) OR (`entry`=17491 AND `groupid`=0 AND `id`=6) OR (`entry`=18103 AND `groupid`=0 AND `id`=2) OR (`entry`=18103 AND `groupid`=0 AND `id`=3) OR (`entry`=18103 AND `groupid`=0 AND `id`=4) OR (`entry`=19283 AND `groupid`=0 AND `id`=3) OR (`entry`=21114 AND `groupid`=0 AND `id`=6) OR (`entry`=21661 AND `groupid`=1 AND `id`=3) OR (`entry`=21661 AND `groupid`=1 AND `id`=4) OR (`entry`=21661 AND `groupid`=1 AND `id`=5) OR (`entry`=21661 AND `groupid`=1 AND `id`=6) OR (`entry`=21661 AND `groupid`=1 AND `id`=7) OR (`entry`=22314 AND `groupid`=0 AND `id`=4) OR (`entry`=23311 AND `groupid`=0 AND `id`=7) OR (`entry`=23861 AND `groupid`=0 AND `id`=7) OR (`entry`=25428 AND `groupid`=0 AND `id`=3) OR (`entry`=25429 AND `groupid`=0 AND `id`=3) OR (`entry`=25682 AND `groupid`=0 AND `id`=1) OR (`entry`=25682 AND `groupid`=0 AND `id`=2) OR (`entry`=28608 AND `groupid`=0 AND `id`=3) OR (`entry`=28608 AND `groupid`=0 AND `id`=4) OR (`entry`=28608 AND `groupid`=0 AND `id`=5) OR (`entry`=28608 AND `groupid`=0 AND `id`=6) OR (`entry`=28609 AND `groupid`=0 AND `id`=3) OR (`entry`=28609 AND `groupid`=0 AND `id`=4) OR (`entry`=28609 AND `groupid`=0 AND `id`=5) OR (`entry`=28609 AND `groupid`=0 AND `id`=6) OR (`entry`=28611 AND `groupid`=0 AND `id`=3) OR (`entry`=28611 AND `groupid`=0 AND `id`=4) OR (`entry`=28611 AND `groupid`=0 AND `id`=5) OR (`entry`=28611 AND `groupid`=0 AND `id`=6) OR (`entry`=28714 AND `groupid`=0 AND `id`=3) OR (`entry`=28714 AND `groupid`=0 AND `id`=4) OR (`entry`=28714 AND `groupid`=0 AND `id`=5) OR (`entry`=28714 AND `groupid`=0 AND `id`=6) OR (`entry`=28715 AND `groupid`=0 AND `id`=3) OR (`entry`=28715 AND `groupid`=0 AND `id`=4) OR (`entry`=28715 AND `groupid`=0 AND `id`=5) OR (`entry`=28715 AND `groupid`=0 AND `id`=6) OR (`entry`=28721 AND `groupid`=0 AND `id`=6) OR (`entry`=28723 AND `groupid`=0 AND `id`=3) OR (`entry`=28723 AND `groupid`=0 AND `id`=4) OR (`entry`=28723 AND `groupid`=0 AND `id`=5) OR (`entry`=28723 AND `groupid`=0 AND `id`=6) OR (`entry`=28725 AND `groupid`=0 AND `id`=4) OR (`entry`=28725 AND `groupid`=0 AND `id`=5) OR (`entry`=28725 AND `groupid`=0 AND `id`=6) OR (`entry`=28726 AND `groupid`=0 AND `id`=6) OR (`entry`=28727 AND `groupid`=0 AND `id`=4) OR (`entry`=28727 AND `groupid`=0 AND `id`=5) OR (`entry`=28727 AND `groupid`=0 AND `id`=6) OR (`entry`=28750 AND `groupid`=0 AND `id`=0) OR (`entry`=28750 AND `groupid`=0 AND `id`=3) OR (`entry`=28989 AND `groupid`=0 AND `id`=6) OR (`entry`=28994 AND `groupid`=0 AND `id`=4) OR (`entry`=28994 AND `groupid`=0 AND `id`=5) OR (`entry`=28994 AND `groupid`=0 AND `id`=6) OR (`entry`=28997 AND `groupid`=0 AND `id`=4) OR (`entry`=28997 AND `groupid`=0 AND `id`=5) OR (`entry`=28997 AND `groupid`=0 AND `id`=6) OR (`entry`=29647 AND `groupid`=1 AND `id`=4) OR (`entry`=29647 AND `groupid`=1 AND `id`=8) OR (`entry`=29647 AND `groupid`=1 AND `id`=9) OR (`entry`=29647 AND `groupid`=1 AND `id`=10) OR (`entry`=29686 AND `groupid`=0 AND `id`=3) OR (`entry`=29686 AND `groupid`=0 AND `id`=4) OR (`entry`=29686 AND `groupid`=0 AND `id`=5) OR (`entry`=29686 AND `groupid`=0 AND `id`=6) OR (`entry`=29884 AND `groupid`=1 AND `id`=8) OR (`entry`=29884 AND `groupid`=1 AND `id`=9) OR (`entry`=29884 AND `groupid`=1 AND `id`=10) OR (`entry`=29491 AND `groupid`=0 AND `id`=2) OR (`entry`=29491 AND `groupid`=0 AND `id`=3) OR (`entry`=29491 AND `groupid`=0 AND `id`=4) OR (`entry`=29491 AND `groupid`=0 AND `id`=5) OR (`entry`=29491 AND `groupid`=0 AND `id`=6) OR (`entry`=29523 AND `groupid`=0 AND `id`=4) OR (`entry`=29523 AND `groupid`=0 AND `id`=5) OR (`entry`=29523 AND `groupid`=0 AND `id`=6) OR (`entry`=30012 AND `groupid`=0 AND `id`=4) OR (`entry`=31397 AND `groupid`=0 AND `id`=5) OR (`entry`=31397 AND `groupid`=0 AND `id`=6) OR (`entry`=31397 AND `groupid`=0 AND `id`=7) OR (`entry`=33027 AND `groupid`=0 AND `id`=5) OR (`entry`=33027 AND `groupid`=0 AND `id`=6) OR (`entry`=33853 AND `groupid`=0 AND `id`=3) OR (`entry`=36764 AND `groupid`=0 AND `id`=5) OR (`entry`=36764 AND `groupid`=0 AND `id`=6) OR (`entry`=36764 AND `groupid`=0 AND `id`=7) OR (`entry`=36764 AND `groupid`=0 AND `id`=8) OR (`entry`=36764 AND `groupid`=0 AND `id`=9) OR (`entry`=36764 AND `groupid`=0 AND `id`=10) OR (`entry`=36764 AND `groupid`=0 AND `id`=11) OR (`entry`=36764 AND `groupid`=0 AND `id`=12) OR (`entry`=36764 AND `groupid`=0 AND `id`=13) OR (`entry`=36764 AND `groupid`=0 AND `id`=14) OR (`entry`=36764 AND `groupid`=0 AND `id`=15) OR (`entry`=36764 AND `groupid`=0 AND `id`=16) OR (`entry`=36764 AND `groupid`=0 AND `id`=17) OR (`entry`=36764 AND `groupid`=0 AND `id`=18) OR (`entry`=36764 AND `groupid`=0 AND `id`=19) OR (`entry`=36764 AND `groupid`=0 AND `id`=20) OR (`entry`=36764 AND `groupid`=0 AND `id`=21) OR (`entry`=36764 AND `groupid`=0 AND `id`=22) OR (`entry`=36764 AND `groupid`=0 AND `id`=23) OR (`entry`=36764 AND `groupid`=0 AND `id`=24) OR (`entry`=36765 AND `groupid`=0 AND `id`=5) OR (`entry`=36765 AND `groupid`=0 AND `id`=6) OR (`entry`=36765 AND `groupid`=0 AND `id`=7) OR (`entry`=36765 AND `groupid`=0 AND `id`=8) OR (`entry`=36765 AND `groupid`=0 AND `id`=9) OR (`entry`=36765 AND `groupid`=0 AND `id`=10) OR (`entry`=36765 AND `groupid`=0 AND `id`=11) OR (`entry`=36765 AND `groupid`=0 AND `id`=12) OR (`entry`=36765 AND `groupid`=0 AND `id`=13) OR (`entry`=36765 AND `groupid`=0 AND `id`=14) OR (`entry`=36765 AND `groupid`=0 AND `id`=15) OR (`entry`=36765 AND `groupid`=0 AND `id`=16) OR (`entry`=36765 AND `groupid`=0 AND `id`=17) OR (`entry`=36765 AND `groupid`=0 AND `id`=18) OR (`entry`=36765 AND `groupid`=0 AND `id`=19) OR (`entry`=36765 AND `groupid`=0 AND `id`=20) OR (`entry`=36765 AND `groupid`=0 AND `id`=21) OR (`entry`=36765 AND `groupid`=0 AND `id`=22) OR (`entry`=36765 AND `groupid`=0 AND `id`=23) OR (`entry`=36765 AND `groupid`=0 AND `id`=24) OR (`entry`=36766 AND `groupid`=0 AND `id`=5) OR (`entry`=36766 AND `groupid`=0 AND `id`=6) OR (`entry`=36766 AND `groupid`=0 AND `id`=7) OR (`entry`=36766 AND `groupid`=0 AND `id`=8) OR (`entry`=36766 AND `groupid`=0 AND `id`=9) OR (`entry`=36766 AND `groupid`=0 AND `id`=10) OR (`entry`=36766 AND `groupid`=0 AND `id`=11) OR (`entry`=36766 AND `groupid`=0 AND `id`=12) OR (`entry`=36766 AND `groupid`=0 AND `id`=13) OR (`entry`=36766 AND `groupid`=0 AND `id`=14) OR (`entry`=36766 AND `groupid`=0 AND `id`=15) OR (`entry`=36766 AND `groupid`=0 AND `id`=16) OR (`entry`=36766 AND `groupid`=0 AND `id`=17) OR (`entry`=36766 AND `groupid`=0 AND `id`=18) OR (`entry`=36766 AND `groupid`=0 AND `id`=19) OR (`entry`=36766 AND `groupid`=0 AND `id`=20) OR (`entry`=36766 AND `groupid`=0 AND `id`=21) OR (`entry`=36766 AND `groupid`=0 AND `id`=22) OR (`entry`=36766 AND `groupid`=0 AND `id`=23) OR (`entry`=36766 AND `groupid`=0 AND `id`=24) OR (`entry`=36767 AND `groupid`=0 AND `id`=5) OR (`entry`=36767 AND `groupid`=0 AND `id`=6) OR (`entry`=36767 AND `groupid`=0 AND `id`=7) OR (`entry`=36767 AND `groupid`=0 AND `id`=8) OR (`entry`=36767 AND `groupid`=0 AND `id`=9) OR (`entry`=36767 AND `groupid`=0 AND `id`=10) OR (`entry`=36767 AND `groupid`=0 AND `id`=11) OR (`entry`=36767 AND `groupid`=0 AND `id`=12) OR (`entry`=36767 AND `groupid`=0 AND `id`=13) OR (`entry`=36767 AND `groupid`=0 AND `id`=14) OR (`entry`=36767 AND `groupid`=0 AND `id`=15) OR (`entry`=36767 AND `groupid`=0 AND `id`=16) OR (`entry`=36767 AND `groupid`=0 AND `id`=17) OR (`entry`=36767 AND `groupid`=0 AND `id`=18) OR (`entry`=36767 AND `groupid`=0 AND `id`=19) OR (`entry`=36767 AND `groupid`=0 AND `id`=20) OR (`entry`=36767 AND `groupid`=0 AND `id`=21) OR (`entry`=36767 AND `groupid`=0 AND `id`=22) OR (`entry`=36767 AND `groupid`=0 AND `id`=23) OR (`entry`=36767 AND `groupid`=0 AND `id`=24) OR (`entry`=36770 AND `groupid`=0 AND `id`=5) OR (`entry`=36770 AND `groupid`=0 AND `id`=6) OR (`entry`=36770 AND `groupid`=0 AND `id`=7) OR (`entry`=36770 AND `groupid`=0 AND `id`=8) OR (`entry`=36770 AND `groupid`=0 AND `id`=9) OR (`entry`=36770 AND `groupid`=0 AND `id`=10) OR (`entry`=36770 AND `groupid`=0 AND `id`=11) OR (`entry`=36770 AND `groupid`=0 AND `id`=12) OR (`entry`=36770 AND `groupid`=0 AND `id`=13) OR (`entry`=36770 AND `groupid`=0 AND `id`=14) OR (`entry`=36770 AND `groupid`=0 AND `id`=15) OR (`entry`=36770 AND `groupid`=0 AND `id`=16) OR (`entry`=36770 AND `groupid`=0 AND `id`=17) OR (`entry`=36770 AND `groupid`=0 AND `id`=18) OR (`entry`=36770 AND `groupid`=0 AND `id`=19) OR (`entry`=36770 AND `groupid`=0 AND `id`=20) OR (`entry`=36770 AND `groupid`=0 AND `id`=21) OR (`entry`=36770 AND `groupid`=0 AND `id`=22) OR (`entry`=36770 AND `groupid`=0 AND `id`=23) OR (`entry`=36770 AND `groupid`=0 AND `id`=24) OR (`entry`=36771 AND `groupid`=0 AND `id`=5) OR (`entry`=36771 AND `groupid`=0 AND `id`=6) OR (`entry`=36771 AND `groupid`=0 AND `id`=7) OR (`entry`=36771 AND `groupid`=0 AND `id`=8) OR (`entry`=36771 AND `groupid`=0 AND `id`=9) OR (`entry`=36771 AND `groupid`=0 AND `id`=10) OR (`entry`=36771 AND `groupid`=0 AND `id`=11) OR (`entry`=36771 AND `groupid`=0 AND `id`=12) OR (`entry`=36771 AND `groupid`=0 AND `id`=13) OR (`entry`=36771 AND `groupid`=0 AND `id`=14) OR (`entry`=36771 AND `groupid`=0 AND `id`=15) OR (`entry`=36771 AND `groupid`=0 AND `id`=16) OR (`entry`=36771 AND `groupid`=0 AND `id`=17) OR (`entry`=36771 AND `groupid`=0 AND `id`=18) OR (`entry`=36771 AND `groupid`=0 AND `id`=19) OR (`entry`=36771 AND `groupid`=0 AND `id`=20) OR (`entry`=36771 AND `groupid`=0 AND `id`=21) OR (`entry`=36771 AND `groupid`=0 AND `id`=22) OR (`entry`=36771 AND `groupid`=0 AND `id`=23) OR (`entry`=36771 AND `groupid`=0 AND `id`=24) OR (`entry`=36772 AND `groupid`=0 AND `id`=5) OR (`entry`=36772 AND `groupid`=0 AND `id`=6) OR (`entry`=36772 AND `groupid`=0 AND `id`=7) OR (`entry`=36772 AND `groupid`=0 AND `id`=8) OR (`entry`=36772 AND `groupid`=0 AND `id`=9) OR (`entry`=36772 AND `groupid`=0 AND `id`=10) OR (`entry`=36772 AND `groupid`=0 AND `id`=11) OR (`entry`=36772 AND `groupid`=0 AND `id`=12) OR (`entry`=36772 AND `groupid`=0 AND `id`=13) OR (`entry`=36772 AND `groupid`=0 AND `id`=14) OR (`entry`=36772 AND `groupid`=0 AND `id`=15) OR (`entry`=36772 AND `groupid`=0 AND `id`=16) OR (`entry`=36772 AND `groupid`=0 AND `id`=17) OR (`entry`=36772 AND `groupid`=0 AND `id`=18) OR (`entry`=36772 AND `groupid`=0 AND `id`=19) OR (`entry`=36772 AND `groupid`=0 AND `id`=20) OR (`entry`=36772 AND `groupid`=0 AND `id`=21) OR (`entry`=36772 AND `groupid`=0 AND `id`=22) OR (`entry`=36772 AND `groupid`=0 AND `id`=23) OR (`entry`=36772 AND `groupid`=0 AND `id`=24) OR (`entry`=36773 AND `groupid`=0 AND `id`=5) OR (`entry`=36773 AND `groupid`=0 AND `id`=6) OR (`entry`=36773 AND `groupid`=0 AND `id`=7) OR (`entry`=36773 AND `groupid`=0 AND `id`=8) OR (`entry`=36773 AND `groupid`=0 AND `id`=9) OR (`entry`=36773 AND `groupid`=0 AND `id`=10) OR (`entry`=36773 AND `groupid`=0 AND `id`=11) OR (`entry`=36773 AND `groupid`=0 AND `id`=12) OR (`entry`=36773 AND `groupid`=0 AND `id`=13) OR (`entry`=36773 AND `groupid`=0 AND `id`=14) OR (`entry`=36773 AND `groupid`=0 AND `id`=15) OR (`entry`=36773 AND `groupid`=0 AND `id`=16) OR (`entry`=36773 AND `groupid`=0 AND `id`=17) OR (`entry`=36773 AND `groupid`=0 AND `id`=18) OR (`entry`=36773 AND `groupid`=0 AND `id`=19) OR (`entry`=36773 AND `groupid`=0 AND `id`=20) OR (`entry`=36773 AND `groupid`=0 AND `id`=21) OR (`entry`=36773 AND `groupid`=0 AND `id`=22) OR (`entry`=36773 AND `groupid`=0 AND `id`=23) OR (`entry`=36773 AND `groupid`=0 AND `id`=24) OR (`entry`=36913 AND `groupid`=0 AND `id`=7);
+INSERT INTO `creature_text` (`entry`, `groupid`, `id`, `text`, `type`, `probability`, `sound`, `BroadcastTextId`, `comment`) VALUES
+(315, 0, 2, 'Tilloa is that you? Why no! It''s just some dirty $r!', 12, 100, 0, 507, 'Stalvan Mistmantle - On Aggro'),
+
+(706, 0, 3, 'My weapon be thirsty!', 12, 100, 0, 1908, 'Frostmane Troll Whelp - On Aggro'),
+
+(1398, 0, 3, 'The Stonesplinter Tribe shall see to your doom!', 12, 100, 0, 445, 'Boss Galgosh - On Aggro'),
+(1398, 0, 4, 'Die, $R! These lands belong to the Stonesplinter Tribe!', 12, 100, 0, 446, 'Boss Galgosh - On Aggro'),
+(1398, 0, 5, 'The Loch belongs to the Stonesplinter Tribe now, $n! Now die!', 12, 100, 0, 448, 'Boss Galgosh - On Aggro'),
+
+(1399, 0, 3, 'A $C called $n? You''ll make a fine breakfast!', 12, 100, 0, 444, 'Magosh - on Aggro'),
+(1399, 0, 4, 'The Stonesplinter Tribe shall see to your doom!', 12, 100, 0, 445, 'Magosh - on Aggro'),
+(1399, 0, 5, 'The only good $R is a dead $R!', 12, 100, 0, 447, 'Magosh - on Aggro'),
+
+(1410, 0, 2, 'Kill them before they get away!', 12, 100, 0, 16250, 'Firewing Bloodwarder - On Aggro'),
+(1410, 0, 3, 'You know too much!', 12, 100, 0, 16251, 'Firewing Bloodwarder - On Aggro'),
+(1410, 0, 4, 'For Kael''thas!', 12, 100, 0, 16252, 'Firewing Bloodwarder - On Aggro'),
+(1410, 0, 5, 'They mustn''t escape!', 12, 100, 0, 16253, 'Firewing Bloodwarder - On Aggro'),
+
+(1493, 0, 0, 'YOU WERE SUCH GOOD SPORT THE LAST TIME...COME OUT!', 14, 100, 0, 772, 'Mok''rash'),
+(1493, 0, 6, 'SMOTTS!', 14, 100, 0, 773, 'Mok''rash'),
+(1493, 0, 7, 'DON''T YOU WANT TO FIGHT, SMOTTS!?', 14, 100, 0, 776, 'Mok''rash'),
+
+(1719, 0, 3, 'What am I going to do?', 12, 100, 0, 1658, 'Warden Thelwater'),
+(1719, 0, 4, 'How could this happen?', 12, 100, 0, 1660, 'Warden Thelwater'),
+
+(1976, 0, 3, 'You dare spill blood on neutral ground? OUT! OUT, I SAY!', 12, 100, 0, 10948, 'Stormwind City Patroller - On Aggro'),
+(1976, 0, 4, 'We don''t take kindly to miscreants, $r.', 12, 100, 0, 10949, 'Stormwind City Patroller - On Aggro'),
+(1976, 0, 5, 'Get a rope!', 12, 100, 0, 10952, 'Stormwind City Patroller - On Aggro'),
+(1976, 0, 6, 'Believe me when I tell you this: You''re gonna wish you weren''t born, sissy!', 12, 100, 0, 10954, 'Stormwind City Patroller - On Aggro'),
+(1976, 0, 7, 'Your actions shame us all, $c. I hurt inside as I beat you senseless.', 12, 100, 0, 10955, 'Stormwind City Patroller - On Aggro'),
+
+(2044, 0, 2, 'Let the legend of Stalvan rest!', 12, 100, 0, 503, 'Forlorn Spirit'),
+
+(2396, 0, 2, 'My trees.... they have withered up and died just like me.', 12, 100, 0, 614, 'Hans Zandin'),
+
+(2922, 0, 3, 'I am well versed in over 4 languages.', 12, 100, 0, 898, 'Servo'),
+(2922, 0, 4, 'Master, where have all the trees gone?', 12, 100, 0, 900, 'Servo'),
+
+(3218, 0, 3, 'You dare spill blood on neutral ground? OUT! OUT, I SAY!', 12, 100, 0, 10948, 'Brave Swiftwind - On Aggro'),
+(3218, 0, 4, 'We don''t take kindly to miscreants, $r.', 12, 100, 0, 10949, 'Brave Swiftwind - On Aggro'),
+(3218, 0, 5, 'Get a rope!', 12, 100, 0, 10952, 'Brave Swiftwind - On Aggro'),
+(3218, 0, 6, 'Believe me when I tell you this: You''re gonna wish you weren''t born, sissy!', 12, 100, 0, 10954, 'Brave Swiftwind - On Aggro'),
+(3218, 0, 7, 'Your actions shame us all, $c. I hurt inside as I beat you senseless.', 12, 100, 0, 10955, 'Brave Swiftwind - On Aggro'),
+
+(3296, 0, 3, 'You dare spill blood on neutral ground? OUT! OUT, I SAY!', 12, 100, 0, 10948, 'Orgrimmar Grunt - On Aggro'),
+(3296, 0, 4, 'We don''t take kindly to miscreants, $r.', 12, 100, 0, 10949, 'Orgrimmar Grunt - On Aggro'),
+(3296, 0, 5, 'Get a rope!', 12, 100, 0, 10952, 'Orgrimmar Grunt - On Aggro'),
+(3296, 0, 6, 'Believe me when I tell you this: You''re gonna wish you weren''t born, sissy!', 12, 100, 0, 10954, 'Orgrimmar Grunt - On Aggro'),
+(3296, 0, 7, 'Your actions shame us all, $c. I hurt inside as I beat you senseless.', 12, 100, 0, 10955, 'Orgrimmar Grunt - On Aggro'),
+
+(3502, 0, 3, 'You dare spill blood on neutral ground? OUT! OUT, I SAY!', 12, 100, 0, 10948, 'Ratchet Bruiser - On Aggro'),
+(3502, 0, 4, 'We don''t take kindly to miscreants, $r.', 12, 100, 0, 10949, 'Ratchet Bruiser - On Aggro'),
+(3502, 0, 5, 'Get a rope!', 12, 100, 0, 10952, 'Ratchet Bruiser - On Aggro'),
+(3502, 0, 6, 'Believe me when I tell you this: You''re gonna wish you weren''t born, sissy!', 12, 100, 0, 10954, 'Ratchet Bruiser - On Aggro'),
+(3502, 0, 7, 'Your actions shame us all, $c. I hurt inside as I beat you senseless.', 12, 100, 0, 10955, 'Ratchet Bruiser - On Aggro'),
+
+(3504, 0, 3, 'Why are we goin'' this way?', 12, 100, 0, 1093, 'Gil'),
+(3504, 1, 3, 'I need to pee.', 12, 100, 0, 1095, 'Gil'),
+
+(3518, 0, 2, 'Warm, wholesome bread!', 12, 100, 0, 1102, 'Thomas Miller'),
+(3518, 0, 3, 'Rolls, buns and bread. Baked fresh!', 12, 100, 0, 1103, 'Thomas Miller'),
+
+(3520, 0, 3, 'One of these days I''m gonna drown him in that blue robe. And all his brooms too.', 12, 100, 0, 1109, 'Ol'' Emma'),
+(3520, 1, 3, 'Deja vu. For a moment, I thought I was back home... before the plague...', 12, 100, 0, 1112, 'Ol'' Emma'),
+
+(4624, 0, 3, 'You dare spill blood on neutral ground? OUT! OUT, I SAY!', 12, 100, 0, 10948, 'Booty Bay Bruiser - On Aggro'),
+(4624, 0, 4, 'We don''t take kindly to miscreants, $r.', 12, 100, 0, 10949, 'Booty Bay Bruiser - On Aggro'),
+(4624, 0, 5, 'Get a rope!', 12, 100, 0, 10952, 'Booty Bay Bruiser - On Aggro'),
+(4624, 0, 6, 'Believe me when I tell you this: You''re gonna wish you weren''t born, sissy!', 12, 100, 0, 10954, 'Booty Bay Bruiser - On Aggro'),
+(4624, 0, 7, 'Your actions shame us all, $c. I hurt inside as I beat you senseless.', 12, 100, 0, 10955, 'Booty Bay Bruiser - On Aggro'),
+
+(4979, 2, 3, 'That''s the funniest thing I''ve read in a long time. You''ve just made my day!', 12, 100, 0, 22114, 'Theramore Guard'),
+
+(5355, 0, 0, 'Kill them before they get away!', 12, 100, 0, 16250, 'Firewing Defender - On Aggro'),
+(5355, 0, 1, 'For Kael''thas!', 12, 100, 0, 16252, 'Firewing Defender - On Aggro'),
+(5355, 0, 4, 'They mustn''t escape!', 12, 100, 0, 16253, 'Firewing Defender - On Aggro'),
+(5355, 0, 5, 'I will have your energy and then your life!', 12, 100, 0, 16254, 'Firewing Defender - On Aggro'),
+
+(5391, 0, 1, 'I''m glad you''re here! Because I need your help!!', 12, 100, 0, 1631, 'Galen Goodward'),
+(5391, 2, 2, 'Help! The beast is on me!', 12, 100, 0, 1630, 'Galen Goodward'),
+
+(5662, 0, 8, 'Can you see yourselves? That is the most pathetic excuse for sword slinging I''ve ever seen! ', 12, 100, 0, 1965, 'Sergeant Houser'),
+
+(5698, 0, 8, 'Impressive, very impressive. Does she do tricks?', 12, 100, 0, 2020, 'Joanna Whitehall'),
+
+(5699, 0, 5, 'Astounding. You managed to dominate her, yet she retains self awareness and function. How did you do it?', 12, 100, 0, 2015, 'Leona Tharpe'),
+
+(5955, 0, 2, 'Do we have much further to go?', 12, 100, 0, 2221, 'Tooga'),
+(5955, 0, 3, 'Are we there yet?', 12, 100, 0, 2223, 'Tooga'),
+(5955, 0, 4, 'I keep getting sand stuck in my toes.', 12, 100, 0, 2224, 'Tooga'),
+(5955, 0, 5, 'How much further to go?', 12, 100, 0, 2225, 'Tooga'),
+(5955, 0, 6, 'I wish you could just pick me up and carry me.', 12, 100, 0, 2226, 'Tooga'),
+(5955, 0, 7, 'Have you heard the one about the ogre, the goblin and the pit lord?', 12, 100, 0, 2227, 'Tooga'),
+
+(10541, 0, 3, 'Holy Krakle! The temperature is 428,000 degrees Kraklenheit! ', 12, 100, 0, 5763, 'Krakle''s Thermometer'),
+(10541, 1, 3, 'The temperature is 564 degrees Kraklenheit.', 12, 100, 0, 5765, 'Krakle''s Thermometer'),
+(10541, 1, 4, 'The temperature is 12 degrees Kraklenheit. How exciting.', 12, 100, 0, 5767, 'Krakle''s Thermometer'),
+(10541, 1, 5, '18 degrees Kraklenheit. It''s kind of cold, actually...', 12, 100, 0, 6009, 'Krakle''s Thermometer'),
+(10541, 1, 6, 'It''s 40 degrees Kraklenheit. Can you feel the heat? No? I really couldn''t either.', 12, 100, 0, 6010, 'Krakle''s Thermometer'),
+
+(10799, 0, 3, '%s whimpers.', 12, 100, 0, 6101, 'Warosh'),
+
+(11136, 0, 2, 'FREE!!!', 12, 100, 0, 6451, 'Freed Soul'),
+(11136, 0, 3, 'The curse ends!', 12, 100, 0, 6452, 'Freed Soul'),
+(11136, 0, 4, 'May Kel''Thuzad one day feel our vengeance.', 12, 100, 0, 6454, 'Freed Soul'),
+
+(11190, 0, 3, 'You dare spill blood on neutral ground? OUT! OUT, I SAY!', 12, 100, 0, 10948, 'Everlook Bruiser - On Aggro'),
+(11190, 0, 4, 'We don''t take kindly to miscreants, $r.', 12, 100, 0, 10949, 'Everlook Bruiser - On Aggro'),
+(11190, 0, 5, 'Get a rope!', 12, 100, 0, 10952, 'Everlook Bruiser - On Aggro'),
+(11190, 0, 6, 'Believe me when I tell you this: You''re gonna wish you weren''t born, sissy!', 12, 100, 0, 10954, 'Everlook Bruiser - On Aggro'),
+(11190, 0, 7, 'Your actions shame us all, $c. I hurt inside as I beat you senseless.', 12, 100, 0, 10955, 'Everlook Bruiser - On Aggro'),
+
+(11582, 0, 3, 'Note the weak binding structure of this one. Be sure to finish your incantations or this is what you will end up with.', 12, 100, 0, 5951, 'Scholomance Dark Summoner'),
+(11582, 0, 4, 'Wow, this one is just plain useless. Let me try again.', 12, 100, 0, 5953, 'Scholomance Dark Summoner'),
+
+(12337, 0, 3, 'These orders must get to High General Abbendis!', 12, 100, 0, 7598, 'Crimson Courier'),
+
+(15184, 0, 3, 'You dare spill blood on neutral ground? OUT! OUT, I SAY!', 12, 100, 0, 10948, 'Cenarion Hold Infantry - On Aggro'),
+(15184, 0, 4, 'We don''t take kindly to miscreants, $r.', 12, 100, 0, 10949, 'Cenarion Hold Infantry - On Aggro'),
+(15184, 0, 5, 'Get a rope!', 12, 100, 0, 10952, 'Cenarion Hold Infantry - On Aggro'),
+(15184, 0, 6, 'Believe me when I tell you this: You''re gonna wish you weren''t born, sissy!', 12, 100, 0, 10954, 'Cenarion Hold Infantry - On Aggro'),
+(15184, 0, 7, 'Your actions shame us all, $c. I hurt inside as I beat you senseless.', 12, 100, 0, 10955, 'Cenarion Hold Infantry - On Aggro'),
+
+(17259, 0, 3, 'For Kargath! For Victory!', 12, 100, 0, 16698, 'Bonechewer Hungerer - On Aggro'),
+(17259, 0, 4, 'Gakarah ma!', 12, 100, 0, 16699, 'Bonechewer Hungerer - On Aggro'),
+(17259, 0, 5, 'Lok''tar Illadari!\n', 12, 100, 0, 16701, 'Bonechewer Hungerer - On Aggro'),
+(17259, 0, 6, 'Lok narash!', 12, 100, 0, 16703, 'Bonechewer Hungerer - On Aggro'),
+
+(17271, 0, 3, 'Gakarah ma!', 12, 100, 0, 16699, 'Bonechewer Destroyer - On Aggro'),
+(17271, 0, 4, 'Lok''tar Illadari!\n', 12, 100, 0, 16701, 'Bonechewer Destroyer - On Aggro'),
+(17271, 0, 5, 'This world is OURS!', 12, 100, 0, 16702, 'Bonechewer Destroyer - On Aggro'),
+(17271, 0, 6, 'Lok narash!', 12, 100, 0, 16703, 'Bonechewer Destroyer - On Aggro'),
+
+(17491, 0, 2, 'For Kargath! For Victory!', 12, 100, 0, 16698, 'Laughing Skull Rogue - On Aggro'),
+(17491, 0, 3, 'The blood is our power! ', 12, 100, 0, 16700, 'Laughing Skull Rogue - On Aggro'),
+(17491, 0, 4, 'Lok''tar Illadari!\n', 12, 100, 0,16701 , 'Laughing Skull Rogue - On Aggro'),
+(17491, 0, 5, 'This world is OURS!', 12, 100, 0, 16702, 'Laughing Skull Rogue - On Aggro'),
+(17491, 0, 6, 'Lok narash!', 12, 100, 0, 16703, 'Laughing Skull Rogue - On Aggro'),
+
+(18103, 0, 2, 'Happiness is mandatory, citizen.', 12, 100, 0, 14782, 'Arcane Guardian - Random Talk'),
+(18103, 0, 3, 'Remain strong. Kael''thas will - error - Lor''themar will lead you to power and glory!', 12, 100, 0, 14784, 'Arcane Guardian - Random Talk'),
+(18103, 0, 4, 'Do not disturb the serenity of the city. Peace must be upheld.', 12, 100, 0, 14785, 'Arcane Guardian - Random Talk'),
+
+(19283, 0, 3, 'Any spare copper?', 12, 100, 0, 16614, 'Vagrant - Random Talk'),
+
+(21114, 0, 6, 'This is going to hurt in the morning.', 12, 100, 0, 18797, 'Station Technician - On Burning'),
+
+(21661, 1, 3, 'Ruin finds us all!', 12, 100, 0, 16798, 'Cabal Skirmisher'),
+(21661, 1, 4, 'In Sargeras'' name!', 12, 100, 0, 16799, 'Cabal Skirmisher'),
+(21661, 1, 5, 'I do as I must!', 12, 100, 0, 16801, 'Cabal Skirmisher'),
+(21661, 1, 6, 'The Legion reigns!', 12, 100, 0, 16802, 'Cabal Skirmisher'),
+(21661, 1, 7, 'You''ll go nowhere, fool!', 12, 100, 0, 20164, 'Cabal Skirmisher'),
+
+(22314, 0, 4, 'Yay! We love you! You saved us!', 12, 100, 0, 20111, 'Captive Child'),
+
+(23311, 0, 7, 'Hey... me not feel so good.', 12, 100, 0, 21122, 'Disobedient Dragonmaw Peon - On Script Action'),
+
+(23861, 0, 7, 'It is too late for Jarl... its hold is too strong...', 12, 100, 0, 22366, 'Restless Apparition - On Script Action'),
+
+(25428, 0, 3, 'Grr... na su ka Magmoth!', 12, 100, 0, 24651, 'Magmoth Shaman - On Aggro'),
+
+(25429, 0, 3, 'Grr... na su ka Magmoth!', 12, 100, 0, 24651, 'Magmoth Forager - On Aggro'),
+
+(25682, 0, 1, 'Die!', 12, 100, 0, 24874, 'Lich-Lord Chillwinter - On Aggro'),
+(25682, 0, 2, 'Filthy breather!', 12, 100, 0, 24876, 'Lich-Lord Chillwinter - On Aggro'),
+
+(28608, 0, 3, 'Scourge filth! DIE!', 12, 100, 0, 28597, 'Scarlet Medic - On Aggro'),
+(28608, 0, 4, 'I will present your head to Abbendis myself!', 12, 100, 0, 28599, 'Scarlet Medic - On Aggro'),
+(28608, 0, 5, 'By the Light be cleansed!', 12, 100, 0, 28602, 'Scarlet Medic - On Aggro'),
+(28608, 0, 6, 'Light bless you, my child.', 12, 100, 0, 28603, 'Scarlet Medic - On Aggro'),
+
+(28609, 0, 3, 'Scourge filth! DIE!', 12, 100, 0, 28597, 'Scarlet Infantryman - On Aggro'),
+(28609, 0, 4, 'I will present your head to Abbendis myself!', 12, 100, 0, 28599, 'Scarlet Infantryman - On Aggro'),
+(28609, 0, 5, 'By the Light be cleansed!', 12, 100, 0, 28602, 'Scarlet Infantryman - On Aggro'),
+(28609, 0, 6, 'Light bless you, my child.', 12, 100, 0, 28603, 'Scarlet Infantryman - On Aggro'),
+
+(28611, 0, 3, 'Scourge filth! DIE!', 12, 100, 0, 28597, 'Scarlet Captain - On Aggro'),
+(28611, 0, 4, 'I will present your head to Abbendis myself!', 12, 100, 0, 28599, 'Scarlet Captain - On Aggro'),
+(28611, 0, 5, 'By the Light be cleansed!', 12, 100, 0, 28602, 'Scarlet Captain - On Aggro'),
+(28611, 0, 6, 'Light bless you, my child.', 12, 100, 0, 28603, 'Scarlet Captain - On Aggro'),
+
+(28714, 0, 3, 'Welcome!', 12, 100, 0, 32807, 'Ildine Sorrowspear - Player In Range'),
+(28714, 0, 4, 'Greetings, $c.', 12, 100, 0, 32808, 'Ildine Sorrowspear - Player In Range'),
+(28714, 0, 5, 'Greetings! Please have a look around.', 12, 100, 0, 32809, 'Ildine Sorrowspear - Player In Range'),
+(28714, 0, 6, 'Welcome. May I help you find something?', 12, 100, 0, 32811, 'Ildine Sorrowspear - Player In Range'),
+
+(28715, 0, 3, 'Let me know if you need help finding anything, $c.', 12, 100, 0, 32810, 'Endora Moorehead - Player In Range'),
+(28715, 0, 4, 'Welcome. May I help you find something?', 12, 100, 0, 32811, 'Endora Moorehead - Player In Range'),
+(28715, 0, 5, 'Greetings.', 12, 100, 0, 32935, 'Endora Moorehead - Player In Range'),
+(28715, 0, 6, 'Welcome.', 12, 100, 0, 32936, 'Endora Moorehead - Player In Range'),
+
+(28721, 0, 6, 'Welcome!', 12, 100, 0, 32807, 'Tiffany Cartier - Player In Range'),
+
+(28723, 0, 3, 'Welcome!', 12, 100, 0, 32807, 'Larana Drome - Player In Range'),
+(28723, 0, 4, 'Greetings! Please have a look around.', 12, 100, 0, 32809, 'Larana Drome - Player In Range'),
+(28723, 0, 5, 'Let me know if you need help finding anything, $c.', 12, 100, 0, 32810, 'Larana Drome - Player In Range'),
+(28723, 0, 6, 'Welcome. May I help you find something?', 12, 100, 0, 32811, 'Larana Drome - Player In Range'),
+
+(28725, 0, 4, 'Greetings, $c.', 12, 100, 0, 32808, 'Patricia Egan - Player In Range'),
+(28725, 0, 5, 'Let me know if you need help finding anything, $c.', 12, 100, 0, 32810, 'Patricia Egan - Player In Range'),
+(28725, 0, 6, 'Greetings.', 12, 100, 0, 32935, 'Patricia Egan - Player In Range'),
+
+(28726, 0, 6, 'Welcome.', 12, 100, 0, 32936, 'Dominique Stefano - Player In Range'),
+
+(28727, 0, 4, 'Greetings, $c.', 12, 100, 0, 32808, 'Edward Egan - Player In Range'),
+(28727, 0, 5, 'Let me know if you need help finding anything, $c.', 12, 100, 0, 32810, 'Edward Egan - Player In Range'),
+(28727, 0, 6, 'Welcome.', 12, 100, 0, 32936, 'Edward Egan - Player In Range'),
+
+(28750, 0, 0, 'Rmmurphum mmph hmrphum!', 12, 100, 0, 28657, 'Blight Geist'),
+(28750, 0, 3, 'Umphrum mmphur, murruphru...', 12, 100, 0, 28658, 'Blight Geist'),
+
+(28989, 0, 6, 'Welcome!', 12, 100, 0, 32807, 'Aemara - Player In Range'),
+
+(28994, 0, 4, 'Welcome!', 12, 100, 0, 32807, 'Abra Cadabra - Player In Range'),
+(28994, 0, 5, 'Greetings, $c.', 12, 100, 0, 32808, 'Abra Cadabra - Player In Range'),
+(28994, 0, 6, 'Greetings! Please have a look around.', 12, 100, 0, 32809, 'Abra Cadabra - Player In Range'),
+
+(28997, 0, 4, 'Greetings! Please have a look around.', 12, 100, 0, 32809, 'Griselda Hunderland - Player In Range'),
+(28997, 0, 5, 'Welcome. May I help you find something?', 12, 100, 0, 32811, 'Griselda Hunderland - Player In Range'),
+(28997, 0, 6, 'Welcome.', 12, 100, 0, 32936, 'Griselda Hunderland - Player In Range'),
+
+(29647, 1, 4, 'How long do you think this cage can hold me, fiends!', 12, 100, 0, 30497, 'Gymer - In Cage'),
+
+(29686, 0, 3, 'TROLL MAKE ME ANGRY!', 12, 100, 0, 30371, 'Captured Rageclaw'),
+(29686, 0, 4, 'Rageclaw free! Troll die now!', 12, 100, 0, 30396, 'Captured Rageclaw'),
+(29686, 0, 5, 'Revenge for Rageclaw!', 12, 100, 0, 30399, 'Captured Rageclaw'),
+(29686, 0, 6, 'This mean war!', 12, 100, 0, 30401, 'Captured Rageclaw'),
+
+(29884, 1, 8, 'LET THE STORM''S FURY CONSUME YOU!', 14, 100, 0, 30588, 'Gymer'),
+(29884, 1, 9, 'NO ESCAPE FOR THE WICKED!', 14, 100, 0, 30589, 'Gymer'),
+(29884, 1, 10, 'IT IS THE WRATH OF THE STORM KING!', 14, 100, 0, 30592, 'Gymer'),
+
+(29491, 0, 2, 'Welcome!', 12, 100, 0, 32807, 'Karandonna - Player In Range'),
+(29491, 0, 3, 'Greetings, $c.', 12, 100, 0, 32808, 'Karandonna - Player In Range'),
+(29491, 0, 4, 'Greetings! Please have a look around.', 12, 100, 0, 32809, 'Karandonna - Player In Range'),
+(29491, 0, 5, 'Let me know if you need help finding anything, $c.', 12, 100, 0, 32810, 'Karandonna - Player In Range'),
+(29491, 0, 6, 'Greetings.', 12, 100, 0, 32935, 'Karandonna - Player In Range'),
+
+(29523, 0, 4, 'Greetings, $c.', 12, 100, 0, 32808, 'Bragund Brightlink - Player In Range'),
+(29523, 0, 5, 'Welcome. May I help you find something?', 12, 100, 0, 32811, 'Bragund Brightlink - Player In Range'),
+(29523, 0, 6, 'Greetings.', 12, 100, 0, 32935, 'Bragund Brightlink - Player In Range'),
+
+(30012, 0, 4, 'I''m not afraid of anything -- bring it on!', 12, 100, 0, 30807, 'Victorious Challenger'),
+
+(31397, 0, 5, 'I won''t leave!', 12, 100, 0, 32469, 'Saronite Mine Slave'),
+(31397, 0, 6, 'I''ll never return. The whole reason for my existence awaits below!', 12, 100, 0, 32472, 'Saronite Mine Slave'),
+(31397, 0, 7, 'I must get further underground to where he is. I must jump!', 12, 100, 0, 32474, 'Saronite Mine Slave'),
+
+(33027, 0, 5, 'Welcome!', 12, 100, 0, 32807, 'Jessica Sellers'),
+(33027, 0, 6, 'Greetings.', 12, 100, 0, 32935, 'Jessica Sellers'),
+
+(33853, 0, 3, 'Show support for your favorite champion! Wear their colors at the next bout and let ''em know who you love!', 12, 100, 0, 33834, ''),
+
+(36764, 0, 5, 'I''d almost given up hope.', 12, 100, 0, 37079, 'Alliance Slave - On Liberation'),
+(36764, 0, 6, 'I thought I might die in this pit. Thank you!', 12, 100, 0, 37262, 'Alliance Slave - On Liberation'),
+(36764, 0, 7, 'Don''t let a single one of them live.', 12, 100, 0, 37264, 'Alliance Slave - On Liberation'),
+(36764, 0, 8, 'Please, carry out our vengeance on the Scourgelord.', 12, 100, 0, 37265, 'Alliance Slave - On Liberation'),
+(36764, 0, 9, 'When you kill the Pit Master, spit on his corpse for me, will you?', 12, 100, 0, 37266, 'Alliance Slave - On Liberation'),
+(36764, 0, 10, 'I''d lost all track of time in this forsaken place. You''re a sight for sore eyes, friend.', 12, 100, 0, 37268, 'Alliance Slave - On Liberation'),
+(36764, 0, 11, 'Too many of us died in this pit. Far too many.', 12, 100, 0, 37270, 'Alliance Slave - On Liberation'),
+(36764, 0, 12, 'I''m so glad you''re here. I wouldn''t have made it much longer.', 12, 100, 0, 37271, 'Alliance Slave - On Liberation'),
+(36764, 0, 13, 'Now is the time for revenge.', 12, 100, 0, 37273, 'Alliance Slave - On Liberation'),
+(36764, 0, 14, 'You deserve a mighty man-hug.', 12, 100, 0, 37274, 'Alliance Slave - On Liberation'),
+(36764, 0, 15, 'I will find a way to repay you someday, hero.', 12, 100, 0, 37275, 'Alliance Slave - On Liberation'),
+(36764, 0, 16, 'I can hardly believe my eyes. Thank you. Really, thank you.', 12, 100, 0, 37276, 'Alliance Slave - On Liberation'),
+(36764, 0, 17, '%s nods his thanks.', 16, 100, 0, 37277, 'Alliance Slave - On Liberation'),
+(36764, 0, 18, '%s offers an appreciative smile.', 16, 100, 0, 37278, 'Alliance Slave - On Liberation'),
+(36764, 0, 19, '%s almost collapses as he stumbles towards you.', 16, 100, 0, 37279, 'Alliance Slave - On Liberation'),
+(36764, 0, 20, '%s stares at you for a moment, clearly finding it hard to believe that you''re real.', 16, 100, 0, 37280, 'Alliance Slave - On Liberation'),
+(36764, 0, 21, '%s offers a quick, cynical laugh at his fortune.', 16, 100, 0, 37281, 'Alliance Slave - On Liberation'),
+(36764, 0, 22, '%s raises an empty hand in toast to you.', 16, 100, 0, 37282, 'Alliance Slave - On Liberation'),
+(36764, 0, 23, '%s closes his eyes, savoring freedom for a moment.', 16, 100, 0, 37283, 'Alliance Slave - On Liberation'),
+(36764, 0, 24, 'I''m going to return to help free the rest of the slaves. Thank you again, hero.', 16, 100, 0, 37293, 'Alliance Slave - On Liberation'),
+
+(36765, 0, 5, 'I''d almost given up hope.', 12, 100, 0, 37079, 'Alliance Slave - On Liberation'),
+(36765, 0, 6, 'I thought I might die in this pit. Thank you!', 12, 100, 0, 37262, 'Alliance Slave - On Liberation'),
+(36765, 0, 7, 'Don''t let a single one of them live.', 12, 100, 0, 37264, 'Alliance Slave - On Liberation'),
+(36765, 0, 8, 'Please, carry out our vengeance on the Scourgelord.', 12, 100, 0, 37265, 'Alliance Slave - On Liberation'),
+(36765, 0, 9, 'When you kill the Pit Master, spit on his corpse for me, will you?', 12, 100, 0, 37266, 'Alliance Slave - On Liberation'),
+(36765, 0, 10, 'I''d lost all track of time in this forsaken place. You''re a sight for sore eyes, friend.', 12, 100, 0, 37268, 'Alliance Slave - On Liberation'),
+(36765, 0, 11, 'Too many of us died in this pit. Far too many.', 12, 100, 0, 37270, 'Alliance Slave - On Liberation'),
+(36765, 0, 12, 'I''m so glad you''re here. I wouldn''t have made it much longer.', 12, 100, 0, 37271, 'Alliance Slave - On Liberation'),
+(36765, 0, 13, 'Now is the time for revenge.', 12, 100, 0, 37273, 'Alliance Slave - On Liberation'),
+(36765, 0, 14, 'You deserve a mighty man-hug.', 12, 100, 0, 37274, 'Alliance Slave - On Liberation'),
+(36765, 0, 15, 'I will find a way to repay you someday, hero.', 12, 100, 0, 37275, 'Alliance Slave - On Liberation'),
+(36765, 0, 16, 'I can hardly believe my eyes. Thank you. Really, thank you.', 12, 100, 0, 37276, 'Alliance Slave - On Liberation'),
+(36765, 0, 17, '%s nods his thanks.', 16, 100, 0, 37277, 'Alliance Slave - On Liberation'),
+(36765, 0, 18, '%s offers an appreciative smile.', 16, 100, 0, 37278, 'Alliance Slave - On Liberation'),
+(36765, 0, 19, '%s almost collapses as he stumbles towards you.', 16, 100, 0, 37279, 'Alliance Slave - On Liberation'),
+(36765, 0, 20, '%s stares at you for a moment, clearly finding it hard to believe that you''re real.', 16, 100, 0, 37280, 'Alliance Slave - On Liberation'),
+(36765, 0, 21, '%s offers a quick, cynical laugh at his fortune.', 16, 100, 0, 37281, 'Alliance Slave - On Liberation'),
+(36765, 0, 22, '%s raises an empty hand in toast to you.', 16, 100, 0, 37282, 'Alliance Slave - On Liberation'),
+(36765, 0, 23, '%s closes his eyes, savoring freedom for a moment.', 16, 100, 0, 37283, 'Alliance Slave - On Liberation'),
+(36765, 0, 24, 'I''m going to return to help free the rest of the slaves. Thank you again, hero.', 16, 100, 0, 37293, 'Alliance Slave - On Liberation'),
+
+(36766, 0, 5, 'I''d almost given up hope.', 12, 100, 0, 37079, 'Alliance Slave - On Liberation'),
+(36766, 0, 6, 'I thought I might die in this pit. Thank you!', 12, 100, 0, 37262, 'Alliance Slave - On Liberation'),
+(36766, 0, 7, 'Don''t let a single one of them live.', 12, 100, 0, 37264, 'Alliance Slave - On Liberation'),
+(36766, 0, 8, 'Please, carry out our vengeance on the Scourgelord.', 12, 100, 0, 37265, 'Alliance Slave - On Liberation'),
+(36766, 0, 9, 'When you kill the Pit Master, spit on his corpse for me, will you?', 12, 100, 0, 37266, 'Alliance Slave - On Liberation'),
+(36766, 0, 10, 'I''d lost all track of time in this forsaken place. You''re a sight for sore eyes, friend.', 12, 100, 0, 37268, 'Alliance Slave - On Liberation'),
+(36766, 0, 11, 'Too many of us died in this pit. Far too many.', 12, 100, 0, 37270, 'Alliance Slave - On Liberation'),
+(36766, 0, 12, 'I''m so glad you''re here. I wouldn''t have made it much longer.', 12, 100, 0, 37271, 'Alliance Slave - On Liberation'),
+(36766, 0, 13, 'Now is the time for revenge.', 12, 100, 0, 37273, 'Alliance Slave - On Liberation'),
+(36766, 0, 14, 'You deserve a mighty man-hug.', 12, 100, 0, 37274, 'Alliance Slave - On Liberation'),
+(36766, 0, 15, 'I will find a way to repay you someday, hero.', 12, 100, 0, 37275, 'Alliance Slave - On Liberation'),
+(36766, 0, 16, 'I can hardly believe my eyes. Thank you. Really, thank you.', 12, 100, 0, 37276, 'Alliance Slave - On Liberation'),
+(36766, 0, 17, '%s nods his thanks.', 16, 100, 0, 37277, 'Alliance Slave - On Liberation'),
+(36766, 0, 18, '%s offers an appreciative smile.', 16, 100, 0, 37278, 'Alliance Slave - On Liberation'),
+(36766, 0, 19, '%s almost collapses as he stumbles towards you.', 16, 100, 0, 37279, 'Alliance Slave - On Liberation'),
+(36766, 0, 20, '%s stares at you for a moment, clearly finding it hard to believe that you''re real.', 16, 100, 0, 37280, 'Alliance Slave - On Liberation'),
+(36766, 0, 21, '%s offers a quick, cynical laugh at his fortune.', 16, 100, 0, 37281, 'Alliance Slave - On Liberation'),
+(36766, 0, 22, '%s raises an empty hand in toast to you.', 16, 100, 0, 37282, 'Alliance Slave - On Liberation'),
+(36766, 0, 23, '%s closes his eyes, savoring freedom for a moment.', 16, 100, 0, 37283, 'Alliance Slave - On Liberation'),
+(36766, 0, 24, 'I''m going to return to help free the rest of the slaves. Thank you again, hero.', 16, 100, 0, 37293, 'Alliance Slave - On Liberation'),
+
+(36767, 0, 5, 'I''d almost given up hope.', 12, 100, 0, 37079, 'Alliance Slave - On Liberation'),
+(36767, 0, 6, 'I thought I might die in this pit. Thank you!', 12, 100, 0, 37262, 'Alliance Slave - On Liberation'),
+(36767, 0, 7, 'Don''t let a single one of them live.', 12, 100, 0, 37264, 'Alliance Slave - On Liberation'),
+(36767, 0, 8, 'Please, carry out our vengeance on the Scourgelord.', 12, 100, 0, 37265, 'Alliance Slave - On Liberation'),
+(36767, 0, 9, 'When you kill the Pit Master, spit on his corpse for me, will you?', 12, 100, 0, 37266, 'Alliance Slave - On Liberation'),
+(36767, 0, 10, 'I''d lost all track of time in this forsaken place. You''re a sight for sore eyes, friend.', 12, 100, 0, 37268, 'Alliance Slave - On Liberation'),
+(36767, 0, 11, 'Too many of us died in this pit. Far too many.', 12, 100, 0, 37270, 'Alliance Slave - On Liberation'),
+(36767, 0, 12, 'I''m so glad you''re here. I wouldn''t have made it much longer.', 12, 100, 0, 37271, 'Alliance Slave - On Liberation'),
+(36767, 0, 13, 'Now is the time for revenge.', 12, 100, 0, 37273, 'Alliance Slave - On Liberation'),
+(36767, 0, 14, 'You deserve a mighty man-hug.', 12, 100, 0, 37274, 'Alliance Slave - On Liberation'),
+(36767, 0, 15, 'I will find a way to repay you someday, hero.', 12, 100, 0, 37275, 'Alliance Slave - On Liberation'),
+(36767, 0, 16, 'I can hardly believe my eyes. Thank you. Really, thank you.', 12, 100, 0, 37276, 'Alliance Slave - On Liberation'),
+(36767, 0, 17, '%s nods his thanks.', 16, 100, 0, 37277, 'Alliance Slave - On Liberation'),
+(36767, 0, 18, '%s offers an appreciative smile.', 16, 100, 0, 37278, 'Alliance Slave - On Liberation'),
+(36767, 0, 19, '%s almost collapses as he stumbles towards you.', 16, 100, 0, 37279, 'Alliance Slave - On Liberation'),
+(36767, 0, 20, '%s stares at you for a moment, clearly finding it hard to believe that you''re real.', 16, 100, 0, 37280, 'Alliance Slave - On Liberation'),
+(36767, 0, 21, '%s offers a quick, cynical laugh at his fortune.', 16, 100, 0, 37281, 'Alliance Slave - On Liberation'),
+(36767, 0, 22, '%s raises an empty hand in toast to you.', 16, 100, 0, 37282, 'Alliance Slave - On Liberation'),
+(36767, 0, 23, '%s closes his eyes, savoring freedom for a moment.', 16, 100, 0, 37283, 'Alliance Slave - On Liberation'),
+(36767, 0, 24, 'I''m going to return to help free the rest of the slaves. Thank you again, hero.', 16, 100, 0, 37293, 'Alliance Slave - On Liberation'),
+
+(36770, 0, 5, 'I''d almost given up hope.', 12, 100, 0, 37079, 'Horde Slave - On Liberation'),
+(36770, 0, 6, 'I thought I might die in this pit. Thank you!', 12, 100, 0, 37262, 'Horde Slave - On Liberation'),
+(36770, 0, 7, 'Don''t let a single one of them live.', 12, 100, 0, 37264, 'Horde Slave - On Liberation'),
+(36770, 0, 8, 'Please, carry out our vengeance on the Scourgelord.', 12, 100, 0, 37265, 'Horde Slave - On Liberation'),
+(36770, 0, 9, 'When you kill the Pit Master, spit on his corpse for me, will you?', 12, 100, 0, 37266, 'Horde Slave - On Liberation'),
+(36770, 0, 10, 'I''d lost all track of time in this forsaken place. You''re a sight for sore eyes, friend.', 12, 100, 0, 37268, 'Horde Slave - On Liberation'),
+(36770, 0, 11, 'Too many of us died in this pit. Far too many.', 12, 100, 0, 37270, 'Horde Slave - On Liberation'),
+(36770, 0, 12, 'I''m so glad you''re here. I wouldn''t have made it much longer.', 12, 100, 0, 37271, 'Horde Slave - On Liberation'),
+(36770, 0, 13, 'Now is the time for revenge.', 12, 100, 0, 37273, 'Horde Slave - On Liberation'),
+(36770, 0, 14, 'You deserve a mighty man-hug.', 12, 100, 0, 37274, 'Horde Slave - On Liberation'),
+(36770, 0, 15, 'I will find a way to repay you someday, hero.', 12, 100, 0, 37275, 'Horde Slave - On Liberation'),
+(36770, 0, 16, 'I can hardly believe my eyes. Thank you. Really, thank you.', 12, 100, 0, 37276, 'Horde Slave - On Liberation'),
+(36770, 0, 17, '%s nods his thanks.', 16, 100, 0, 37277, 'Horde Slave - On Liberation'),
+(36770, 0, 18, '%s offers an appreciative smile.', 16, 100, 0, 37278, 'Horde Slave - On Liberation'),
+(36770, 0, 19, '%s almost collapses as he stumbles towards you.', 16, 100, 0, 37279, 'Horde Slave - On Liberation'),
+(36770, 0, 20, '%s stares at you for a moment, clearly finding it hard to believe that you''re real.', 16, 100, 0, 37280, 'Horde Slave - On Liberation'),
+(36770, 0, 21, '%s offers a quick, cynical laugh at his fortune.', 16, 100, 0, 37281, 'Horde Slave - On Liberation'),
+(36770, 0, 22, '%s raises an empty hand in toast to you.', 16, 100, 0, 37282, 'Horde Slave - On Liberation'),
+(36770, 0, 23, '%s closes his eyes, savoring freedom for a moment.', 16, 100, 0, 37283, 'Horde Slave - On Liberation'),
+(36770, 0, 24, 'I''m going to return to help free the rest of the slaves. Thank you again, hero.', 16, 100, 0, 37293, 'Horde Slave - On Liberation'),
+
+(36771, 0, 5, 'I''d almost given up hope.', 12, 100, 0, 37079, 'Horde Slave - On Liberation'),
+(36771, 0, 6, 'I thought I might die in this pit. Thank you!', 12, 100, 0, 37262, 'Horde Slave - On Liberation'),
+(36771, 0, 7, 'Don''t let a single one of them live.', 12, 100, 0, 37264, 'Horde Slave - On Liberation'),
+(36771, 0, 8, 'Please, carry out our vengeance on the Scourgelord.', 12, 100, 0, 37265, 'Horde Slave - On Liberation'),
+(36771, 0, 9, 'When you kill the Pit Master, spit on his corpse for me, will you?', 12, 100, 0, 37266, 'Horde Slave - On Liberation'),
+(36771, 0, 10, 'I''d lost all track of time in this forsaken place. You''re a sight for sore eyes, friend.', 12, 100, 0, 37268, 'Horde Slave - On Liberation'),
+(36771, 0, 11, 'Too many of us died in this pit. Far too many.', 12, 100, 0, 37270, 'Horde Slave - On Liberation'),
+(36771, 0, 12, 'I''m so glad you''re here. I wouldn''t have made it much longer.', 12, 100, 0, 37271, 'Horde Slave - On Liberation'),
+(36771, 0, 13, 'Now is the time for revenge.', 12, 100, 0, 37273, 'Horde Slave - On Liberation'),
+(36771, 0, 14, 'You deserve a mighty man-hug.', 12, 100, 0, 37274, 'Horde Slave - On Liberation'),
+(36771, 0, 15, 'I will find a way to repay you someday, hero.', 12, 100, 0, 37275, 'Horde Slave - On Liberation'),
+(36771, 0, 16, 'I can hardly believe my eyes. Thank you. Really, thank you.', 12, 100, 0, 37276, 'Horde Slave - On Liberation'),
+(36771, 0, 17, '%s nods his thanks.', 16, 100, 0, 37277, 'Horde Slave - On Liberation'),
+(36771, 0, 18, '%s offers an appreciative smile.', 16, 100, 0, 37278, 'Horde Slave - On Liberation'),
+(36771, 0, 19, '%s almost collapses as he stumbles towards you.', 16, 100, 0, 37279, 'Horde Slave - On Liberation'),
+(36771, 0, 20, '%s stares at you for a moment, clearly finding it hard to believe that you''re real.', 16, 100, 0, 37280, 'Horde Slave - On Liberation'),
+(36771, 0, 21, '%s offers a quick, cynical laugh at his fortune.', 16, 100, 0, 37281, 'Horde Slave - On Liberation'),
+(36771, 0, 22, '%s raises an empty hand in toast to you.', 16, 100, 0, 37282, 'Horde Slave - On Liberation'),
+(36771, 0, 23, '%s closes his eyes, savoring freedom for a moment.', 16, 100, 0, 37283, 'Horde Slave - On Liberation'),
+(36771, 0, 24, 'I''m going to return to help free the rest of the slaves. Thank you again, hero.', 16, 100, 0, 37293, 'Horde Slave - On Liberation'),
+
+(36772, 0, 5, 'I''d almost given up hope.', 12, 100, 0, 37079, 'Horde Slave - On Liberation'),
+(36772, 0, 6, 'I thought I might die in this pit. Thank you!', 12, 100, 0, 37262, 'Horde Slave - On Liberation'),
+(36772, 0, 7, 'Don''t let a single one of them live.', 12, 100, 0, 37264, 'Horde Slave - On Liberation'),
+(36772, 0, 8, 'Please, carry out our vengeance on the Scourgelord.', 12, 100, 0, 37265, 'Horde Slave - On Liberation'),
+(36772, 0, 9, 'When you kill the Pit Master, spit on his corpse for me, will you?', 12, 100, 0, 37266, 'Horde Slave - On Liberation'),
+(36772, 0, 10, 'I''d lost all track of time in this forsaken place. You''re a sight for sore eyes, friend.', 12, 100, 0, 37268, 'Horde Slave - On Liberation'),
+(36772, 0, 11, 'Too many of us died in this pit. Far too many.', 12, 100, 0, 37270, 'Horde Slave - On Liberation'),
+(36772, 0, 12, 'I''m so glad you''re here. I wouldn''t have made it much longer.', 12, 100, 0, 37271, 'Horde Slave - On Liberation'),
+(36772, 0, 13, 'Now is the time for revenge.', 12, 100, 0, 37273, 'Horde Slave - On Liberation'),
+(36772, 0, 14, 'You deserve a mighty man-hug.', 12, 100, 0, 37274, 'Horde Slave - On Liberation'),
+(36772, 0, 15, 'I will find a way to repay you someday, hero.', 12, 100, 0, 37275, 'Horde Slave - On Liberation'),
+(36772, 0, 16, 'I can hardly believe my eyes. Thank you. Really, thank you.', 12, 100, 0, 37276, 'Horde Slave - On Liberation'),
+(36772, 0, 17, '%s nods his thanks.', 16, 100, 0, 37277, 'Horde Slave - On Liberation'),
+(36772, 0, 18, '%s offers an appreciative smile.', 16, 100, 0, 37278, 'Horde Slave - On Liberation'),
+(36772, 0, 19, '%s almost collapses as he stumbles towards you.', 16, 100, 0, 37279, 'Horde Slave - On Liberation'),
+(36772, 0, 20, '%s stares at you for a moment, clearly finding it hard to believe that you''re real.', 16, 100, 0, 37280, 'Horde Slave - On Liberation'),
+(36772, 0, 21, '%s offers a quick, cynical laugh at his fortune.', 16, 100, 0, 37281, 'Horde Slave - On Liberation'),
+(36772, 0, 22, '%s raises an empty hand in toast to you.', 16, 100, 0, 37282, 'Horde Slave - On Liberation'),
+(36772, 0, 23, '%s closes his eyes, savoring freedom for a moment.', 16, 100, 0, 37283, 'Horde Slave - On Liberation'),
+(36772, 0, 24, 'I''m going to return to help free the rest of the slaves. Thank you again, hero.', 16, 100, 0, 37293, 'Horde Slave - On Liberation'),
+
+(36773, 0, 5, 'I''d almost given up hope.', 12, 100, 0, 37079, 'Horde Slave - On Liberation'),
+(36773, 0, 6, 'I thought I might die in this pit. Thank you!', 12, 100, 0, 37262, 'Horde Slave - On Liberation'),
+(36773, 0, 7, 'Don''t let a single one of them live.', 12, 100, 0, 37264, 'Horde Slave - On Liberation'),
+(36773, 0, 8, 'Please, carry out our vengeance on the Scourgelord.', 12, 100, 0, 37265, 'Horde Slave - On Liberation'),
+(36773, 0, 9, 'When you kill the Pit Master, spit on his corpse for me, will you?', 12, 100, 0, 37266, 'Horde Slave - On Liberation'),
+(36773, 0, 10, 'I''d lost all track of time in this forsaken place. You''re a sight for sore eyes, friend.', 12, 100, 0, 37268, 'Horde Slave - On Liberation'),
+(36773, 0, 11, 'Too many of us died in this pit. Far too many.', 12, 100, 0, 37270, 'Horde Slave - On Liberation'),
+(36773, 0, 12, 'I''m so glad you''re here. I wouldn''t have made it much longer.', 12, 100, 0, 37271, 'Horde Slave - On Liberation'),
+(36773, 0, 13, 'Now is the time for revenge.', 12, 100, 0, 37273, 'Horde Slave - On Liberation'),
+(36773, 0, 14, 'You deserve a mighty man-hug.', 12, 100, 0, 37274, 'Horde Slave - On Liberation'),
+(36773, 0, 15, 'I will find a way to repay you someday, hero.', 12, 100, 0, 37275, 'Horde Slave - On Liberation'),
+(36773, 0, 16, 'I can hardly believe my eyes. Thank you. Really, thank you.', 12, 100, 0, 37276, 'Horde Slave - On Liberation'),
+(36773, 0, 17, '%s nods his thanks.', 16, 100, 0, 37277, 'Horde Slave - On Liberation'),
+(36773, 0, 18, '%s offers an appreciative smile.', 16, 100, 0, 37278, 'Horde Slave - On Liberation'),
+(36773, 0, 19, '%s almost collapses as he stumbles towards you.', 16, 100, 0, 37279, 'Horde Slave - On Liberation'),
+(36773, 0, 20, '%s stares at you for a moment, clearly finding it hard to believe that you''re real.', 16, 100, 0, 37280, 'Horde Slave - On Liberation'),
+(36773, 0, 21, '%s offers a quick, cynical laugh at his fortune.', 16, 100, 0, 37281, 'Horde Slave - On Liberation'),
+(36773, 0, 22, '%s raises an empty hand in toast to you.', 16, 100, 0, 37282, 'Horde Slave - On Liberation'),
+(36773, 0, 23, '%s closes his eyes, savoring freedom for a moment.', 16, 100, 0, 37283, 'Horde Slave - On Liberation'),
+(36773, 0, 24, 'I''m going to return to help free the rest of the slaves. Thank you again, hero.', 16, 100, 0, 37293, 'Horde Slave - On Liberation'),
+
+(36913, 0, 7, 'He watches your every move...', 15, 100, 0, 38354, 'Eye of the Lich King - Whisper');
diff --git a/sql/updates/world/2014_10_15_00_world.sql b/sql/updates/world/2014_10_15_00_world.sql
new file mode 100644
index 00000000000..4414565d5bf
--- /dev/null
+++ b/sql/updates/world/2014_10_15_00_world.sql
@@ -0,0 +1 @@
+UPDATE `creature_text` SET `language`=0 WHERE `entry`=23678 AND `groupid`=1;
diff --git a/sql/updates/world/2014_10_16_00_world.sql b/sql/updates/world/2014_10_16_00_world.sql
new file mode 100644
index 00000000000..45b34d2cdc6
--- /dev/null
+++ b/sql/updates/world/2014_10_16_00_world.sql
@@ -0,0 +1,21 @@
+DELETE FROM `creature_text` WHERE `entry` IN(23439,25510,25511,25513,25512);
+
+INSERT INTO `creature_text` (`entry`, `groupid`, `id`, `text`, `type`, `language`, `probability`, `emote`, `duration`, `sound`, `comment`, `BroadcastTextID`) VALUES
+(23439, 0, 0, '%s feeds on the freshly-killed warp chaser.', 16, 0, 100, 35, 0, 0, 'Hungry Nether Ray',21657),
+(25510, 0, 0, 'The Serpent''s Maw is engulfed in tuskarr fire!', 41, 0, 100, 0, 0, 0, '1st Kvaldir Vessel (The Serpent''s Maw)',24722),
+(25512, 0, 0, 'Bor''s Hammer is engulfed in tuskarr fire!', 41, 0, 100, 0, 0, 0, '3rd Kvaldir Vessel (Bor''s Hammer)',24724),
+(25511, 0, 0, 'The Kur Drakkar is engulfed in tuskarr fire!', 41, 0, 100, 0, 0, 0, '2nd Kvaldir Vessel (The Kur Drakkar)',24723),
+(25513, 0, 0, 'Bor''s Anvil is engulfed in tuskarr fire!', 41, 0, 100, 0, 0, 0, '4th Kvaldir Vessel (Bor''s Anvil)',24725);
+
+UPDATE `smart_scripts` SET `link`=1 WHERE `entryorguid` IN(25510,25511,25512,25513) AND `source_type`=0 AND `id`=0 AND `link`=0;
+UPDATE `smart_scripts` SET `link`=2 WHERE `entryorguid`=23439 AND `source_type`=0 AND `id`=1 AND `link`=0;
+
+DELETE FROM `smart_scripts` WHERE `entryorguid` IN(25510,25511,25512,25513) AND `source_type`=0 AND `id`=1;
+DELETE FROM `smart_scripts` WHERE `entryorguid` =23439 AND `source_type`=0 AND `id`=2;
+
+INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES
+(25510, 0, 1, 0, 61, 0, 100, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, '1st Kvaldir Vessel (The Serpent\'s Maw) - On Spellhit \'Use Tuskarr Torch\' - Say'),
+(25511, 0, 1, 0, 61, 0, 100, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, '2nd Kvaldir Vessel (The Kur Drakkar) - On Spellhit \'Use Tuskarr Torch\' - Say'),
+(25512, 0, 1, 0, 61, 0, 100, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, '3rd Kvaldir Vessel (Bor''s Hammer) - On Spellhit \'Use Tuskarr Torch\' - Say'),
+(25513, 0, 1, 0, 61, 0, 100, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, '4th Kvaldir Vessel (Bor''s Anvil) - On Spellhit \'Use Tuskarr Torch\' - Say'),
+(23439, 0, 2, 0, 61, 0, 100, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Hungry Nether Ray - On Data Set 1 1 - Cast \'Lucille Feed Credit Trigger\'');
diff --git a/sql/updates/world/2014_10_17_00_world.sql b/sql/updates/world/2014_10_17_00_world.sql
new file mode 100644
index 00000000000..858bac569f2
--- /dev/null
+++ b/sql/updates/world/2014_10_17_00_world.sql
@@ -0,0 +1,117 @@
+-- Skeletal Guardian SAI
+SET @ENTRY := 10390;
+UPDATE `creature_template` SET `AIName`="SmartAI" WHERE `entry`=@ENTRY;
+DELETE FROM `smart_scripts` WHERE `entryorguid`=@ENTRY AND `source_type`=0;
+INSERT INTO `smart_scripts` (`entryorguid`,`source_type`,`id`,`link`,`event_type`,`event_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action_type`,`action_param1`,`action_param2`,`action_param3`,`action_param4`,`action_param5`,`action_param6`,`target_type`,`target_param1`,`target_param2`,`target_param3`,`target_x`,`target_y`,`target_z`,`target_o`,`comment`) VALUES
+(@ENTRY,0,0,0,1,0,100,2,1000,1000,1800000,1800000,11,13787,1,0,0,0,0,1,0,0,0,0,0,0,0,"Skeletal Guardian - Out of Combat - Cast 'Demon Armor' (Normal Dungeon)"),
+(@ENTRY,0,1,0,4,0,100,2,0,0,0,0,11,16799,0,0,0,0,0,2,0,0,0,0,0,0,0,"Skeletal Guardian - On Aggro - Cast 'Frostbolt' (Normal Dungeon)"),
+(@ENTRY,0,2,0,0,0,100,2,2400,3800,2400,3800,11,9613,64,0,0,0,0,2,0,0,0,0,0,0,0,"Skeletal Guardian - In Combat CMC - Cast 'Shadow Bolt' (Normal Dungeon)"),
+(@ENTRY,0,3,0,0,0,85,2,9000,12000,9000,12000,11,9672,0,0,0,0,0,2,0,0,0,0,0,0,0,"Skeletal Guardian - In Combat Range - Cast 'Frostbolt' (Normal Dungeon)"),
+(@ENTRY,0,4,0,0,0,85,2,6000,7000,9000,12000,11,37361,0,0,0,0,0,2,0,0,0,0,0,0,0,"Skeletal Guardian - In Combat - Cast 'Arcane Bolt' (Normal Dungeon)"),
+(@ENTRY,0,5,0,0,0,85,2,14000,18000,14000,18000,11,11975,1,0,0,0,0,1,0,0,0,0,0,0,0,"Skeletal Guardian - In Combat - Cast 'Arcane Explosion' (Normal Dungeon)");
+
+-- Skul SAI
+SET @ENTRY := 10393;
+UPDATE `creature_template` SET `AIName`="SmartAI" WHERE `entry`=@ENTRY;
+DELETE FROM `smart_scripts` WHERE `entryorguid`=@ENTRY AND `source_type`=0;
+INSERT INTO `smart_scripts` (`entryorguid`,`source_type`,`id`,`link`,`event_type`,`event_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action_type`,`action_param1`,`action_param2`,`action_param3`,`action_param4`,`action_param5`,`action_param6`,`target_type`,`target_param1`,`target_param2`,`target_param3`,`target_x`,`target_y`,`target_z`,`target_o`,`comment`) VALUES
+(@ENTRY,0,0,0,1,0,100,2,1000,1000,1800000,1800000,11,12544,1,0,0,0,0,1,0,0,0,0,0,0,0,"Skul - Out of Combat - Cast 'Frost Armor' (Normal Dungeon)"),
+(@ENTRY,0,1,0,0,0,100,2,0,0,2400,3800,11,16799,64,0,0,0,0,2,0,0,0,0,0,0,0,"Skul - In Combat - Cast 'Frostbolt' (Normal Dungeon)"),
+(@ENTRY,0,2,0,0,0,50,2,6000,8000,16000,20000,11,15499,1,0,0,0,0,5,0,0,0,0,0,0,0,"Skul - In Combat - Cast 'Frost Shock' (Normal Dungeon)"),
+(@ENTRY,0,3,0,0,0,40,2,9000,11000,9000,11000,11,15230,0,0,0,0,0,2,0,0,0,0,0,0,0,"Skul - In Combat - Cast 'Arcane Bolt' (Normal Dungeon)"),
+(@ENTRY,0,4,0,2,0,100,3,0,15,0,0,25,1,0,0,0,0,0,0,0,0,0,0,0,0,0,"Skul - Between 0-15% Health - Flee For Assist (No Repeat) (Normal Dungeon)");
+
+-- Thuzadin Shadowcaster SAI
+SET @ENTRY := 10398;
+UPDATE `creature_template` SET `AIName`="SmartAI" WHERE `entry`=@ENTRY;
+DELETE FROM `smart_scripts` WHERE `entryorguid`=@ENTRY AND `source_type`=0;
+INSERT INTO `smart_scripts` (`entryorguid`,`source_type`,`id`,`link`,`event_type`,`event_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action_type`,`action_param1`,`action_param2`,`action_param3`,`action_param4`,`action_param5`,`action_param6`,`target_type`,`target_param1`,`target_param2`,`target_param3`,`target_x`,`target_y`,`target_z`,`target_o`,`comment`) VALUES
+(@ENTRY,0,0,0,0,0,100,2,0,0,2400,3800,11,15232,64,0,0,0,0,2,0,0,0,0,0,0,0,"Thuzadin Shadowcaster - In Combat CMC - Cast 'Shadow Bolt' (Normal Dungeon)"),
+(@ENTRY,0,1,0,0,0,100,2,4000,6000,20000,25000,11,11443,1,0,0,0,0,2,0,0,0,0,0,0,0,"Thuzadin Shadowcaster - In Combat - Cast 'Cripple' (Normal Dungeon)"),
+(@ENTRY,0,2,0,0,0,100,2,7000,12000,15000,20000,11,16429,33,0,0,0,0,5,0,0,0,0,0,0,0,"Thuzadin Shadowcaster - In Combat - Cast 'Piercing Shadow' (Normal Dungeon)");
+
+-- Crimson Conjuror SAI
+SET @ENTRY := 10419;
+UPDATE `creature_template` SET `AIName`="SmartAI" WHERE `entry`=@ENTRY;
+DELETE FROM `smart_scripts` WHERE `entryorguid`=@ENTRY AND `source_type`=0;
+INSERT INTO `smart_scripts` (`entryorguid`,`source_type`,`id`,`link`,`event_type`,`event_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action_type`,`action_param1`,`action_param2`,`action_param3`,`action_param4`,`action_param5`,`action_param6`,`target_type`,`target_param1`,`target_param2`,`target_param3`,`target_x`,`target_y`,`target_z`,`target_o`,`comment`) VALUES
+(@ENTRY,0,0,0,0,0,100,2,0,40,2400,3800,11,12675,64,0,0,0,0,2,0,0,0,0,0,0,0,"Crimson Conjuror - In Combat CMC - Cast 'Frostbolt' (Normal Dungeon)"),
+(@ENTRY,0,1,0,0,0,85,2,7000,7000,10000,10000,11,17195,1,0,0,0,0,5,0,0,0,0,0,0,0,"Crimson Conjuror - In Combat - Cast 'Scorch' (Normal Dungeon)"),
+(@ENTRY,0,2,0,0,0,100,2,10000,10000,15000,15000,11,12674,1,0,0,0,0,1,0,0,0,0,0,0,0,"Crimson Conjuror - In Combat - Cast 'Frost Nova' (Normal Dungeon)"),
+(@ENTRY,0,3,0,0,0,100,2,5000,5000,35000,45000,11,17162,1,0,0,0,0,1,0,0,0,0,0,0,0,"Crimson Conjuror - In Combat - Cast 'Summon Water Elemental' (Normal Dungeon)");
+
+-- Crimson Sorcerer SAI
+SET @ENTRY := 10422;
+UPDATE `creature_template` SET `AIName`="SmartAI" WHERE `entry`=@ENTRY;
+DELETE FROM `smart_scripts` WHERE `entryorguid`=@ENTRY AND `source_type`=0;
+INSERT INTO `smart_scripts` (`entryorguid`,`source_type`,`id`,`link`,`event_type`,`event_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action_type`,`action_param1`,`action_param2`,`action_param3`,`action_param4`,`action_param5`,`action_param6`,`target_type`,`target_param1`,`target_param2`,`target_param3`,`target_x`,`target_y`,`target_z`,`target_o`,`comment`) VALUES
+(@ENTRY,0,0,0,1,0,100,2,1000,1000,1800000,1800000,11,12544,1,0,0,0,0,1,0,0,0,0,0,0,0,"Crimson Sorcerer - Out of Combat - Cast 'Frost Armor' (Normal Dungeon)"),
+(@ENTRY,0,1,0,1,0,100,2,3000,3000,1800000,1800000,11,17150,1,0,0,0,0,1,0,0,0,0,0,0,0,"Crimson Sorcerer - Out of Combat - Cast 'Arcane Might' (Normal Dungeon)"),
+(@ENTRY,0,2,0,0,0,100,2,0,0,2400,3800,11,15230,64,0,0,0,0,2,0,0,0,0,0,0,0,"Crimson Sorcerer - In Combat CMC - Cast 'Arcane Bolt' (Normal Dungeon)"),
+(@ENTRY,0,3,0,0,0,100,2,7000,14000,21000,26000,11,13323,1,0,0,0,0,6,0,0,0,0,0,0,0,"Crimson Sorcerer - In Combat - Cast 'Polymorph' (Normal Dungeon)"),
+(@ENTRY,0,4,0,0,0,100,2,5000,6000,8500,10000,11,14145,0,0,0,0,0,2,0,0,0,0,0,0,0,"Crimson Sorcerer - In Combat - Cast 'Fire Blast' (Normal Dungeon)");
+
+-- Chromatic Whelp SAI
+SET @ENTRY := 10442;
+UPDATE `creature_template` SET `AIName`="SmartAI" WHERE `entry`=@ENTRY;
+DELETE FROM `smart_scripts` WHERE `entryorguid`=@ENTRY AND `source_type`=0;
+INSERT INTO `smart_scripts` (`entryorguid`,`source_type`,`id`,`link`,`event_type`,`event_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action_type`,`action_param1`,`action_param2`,`action_param3`,`action_param4`,`action_param5`,`action_param6`,`target_type`,`target_param1`,`target_param2`,`target_param3`,`target_x`,`target_y`,`target_z`,`target_o`,`comment`) VALUES
+(@ENTRY,0,0,0,4,0,100,2,0,0,0,0,11,16249,0,0,0,0,0,2,0,0,0,0,0,0,0,"Chromatic Whelp - On Aggro - Cast 'Frostbolt' (Normal Dungeon)"),
+(@ENTRY,0,1,0,0,0,100,2,2400,3800,2400,3800,11,12167,64,0,0,0,0,2,0,0,0,0,0,0,0,"Chromatic Whelp - In Combat CMC - Cast 'Lightning Bolt' (Normal Dungeon)"),
+(@ENTRY,0,2,0,0,0,100,2,16200,26500,7000,27900,11,16249,0,0,0,0,0,2,0,0,0,0,0,0,0,"Chromatic Whelp - In Combat - Cast 'Frostbolt' (Normal Dungeon)"),
+(@ENTRY,0,3,0,0,0,100,2,10800,19600,15700,20400,11,16250,1,0,0,0,0,2,0,0,0,0,0,0,0,"Chromatic Whelp - In Combat - Cast 'Fireball Volley' (Normal Dungeon)");
+
+-- Scholomance Adept SAI
+SET @ENTRY := 10469;
+UPDATE `creature_template` SET `AIName`="SmartAI" WHERE `entry`=@ENTRY;
+DELETE FROM `smart_scripts` WHERE `entryorguid`=@ENTRY AND `source_type`=0;
+INSERT INTO `smart_scripts` (`entryorguid`,`source_type`,`id`,`link`,`event_type`,`event_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action_type`,`action_param1`,`action_param2`,`action_param3`,`action_param4`,`action_param5`,`action_param6`,`target_type`,`target_param1`,`target_param2`,`target_param3`,`target_x`,`target_y`,`target_z`,`target_o`,`comment`) VALUES
+(@ENTRY,0,0,0,0,0,100,2,0,0,3200,4800,11,15043,64,0,0,0,0,2,0,0,0,0,0,0,0,"Scholomance Adept - In Combat CMC - Cast 'Frostbolt' (Normal Dungeon)"),
+(@ENTRY,0,1,0,0,0,100,2,7300,17300,9400,14300,11,15244,1,0,0,0,0,1,0,0,0,0,0,0,0,"Scholomance Adept - In Combat - Cast 'Cone of Cold' (Normal Dungeon)"),
+(@ENTRY,0,2,0,0,0,100,2,7600,19700,12200,24700,11,15499,0,0,0,0,0,2,0,0,0,0,0,0,0,"Scholomance Adept - In Combat - Cast 'Frost Shock' (Normal Dungeon)"),
+(@ENTRY,0,3,0,2,0,100,3,0,15,0,0,25,1,0,0,0,0,0,0,0,0,0,0,0,0,0,"Scholomance Adept - Between 0-15% Health - Flee For Assist (No Repeat) (Normal Dungeon)");
+
+-- Scholomance Neophyte SAI
+SET @ENTRY := 10470;
+UPDATE `creature_template` SET `AIName`="SmartAI" WHERE `entry`=@ENTRY;
+DELETE FROM `smart_scripts` WHERE `entryorguid`=@ENTRY AND `source_type`=0;
+INSERT INTO `smart_scripts` (`entryorguid`,`source_type`,`id`,`link`,`event_type`,`event_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action_type`,`action_param1`,`action_param2`,`action_param3`,`action_param4`,`action_param5`,`action_param6`,`target_type`,`target_param1`,`target_param2`,`target_param3`,`target_x`,`target_y`,`target_z`,`target_o`,`comment`) VALUES
+(@ENTRY,0,0,0,0,0,100,2,0,0,3400,4800,11,12739,64,0,0,0,0,2,0,0,0,0,0,0,0,"Scholomance Neophyte - In Combat CMC - Cast 'Shadow Bolt'"),
+(@ENTRY,0,1,0,0,0,100,2,8600,26300,18400,36000,11,17165,1,0,0,0,0,2,0,0,0,0,0,0,0,"Scholomance Neophyte - In Combat - Cast 'Mind Flay'");
+
+-- Scholomance Necrolyte SAI
+SET @ENTRY := 10476;
+UPDATE `creature_template` SET `AIName`="SmartAI" WHERE `entry`=@ENTRY;
+DELETE FROM `smart_scripts` WHERE `entryorguid`=@ENTRY AND `source_type`=0;
+INSERT INTO `smart_scripts` (`entryorguid`,`source_type`,`id`,`link`,`event_type`,`event_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action_type`,`action_param1`,`action_param2`,`action_param3`,`action_param4`,`action_param5`,`action_param6`,`target_type`,`target_param1`,`target_param2`,`target_param3`,`target_x`,`target_y`,`target_z`,`target_o`,`comment`) VALUES
+(@ENTRY,0,0,0,0,0,100,2,0,0,2400,3800,11,12739,64,0,0,0,0,2,0,0,0,0,0,0,0,"Scholomance Necrolyte - In Combat CMC - Cast 'Shadow Bolt' (Normal Dungeon)"),
+(@ENTRY,0,1,0,0,0,100,2,1400,6200,7400,22000,11,17234,1,0,0,0,0,2,0,0,0,0,0,0,0,"Scholomance Necrolyte - In Combat - Cast 'Shadow Shock' (Normal Dungeon)"),
+(@ENTRY,0,2,0,0,0,100,2,1400,22000,22000,33200,11,17151,32,0,0,0,0,1,0,0,0,0,0,0,0,"Scholomance Necrolyte - In Combat - Cast 'Shadow Barrier' (Normal Dungeon)");
+
+-- Hearthsinger Forresten SAI
+SET @ENTRY := 10558;
+UPDATE `creature_template` SET `AIName`="SmartAI" WHERE `entry`=@ENTRY;
+DELETE FROM `smart_scripts` WHERE `entryorguid`=@ENTRY AND `source_type`=0;
+INSERT INTO `smart_scripts` (`entryorguid`,`source_type`,`id`,`link`,`event_type`,`event_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action_type`,`action_param1`,`action_param2`,`action_param3`,`action_param4`,`action_param5`,`action_param6`,`target_type`,`target_param1`,`target_param2`,`target_param3`,`target_x`,`target_y`,`target_z`,`target_o`,`comment`) VALUES
+(@ENTRY,0,0,0,0,0,100,2,5,30,2300,3900,11,16100,64,0,0,0,0,2,0,0,0,0,0,0,0,"Hearthsinger Forresten - In Combat CMC - Cast 'Shoot' (Normal Dungeon)"),
+(@ENTRY,0,1,0,0,0,100,2,3000,5000,12000,19000,11,16244,1,0,0,0,0,1,0,0,0,0,0,0,0,"Hearthsinger Forresten - In Combat - Cast 'Demoralizing Shout' (Normal Dungeon)"),
+(@ENTRY,0,2,0,0,0,100,2,7000,9000,20000,25000,11,16798,1,0,0,0,0,6,0,0,0,0,0,0,0,"Hearthsinger Forresten - In Combat - Cast 'Enchanting Lullaby' (Normal Dungeon)"),
+(@ENTRY,0,3,0,2,0,100,3,0,15,0,0,25,1,0,0,0,0,0,1,0,0,0,0,0,0,0,"Hearthsinger Forresten - Between 0-15% Health - Flee For Assist (No Repeat) (Normal Dungeon)");
+
+-- Lady Vespia SAI
+SET @ENTRY := 10559;
+UPDATE `creature_template` SET `AIName`="SmartAI" WHERE `entry`=@ENTRY;
+DELETE FROM `smart_scripts` WHERE `entryorguid`=@ENTRY AND `source_type`=0;
+INSERT INTO `smart_scripts` (`entryorguid`,`source_type`,`id`,`link`,`event_type`,`event_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action_type`,`action_param1`,`action_param2`,`action_param3`,`action_param4`,`action_param5`,`action_param6`,`target_type`,`target_param1`,`target_param2`,`target_param3`,`target_x`,`target_y`,`target_z`,`target_o`,`comment`) VALUES
+(@ENTRY,0,0,0,0,0,100,0,5400,7100,14300,19600,11,8398,0,0,0,0,0,2,0,0,0,0,0,0,0,"Lady Vespia - In Combat - Cast 'Frostbolt Volley' (Normal Dungeon)"),
+(@ENTRY,0,1,0,0,0,100,0,15300,19100,9500,22100,11,13586,0,0,0,0,0,2,0,0,0,0,0,0,0,"Lady Vespia - In Combat - Cast 'Aqua Jet' (Normal Dungeon)"),
+(@ENTRY,0,2,0,2,0,100,1,0,15,0,0,25,1,0,0,0,0,0,1,0,0,0,0,0,0,0,"Lady Vespia - Between 0-15% Health - Flee For Assist (No Repeat) (Normal Dungeon)");
+
+-- Urok Ogre Magus SAI
+SET @ENTRY := 10602;
+UPDATE `creature_template` SET `AIName`="SmartAI" WHERE `entry`=@ENTRY;
+DELETE FROM `smart_scripts` WHERE `entryorguid`=@ENTRY AND `source_type`=0;
+INSERT INTO `smart_scripts` (`entryorguid`,`source_type`,`id`,`link`,`event_type`,`event_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action_type`,`action_param1`,`action_param2`,`action_param3`,`action_param4`,`action_param5`,`action_param6`,`target_type`,`target_param1`,`target_param2`,`target_param3`,`target_x`,`target_y`,`target_z`,`target_o`,`comment`) VALUES
+(@ENTRY,0,0,0,0,0,100,2,0,0,2400,3800,11,15979,64,0,0,0,0,2,0,0,0,0,0,0,0,"Urok Ogre Magus - In Combat CMC - Cast 'Arcane Bolt' (Normal Dungeon)"),
+(@ENTRY,0,1,0,0,0,100,2,8000,11000,17000,24000,11,13747,1,0,0,0,0,5,0,0,0,0,0,0,0,"Urok Ogre Magus - In Combat - Cast 'Slow' (Normal Dungeon)"),
+(@ENTRY,0,2,0,2,0,100,3,0,30,30000,35000,11,6742,1,0,0,0,0,1,0,0,0,0,0,0,0,"Urok Ogre Magus - Between 0-30% Health - Cast 'Bloodlust' (No Repeat) (Normal Dungeon)");
diff --git a/src/server/CMakeLists.txt b/src/server/CMakeLists.txt
index 05cbe51b15d..e691b9527a5 100644
--- a/src/server/CMakeLists.txt
+++ b/src/server/CMakeLists.txt
@@ -25,6 +25,8 @@ if( SERVERS )
add_subdirectory(game)
add_subdirectory(collision)
add_subdirectory(authserver)
+ add_subdirectory(ipc)
+ add_subdirectory(bnetserver)
add_subdirectory(scripts)
add_subdirectory(worldserver)
else()
diff --git a/src/server/authserver/Authentication/AuthCodes.h b/src/server/authserver/Authentication/AuthCodes.h
index c42a11007d8..bc7f0c43f17 100644
--- a/src/server/authserver/Authentication/AuthCodes.h
+++ b/src/server/authserver/Authentication/AuthCodes.h
@@ -104,63 +104,6 @@ enum GameAccountFlags
GAMEACCOUNT_FLAG_DEATH_KNIGHT_OK = 0x20000000,
};
-namespace Battlenet
-{
- enum AuthResult
- {
- AUTH_OK = 0,
- AUTH_INTERNAL_ERROR = 100,
- AUTH_CORRUPTED_MODULE = 101,
- AUTH_NO_BATTLETAGS = 102,
- AUTH_BAD_SERVER_PROOF = 103,
- AUTH_UNKNOWN_ACCOUNT = 104,
- AUTH_CLOSED = 105,
- AUTH_LOGIN_TIMEOUT = 106,
- AUTH_NO_GAME_ACCOUNTS = 107,
- AUTH_INVALID_TOKEN = 108,
- AUTH_INVALID_PROGRAM = 109,
- AUTH_INVALID_OS = 110,
- AUTH_UNSUPPORTED_LANGUAGE = 111,
- AUTH_REGION_BAD_VERSION = 112,
- AUTH_TEMP_OUTAGE = 113,
- AUTH_CANT_DOWNLOAD_MODULE = 114,
- AUTH_DUPLICATE_LOGON = 115,
- AUTH_BAD_CREDENTIALS_2 = 116,
- AUTH_VERSION_CHECK_SUCCEEDED = 117,
- AUTH_BAD_VERSION_HASH = 118,
- AUTH_CANT_RETRIEVE_PORTAL_LIST = 119,
- AUTH_DARK_PORTAL_DOES_NOT_EXIST = 120,
- AUTH_DARK_PORTAL_FILE_CORRUPTED = 121,
- AUTH_BATTLENET_MAINTENANCE = 122,
- AUTH_LOGON_TOO_FAST = 123,
- AUTH_USE_GRUNT_LOGON = 124,
- AUTH_NO_GAME_ACCOUNTS_IN_REGION = 140,
- AUTH_ACCOUNT_LOCKED = 141,
-
- LOGIN_SERVER_BUSY = 200,
- LOGIN_NO_GAME_ACCOUNT = 201,
- LOGIN_BANNED = 202,
- LOGIN_SUSPENDED = 203,
- LOGIN_GAME_ACCOUNT_LOCKED = 204,
- LOGIN_ALREADY_ONLINE = 205,
- LOGIN_NOTIME = 206,
- LOGIN_EXPIRED = 207,
- LOGIN_EXPIRED_2 = 208,
- LOGIN_PARENTALCONTROL = 209,
- LOGIN_TRIAL_EXPIRED = 210,
- LOGIN_ANTI_INDULGENCE = 211,
- LOGIN_INCORRECT_REGION = 212,
- LOGIN_LOCKED_ENFORCED = 213,
- LOGIN_CHARGEBACK = 214,
- LOGIN_IGR_WITHOUT_BNET = 215,
- LOGIN_UNLOCKABLE_LOCK = 216,
- LOGIN_IGR_REQUIRED = 217,
- LOGIN_PAYMENT_CHANGED = 218,
- LOGIN_INVALID_PAYMENT = 219,
- LOGIN_INVALID_ACCOUNT_STATE = 220
- };
-}
-
enum ExpansionFlags
{
POST_BC_EXP_FLAG = 0x2,
diff --git a/src/server/authserver/CMakeLists.txt b/src/server/authserver/CMakeLists.txt
index ae706973ff7..b40b8c906f4 100644
--- a/src/server/authserver/CMakeLists.txt
+++ b/src/server/authserver/CMakeLists.txt
@@ -58,7 +58,6 @@ include_directories(
${CMAKE_CURRENT_SOURCE_DIR}/Authentication
${CMAKE_CURRENT_SOURCE_DIR}/Realms
${CMAKE_CURRENT_SOURCE_DIR}/Server
- ${CMAKE_CURRENT_SOURCE_DIR}/Server/BattlenetPackets
${MYSQL_INCLUDE_DIR}
${OPENSSL_INCLUDE_DIR}
${VALGRIND_INCLUDE_DIR}
diff --git a/src/server/authserver/Main.cpp b/src/server/authserver/Main.cpp
index e614b2b79fa..5f08ebe3127 100644
--- a/src/server/authserver/Main.cpp
+++ b/src/server/authserver/Main.cpp
@@ -25,8 +25,6 @@
*/
#include "AuthSocketMgr.h"
-#include "BattlenetManager.h"
-#include "BattlenetSessionManager.h"
#include "Common.h"
#include "Config.h"
#include "DatabaseEnv.h"
@@ -117,18 +115,9 @@ int main(int argc, char** argv)
return 1;
}
- int32 bnport = sConfigMgr->GetIntDefault("BattlenetPort", 1119);
- if (bnport < 0 || bnport > 0xFFFF)
- {
- TC_LOG_ERROR("server.authserver", "Specified battle.net port (%d) out of allowed range (1-65535)", bnport);
- StopDB();
- return 1;
- }
-
std::string bindIp = sConfigMgr->GetStringDefault("BindIP", "0.0.0.0");
sAuthSocketMgr.StartNetwork(_ioService, bindIp, port);
- sBattlenetSessionMgr.StartNetwork(_ioService, bindIp, bnport);
// Set signal handlers
boost::asio::signal_set signals(_ioService, SIGINT, SIGTERM);
@@ -145,8 +134,6 @@ int main(int argc, char** argv)
_dbPingTimer.expires_from_now(boost::posix_time::minutes(_dbPingInterval));
_dbPingTimer.async_wait(KeepDatabaseAliveHandler);
- sBattlenetMgr->Load();
-
// Start the io service worker loop
_ioService.run();
diff --git a/src/server/authserver/PrecompiledHeaders/authPCH.h b/src/server/authserver/PrecompiledHeaders/authPCH.h
index b509f8caaa0..90424161344 100644
--- a/src/server/authserver/PrecompiledHeaders/authPCH.h
+++ b/src/server/authserver/PrecompiledHeaders/authPCH.h
@@ -2,9 +2,6 @@
#include "Configuration/Config.h"
#include "Database/DatabaseEnv.h"
#include "Log.h"
-#include "BattlenetManager.h"
#include "RealmList.h"
#include "ByteBuffer.h"
-#include "BattlenetPackets.h"
#include "AuthSession.h"
-#include "BattlenetSession.h"
diff --git a/src/server/authserver/Realms/RealmList.cpp b/src/server/authserver/Realms/RealmList.cpp
index 2110dc1fecc..15302c74ac6 100644
--- a/src/server/authserver/Realms/RealmList.cpp
+++ b/src/server/authserver/Realms/RealmList.cpp
@@ -19,7 +19,6 @@
#include <boost/asio/ip/tcp.hpp>
#include "Common.h"
#include "RealmList.h"
-#include "BattlenetManager.h"
#include "Database/DatabaseEnv.h"
#include "Util.h"
@@ -78,7 +77,7 @@ void RealmList::Initialize(boost::asio::io_service& ioService, uint32 updateInte
}
void RealmList::UpdateRealm(uint32 id, const std::string& name, ip::address const& address, ip::address const& localAddr,
- ip::address const& localSubmask, uint16 port, uint8 icon, RealmFlags flag, uint8 timezone, AccountTypes allowedSecurityLevel, float population, uint32 build, uint8 region, uint8 battlegroup)
+ ip::address const& localSubmask, uint16 port, uint8 icon, RealmFlags flag, uint8 timezone, AccountTypes allowedSecurityLevel, float population, uint32 build)
{
// Create new if not exist or update existed
Realm& realm = m_realms[name];
@@ -91,15 +90,11 @@ void RealmList::UpdateRealm(uint32 id, const std::string& name, ip::address cons
realm.allowedSecurityLevel = allowedSecurityLevel;
realm.populationLevel = population;
- // Append port to IP address.
-
realm.ExternalAddress = address;
realm.LocalAddress = localAddr;
realm.LocalSubnetMask = localSubmask;
realm.port = port;
realm.gamebuild = build;
- realm.Region = region;
- realm.Battlegroup = battlegroup;
}
void RealmList::UpdateIfNeed()
@@ -175,11 +170,9 @@ void RealmList::UpdateRealms(bool init)
uint8 allowedSecurityLevel = fields[9].GetUInt8();
float pop = fields[10].GetFloat();
uint32 build = fields[11].GetUInt32();
- uint8 region = fields[12].GetUInt8();
- uint8 battlegroup = fields[13].GetUInt8();
UpdateRealm(realmId, name, externalAddress, localAddress, localSubmask, port, icon, flag, timezone,
- (allowedSecurityLevel <= SEC_ADMINISTRATOR ? AccountTypes(allowedSecurityLevel) : SEC_ADMINISTRATOR), pop, build, region, battlegroup);
+ (allowedSecurityLevel <= SEC_ADMINISTRATOR ? AccountTypes(allowedSecurityLevel) : SEC_ADMINISTRATOR), pop, build);
if (init)
TC_LOG_INFO("server.authserver", "Added realm \"%s\" at %s:%u.", name.c_str(), m_realms[name].ExternalAddress.to_string().c_str(), port);
@@ -193,16 +186,3 @@ void RealmList::UpdateRealms(bool init)
while (result->NextRow());
}
}
-
-Realm const* RealmList::GetRealm(Battlenet::RealmId const& id) const
-{
- auto itr = std::find_if(m_realms.begin(), m_realms.end(), [id](RealmMap::value_type const& pair)
- {
- return pair.second.Region == id.Region && pair.second.Battlegroup == id.Battlegroup && pair.second.m_ID == id.Index;
- });
-
- if (itr != m_realms.end())
- return &itr->second;
-
- return NULL;
-}
diff --git a/src/server/authserver/Realms/RealmList.h b/src/server/authserver/Realms/RealmList.h
index 0063b1a60c8..9d5771144a9 100644
--- a/src/server/authserver/Realms/RealmList.h
+++ b/src/server/authserver/Realms/RealmList.h
@@ -54,17 +54,10 @@ struct Realm
AccountTypes allowedSecurityLevel;
float populationLevel;
uint32 gamebuild;
- uint8 Region;
- uint8 Battlegroup;
ip::tcp::endpoint GetAddressForClient(ip::address const& clientAddr) const;
};
-namespace Battlenet
-{
- struct RealmId;
-}
-
/// Storage object for the list of realms on the server
class RealmList
{
@@ -88,14 +81,13 @@ public:
RealmMap::const_iterator begin() const { return m_realms.begin(); }
RealmMap::const_iterator end() const { return m_realms.end(); }
uint32 size() const { return m_realms.size(); }
- Realm const* GetRealm(Battlenet::RealmId const& id) const;
private:
RealmList();
void UpdateRealms(bool init = false);
void UpdateRealm(uint32 id, const std::string& name, ip::address const& address, ip::address const& localAddr,
- ip::address const& localSubmask, uint16 port, uint8 icon, RealmFlags flag, uint8 timezone, AccountTypes allowedSecurityLevel, float population, uint32 build, uint8 region, uint8 battlegroup);
+ ip::address const& localSubmask, uint16 port, uint8 icon, RealmFlags flag, uint8 timezone, AccountTypes allowedSecurityLevel, float population, uint32 build);
RealmMap m_realms;
uint32 m_UpdateInterval;
diff --git a/src/server/authserver/Server/BattlenetPackets/ConnectionPackets.h b/src/server/authserver/Server/BattlenetPackets/ConnectionPackets.h
deleted file mode 100644
index 50ec9416ec1..00000000000
--- a/src/server/authserver/Server/BattlenetPackets/ConnectionPackets.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2008-2014 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 ConnectionPackets_h__
-#define ConnectionPackets_h__
-
-#include "BattlenetPacketsBase.h"
-
-namespace Battlenet
-{
- namespace Connection
- {
- enum Opcode
- {
- CMSG_PING = 0x0,
- CMSG_ENABLE_ENCRYPTION = 0x5,
- CMSG_LOGOUT_REQUEST = 0x6,
- CMSG_DISCONNECT_REQUEST = 0x7, // Not implemented
- CMSG_CONNECTION_CLOSING = 0x9, // Not implemented
-
- SMSG_PONG = 0x0,
- SMSG_BOOM = 0x1, // Not implemented
- SMSG_REGULATOR_UPDATE = 0x2, // Not implemented
- SMSG_SERVER_VERSION = 0x3, // Not implemented
- SMSG_STUN_SERVERS = 0x4 // Not implemented
- };
-
- class Pong final : public ServerPacket
- {
- public:
- Pong() : ServerPacket(PacketHeader(SMSG_PONG, CONNECTION))
- {
- }
-
- void Write() override { }
- std::string ToString() const override;
- };
- }
-}
-
-#endif // ConnectionPackets_h__
diff --git a/src/server/authserver/authserver.conf.dist b/src/server/authserver/authserver.conf.dist
index e0ef6982353..b7dee9ac08b 100644
--- a/src/server/authserver/authserver.conf.dist
+++ b/src/server/authserver/authserver.conf.dist
@@ -54,13 +54,6 @@ MaxPingTime = 30
RealmServerPort = 3724
#
-# BattlenetPort
-# Description: TCP port to reach the auth server for battle.net connections.
-# Default: 1119
-
-BattlenetPort = 1119
-
-#
#
# BindIP
# Description: Bind auth server to IP/hostname
diff --git a/src/server/bnetserver/Authentication/AuthCodes.cpp b/src/server/bnetserver/Authentication/AuthCodes.cpp
new file mode 100644
index 00000000000..908bc30b719
--- /dev/null
+++ b/src/server/bnetserver/Authentication/AuthCodes.cpp
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2008-2014 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 "AuthCodes.h"
+#include <cstddef>
+
+namespace AuthHelper
+{
+ static RealmBuildInfo const PostBcAcceptedClientBuilds[] =
+ {
+ {15595, 4, 3, 4, ' '},
+ {14545, 4, 2, 2, ' '},
+ {13623, 4, 0, 6, 'a'},
+ {13930, 3, 3, 5, 'a'}, // 3.3.5a China Mainland build
+ {12340, 3, 3, 5, 'a'},
+ {11723, 3, 3, 3, 'a'},
+ {11403, 3, 3, 2, ' '},
+ {11159, 3, 3, 0, 'a'},
+ {10505, 3, 2, 2, 'a'},
+ {9947, 3, 1, 3, ' '},
+ {8606, 2, 4, 3, ' '},
+ {6141, 1, 12, 3, ' '},
+ {6005, 1, 12, 2, ' '},
+ {5875, 1, 12, 1, ' '},
+ {0, 0, 0, 0, ' '} // terminator
+ };
+
+ RealmBuildInfo const* GetBuildInfo(int build)
+ {
+ for (int i = 0; PostBcAcceptedClientBuilds[i].Build; ++i)
+ if (PostBcAcceptedClientBuilds[i].Build == build)
+ return &PostBcAcceptedClientBuilds[i];
+
+ return nullptr;
+ }
+
+ bool IsBuildSupportingBattlenet(int build)
+ {
+ return build >= 15595;
+ }
+}
diff --git a/src/server/bnetserver/Authentication/AuthCodes.h b/src/server/bnetserver/Authentication/AuthCodes.h
new file mode 100644
index 00000000000..3c3b002551c
--- /dev/null
+++ b/src/server/bnetserver/Authentication/AuthCodes.h
@@ -0,0 +1,128 @@
+/*
+ * Copyright (C) 2008-2014 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 _AUTHCODES_H
+#define _AUTHCODES_H
+
+enum GameAccountFlags
+{
+ GAMEACCOUNT_FLAG_GM = 0x00000001,
+ GAMEACCOUNT_FLAG_NOKICK = 0x00000002,
+ GAMEACCOUNT_FLAG_COLLECTOR = 0x00000004,
+ GAMEACCOUNT_FLAG_WOW_TRIAL = 0x00000008,
+ GAMEACCOUNT_FLAG_CANCELLED = 0x00000010,
+ GAMEACCOUNT_FLAG_IGR = 0x00000020,
+ GAMEACCOUNT_FLAG_WHOLESALER = 0x00000040,
+ GAMEACCOUNT_FLAG_PRIVILEGED = 0x00000080,
+ GAMEACCOUNT_FLAG_EU_FORBID_ELV = 0x00000100,
+ GAMEACCOUNT_FLAG_EU_FORBID_BILLING = 0x00000200,
+ GAMEACCOUNT_FLAG_WOW_RESTRICTED = 0x00000400,
+ GAMEACCOUNT_FLAG_REFERRAL = 0x00000800,
+ GAMEACCOUNT_FLAG_BLIZZARD = 0x00001000,
+ GAMEACCOUNT_FLAG_RECURRING_BILLING = 0x00002000,
+ GAMEACCOUNT_FLAG_NOELECTUP = 0x00004000,
+ GAMEACCOUNT_FLAG_KR_CERTIFICATE = 0x00008000,
+ GAMEACCOUNT_FLAG_EXPANSION_COLLECTOR = 0x00010000,
+ GAMEACCOUNT_FLAG_DISABLE_VOICE = 0x00020000,
+ GAMEACCOUNT_FLAG_DISABLE_VOICE_SPEAK = 0x00040000,
+ GAMEACCOUNT_FLAG_REFERRAL_RESURRECT = 0x00080000,
+ GAMEACCOUNT_FLAG_EU_FORBID_CC = 0x00100000,
+ GAMEACCOUNT_FLAG_OPENBETA_DELL = 0x00200000,
+ GAMEACCOUNT_FLAG_PROPASS = 0x00400000,
+ GAMEACCOUNT_FLAG_PROPASS_LOCK = 0x00800000,
+ GAMEACCOUNT_FLAG_PENDING_UPGRADE = 0x01000000,
+ GAMEACCOUNT_FLAG_RETAIL_FROM_TRIAL = 0x02000000,
+ GAMEACCOUNT_FLAG_EXPANSION2_COLLECTOR = 0x04000000,
+ GAMEACCOUNT_FLAG_OVERMIND_LINKED = 0x08000000,
+ GAMEACCOUNT_FLAG_DEMOS = 0x10000000,
+ GAMEACCOUNT_FLAG_DEATH_KNIGHT_OK = 0x20000000,
+};
+
+namespace Battlenet
+{
+ enum AuthResult
+ {
+ AUTH_OK = 0,
+ AUTH_INTERNAL_ERROR = 100,
+ AUTH_CORRUPTED_MODULE = 101,
+ AUTH_NO_BATTLETAGS = 102,
+ AUTH_BAD_SERVER_PROOF = 103,
+ AUTH_UNKNOWN_ACCOUNT = 104,
+ AUTH_CLOSED = 105,
+ AUTH_LOGIN_TIMEOUT = 106,
+ AUTH_NO_GAME_ACCOUNTS = 107,
+ AUTH_INVALID_TOKEN = 108,
+ AUTH_INVALID_PROGRAM = 109,
+ AUTH_INVALID_OS = 110,
+ AUTH_UNSUPPORTED_LANGUAGE = 111,
+ AUTH_REGION_BAD_VERSION = 112,
+ AUTH_TEMP_OUTAGE = 113,
+ AUTH_CANT_DOWNLOAD_MODULE = 114,
+ AUTH_DUPLICATE_LOGON = 115,
+ AUTH_BAD_CREDENTIALS_2 = 116,
+ AUTH_VERSION_CHECK_SUCCEEDED = 117,
+ AUTH_BAD_VERSION_HASH = 118,
+ AUTH_CANT_RETRIEVE_PORTAL_LIST = 119,
+ AUTH_DARK_PORTAL_DOES_NOT_EXIST = 120,
+ AUTH_DARK_PORTAL_FILE_CORRUPTED = 121,
+ AUTH_BATTLENET_MAINTENANCE = 122,
+ AUTH_LOGON_TOO_FAST = 123,
+ AUTH_USE_GRUNT_LOGON = 124,
+ AUTH_NO_GAME_ACCOUNTS_IN_REGION = 140,
+ AUTH_ACCOUNT_LOCKED = 141,
+
+ LOGIN_SERVER_BUSY = 200,
+ LOGIN_NO_GAME_ACCOUNT = 201,
+ LOGIN_BANNED = 202,
+ LOGIN_SUSPENDED = 203,
+ LOGIN_GAME_ACCOUNT_LOCKED = 204,
+ LOGIN_ALREADY_ONLINE = 205,
+ LOGIN_NOTIME = 206,
+ LOGIN_EXPIRED = 207,
+ LOGIN_EXPIRED_2 = 208,
+ LOGIN_PARENTALCONTROL = 209,
+ LOGIN_TRIAL_EXPIRED = 210,
+ LOGIN_ANTI_INDULGENCE = 211,
+ LOGIN_INCORRECT_REGION = 212,
+ LOGIN_LOCKED_ENFORCED = 213,
+ LOGIN_CHARGEBACK = 214,
+ LOGIN_IGR_WITHOUT_BNET = 215,
+ LOGIN_UNLOCKABLE_LOCK = 216,
+ LOGIN_IGR_REQUIRED = 217,
+ LOGIN_PAYMENT_CHANGED = 218,
+ LOGIN_INVALID_PAYMENT = 219,
+ LOGIN_INVALID_ACCOUNT_STATE = 220
+ };
+}
+
+struct RealmBuildInfo
+{
+ int Build;
+ int MajorVersion;
+ int MinorVersion;
+ int BugfixVersion;
+ int HotfixVersion;
+};
+
+namespace AuthHelper
+{
+ RealmBuildInfo const* GetBuildInfo(int build);
+ bool IsBuildSupportingBattlenet(int build);
+}
+
+#endif
diff --git a/src/server/authserver/Server/BattlenetPacketCrypt.cpp b/src/server/bnetserver/Authentication/BattlenetPacketCrypt.cpp
index de4cf73f71c..de4cf73f71c 100644
--- a/src/server/authserver/Server/BattlenetPacketCrypt.cpp
+++ b/src/server/bnetserver/Authentication/BattlenetPacketCrypt.cpp
diff --git a/src/server/authserver/Server/BattlenetPacketCrypt.h b/src/server/bnetserver/Authentication/BattlenetPacketCrypt.h
index dde687651d3..a09d3417dfe 100644
--- a/src/server/authserver/Server/BattlenetPacketCrypt.h
+++ b/src/server/bnetserver/Authentication/BattlenetPacketCrypt.h
@@ -15,8 +15,8 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef __BATTLENETPACKETCRYPT_H__
-#define __BATTLENETPACKETCRYPT_H__
+#ifndef BattlenetPacketCrypt_h__
+#define BattlenetPacketCrypt_h__
#include "PacketCrypt.h"
@@ -32,5 +32,5 @@ namespace Battlenet
void Init(BigNumber* K) override;
};
}
+#endif // BattlenetPacketCrypt_h__
-#endif // __BATTLENETPACKETCRYPT_H__
diff --git a/src/server/bnetserver/CMakeLists.txt b/src/server/bnetserver/CMakeLists.txt
new file mode 100644
index 00000000000..5b854018d47
--- /dev/null
+++ b/src/server/bnetserver/CMakeLists.txt
@@ -0,0 +1,121 @@
+# Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
+#
+# This file is free software; as a special exception the author gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+########### bnetserver ###############
+
+file(GLOB_RECURSE sources_authentication Authentication/*.cpp Authentication/*.h)
+file(GLOB_RECURSE sources_realms Realms/*.cpp Realms/*.h)
+file(GLOB_RECURSE sources_server Server/*.cpp Server/*.h)
+file(GLOB_RECURSE sources_packets Packets/*.cpp Packets/*.h)
+file(GLOB sources_localdir *.cpp *.h)
+
+if (USE_COREPCH)
+ set(bnetserver_PCH_HDR PrecompiledHeaders/bnetPCH.h)
+ set(bnetserver_PCH_SRC PrecompiledHeaders/bnetPCH.cpp)
+endif()
+
+set(bnetserver_SRCS
+ ${bnetserver_SRCS}
+ ${sources_authentication}
+ ${sources_realms}
+ ${sources_server}
+ ${sources_packets}
+ ${sources_localdir}
+)
+
+if( WIN32 )
+ set(bnetserver_SRCS
+ ${bnetserver_SRCS}
+ ${sources_windows_Debugging}
+ )
+ if ( MSVC )
+ set(bnetserver_SRCS
+ ${bnetserver_SRCS}
+ bnetserver.rc
+ )
+ endif ()
+endif()
+
+include_directories(
+ ${CMAKE_BINARY_DIR}
+ ${CMAKE_SOURCE_DIR}/dep/zmqpp
+ ${CMAKE_SOURCE_DIR}/src/server/shared
+ ${CMAKE_SOURCE_DIR}/src/server/shared/Configuration
+ ${CMAKE_SOURCE_DIR}/src/server/shared/Database
+ ${CMAKE_SOURCE_DIR}/src/server/shared/Debugging
+ ${CMAKE_SOURCE_DIR}/src/server/shared/Packets
+ ${CMAKE_SOURCE_DIR}/src/server/shared/Cryptography
+ ${CMAKE_SOURCE_DIR}/src/server/shared/Cryptography/Authentication
+ ${CMAKE_SOURCE_DIR}/src/server/shared/Logging
+ ${CMAKE_SOURCE_DIR}/src/server/shared/Networking
+ ${CMAKE_SOURCE_DIR}/src/server/shared/Threading
+ ${CMAKE_SOURCE_DIR}/src/server/shared/Utilities
+ ${CMAKE_SOURCE_DIR}/src/server/ipc
+ ${CMAKE_CURRENT_SOURCE_DIR}
+ ${CMAKE_CURRENT_SOURCE_DIR}/Authentication
+ ${CMAKE_CURRENT_SOURCE_DIR}/Realms
+ ${CMAKE_CURRENT_SOURCE_DIR}/Server
+ ${CMAKE_CURRENT_SOURCE_DIR}/Packets
+ ${MYSQL_INCLUDE_DIR}
+ ${OPENSSL_INCLUDE_DIR}
+ ${VALGRIND_INCLUDE_DIR}
+ ${ZMQ_INCLUDE_DIR}
+)
+
+add_executable(bnetserver
+ ${bnetserver_SRCS}
+ ${bnetserver_PCH_SRC}
+)
+
+add_dependencies(bnetserver revision.h)
+
+if( NOT WIN32 )
+ set_target_properties(bnetserver PROPERTIES
+ COMPILE_DEFINITIONS _TRINITY_BNET_CONFIG="${CONF_DIR}/bnetserver.conf"
+ )
+endif()
+
+target_link_libraries(bnetserver
+ ipc
+ shared
+ zmqpp
+ ${MYSQL_LIBRARY}
+ ${OPENSSL_LIBRARIES}
+ ${ZMQ_LIBRARY}
+ ${CMAKE_THREAD_LIBS_INIT}
+ ${Boost_LIBRARIES}
+)
+
+if( WIN32 )
+ if ( MSVC )
+ add_custom_command(TARGET bnetserver
+ POST_BUILD
+ COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/bnetserver.conf.dist ${CMAKE_BINARY_DIR}/bin/$(ConfigurationName)/
+ )
+ elseif ( MINGW )
+ add_custom_command(TARGET bnetserver
+ POST_BUILD
+ COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/bnetserver.conf.dist ${CMAKE_BINARY_DIR}/bin/
+ )
+ endif()
+endif()
+
+if( UNIX )
+ install(TARGETS bnetserver DESTINATION bin)
+ install(FILES bnetserver.conf.dist DESTINATION ${CONF_DIR})
+elseif( WIN32 )
+ install(TARGETS bnetserver DESTINATION "${CMAKE_INSTALL_PREFIX}")
+ install(FILES bnetserver.conf.dist DESTINATION "${CMAKE_INSTALL_PREFIX}")
+endif()
+
+# Generate precompiled header
+if (USE_COREPCH)
+ add_cxx_pch(bnetserver ${bnetserver_PCH_HDR} ${bnetserver_PCH_SRC})
+endif()
diff --git a/src/server/bnetserver/Main.cpp b/src/server/bnetserver/Main.cpp
new file mode 100644
index 00000000000..ce90019c011
--- /dev/null
+++ b/src/server/bnetserver/Main.cpp
@@ -0,0 +1,244 @@
+/*
+ * Copyright (C) 2008-2014 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/>.
+ */
+
+/**
+* @file main.cpp
+* @brief Authentication Server main program
+*
+* This file contains the main program for the
+* authentication server
+*/
+
+#include "ComponentManager.h"
+#include "ModuleManager.h"
+#include "SessionManager.h"
+#include "Common.h"
+#include "Config.h"
+#include "DatabaseEnv.h"
+#include "Log.h"
+#include "ProcessPriority.h"
+#include "RealmList.h"
+#include "SystemConfig.h"
+#include "Util.h"
+#include "ZmqContext.h"
+#include <cstdlib>
+#include <iostream>
+#include <boost/date_time/posix_time/posix_time.hpp>
+#include <boost/program_options.hpp>
+#include <openssl/opensslv.h>
+#include <openssl/crypto.h>
+
+using boost::asio::ip::tcp;
+using namespace boost::program_options;
+
+#ifndef _TRINITY_BNET_CONFIG
+# define _TRINITY_BNET_CONFIG "bnetserver.conf"
+#endif
+
+bool StartDB();
+void StopDB();
+void SignalHandler(const boost::system::error_code& error, int signalNumber);
+void KeepDatabaseAliveHandler(const boost::system::error_code& error);
+variables_map GetConsoleArguments(int argc, char** argv, std::string& configFile);
+
+boost::asio::io_service _ioService;
+boost::asio::deadline_timer _dbPingTimer(_ioService);
+uint32 _dbPingInterval;
+LoginDatabaseWorkerPool LoginDatabase;
+
+int main(int argc, char** argv)
+{
+ std::string configFile = _TRINITY_BNET_CONFIG;
+ auto vm = GetConsoleArguments(argc, argv, configFile);
+ // exit if help is enabled
+ if (vm.count("help"))
+ return 0;
+
+ std::string configError;
+ if (!sConfigMgr->LoadInitial(configFile, configError))
+ {
+ printf("Error in config file: %s\n", configError.c_str());
+ return 1;
+ }
+
+ TC_LOG_INFO("server.bnetserver", "%s (bnetserver)", _FULLVERSION);
+ TC_LOG_INFO("server.bnetserver", "<Ctrl-C> to stop.\n");
+ TC_LOG_INFO("server.bnetserver", "Using configuration file %s.", configFile.c_str());
+ TC_LOG_INFO("server.bnetserver", "Using SSL version: %s (library: %s)", OPENSSL_VERSION_TEXT, SSLeay_version(SSLEAY_VERSION));
+ TC_LOG_INFO("server.bnetserver", "Using Boost version: %i.%i.%i", BOOST_VERSION / 100000, BOOST_VERSION / 100 % 1000, BOOST_VERSION % 100);
+
+ // bnetserver PID file creation
+ std::string pidFile = sConfigMgr->GetStringDefault("PidFile", "");
+ if (!pidFile.empty())
+ {
+ if (uint32 pid = CreatePIDFile(pidFile))
+ TC_LOG_INFO("server.bnetserver", "Daemon PID: %u\n", pid);
+ else
+ {
+ TC_LOG_ERROR("server.bnetserver", "Cannot create PID file %s.\n", pidFile.c_str());
+ return 1;
+ }
+ }
+
+ int32 worldListenPort = sConfigMgr->GetIntDefault("WorldserverListenPort", 1118);
+ if (worldListenPort < 0 || worldListenPort > 0xFFFF)
+ {
+ TC_LOG_ERROR("server.bnetserver", "Specified worldserver listen port (%d) out of allowed range (1-65535)", worldListenPort);
+ return 1;
+ }
+
+ // Initialize the database connection
+ if (!StartDB())
+ return 1;
+
+ sIpcContext->Initialize();
+
+ // Get the list of realms for the server
+ sRealmList->Initialize(_ioService, sConfigMgr->GetIntDefault("RealmsStateUpdateDelay", 10), worldListenPort);
+
+ // Start the listening port (acceptor) for auth connections
+ int32 bnport = sConfigMgr->GetIntDefault("BattlenetPort", 1119);
+ if (bnport < 0 || bnport > 0xFFFF)
+ {
+ TC_LOG_ERROR("server.bnetserver", "Specified battle.net port (%d) out of allowed range (1-65535)", bnport);
+ StopDB();
+ return 1;
+ }
+
+ std::string bindIp = sConfigMgr->GetStringDefault("BindIP", "0.0.0.0");
+
+ sSessionMgr.StartNetwork(_ioService, bindIp, bnport);
+
+ // Set signal handlers
+ boost::asio::signal_set signals(_ioService, SIGINT, SIGTERM);
+#if PLATFORM == PLATFORM_WINDOWS
+ signals.add(SIGBREAK);
+#endif
+ signals.async_wait(SignalHandler);
+
+ // Set process priority according to configuration settings
+ SetProcessPriority("server.bnetserver");
+
+ // Enabled a timed callback for handling the database keep alive ping
+ _dbPingInterval = sConfigMgr->GetIntDefault("MaxPingTime", 30);
+ _dbPingTimer.expires_from_now(boost::posix_time::minutes(_dbPingInterval));
+ _dbPingTimer.async_wait(KeepDatabaseAliveHandler);
+
+ sComponentMgr->Load();
+ sModuleMgr->Load();
+
+ // Start the io service worker loop
+ _ioService.run();
+
+ sIpcContext->Close();
+
+ sRealmList->Close();
+
+ // Close the Database Pool and library
+ StopDB();
+
+ TC_LOG_INFO("server.bnetserver", "Halting process...");
+ return 0;
+}
+
+
+/// Initialize connection to the database
+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;
+ }
+
+ 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");
+ return false;
+ }
+
+ TC_LOG_INFO("server.bnetserver", "Started auth database connection pool.");
+ sLog->SetRealmId(0); // Enables DB appenders when realm is set.
+ return true;
+}
+
+/// Close the connection to the database
+void StopDB()
+{
+ LoginDatabase.Close();
+ MySQL::Library_End();
+}
+
+void SignalHandler(const boost::system::error_code& error, int /*signalNumber*/)
+{
+ if (!error)
+ _ioService.stop();
+}
+
+void KeepDatabaseAliveHandler(const boost::system::error_code& error)
+{
+ if (!error)
+ {
+ TC_LOG_INFO("server.bnetserver", "Ping MySQL to keep connection alive");
+ LoginDatabase.KeepAlive();
+
+ _dbPingTimer.expires_from_now(boost::posix_time::minutes(_dbPingInterval));
+ _dbPingTimer.async_wait(KeepDatabaseAliveHandler);
+ }
+}
+
+variables_map GetConsoleArguments(int argc, char** argv, std::string& configFile)
+{
+ options_description all("Allowed options");
+ all.add_options()
+ ("help,h", "print usage message")
+ ("config,c", value<std::string>(&configFile)->default_value(_TRINITY_BNET_CONFIG), "use <arg> as configuration file")
+ ;
+ variables_map variablesMap;
+ try
+ {
+ store(command_line_parser(argc, argv).options(all).allow_unregistered().run(), variablesMap);
+ notify(variablesMap);
+ }
+ catch (std::exception& e) {
+ std::cerr << e.what() << "\n";
+ }
+
+ if (variablesMap.count("help")) {
+ std::cout << all << "\n";
+ }
+
+ return variablesMap;
+}
diff --git a/src/server/bnetserver/Packets/AchievementPackets.h b/src/server/bnetserver/Packets/AchievementPackets.h
new file mode 100644
index 00000000000..99a0f19d0a2
--- /dev/null
+++ b/src/server/bnetserver/Packets/AchievementPackets.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2008-2014 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 AchievementPackets_h__
+#define AchievementPackets_h__
+
+#include "PacketsBase.h"
+
+namespace Battlenet
+{
+ namespace Achievement
+ {
+ enum Opcode
+ {
+ CMSG_LISTEN_REQUEST = 0x0, // Not implemented
+ CMSG_CRITERIA_FLUSH_REQUEST = 0x3, // Not implemented
+ CMSG_CHANGE_TROPHY_CASE_REQUEST = 0x5, // Not implemented
+
+ SMSG_DATA = 0x2, // Not implemented
+ SMSG_CRITERIA_FLUSH_RESPONSE = 0x3, // Not implemented
+ SMSG_ACHIEVEMENT_HANDLE_UPDATE = 0x4, // Not implemented
+ SMSG_CHANGE_TROPHY_CASE_RESULT = 0x6 // Not implemented
+ };
+ }
+}
+
+#endif // AchievementPackets_h__
+
diff --git a/src/server/authserver/Server/BattlenetPackets/AuthenticationPackets.cpp b/src/server/bnetserver/Packets/AuthenticationPackets.cpp
index 4d9c4476295..f6743a7c2f0 100644
--- a/src/server/authserver/Server/BattlenetPackets/AuthenticationPackets.cpp
+++ b/src/server/bnetserver/Packets/AuthenticationPackets.cpp
@@ -16,44 +16,9 @@
*/
#include "AuthenticationPackets.h"
+#include "Session.h"
#include "Util.h"
-void Battlenet::Authentication::LogonRequest3::Read()
-{
- Program = _stream.ReadFourCC();
- Platform = _stream.ReadFourCC();
- Locale = _stream.ReadFourCC();
-
- Components.resize(_stream.Read<uint32>(6));
- for (size_t i = 0; i < Components.size(); ++i)
- {
- Component& component = Components[i];
- component.Program = _stream.ReadFourCC();
- component.Platform = _stream.ReadFourCC();
- component.Build = _stream.Read<uint32>(32);
- }
-
- if (_stream.Read<uint32>(1))
- Login = _stream.ReadString(9, 3);
-
- Compatibility = _stream.Read<uint64>(64);
-}
-
-std::string Battlenet::Authentication::LogonRequest3::ToString() const
-{
- std::ostringstream stream;
- stream << "Battlenet::Authentication::LogonRequest3 Program: " << Program << ", Platform: " << Platform << ", Locale: " << Locale;
- for (Component const& component : Components)
- stream << std::endl << "Battlenet::Component Program: " << component.Program << ", Platform: " << component.Platform << ", Build: " << component.Build;
-
- if (!Login.empty())
- stream << std::endl << " Login: " << Login;
-
- stream << " Compatibility: " << Compatibility;
-
- return stream.str();
-}
-
void Battlenet::Authentication::ResumeRequest::Read()
{
Program = _stream.ReadFourCC();
@@ -81,13 +46,18 @@ std::string Battlenet::Authentication::ResumeRequest::ToString() const
for (Component const& component : Components)
stream << std::endl << "Battlenet::Component Program: " << component.Program << ", Platform: " << component.Platform << ", Build: " << component.Build;
- stream << std::endl << "Battlenet::Authentication::ResumeRequest Login: " << Login;
- stream << std::endl << "Battlenet::Authentication::ResumeRequest Region: " << uint32(Region);
- stream << std::endl << "Battlenet::Authentication::ResumeRequest GameAccountName: " << GameAccountName;
+ stream << std::endl << "Login: " << Login;
+ stream << std::endl << "Region: " << uint32(Region);
+ stream << std::endl << "GameAccountName: " << GameAccountName;
return stream.str();
}
+void Battlenet::Authentication::ResumeRequest::CallHandler(Session* session)
+{
+ session->HandleResumeRequest(*this);
+}
+
Battlenet::Authentication::ProofRequest::~ProofRequest()
{
for (size_t i = 0; i < Modules.size(); ++i)
@@ -147,6 +117,52 @@ std::string Battlenet::Authentication::ProofResponse::ToString() const
return stream.str();
}
+void Battlenet::Authentication::ProofResponse::CallHandler(Session* session)
+{
+ session->HandleProofResponse(*this);
+}
+
+void Battlenet::Authentication::LogonRequest3::Read()
+{
+ Program = _stream.ReadFourCC();
+ Platform = _stream.ReadFourCC();
+ Locale = _stream.ReadFourCC();
+
+ Components.resize(_stream.Read<uint32>(6));
+ for (size_t i = 0; i < Components.size(); ++i)
+ {
+ Component& component = Components[i];
+ component.Program = _stream.ReadFourCC();
+ component.Platform = _stream.ReadFourCC();
+ component.Build = _stream.Read<uint32>(32);
+ }
+
+ if (_stream.Read<uint32>(1))
+ Login = _stream.ReadString(9, 3);
+
+ Compatibility = _stream.Read<uint64>(64);
+}
+
+std::string Battlenet::Authentication::LogonRequest3::ToString() const
+{
+ std::ostringstream stream;
+ stream << "Battlenet::Authentication::LogonRequest3 Program: " << Program << ", Platform: " << Platform << ", Locale: " << Locale;
+ for (Component const& component : Components)
+ stream << std::endl << "Battlenet::Component Program: " << component.Program << ", Platform: " << component.Platform << ", Build: " << component.Build;
+
+ if (!Login.empty())
+ stream << std::endl << " Login: " << Login;
+
+ stream << " Compatibility: " << Compatibility;
+
+ return stream.str();
+}
+
+void Battlenet::Authentication::LogonRequest3::CallHandler(Session* session)
+{
+ session->HandleLogonRequest(*this);
+}
+
Battlenet::Authentication::LogonResponse::~LogonResponse()
{
for (ModuleInfo* m : Modules)
diff --git a/src/server/authserver/Server/BattlenetPackets/AuthenticationPackets.h b/src/server/bnetserver/Packets/AuthenticationPackets.h
index 44e3d7e18b8..bcaa0e72011 100644
--- a/src/server/authserver/Server/BattlenetPackets/AuthenticationPackets.h
+++ b/src/server/bnetserver/Packets/AuthenticationPackets.h
@@ -18,7 +18,9 @@
#ifndef AuthenticationPackets_h__
#define AuthenticationPackets_h__
-#include "BattlenetPacketsBase.h"
+#include "PacketsBase.h"
+#include "ComponentManager.h"
+#include "ModuleManager.h"
namespace Battlenet
{
@@ -41,25 +43,6 @@ namespace Battlenet
SMSG_GENERATE_SINGLE_SIGN_ON_TOKEN_REQUEST_2 = 0x8 // Not implemented
};
- class LogonRequest3 final : public ClientPacket
- {
- public:
- LogonRequest3(PacketHeader const& header, BitStream& stream) : ClientPacket(header, stream)
- {
- ASSERT(header == PacketHeader(CMSG_LOGON_REQUEST_3, AUTHENTICATION) && "Invalid packet header for LogonRequest3");
- }
-
- void Read() override;
- std::string ToString() const override;
-
- std::string Program;
- std::string Platform;
- std::string Locale;
- std::vector<Component> Components;
- std::string Login;
- uint64 Compatibility;
- };
-
class ResumeRequest final : public ClientPacket
{
public:
@@ -70,6 +53,7 @@ namespace Battlenet
void Read() override;
std::string ToString() const override;
+ void CallHandler(Session* session) override;
std::string Program;
std::string Platform;
@@ -92,20 +76,29 @@ namespace Battlenet
void Read() override;
std::string ToString() const override;
+ void CallHandler(Session* session) override;
std::vector<BitStream*> Modules;
};
- class ProofRequest final : public ServerPacket
+ class LogonRequest3 final : public ClientPacket
{
public:
- ProofRequest() : ServerPacket(PacketHeader(SMSG_PROOF_REQUEST, AUTHENTICATION)) { }
- ~ProofRequest();
+ LogonRequest3(PacketHeader const& header, BitStream& stream) : ClientPacket(header, stream)
+ {
+ ASSERT(header == PacketHeader(CMSG_LOGON_REQUEST_3, AUTHENTICATION) && "Invalid packet header for LogonRequest3");
+ }
- void Write() override;
+ void Read() override;
std::string ToString() const override;
+ void CallHandler(Session* session) override;
- std::vector<ModuleInfo*> Modules;
+ std::string Program;
+ std::string Platform;
+ std::string Locale;
+ std::vector<Component> Components;
+ std::string Login;
+ uint64 Compatibility;
};
class ResponseFailure
@@ -192,6 +185,18 @@ namespace Battlenet
int32 PingTimeout;
Regulator RegulatorRules;
};
+
+ class ProofRequest final : public ServerPacket
+ {
+ public:
+ ProofRequest() : ServerPacket(PacketHeader(SMSG_PROOF_REQUEST, AUTHENTICATION)) { }
+ ~ProofRequest();
+
+ void Write() override;
+ std::string ToString() const override;
+
+ std::vector<ModuleInfo*> Modules;
+ };
}
}
diff --git a/src/server/authserver/Server/BattlenetBitStream.cpp b/src/server/bnetserver/Packets/BitStream.cpp
index 712c9e58f08..5f002f6b1d9 100644
--- a/src/server/authserver/Server/BattlenetBitStream.cpp
+++ b/src/server/bnetserver/Packets/BitStream.cpp
@@ -15,7 +15,7 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "BattlenetBitStream.h"
+#include "BitStream.h"
template<>
bool Battlenet::BitStream::Read<bool>(uint32 /*bitCount*/)
diff --git a/src/server/authserver/Server/BattlenetBitStream.h b/src/server/bnetserver/Packets/BitStream.h
index 3601c3b0b0c..54c61ab3bbf 100644
--- a/src/server/authserver/Server/BattlenetBitStream.h
+++ b/src/server/bnetserver/Packets/BitStream.h
@@ -15,8 +15,8 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef __BATTLENETBITSTREAM_H__
-#define __BATTLENETBITSTREAM_H__
+#ifndef BitStream_h__
+#define BitStream_h__
#include "Common.h"
#include "ByteConverter.h"
@@ -212,14 +212,6 @@ namespace Battlenet
}
}
- void SetReadPos(uint32 bits)
- {
- if (bits > _writePos)
- throw BitStreamPositionException(true, bits, 0, _writePos);
-
- _readPos = bits;
- }
-
bool IsRead() const { return _readPos >= _writePos; }
uint8* GetBuffer() { return _buffer.data(); }
@@ -227,6 +219,10 @@ namespace Battlenet
size_t GetSize() const { return ((_writePos + 7) & ~7) / 8; }
+ // These methods are meant to only be used when their corresponding actions in the client ignore the value completely
+ void ReadSkip(uint32 bitCount) { _readPos += bitCount; }
+ void WriteSkip(uint32 bitCount) { Write(0, bitCount); }
+
private:
uint32 _writePos;
uint32 _readPos;
@@ -240,4 +236,4 @@ namespace Battlenet
void BitStream::Write<bool>(bool value, uint32 bitCount);
}
-#endif // __BATTLENETBITSTREAM_H__
+#endif // BitStream_h__
diff --git a/src/server/bnetserver/Packets/CachePackets.cpp b/src/server/bnetserver/Packets/CachePackets.cpp
new file mode 100644
index 00000000000..deacfd34065
--- /dev/null
+++ b/src/server/bnetserver/Packets/CachePackets.cpp
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2008-2014 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 "Session.h"
+#include "Util.h"
+#include "CachePackets.h"
+
+void Battlenet::Cache::GetStreamItemsRequest::Read()
+{
+ _stream.WriteSkip(31);
+ Index = _stream.Read<uint32>(32);
+ ReferenceTime = _stream.Read<int32>(32) - std::numeric_limits<int32>::min();
+ _stream.Read<bool>(1); // StreamDirection
+ _stream.Read<uint8>(6); // Module count, always 0
+ Locale = _stream.ReadFourCC();
+ if (_stream.Read<bool>(1))
+ {
+ ItemName = _stream.ReadFourCC();
+ Channel = _stream.ReadFourCC();
+ }
+ else
+ _stream.Read<uint16>(16);
+}
+
+std::string Battlenet::Cache::GetStreamItemsRequest::ToString() const
+{
+ std::ostringstream stream;
+ stream << "Battlenet::Cache::GetStreamItemsRequest Channel: " << Channel << ", ItemName: " << ItemName
+ << ", Locale: " << Locale << ", Index: " << Index;
+ return stream.str();
+}
+
+void Battlenet::Cache::GetStreamItemsRequest::CallHandler(Session* session)
+{
+ session->HandleGetStreamItemsRequest(*this);
+}
+
+Battlenet::Cache::GetStreamItemsResponse::~GetStreamItemsResponse()
+{
+ for (size_t i = 0; i < Modules.size(); ++i)
+ delete Modules[i];
+}
+
+void Battlenet::Cache::GetStreamItemsResponse::Write()
+{
+ _stream.Write(0, 16);
+ _stream.Write(1, 16);
+ _stream.Write(Index, 32);
+ _stream.Write(Modules.size(), 6);
+ for (ModuleInfo const* info : Modules)
+ {
+ _stream.WriteBytes(info->Type.c_str(), 4);
+ _stream.WriteFourCC(info->Region);
+ _stream.WriteBytes(info->ModuleId, 32);
+ _stream.WriteSkip(27);
+ _stream.WriteBytes(info->Data, 4);
+ }
+}
+
+std::string Battlenet::Cache::GetStreamItemsResponse::ToString() const
+{
+ std::ostringstream stream;
+ stream << "Battlenet::Cache::GetStreamItemsResponse modules " << Modules.size();
+ for (ModuleInfo const* module : Modules)
+ stream << std::endl << "Battlenet::ModuleInfo Locale " << module->Region.c_str() << ", ModuleId " << ByteArrayToHexStr(module->ModuleId, 32) << ", Data " << ByteArrayToHexStr(module->Data, module->DataSize);
+
+ return stream.str();
+}
diff --git a/src/server/bnetserver/Packets/CachePackets.h b/src/server/bnetserver/Packets/CachePackets.h
new file mode 100644
index 00000000000..a65ab2651c8
--- /dev/null
+++ b/src/server/bnetserver/Packets/CachePackets.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2008-2014 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 CachePackets_h__
+#define CachePackets_h__
+
+#include "ModuleManager.h"
+#include "PacketsBase.h"
+
+namespace Battlenet
+{
+ namespace Cache
+ {
+ enum Opcode
+ {
+ CMSG_GATEWAY_LOOKUP_REQUEST = 0x2, // Not implemented
+ CMSG_CONNECT_REQUEST = 0x4, // Not implemented
+ CMSG_DATA_CHUNK = 0x7, // Not implemented
+ CMSG_GET_STREAM_ITEMS_REQUEST = 0x9,
+
+ SMSG_GATEWAY_LOOKUP_RESPONSE = 0x3, // Not implemented
+ SMSG_CONNECT_RESPONSE = 0x4, // Not implemented
+ SMSG_PUBLISH_LIST_RESPONSE = 0x7, // Not implemented
+ SMSG_RESULT = 0x8, // Not implemented
+ SMSG_GET_STREAM_ITEMS_RESPONSE = 0x9
+ };
+
+ class GetStreamItemsRequest final : public ClientPacket
+ {
+ public:
+ GetStreamItemsRequest(PacketHeader const& header, BitStream& stream) : ClientPacket(header, stream)
+ {
+ ASSERT(header == PacketHeader(CMSG_GET_STREAM_ITEMS_REQUEST, CACHE) && "Invalid packet header for GetStreamItemsRequest");
+ }
+
+ void Read() override;
+ std::string ToString() const override;
+ void CallHandler(Session* session);
+
+ std::string Channel;
+ std::string ItemName;
+ std::string Locale;
+ uint32 Index;
+ int32 ReferenceTime;
+ };
+
+ class GetStreamItemsResponse final : public ServerPacket
+ {
+ public:
+ GetStreamItemsResponse() : ServerPacket(PacketHeader(SMSG_GET_STREAM_ITEMS_RESPONSE, CACHE))
+ {
+ }
+
+ ~GetStreamItemsResponse();
+
+ void Write() override;
+ std::string ToString() const override;
+
+ uint32 Index;
+ std::vector<ModuleInfo*> Modules;
+ };
+ }
+}
+
+#endif // CachePackets_h__
diff --git a/src/server/bnetserver/Packets/ChatPackets.h b/src/server/bnetserver/Packets/ChatPackets.h
new file mode 100644
index 00000000000..fc4b638754c
--- /dev/null
+++ b/src/server/bnetserver/Packets/ChatPackets.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2008-2014 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 ChatPackets_h__
+#define ChatPackets_h__
+
+#include "PacketsBase.h"
+
+namespace Battlenet
+{
+ namespace Chat
+ {
+ enum Opcode
+ {
+ CMSG_JOIN_REQUEST_2 = 0x00, // Not implemented
+ CMSG_LEAVE_REQUEST = 0x02, // Not implemented
+ CMSG_INVITE_REQUEST = 0x03, // Not implemented
+ CMSG_CREATE_AND_INVITE_REQUEST = 0x0A, // Not implemented
+ CMSG_MESSAGE_SEND = 0x0B, // Not implemented
+ CMSG_DATAGRAM_CONNECTION_UPDATE = 0x0D, // Not implemented
+ CMSG_REPORT_SPAM_REQUEST = 0x0E, // Not implemented
+ CMSG_WHISPER_SEND = 0x13, // Not implemented
+ CMSG_ENUM_CATEGORY_DESCRIPTIONS = 0x15, // Not implemented
+ CMSG_ENUM_CONFERENCE_DESCRIPTIONS = 0x17, // Not implemented
+ CMSG_ENUM_CONFERENCE_MEMBER_COUNTS = 0x19, // Not implemented
+ CMSG_MODIFY_CHANNEL_LIST_REQUEST = 0x1B, // Not implemented
+
+ SMSG_MEMBERSHIP_CHANGE_NOTIFY = 0x01, // Not implemented
+ SMSG_INVITE_NOTIFY = 0x04, // Not implemented
+ SMSG_INVITE_CANCELED = 0x07, // Not implemented
+ SMSG_MESSAGE_RECV = 0x0B, // Not implemented
+ SMSG_MESSAGE_UNDELIVERABLE = 0x0C, // Not implemented
+ SMSG_DATAGRAM_CONNECTION_UPDATE = 0x0D, // Not implemented
+ SMSG_INVITE_FAILURE = 0x0F, // Not implemented
+ SMSG_SYSTEM_MESSAGE = 0x10, // Not implemented
+ SMSG_MESSAGE_BLOCKED = 0x12, // Not implemented
+ SMSG_WHISPER_RECV = 0x13, // Not implemented
+ SMSG_WHISPER_UNDELIVERABLE = 0x14, // Not implemented
+ SMSG_CATEGORY_DESCRIPTIONS = 0x16, // Not implemented
+ SMSG_CONFERENCE_DESCRIPTIONS = 0x18, // Not implemented
+ SMSG_CONFERENCE_MEMBER_COUNTS = 0x1A, // Not implemented
+ SMSG_JOIN_NOTIFY_2 = 0x1B, // Not implemented
+ SMSG_MODIFY_CHANNEL_LIST_RESPONSE = 0x1C, // Not implemented
+ SMSG_CONFIG_CHANGED = 0x1D // Not implemented
+ };
+ }
+}
+
+#endif // ChatPackets_h__
diff --git a/src/server/bnetserver/Packets/ConnectionPackets.cpp b/src/server/bnetserver/Packets/ConnectionPackets.cpp
new file mode 100644
index 00000000000..3b7a9949552
--- /dev/null
+++ b/src/server/bnetserver/Packets/ConnectionPackets.cpp
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2008-2014 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 "Session.h"
+#include "ConnectionPackets.h"
+
+std::string Battlenet::Connection::Ping::ToString() const
+{
+ return "Battlenet::Connection::Ping";
+}
+
+void Battlenet::Connection::Ping::CallHandler(Session* session)
+{
+ session->HandlePing(*this);
+}
+
+std::string Battlenet::Connection::EnableEncryption::ToString() const
+{
+ return "Battlenet::Connection::EnableEncryption";
+}
+
+void Battlenet::Connection::EnableEncryption::CallHandler(Session* session)
+{
+ session->HandleEnableEncryption(*this);
+}
+
+std::string Battlenet::Connection::LogoutRequest::ToString() const
+{
+ return "Battlenet::Connection::LogoutRequest";
+}
+
+void Battlenet::Connection::LogoutRequest::CallHandler(Session* session)
+{
+ session->HandleLogoutRequest(*this);
+}
+
+void Battlenet::Connection::DisconnectRequest::Read()
+{
+ Timeout = _stream.Read<uint16>(16);
+ Tick = _stream.Read<uint32>(32);
+}
+
+std::string Battlenet::Connection::DisconnectRequest::ToString() const
+{
+ std::ostringstream str;
+ str << "Battlenet::Connection::DisconnectRequest Timeout: " << Timeout << ", Tick: " << Tick;
+ return str.str();
+}
+
+void Battlenet::Connection::ConnectionClosing::Read()
+{
+ Packets.resize(_stream.Read<uint8>(6));
+ for (size_t i = 0; i < Packets.size(); ++i)
+ {
+ PacketInfo& info = Packets[i];
+ info.CommandName = _stream.ReadFourCC();
+ info.Timestamp = _stream.Read<uint32>(32);
+ info.Size = _stream.Read<uint32>(16);
+ info.Channel = _stream.ReadFourCC();
+ info.LayerId = _stream.Read<uint32>(16);
+ }
+
+ Reason = _stream.Read<ClosingReason>(4);
+ _stream.ReadBytes(_stream.Read<uint8>(8)); // BadData
+
+ if (_stream.Read<bool>(1)) // HasHeader
+ {
+ Header.Opcode = _stream.Read<uint32>(6);
+ if (_stream.Read<bool>(1))
+ Header.Channel = _stream.Read<int32>(4);
+ }
+
+ Now = _stream.Read<time_t>(32);
+}
+
+std::string Battlenet::Connection::ConnectionClosing::ToString() const
+{
+ std::ostringstream stream;
+ stream << "Battlenet::Connection::ConnectionClosing Reason: " << Reason << ", Now: " << Now << ", Packet history size: " << Packets.size();
+ for (PacketInfo const& packet : Packets)
+ stream << std::endl << "Battlenet::Connection::ConnectionClosing::PacketInfo LayerId: " << packet.LayerId
+ << ", Channel: " << packet.Channel << ", CommandName: " << packet.CommandName << ", Size: " << packet.Size << ", Timestamp: " << packet.Timestamp;
+
+ return stream.str();
+}
+
+void Battlenet::Connection::ConnectionClosing::CallHandler(Session* session)
+{
+ session->HandleConnectionClosing(*this);
+}
+
+std::string Battlenet::Connection::Pong::ToString() const
+{
+ return "Battlenet::Connection::Pong";
+}
diff --git a/src/server/bnetserver/Packets/ConnectionPackets.h b/src/server/bnetserver/Packets/ConnectionPackets.h
new file mode 100644
index 00000000000..8572cd5d854
--- /dev/null
+++ b/src/server/bnetserver/Packets/ConnectionPackets.h
@@ -0,0 +1,153 @@
+/*
+ * Copyright (C) 2008-2014 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 ConnectionPackets_h__
+#define ConnectionPackets_h__
+
+#include "PacketsBase.h"
+
+namespace Battlenet
+{
+ namespace Connection
+ {
+ enum Opcode
+ {
+ CMSG_PING = 0x0,
+ CMSG_ENABLE_ENCRYPTION = 0x5,
+ CMSG_LOGOUT_REQUEST = 0x6,
+ CMSG_DISCONNECT_REQUEST = 0x7, // Not handled
+ CMSG_CONNECTION_CLOSING = 0x9,
+
+ SMSG_PONG = 0x0,
+ SMSG_BOOM = 0x1, // Not implemented
+ SMSG_REGULATOR_UPDATE = 0x2, // Not implemented
+ SMSG_SERVER_VERSION = 0x3, // Not implemented
+ SMSG_STUN_SERVERS = 0x4 // Not implemented
+ };
+
+ class Ping final : public ClientPacket
+ {
+ public:
+ Ping(PacketHeader const& header, BitStream& stream) : ClientPacket(header, stream)
+ {
+ ASSERT(header == PacketHeader(CMSG_PING, CONNECTION) && "Invalid packet header for Ping");
+ }
+
+ void Read() override { }
+ std::string ToString() const override;
+ void CallHandler(Session* session) override;
+ };
+
+ class EnableEncryption final : public ClientPacket
+ {
+ public:
+ EnableEncryption(PacketHeader const& header, BitStream& stream) : ClientPacket(header, stream)
+ {
+ ASSERT(header == PacketHeader(CMSG_ENABLE_ENCRYPTION, CONNECTION) && "Invalid packet header for EnableEncryption");
+ }
+
+ void Read() override { }
+ std::string ToString() const override;
+ void CallHandler(Session* session) override;
+ };
+
+ class LogoutRequest final : public ClientPacket
+ {
+ public:
+ LogoutRequest(PacketHeader const& header, BitStream& stream) : ClientPacket(header, stream)
+ {
+ ASSERT(header == PacketHeader(CMSG_LOGOUT_REQUEST, CONNECTION) && "Invalid packet header for LogoutRequest");
+ }
+
+ void Read() override { }
+ std::string ToString() const override;
+ void CallHandler(Session* session) override;
+ };
+
+ class DisconnectRequest final : public ClientPacket
+ {
+ public:
+ DisconnectRequest(PacketHeader const& header, BitStream& stream) : ClientPacket(header, stream)
+ {
+ ASSERT(header == PacketHeader(CMSG_DISCONNECT_REQUEST, CONNECTION) && "Invalid packet header for DisconnectRequest");
+ }
+
+ void Read() override;
+ std::string ToString() const override;
+
+ uint16 Timeout;
+ uint32 Tick;
+ };
+
+ class ConnectionClosing final : public ClientPacket
+ {
+ public:
+ enum ClosingReason
+ {
+ PACKET_TOO_LARGE,
+ PACKET_CORRUPT,
+ PACKET_INVALID,
+ PACKET_INCORRECT,
+ HEADER_CORRUPT,
+ HEADER_IGNORED,
+ HEADER_INCORRECT,
+ PACKET_REJECTED,
+ CHANNEL_UNHANDLED,
+ COMMAND_UNHANDLED,
+ COMMAND_BAD_PERMISSIONS,
+ DIRECT_CALL,
+ TIMEOUT,
+ };
+
+ struct PacketInfo
+ {
+ uint16 LayerId;
+ std::string Channel;
+ uint32 Timestamp;
+ std::string CommandName;
+ uint16 Size;
+ };
+
+ ConnectionClosing(PacketHeader const& header, BitStream& stream) : ClientPacket(header, stream)
+ {
+ ASSERT(header == PacketHeader(CMSG_CONNECTION_CLOSING, CONNECTION) && "Invalid packet header for ConnectionClosing");
+ }
+
+ void Read() override;
+ std::string ToString() const override;
+ void CallHandler(Session* session) override;
+
+ PacketHeader Header;
+ ClosingReason Reason;
+ std::vector<PacketInfo> Packets;
+ time_t Now;
+ };
+
+ class Pong final : public ServerPacket
+ {
+ public:
+ Pong() : ServerPacket(PacketHeader(SMSG_PONG, CONNECTION))
+ {
+ }
+
+ void Write() override { }
+ std::string ToString() const override;
+ };
+ }
+}
+
+#endif // ConnectionPackets_h__
diff --git a/src/server/bnetserver/Packets/FriendsPackets.cpp b/src/server/bnetserver/Packets/FriendsPackets.cpp
new file mode 100644
index 00000000000..2659ec6204f
--- /dev/null
+++ b/src/server/bnetserver/Packets/FriendsPackets.cpp
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 2008-2014 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 "Session.h"
+#include "FriendsPackets.h"
+
+void Battlenet::Friends::GetFriendsOfFriend::Read()
+{
+ uint8 unk = _stream.Read<uint8>(2);
+ uint32 unk1 = _stream.Read<uint32>(32);
+}
+
+std::string Battlenet::Friends::GetFriendsOfFriend::ToString() const
+{
+ return "Battlenet::Friends::GetFriendsOfFriend";
+}
+
+void Battlenet::Friends::SocialNetworkCheckConnected::Read()
+{
+ SocialNetworkId = _stream.Read<uint32>(32);
+}
+
+std::string Battlenet::Friends::SocialNetworkCheckConnected::ToString() const
+{
+ return "Battlenet::Friends::SocialNetworkCheckConnected SocialNetworkId " + std::to_string(SocialNetworkId);
+}
+
+void Battlenet::Friends::SocialNetworkCheckConnected::CallHandler(Session* session)
+{
+ session->HandleSocialNetworkCheckConnected(*this);
+}
+
+void Battlenet::Friends::RealIdFriendInvite::Read()
+{
+ _stream.Read<uint32>(32);
+ uint8 type = _stream.Read<uint8>(3);
+
+ switch (type)
+ {
+ case 0:
+ {
+ _stream.Read<uint32>(32); // Presence Id?
+ break;
+ }
+ case 1: // GameAccount?
+ {
+ _stream.Read<uint8>(8);
+ _stream.Read<uint32>(32);
+ _stream.Read<uint32>(32);
+ uint8 size = _stream.Read<uint8>(7); // Only if *(a1 + 16) <= 0x64
+ _stream.ReadBytes(size);
+ break;
+ }
+ case 2:
+ Email = _stream.ReadString(9, 3);
+ break;
+ case 3:
+ {
+ _stream.Read<uint32>(32);
+ break;
+ }
+ case 4:
+ {
+ _stream.Read<uint64>(64);
+ _stream.Read<uint32>(32);
+ break;
+ }
+ }
+
+ _stream.Read<uint8>(1);
+
+ if (_stream.Read<uint8>(1))
+ Message = _stream.ReadString(9);
+
+ _stream.Read<uint32>(32);
+}
+
+std::string Battlenet::Friends::RealIdFriendInvite::ToString() const
+{
+ return "Battlenet::Friends::RealIdFriendInvite Mail: " + Email + " Message: " + Message;
+}
+
+std::string Battlenet::Friends::FriendInviteResult::ToString() const
+{
+ return "Battlenet::Friends::RealIdFriendInviteResult";
+}
+
+void Battlenet::Friends::FriendInviteResult::Write()
+{
+ bool hasNames = false;
+ _stream.Write(hasNames, 1);
+ if (hasNames)
+ {
+ _stream.WriteString("Testing1", 8);
+ _stream.WriteString("Testing2", 8);
+ }
+ _stream.Write(5, 32);
+
+ _stream.Write(0, 0xC); // Ignored
+
+ _stream.Write(1, 16);
+
+ bool moreInfo = true;
+ _stream.Write(moreInfo, 1);
+ if (moreInfo)
+ {
+ _stream.Write(0, 8);
+ _stream.Write(4, 32);
+ _stream.Write(3, 32);
+ _stream.WriteString("Testing3", 7, 2);
+ }
+}
+
+std::string Battlenet::Friends::SocialNetworkCheckConnectedResult::ToString() const
+{
+ return "Battlenet::Friends::SocialNetworkCheckConnectedResult";
+}
+
+void Battlenet::Friends::SocialNetworkCheckConnectedResult::Write()
+{
+ _stream.WriteSkip(23);
+ _stream.Write(Result, 16);
+ _stream.Write(SocialNetworkId, 32);
+}
diff --git a/src/server/bnetserver/Packets/FriendsPackets.h b/src/server/bnetserver/Packets/FriendsPackets.h
new file mode 100644
index 00000000000..ea4d6d2ea92
--- /dev/null
+++ b/src/server/bnetserver/Packets/FriendsPackets.h
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 2008-2014 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 FriendsPackets_h__
+#define FriendsPackets_h__
+
+#include "PacketsBase.h"
+
+namespace Battlenet
+{
+ namespace Friends
+ {
+ enum Opcode
+ {
+ CMSG_FRIEND_INVITE = 0x01, // Not implemented
+ CMSG_FRIEND_INVITE_RESPONSE = 0x02, // Not implemented
+ CMSG_FRIEND_REMOVE = 0x04, // Not implemented
+ CMSG_FRIEND_NOTE = 0x05, // Not implemented
+ CMSG_TOONS_OF_FRIEND_REQUEST = 0x06, // Not implemented
+ CMSG_BLOCK_ADD = 0x08, // Not implemented
+ CMSG_BLOCK_REMOVE = 0x0A, // Not implemented
+ CMSG_GET_FRIENDS_OF_FRIEND = 0x0B, // Not implemented
+ CMSG_GET_SOCIAL_NETWORK_FRIENDS = 0x0D, // Won't support
+ CMSG_SOCIAL_NETWORK_CONNECT = 0x0F, // Won't support
+ CMSG_SOCIAL_NETWORK_DISCONNECT = 0x11, // Won't support
+ CMSG_SOCIAL_NETWORK_CHECK_CONNECTED = 0x13,
+ CMSG_REALID_FRIEND_INVITE = 0x16, // Not implemented
+
+ SMSG_FRIEND_INVITE_NOTIFY = 0x01, // Not implemented
+ SMSG_FRIEND_INVITE_RESULT = 0x03, // Not implemented
+ SMSG_TOONS_OF_FRIEND_NOTIFY = 0x06, // Not implemented
+ SMSG_BLOCK_INVITE_NOTIFY = 0x07, // Not implemented
+ SMSG_BLOCK_ADD_FAILURE = 0x09, // Not implemented
+ SMSG_FRIENDS_OF_FRIEND = 0x0C, // Not implemented
+ SMSG_SOCIAL_NETWORK_FRIENDS = 0x0E, // Won't support
+ SMSG_SOCIAL_NETWORK_CONNECT_RESULT = 0x10, // Won't support
+ SMSG_SOCIAL_NETWORK_DISCONNECT_RESULT = 0x12, // Won't support
+ SMSG_SOCIAL_NETWORK_CHECK_CONNECTED_RESULT = 0x14,
+ SMSG_MAX_FRIENDS_NOTIFY = 0x15, // Not implemented
+ SMSG_FRIENDS_LIST_NOTIFY_3 = 0x18 // Not implemented
+ };
+
+ class GetFriendsOfFriend final : public ClientPacket
+ {
+ public:
+ GetFriendsOfFriend(PacketHeader const& header, BitStream& stream) : ClientPacket(header, stream)
+ {
+ ASSERT(header == PacketHeader(CMSG_GET_FRIENDS_OF_FRIEND, FRIENDS) && "Invalid packet header for GetFriendsOfFriend");
+ }
+
+ void Read() override;
+ std::string ToString() const override;
+ };
+
+ class SocialNetworkCheckConnected final : public ClientPacket
+ {
+ public:
+ SocialNetworkCheckConnected(PacketHeader const& header, BitStream& stream) : ClientPacket(header, stream)
+ {
+ ASSERT(header == PacketHeader(CMSG_SOCIAL_NETWORK_CHECK_CONNECTED, FRIENDS) && "Invalid packet header for SocialNetworkCheckConnected");
+ }
+
+ void Read() override;
+ std::string ToString() const override;
+ void CallHandler(Session* session) override;
+
+ uint32 SocialNetworkId;
+ };
+
+ class RealIdFriendInvite final : public ClientPacket
+ {
+ public:
+ RealIdFriendInvite(PacketHeader const& header, BitStream& stream) : ClientPacket(header, stream)
+ {
+ ASSERT(header == PacketHeader(CMSG_REALID_FRIEND_INVITE, FRIENDS) && "Invalid packet header for RealIdFriendInvite");
+ }
+
+ void Read() override;
+ std::string ToString() const override;
+
+ std::string Email;
+ std::string Message;
+ };
+
+ class FriendInviteResult final : public ServerPacket
+ {
+ public:
+ FriendInviteResult() : ServerPacket(PacketHeader(SMSG_FRIEND_INVITE_RESULT, FRIENDS))
+ {
+ }
+
+ void Write() override;
+ std::string ToString() const override;
+ };
+
+ class FriendsOfFriend final : public ServerPacket
+ {
+ public:
+ FriendsOfFriend() : ServerPacket(PacketHeader(SMSG_FRIENDS_OF_FRIEND, FRIENDS))
+ {
+ }
+
+ void Write() override;
+ std::string ToString() const override;
+ };
+
+ class SocialNetworkCheckConnectedResult final : public ServerPacket
+ {
+ public:
+ SocialNetworkCheckConnectedResult() : ServerPacket(PacketHeader(SMSG_SOCIAL_NETWORK_CHECK_CONNECTED_RESULT, FRIENDS)),
+ Result(4601), SocialNetworkId(0) // 4601 = The Facebook add friend service is unavailable right now. Please try again later.
+ {
+ }
+
+ void Write() override;
+ std::string ToString() const override;
+
+ uint16 Result;
+ uint32 SocialNetworkId;
+ };
+ }
+}
+
+#endif // FriendsPackets_h__
diff --git a/src/server/bnetserver/Packets/PacketManager.cpp b/src/server/bnetserver/Packets/PacketManager.cpp
new file mode 100644
index 00000000000..cbfd0c8b2b6
--- /dev/null
+++ b/src/server/bnetserver/Packets/PacketManager.cpp
@@ -0,0 +1,243 @@
+/*
+ * Copyright (C) 2008-2014 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 "PacketManager.h"
+
+Battlenet::ClientPacket* Battlenet::PacketManager::CreateClientPacket(PacketHeader const& header, BitStream& stream)
+{
+ auto packetInfo = _clientPacketTable.find(header);
+ if (packetInfo == _clientPacketTable.end())
+ return nullptr;
+
+ if (!packetInfo->second.Constructor)
+ return nullptr;
+
+ ClientPacket* packet = packetInfo->second.Constructor(header, stream);
+ packet->Read();
+ return packet;
+}
+
+char const* Battlenet::PacketManager::GetClientPacketName(PacketHeader const& header)
+{
+ auto packetInfo = _clientPacketTable.find(header);
+ if (packetInfo == _clientPacketTable.end())
+ return nullptr;
+
+ return packetInfo->second.Name;
+}
+
+char const* Battlenet::PacketManager::GetServerPacketName(PacketHeader const& header)
+{
+ auto packetInfo = _serverPacketTable.find(header);
+ if (packetInfo == _serverPacketTable.end())
+ return nullptr;
+
+ return packetInfo->second.Name;
+}
+
+bool Battlenet::PacketManager::IsHandled(PacketHeader const& header)
+{
+ auto packetInfo = _clientPacketTable.find(header);
+ if (packetInfo == _clientPacketTable.end())
+ return false;
+
+ return packetInfo->second.HasHandler;
+}
+
+Battlenet::PacketManager::PacketManager()
+{
+ RegisterAuthenticationPackets();
+ RegisterConnectionPackets();
+ RegisterWoWRealmPackets();
+ RegisterFriendsPackets();
+ RegisterPresencePackets();
+ RegisterChatPackets();
+ RegisterSupportPackets();
+ RegisterCachePackets();
+ RegisterAchievementPackets();
+ RegisterProfilePackets();
+}
+
+#define REGISTER_CLIENT_PACKET(header, packetClass) RegisterClientPacket<packetClass>(header, #packetClass)
+#define REGISTER_SERVER_PACKET(header, packetClass) RegisterPacketName(_serverPacketTable, header, #packetClass)
+#define REGISTER_CLIENT_PACKET_NAME(header, name) RegisterPacketName(_clientPacketTable, header, name)
+#define REGISTER_SERVER_PACKET_NAME(header, name) RegisterPacketName(_serverPacketTable, header, name)
+
+void Battlenet::PacketManager::RegisterAuthenticationPackets()
+{
+ REGISTER_CLIENT_PACKET_NAME(PacketHeader(Authentication::CMSG_LOGON_REQUEST, AUTHENTICATION), "Authentication::LogonRequest3");
+ REGISTER_CLIENT_PACKET(PacketHeader(Authentication::CMSG_RESUME_REQUEST, AUTHENTICATION), Authentication::ResumeRequest);
+ REGISTER_CLIENT_PACKET(PacketHeader(Authentication::CMSG_PROOF_RESPONSE, AUTHENTICATION), Authentication::ProofResponse);
+ REGISTER_CLIENT_PACKET(PacketHeader(Authentication::CMSG_LOGON_REQUEST_3, AUTHENTICATION), Authentication::LogonRequest3);
+
+ REGISTER_SERVER_PACKET(PacketHeader(Authentication::SMSG_LOGON_RESPONSE, AUTHENTICATION), Authentication::LogonResponse);
+ REGISTER_SERVER_PACKET(PacketHeader(Authentication::SMSG_RESUME_RESPONSE, AUTHENTICATION), Authentication::ResumeResponse);
+ REGISTER_SERVER_PACKET(PacketHeader(Authentication::SMSG_PROOF_REQUEST, AUTHENTICATION), Authentication::ProofRequest);
+ REGISTER_SERVER_PACKET_NAME(PacketHeader(Authentication::SMSG_PATCH, AUTHENTICATION), "Authentication::Patch");
+ REGISTER_SERVER_PACKET_NAME(PacketHeader(Authentication::SMSG_AUTHORIZED_LICENSES, AUTHENTICATION), "Authentication::AuthorizedLicenses");
+}
+
+void Battlenet::PacketManager::RegisterConnectionPackets()
+{
+ REGISTER_CLIENT_PACKET(PacketHeader(Connection::CMSG_PING, CONNECTION), Connection::Ping);
+ REGISTER_CLIENT_PACKET(PacketHeader(Connection::CMSG_ENABLE_ENCRYPTION, CONNECTION), Connection::EnableEncryption);
+ REGISTER_CLIENT_PACKET(PacketHeader(Connection::CMSG_LOGOUT_REQUEST, CONNECTION), Connection::LogoutRequest);
+ REGISTER_CLIENT_PACKET(PacketHeader(Connection::CMSG_DISCONNECT_REQUEST, CONNECTION), Connection::DisconnectRequest);
+ REGISTER_CLIENT_PACKET(PacketHeader(Connection::CMSG_CONNECTION_CLOSING, CONNECTION), Connection::ConnectionClosing);
+
+ REGISTER_SERVER_PACKET(PacketHeader(Connection::SMSG_PONG, CONNECTION), Connection::Pong);
+ REGISTER_SERVER_PACKET_NAME(PacketHeader(Connection::SMSG_BOOM, CONNECTION), "Connection::Boom");
+ REGISTER_SERVER_PACKET_NAME(PacketHeader(Connection::SMSG_REGULATOR_UPDATE, CONNECTION), "Connection::RegulatorUpdate");
+ REGISTER_SERVER_PACKET_NAME(PacketHeader(Connection::SMSG_SERVER_VERSION, CONNECTION), "Connection::ServerVersion");
+ REGISTER_SERVER_PACKET_NAME(PacketHeader(Connection::SMSG_STUN_SERVERS, CONNECTION), "Connection::STUNServers");
+}
+
+void Battlenet::PacketManager::RegisterWoWRealmPackets()
+{
+ REGISTER_CLIENT_PACKET(PacketHeader(WoWRealm::CMSG_LIST_SUBSCRIBE_REQUEST, WOWREALM), WoWRealm::ListSubscribeRequest);
+ REGISTER_CLIENT_PACKET(PacketHeader(WoWRealm::CMSG_LIST_UNSUBSCRIBE, WOWREALM), WoWRealm::ListUnsubscribe);
+ REGISTER_CLIENT_PACKET(PacketHeader(WoWRealm::CMSG_JOIN_REQUEST_V2, WOWREALM), WoWRealm::JoinRequestV2);
+ REGISTER_CLIENT_PACKET_NAME(PacketHeader(WoWRealm::CMSG_MULTI_LOGON_REQUEST_V2, WOWREALM), "WoWRealm::MultiLogonRequestV2");
+
+ REGISTER_SERVER_PACKET(PacketHeader(WoWRealm::SMSG_LIST_SUBSCRIBE_RESPONSE, WOWREALM), WoWRealm::ListSubscribeResponse);
+ REGISTER_SERVER_PACKET(PacketHeader(WoWRealm::SMSG_LIST_UPDATE, WOWREALM), WoWRealm::ListUpdate);
+ REGISTER_SERVER_PACKET(PacketHeader(WoWRealm::SMSG_LIST_COMPLETE, WOWREALM), WoWRealm::ListComplete);
+ REGISTER_SERVER_PACKET(PacketHeader(WoWRealm::SMSG_TOON_READY, WOWREALM), WoWRealm::ToonReady);
+ REGISTER_SERVER_PACKET(PacketHeader(WoWRealm::SMSG_TOON_LOGGED_OUT, WOWREALM), WoWRealm::ToonLoggedOut);
+ REGISTER_SERVER_PACKET(PacketHeader(WoWRealm::SMSG_JOIN_RESPONSE_V2, WOWREALM), WoWRealm::JoinResponseV2);
+}
+
+void Battlenet::PacketManager::RegisterFriendsPackets()
+{
+ REGISTER_CLIENT_PACKET_NAME(PacketHeader(Friends::CMSG_FRIEND_INVITE, FRIENDS), "Friends::FriendInvite");
+ REGISTER_CLIENT_PACKET_NAME(PacketHeader(Friends::CMSG_FRIEND_INVITE_RESPONSE, FRIENDS), "Friends::FriendInviteResponse");
+ REGISTER_CLIENT_PACKET_NAME(PacketHeader(Friends::CMSG_FRIEND_REMOVE, FRIENDS), "Friends::FriendRemove");
+ REGISTER_CLIENT_PACKET_NAME(PacketHeader(Friends::CMSG_FRIEND_NOTE, FRIENDS), "Friends::FriendNote");
+ REGISTER_CLIENT_PACKET_NAME(PacketHeader(Friends::CMSG_TOONS_OF_FRIEND_REQUEST, FRIENDS), "Friends::ToonsOfFriendRequest");
+ REGISTER_CLIENT_PACKET_NAME(PacketHeader(Friends::CMSG_BLOCK_ADD, FRIENDS), "Friends::BlockAdd");
+ REGISTER_CLIENT_PACKET_NAME(PacketHeader(Friends::CMSG_BLOCK_REMOVE, FRIENDS), "Friends::BlockRemove");
+ REGISTER_CLIENT_PACKET_NAME(PacketHeader(Friends::CMSG_GET_FRIENDS_OF_FRIEND, FRIENDS), "Friends::GetFriendsOfFriend");
+ REGISTER_CLIENT_PACKET_NAME(PacketHeader(Friends::CMSG_GET_SOCIAL_NETWORK_FRIENDS, FRIENDS), "Friends::GetSocialNetworkFriends");
+ REGISTER_CLIENT_PACKET_NAME(PacketHeader(Friends::CMSG_SOCIAL_NETWORK_CONNECT, FRIENDS), "Friends::SocialNetworkConnect");
+ REGISTER_CLIENT_PACKET_NAME(PacketHeader(Friends::CMSG_SOCIAL_NETWORK_DISCONNECT, FRIENDS), "Friends::SocialNetworkDisconnect");
+ REGISTER_CLIENT_PACKET(PacketHeader(Friends::CMSG_SOCIAL_NETWORK_CHECK_CONNECTED, FRIENDS), Friends::SocialNetworkCheckConnected);
+ REGISTER_CLIENT_PACKET(PacketHeader(Friends::CMSG_GET_FRIENDS_OF_FRIEND, FRIENDS), Friends::GetFriendsOfFriend);
+ REGISTER_CLIENT_PACKET(PacketHeader(Friends::CMSG_REALID_FRIEND_INVITE, FRIENDS), Friends::RealIdFriendInvite);
+
+ REGISTER_SERVER_PACKET_NAME(PacketHeader(Friends::SMSG_FRIEND_INVITE_NOTIFY, FRIENDS), "Friends::FriendInviteNotify");
+ REGISTER_SERVER_PACKET(PacketHeader(Friends::SMSG_FRIEND_INVITE_RESULT, FRIENDS), Friends::FriendInviteResult);
+ REGISTER_SERVER_PACKET_NAME(PacketHeader(Friends::SMSG_TOONS_OF_FRIEND_NOTIFY, FRIENDS), "Friends::ToonsOfFriendNotify");
+ REGISTER_SERVER_PACKET_NAME(PacketHeader(Friends::SMSG_BLOCK_INVITE_NOTIFY, FRIENDS), "Friends::BlockInviteNotify");
+ REGISTER_SERVER_PACKET_NAME(PacketHeader(Friends::SMSG_BLOCK_ADD_FAILURE, FRIENDS), "Friends::BlockAddFailure");
+ REGISTER_SERVER_PACKET_NAME(PacketHeader(Friends::SMSG_FRIENDS_OF_FRIEND, FRIENDS), "Friends::FriendsOfFriend");
+ REGISTER_SERVER_PACKET_NAME(PacketHeader(Friends::SMSG_SOCIAL_NETWORK_FRIENDS, FRIENDS), "Friends::SocialNetworkFriends");
+ REGISTER_SERVER_PACKET_NAME(PacketHeader(Friends::SMSG_SOCIAL_NETWORK_CONNECT_RESULT, FRIENDS), "Friends::SocialNetworkConnectResult");
+ REGISTER_SERVER_PACKET_NAME(PacketHeader(Friends::SMSG_SOCIAL_NETWORK_DISCONNECT_RESULT, FRIENDS), "Friends::SocialNetworkDisconnectResult");
+ REGISTER_SERVER_PACKET(PacketHeader(Friends::SMSG_SOCIAL_NETWORK_CHECK_CONNECTED_RESULT, FRIENDS), Friends::SocialNetworkCheckConnectedResult);
+ REGISTER_SERVER_PACKET_NAME(PacketHeader(Friends::SMSG_MAX_FRIENDS_NOTIFY, FRIENDS), "Friends::MaxFriendsNotify");
+ REGISTER_SERVER_PACKET_NAME(PacketHeader(Friends::SMSG_FRIENDS_LIST_NOTIFY_3, FRIENDS), "Friends::FriendsListNotify3");
+}
+
+void Battlenet::PacketManager::RegisterPresencePackets()
+{
+ REGISTER_CLIENT_PACKET(PacketHeader(Presence::CMSG_UPDATE_REQUEST, PRESENCE), Presence::UpdateRequest);
+ REGISTER_CLIENT_PACKET(PacketHeader(Presence::CMSG_STATISTIC_SUBSCRIBE, PRESENCE), Presence::StatisticSubscribe);
+
+ REGISTER_SERVER_PACKET_NAME(PacketHeader(Presence::SMSG_UPDATE_NOTIFY, PRESENCE), "Presence::UpdateNotify");
+ REGISTER_SERVER_PACKET_NAME(PacketHeader(Presence::SMSG_FIELD_SPEC_ANNOUNCE, PRESENCE), "Presence::FieldSpecAnnounce");
+ REGISTER_SERVER_PACKET_NAME(PacketHeader(Presence::SMSG_STATISTICS_UPDATE, PRESENCE), "Presence::StatisticsUpdate");
+}
+
+void Battlenet::PacketManager::RegisterChatPackets()
+{
+ REGISTER_CLIENT_PACKET_NAME(PacketHeader(Chat::CMSG_JOIN_REQUEST_2, CHAT), "Chat::JoinRequest2");
+ REGISTER_CLIENT_PACKET_NAME(PacketHeader(Chat::CMSG_LEAVE_REQUEST, CHAT), "Chat::LeaveRequest");
+ REGISTER_CLIENT_PACKET_NAME(PacketHeader(Chat::CMSG_INVITE_REQUEST, CHAT), "Chat::InviteRequest");
+ REGISTER_CLIENT_PACKET_NAME(PacketHeader(Chat::CMSG_CREATE_AND_INVITE_REQUEST, CHAT), "Chat::CreateAndInviteRequest");
+ REGISTER_CLIENT_PACKET_NAME(PacketHeader(Chat::CMSG_MESSAGE_SEND, CHAT), "Chat::MessageSend");
+ REGISTER_CLIENT_PACKET_NAME(PacketHeader(Chat::CMSG_DATAGRAM_CONNECTION_UPDATE, CHAT), "Chat::DatagramConnectionUpdate");
+ REGISTER_CLIENT_PACKET_NAME(PacketHeader(Chat::CMSG_REPORT_SPAM_REQUEST, CHAT), "Chat::ReportSpamRequest");
+ REGISTER_CLIENT_PACKET_NAME(PacketHeader(Chat::CMSG_WHISPER_SEND, CHAT), "Chat::WhisperSend");
+ REGISTER_CLIENT_PACKET_NAME(PacketHeader(Chat::CMSG_ENUM_CATEGORY_DESCRIPTIONS, CHAT), "Chat::EnumCategoryDescriptions");
+ REGISTER_CLIENT_PACKET_NAME(PacketHeader(Chat::CMSG_ENUM_CONFERENCE_DESCRIPTIONS, CHAT), "Chat::EnumConferenceDescriptions");
+ REGISTER_CLIENT_PACKET_NAME(PacketHeader(Chat::CMSG_ENUM_CONFERENCE_MEMBER_COUNTS, CHAT), "Chat::EnumConferenceMemberCounts");
+ REGISTER_CLIENT_PACKET_NAME(PacketHeader(Chat::CMSG_MODIFY_CHANNEL_LIST_REQUEST, CHAT), "Chat::ModifyChannelListRequest");
+
+ REGISTER_SERVER_PACKET_NAME(PacketHeader(Chat::SMSG_MEMBERSHIP_CHANGE_NOTIFY, CHAT), "Chat::MembershipChangeNotify");
+ REGISTER_SERVER_PACKET_NAME(PacketHeader(Chat::SMSG_INVITE_NOTIFY, CHAT), "Chat::InviteNotify");
+ REGISTER_SERVER_PACKET_NAME(PacketHeader(Chat::SMSG_INVITE_CANCELED, CHAT), "Chat::InviteCanceled");
+ REGISTER_SERVER_PACKET_NAME(PacketHeader(Chat::SMSG_MESSAGE_RECV, CHAT), "Chat::MessageRecv");
+ REGISTER_SERVER_PACKET_NAME(PacketHeader(Chat::SMSG_MESSAGE_UNDELIVERABLE, CHAT), "Chat::MessageUndeliverable");
+ REGISTER_SERVER_PACKET_NAME(PacketHeader(Chat::SMSG_DATAGRAM_CONNECTION_UPDATE, CHAT), "Chat::DatagramConnectionUpdate");
+ REGISTER_SERVER_PACKET_NAME(PacketHeader(Chat::SMSG_INVITE_FAILURE, CHAT), "Chat::InviteFailed");
+ REGISTER_SERVER_PACKET_NAME(PacketHeader(Chat::SMSG_SYSTEM_MESSAGE, CHAT), "Chat::SystemMessage");
+ REGISTER_SERVER_PACKET_NAME(PacketHeader(Chat::SMSG_MESSAGE_BLOCKED, CHAT), "Chat::MessageBlocked");
+ REGISTER_SERVER_PACKET_NAME(PacketHeader(Chat::SMSG_WHISPER_RECV, CHAT), "Chat::WhisperRecv");
+ REGISTER_SERVER_PACKET_NAME(PacketHeader(Chat::SMSG_WHISPER_UNDELIVERABLE, CHAT), "Chat::WhisperUndeliverable");
+ REGISTER_SERVER_PACKET_NAME(PacketHeader(Chat::SMSG_CATEGORY_DESCRIPTIONS, CHAT), "Chat::CategoryDescriptions");
+ REGISTER_SERVER_PACKET_NAME(PacketHeader(Chat::SMSG_CONFERENCE_DESCRIPTIONS, CHAT), "Chat::ConferenceDescriptions");
+ REGISTER_SERVER_PACKET_NAME(PacketHeader(Chat::SMSG_CONFERENCE_MEMBER_COUNTS, CHAT), "Chat::ConferenceMemberCounts");
+ REGISTER_SERVER_PACKET_NAME(PacketHeader(Chat::SMSG_JOIN_NOTIFY_2, CHAT), "Chat::JoinNotify2");
+ REGISTER_SERVER_PACKET_NAME(PacketHeader(Chat::SMSG_MODIFY_CHANNEL_LIST_RESPONSE, CHAT), "Chat::ModifyChannelListResponse");
+ REGISTER_SERVER_PACKET_NAME(PacketHeader(Chat::SMSG_CONFIG_CHANGED, CHAT), "Chat::ConfigChanged");
+}
+
+void Battlenet::PacketManager::RegisterSupportPackets()
+{
+ REGISTER_CLIENT_PACKET_NAME(PacketHeader(Support::CMSG_COMPLAINT_REQUEST, SUPPORT), "Support::ComplaintRequest");
+}
+
+void Battlenet::PacketManager::RegisterAchievementPackets()
+{
+ REGISTER_CLIENT_PACKET_NAME(PacketHeader(Achievement::CMSG_LISTEN_REQUEST, ACHIEVEMENT), "Achievement::ListenRequest");
+ REGISTER_CLIENT_PACKET_NAME(PacketHeader(Achievement::CMSG_CRITERIA_FLUSH_REQUEST, ACHIEVEMENT), "Achievement::CriteriaFlushRequest");
+ REGISTER_CLIENT_PACKET_NAME(PacketHeader(Achievement::CMSG_CHANGE_TROPHY_CASE_REQUEST, ACHIEVEMENT), "Achievement::ChangeTrophyCaseRequest");
+
+ REGISTER_SERVER_PACKET_NAME(PacketHeader(Achievement::SMSG_DATA, ACHIEVEMENT), "Achievement::Data");
+ REGISTER_SERVER_PACKET_NAME(PacketHeader(Achievement::SMSG_CRITERIA_FLUSH_RESPONSE, ACHIEVEMENT), "Achievement::CriteriaFlushResponse");
+ REGISTER_SERVER_PACKET_NAME(PacketHeader(Achievement::SMSG_ACHIEVEMENT_HANDLE_UPDATE, ACHIEVEMENT), "Achievement::AchievementHandleUpdate");
+ REGISTER_SERVER_PACKET_NAME(PacketHeader(Achievement::SMSG_CHANGE_TROPHY_CASE_RESULT, ACHIEVEMENT), "Achievement::ChangeTrophyCaseResult");
+}
+
+void Battlenet::PacketManager::RegisterCachePackets()
+{
+ REGISTER_CLIENT_PACKET_NAME(PacketHeader(Cache::CMSG_GATEWAY_LOOKUP_REQUEST, CACHE), "Cache::GatewayLookupRequest");
+ REGISTER_CLIENT_PACKET_NAME(PacketHeader(Cache::CMSG_CONNECT_REQUEST, CACHE), "Cache::ConnectRequest");
+ REGISTER_CLIENT_PACKET_NAME(PacketHeader(Cache::CMSG_DATA_CHUNK, CACHE), "Cache::DataChunk");
+ REGISTER_CLIENT_PACKET(PacketHeader(Cache::CMSG_GET_STREAM_ITEMS_REQUEST, CACHE), Cache::GetStreamItemsRequest);
+
+ REGISTER_SERVER_PACKET_NAME(PacketHeader(Cache::SMSG_GATEWAY_LOOKUP_RESPONSE, CACHE), "Cache::GatewayLookupResponse");
+ REGISTER_SERVER_PACKET_NAME(PacketHeader(Cache::SMSG_CONNECT_RESPONSE, CACHE), "Cache::ConnectResponse");
+ REGISTER_SERVER_PACKET_NAME(PacketHeader(Cache::SMSG_PUBLISH_LIST_RESPONSE, CACHE), "Cache::PublishListResponse");
+ REGISTER_SERVER_PACKET_NAME(PacketHeader(Cache::SMSG_RESULT, CACHE), "Cache::Result");
+ REGISTER_SERVER_PACKET(PacketHeader(Cache::SMSG_GET_STREAM_ITEMS_RESPONSE, CACHE), Cache::GetStreamItemsResponse);
+}
+
+void Battlenet::PacketManager::RegisterProfilePackets()
+{
+ REGISTER_CLIENT_PACKET_NAME(PacketHeader(Profile::CMSG_READ_REQUEST, PROFILE), "Profile::ReadRequest");
+ REGISTER_CLIENT_PACKET_NAME(PacketHeader(Profile::CMSG_ADDRESS_QUERY_REQUEST, PROFILE), "Profile::AddressQueryRequest");
+ REGISTER_CLIENT_PACKET_NAME(PacketHeader(Profile::CMSG_RESOLVE_TOON_HANDLE_TO_NAME_REQUEST, PROFILE), "Profile::ResolveHandleToToonNameRequest");
+ REGISTER_CLIENT_PACKET_NAME(PacketHeader(Profile::CMSG_RESOLVE_TOON_NAME_TO_HANDLE_REQUEST, PROFILE), "Profile::ResolveToonNameToHandleRequest");
+ REGISTER_CLIENT_PACKET_NAME(PacketHeader(Profile::CMSG_CHANGE_SETTINGS, PROFILE), "Profile::ChangeSettings");
+
+ REGISTER_SERVER_PACKET_NAME(PacketHeader(Profile::SMSG_READ_RESPONSE, PROFILE), "Profile::ReadResponse");
+ REGISTER_SERVER_PACKET_NAME(PacketHeader(Profile::SMSG_ADDRESS_QUERY_RESPONSE, PROFILE), "Profile::AddressQueryResponse");
+ REGISTER_SERVER_PACKET_NAME(PacketHeader(Profile::SMSG_RESOLVE_TOON_HANDLE_TO_NAME_RESPONSE, PROFILE), "Profile::ResolveHandleToToonNameResponse");
+ REGISTER_SERVER_PACKET_NAME(PacketHeader(Profile::SMSG_RESOLVE_TOON_NAME_TO_HANDLE_RESPONSE, PROFILE), "Profile::ResolveToonNameToHandleResponse");
+ REGISTER_SERVER_PACKET_NAME(PacketHeader(Profile::SMSG_SETTINGS_AVAILABLE, PROFILE), "Profile::SettingsAvailable");
+}
diff --git a/src/server/bnetserver/Packets/PacketManager.h b/src/server/bnetserver/Packets/PacketManager.h
new file mode 100644
index 00000000000..1e64e6a502c
--- /dev/null
+++ b/src/server/bnetserver/Packets/PacketManager.h
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2008-2014 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 PacketManager_h__
+#define PacketManager_h__
+
+#include "Packets.h"
+#include <map>
+#include <type_traits>
+
+template<typename T>
+struct has_call_handler
+{
+ template<typename U, void(U::*)(Battlenet::Session*)> struct test_has_call_handler { };
+ template<typename U> static char Test(test_has_call_handler<U, &U::CallHandler>*);
+ template<typename U> static int Test(...);
+ static const bool value = sizeof(Test<T>(nullptr)) == sizeof(char);
+};
+
+namespace Battlenet
+{
+ class PacketManager
+ {
+ typedef ClientPacket*(*PacketCreateFn)(PacketHeader const& header, BitStream& stream);
+
+ struct PacketInfo
+ {
+ PacketCreateFn Constructor;
+ char const* Name;
+ bool HasHandler;
+ };
+
+ PacketManager();
+
+ void RegisterAuthenticationPackets();
+ void RegisterConnectionPackets();
+ void RegisterWoWRealmPackets();
+ void RegisterFriendsPackets();
+ void RegisterPresencePackets();
+ void RegisterChatPackets();
+ void RegisterSupportPackets();
+ void RegisterAchievementPackets();
+ void RegisterCachePackets();
+ void RegisterProfilePackets();
+
+ template<class PacketType>
+ static ClientPacket* New(PacketHeader const& header, BitStream& stream)
+ {
+ return new PacketType(header, stream);
+ }
+
+ void RegisterPacketName(std::map<PacketHeader, PacketInfo>& packetTable, PacketHeader const& header, char const* name)
+ {
+ PacketInfo& info = packetTable[header];
+ info.Constructor = nullptr;
+ info.Name = name;
+ info.HasHandler = false;
+ }
+
+ template<class PacketType>
+ void RegisterClientPacket(PacketHeader const& header, char const* name)
+ {
+ PacketInfo& info = _clientPacketTable[header];
+ info.Constructor = &New<PacketType>;
+ info.Name = name;
+ info.HasHandler = has_call_handler<PacketType>::value;
+ }
+
+ public:
+ ClientPacket* CreateClientPacket(PacketHeader const& header, BitStream& stream);
+
+ char const* GetClientPacketName(PacketHeader const& header);
+ char const* GetServerPacketName(PacketHeader const& header);
+
+ bool IsHandled(PacketHeader const& header);
+
+ static PacketManager& Instance()
+ {
+ static PacketManager instance;
+ return instance;
+ }
+
+ private:
+ std::map<PacketHeader, PacketInfo> _clientPacketTable;
+ std::map<PacketHeader, PacketInfo> _serverPacketTable;
+ };
+}
+
+#define sPacketManager Battlenet::PacketManager::Instance()
+
+#endif // PacketManager_h__
diff --git a/src/server/authserver/Server/BattlenetPackets/BattlenetPackets.h b/src/server/bnetserver/Packets/Packets.h
index 15c609b3ba4..f62ba6f65cd 100644
--- a/src/server/authserver/Server/BattlenetPackets/BattlenetPackets.h
+++ b/src/server/bnetserver/Packets/Packets.h
@@ -15,11 +15,18 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef BattlenetPackets_h__
-#define BattlenetPackets_h__
+#ifndef Packets_h__
+#define Packets_h__
#include "AuthenticationPackets.h"
#include "ConnectionPackets.h"
#include "WoWRealmPackets.h"
+#include "FriendsPackets.h"
+#include "PresencePackets.h"
+#include "ChatPackets.h"
+#include "SupportPackets.h"
+#include "AchievementPackets.h"
+#include "CachePackets.h"
+#include "ProfilePackets.h"
-#endif // BattlenetPackets_h__
+#endif // Packets_h__
diff --git a/src/server/authserver/Server/BattlenetPackets/BattlenetPacketsBase.cpp b/src/server/bnetserver/Packets/PacketsBase.cpp
index 034bb8ba0a4..fd3bebcf471 100644
--- a/src/server/authserver/Server/BattlenetPackets/BattlenetPacketsBase.cpp
+++ b/src/server/bnetserver/Packets/PacketsBase.cpp
@@ -15,7 +15,8 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "BattlenetPackets.h"
+#include "Packets.h"
+#include "Session.h"
#include <sstream>
std::string Battlenet::PacketHeader::ToString() const
@@ -36,3 +37,8 @@ Battlenet::ServerPacket::~ServerPacket()
{
delete &_stream;
}
+
+void Battlenet::ClientPacket::CallHandler(Session* session)
+{
+ session->LogUnhandledPacket(GetHeader());
+}
diff --git a/src/server/authserver/Server/BattlenetPackets/BattlenetPacketsBase.h b/src/server/bnetserver/Packets/PacketsBase.h
index af02eb91f43..0f86621d6a6 100644
--- a/src/server/authserver/Server/BattlenetPackets/BattlenetPacketsBase.h
+++ b/src/server/bnetserver/Packets/PacketsBase.h
@@ -15,12 +15,11 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef BattlenetPacketsBase_h__
-#define BattlenetPacketsBase_h__
+#ifndef PacketsBase_h__
+#define PacketsBase_h__
#include "AuthCodes.h"
-#include "BattlenetBitStream.h"
-#include "BattlenetManager.h"
+#include "BitStream.h"
#include "Define.h"
#include "Errors.h"
#include <string>
@@ -31,13 +30,14 @@ using boost::asio::ip::tcp;
namespace Battlenet
{
class BitStream;
+ class Session;
enum Channel
{
AUTHENTICATION = 0,
CONNECTION = 1,
WOWREALM = 2,
- FRIEND = 3,
+ FRIENDS = 3,
PRESENCE = 4,
CHAT = 5,
SUPPORT = 7,
@@ -99,7 +99,8 @@ namespace Battlenet
public:
ClientPacket(PacketHeader const& header, BitStream& stream) : Packet(header, stream) { }
- void Write() override final { ASSERT(!"Write not implemented for this packet."); }
+ void Write() override final { ASSERT(!"Write not implemented for client packets."); }
+ virtual void CallHandler(Session* session);
};
class ServerPacket : public Packet
@@ -116,4 +117,4 @@ namespace Battlenet
};
}
-#endif // BattlenetPacketsBase_h__
+#endif // PacketsBase_h__
diff --git a/src/server/bnetserver/Packets/PresencePackets.cpp b/src/server/bnetserver/Packets/PresencePackets.cpp
new file mode 100644
index 00000000000..b72bf8daca8
--- /dev/null
+++ b/src/server/bnetserver/Packets/PresencePackets.cpp
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2008-2014 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 "Session.h"
+#include "PresencePackets.h"
+
+void Battlenet::Presence::UpdateRequest::Read()
+{
+
+}
+
+std::string Battlenet::Presence::UpdateRequest::ToString() const
+{
+ return "Battlenet::Presence::UpdateRequest";
+}
+
+void Battlenet::Presence::StatisticSubscribe::Read()
+{
+}
+
+std::string Battlenet::Presence::StatisticSubscribe::ToString() const
+{
+ return "Battlenet::Presence::StatisticSubscribe";
+}
diff --git a/src/server/bnetserver/Packets/PresencePackets.h b/src/server/bnetserver/Packets/PresencePackets.h
new file mode 100644
index 00000000000..45b8f3e0e82
--- /dev/null
+++ b/src/server/bnetserver/Packets/PresencePackets.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2008-2014 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 PresencePackets_h__
+#define PresencePackets_h__
+
+#include "PacketsBase.h"
+
+namespace Battlenet
+{
+ namespace Presence
+ {
+ enum Opcode
+ {
+ CMSG_UPDATE_REQUEST = 0x0, // Not implemented
+ CMSG_STATISTIC_SUBSCRIBE = 0x2, // Not implemented
+
+ SMSG_UPDATE_NOTIFY = 0x0, // Not implemented
+ SMSG_FIELD_SPEC_ANNOUNCE = 0x1, // Not implemented
+ SMSG_STATISTICS_UPDATE = 0x3 // Not implemented
+ };
+
+ class UpdateRequest final : public ClientPacket
+ {
+ public:
+ UpdateRequest(PacketHeader const& header, BitStream& stream) : ClientPacket(header, stream)
+ {
+ ASSERT(header == PacketHeader(CMSG_UPDATE_REQUEST, PRESENCE) && "Invalid packet header for UpdateRequest");
+ }
+
+ void Read() override;
+ std::string ToString() const override;
+ };
+
+ class StatisticSubscribe final : public ClientPacket
+ {
+ public:
+ StatisticSubscribe(PacketHeader const& header, BitStream& stream) : ClientPacket(header, stream)
+ {
+ ASSERT(header == PacketHeader(CMSG_STATISTIC_SUBSCRIBE, PRESENCE) && "Invalid packet header for StatisticSubscribe");
+ }
+
+ void Read() override;
+ std::string ToString() const override;
+ };
+ }
+}
+
+#endif // PresencePackets_h__
diff --git a/src/server/bnetserver/Packets/ProfilePackets.h b/src/server/bnetserver/Packets/ProfilePackets.h
new file mode 100644
index 00000000000..bf413471f62
--- /dev/null
+++ b/src/server/bnetserver/Packets/ProfilePackets.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2008-2014 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 ProfilePackets_h__
+#define ProfilePackets_h__
+
+#include "PacketsBase.h"
+
+namespace Battlenet
+{
+ namespace Profile
+ {
+ enum Opcode
+ {
+ CMSG_READ_REQUEST = 0x0, // Not implemented
+ CMSG_ADDRESS_QUERY_REQUEST = 0x1, // Not implemented
+ CMSG_RESOLVE_TOON_HANDLE_TO_NAME_REQUEST = 0x2, // Not implemented
+ CMSG_RESOLVE_TOON_NAME_TO_HANDLE_REQUEST = 0x3, // Not implemented
+ CMSG_CHANGE_SETTINGS = 0x5, // Not implemented
+
+ SMSG_READ_RESPONSE = 0x0, // Not implemented
+ SMSG_ADDRESS_QUERY_RESPONSE = 0x1, // Not implemented
+ SMSG_RESOLVE_TOON_HANDLE_TO_NAME_RESPONSE = 0x2, // Not implemented
+ SMSG_RESOLVE_TOON_NAME_TO_HANDLE_RESPONSE = 0x3, // Not implemented
+ SMSG_SETTINGS_AVAILABLE = 0x4 // Not implemented
+ };
+ }
+}
+
+#endif // ProfilePackets_h__
diff --git a/src/server/authserver/Server/BattlenetPackets/ConnectionPackets.cpp b/src/server/bnetserver/Packets/SupportPackets.h
index 9f53961c6ab..43f51bd564e 100644
--- a/src/server/authserver/Server/BattlenetPackets/ConnectionPackets.cpp
+++ b/src/server/bnetserver/Packets/SupportPackets.h
@@ -15,9 +15,20 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "ConnectionPackets.h"
+#ifndef SupportPackets_h__
+#define SupportPackets_h__
-std::string Battlenet::Connection::Pong::ToString() const
+#include "PacketsBase.h"
+
+namespace Battlenet
{
- return "Battlenet::Connection::Pong";
+ namespace Support
+ {
+ enum Opcode
+ {
+ CMSG_COMPLAINT_REQUEST = 0x0 // Not implemented
+ };
+ }
}
+
+#endif // SupportPackets_h__
diff --git a/src/server/authserver/Server/BattlenetPackets/WoWRealmPackets.cpp b/src/server/bnetserver/Packets/WoWRealmPackets.cpp
index 76577670a50..714c43b8eb4 100644
--- a/src/server/authserver/Server/BattlenetPackets/WoWRealmPackets.cpp
+++ b/src/server/bnetserver/Packets/WoWRealmPackets.cpp
@@ -16,9 +16,50 @@
*/
#include "WoWRealmPackets.h"
+#include "Session.h"
#include <boost/lexical_cast.hpp>
#include <boost/asio/ip/address.hpp>
+std::string Battlenet::WoWRealm::ListSubscribeRequest::ToString() const
+{
+ return "Battlenet::WoWRealm::ListSubscribeRequest";
+}
+
+void Battlenet::WoWRealm::ListSubscribeRequest::CallHandler(Session* session)
+{
+ session->HandleListSubscribeRequest(*this);
+}
+
+std::string Battlenet::WoWRealm::ListUnsubscribe::ToString() const
+{
+ return "Battlenet::WoWRealm::ListUnsubscribe";
+}
+
+void Battlenet::WoWRealm::ListUnsubscribe::CallHandler(Session* session)
+{
+ session->HandleListUnsubscribe(*this);
+}
+
+void Battlenet::WoWRealm::JoinRequestV2::Read()
+{
+ Realm.Battlegroup = _stream.Read<uint8>(8);
+ Realm.Index = _stream.Read<uint32>(32);
+ Realm.Region = _stream.Read<uint8>(8);
+ ClientSeed = _stream.Read<uint32>(32);
+}
+
+std::string Battlenet::WoWRealm::JoinRequestV2::ToString() const
+{
+ std::ostringstream stream;
+ stream << "Battlenet::WoWRealm::JoinRequestV2 ClientSeed " << ClientSeed << " Region " << uint32(Realm.Region) << " Battlegroup " << uint32(Realm.Battlegroup) << " Index " << Realm.Index;
+ return stream.str().c_str();
+}
+
+void Battlenet::WoWRealm::JoinRequestV2::CallHandler(Session* session)
+{
+ session->HandleJoinRequestV2(*this);
+}
+
Battlenet::WoWRealm::ListSubscribeResponse::~ListSubscribeResponse()
{
for (ServerPacket* realmData : RealmData)
@@ -86,7 +127,7 @@ void Battlenet::WoWRealm::ListUpdate::Write()
if (!Version.empty())
{
_stream.WriteString(Version, 5);
- _stream.Write(Build, 32);
+ _stream.Write(Id.Build, 32);
boost::asio::ip::address_v4::bytes_type ip = Address.address().to_v4().to_bytes();
uint16 port = Address.port();
@@ -101,38 +142,53 @@ void Battlenet::WoWRealm::ListUpdate::Write()
_stream.Write(Flags, 8);
}
- _stream.Write(Region, 8);
+ _stream.Write(Id.Region, 8);
_stream.Write(0, 12);
- _stream.Write(Battlegroup, 8);
- _stream.Write(Index, 32);
+ _stream.Write(Id.Battlegroup, 8);
+ _stream.Write(Id.Index, 32);
}
std::string Battlenet::WoWRealm::ListUpdate::ToString() const
{
std::ostringstream stream;
- stream << "Battlenet::WoWRealm::ListUpdate Timezone " << Timezone << " Population " << Population << " Lock " << uint32(Lock) << " Type " << Type << " Name " << Name
- << " Flags " << uint32(Flags) << " Region " << uint32(Region) << " Battlegroup " << uint32(Battlegroup) << " Index " << Index;
+ stream << "Battlenet::WoWRealm::ListUpdate";
+ if (UpdateState == UPDATE)
+ {
+ stream << " Timezone: " << Timezone << " Population: " << Population << " Lock: " << uint32(Lock) << " Type: " << Type << " Name: " << Name
+ << " Flags: " << uint32(Flags) << " Region: " << uint32(Id.Region) << " Battlegroup: " << uint32(Id.Battlegroup) << " Index: " << Id.Index;
- if (!Version.empty())
- stream << " Version " << Version;
+ if (!Version.empty())
+ stream << " Version: " << Version;
+ }
+ else
+ stream << " Delete realm [Region: " << uint32(Id.Region) << " Battlegroup : " << uint32(Id.Battlegroup) << " Index : " << Id.Index << "]";
return stream.str().c_str();
}
-void Battlenet::WoWRealm::JoinRequestV2::Read()
+void Battlenet::WoWRealm::ToonReady::Write()
{
- ClientSeed = _stream.Read<uint32>(32);
- _stream.Read<uint32>(20);
- Realm.Region = _stream.Read<uint8>(8);
- _stream.Read<uint32>(12);
- Realm.Battlegroup = _stream.Read<uint8>(8);
- Realm.Index = _stream.Read<uint32>(32);
+ _stream.Write(Realm.Region, 8);
+ _stream.WriteFourCC(Game);
+ uint32 realmAddress = ((Realm.Battlegroup << 16) & 0xFF0000) | uint16(Realm.Index);
+ _stream.Write(realmAddress, 32);
+ _stream.WriteString(Name, 7, -2);
+ _stream.WriteSkip(21);
+ _stream.Write(0, 64); // Unknown
+ _stream.Write(0, 32); // Unknown
+ _stream.Write(Guid, 64);
+ _stream.Write(realmAddress, 32);
+ _stream.Write(Realm.Region, 8);
+ _stream.WriteFourCC(Game);
}
-std::string Battlenet::WoWRealm::JoinRequestV2::ToString() const
+std::string Battlenet::WoWRealm::ToonReady::ToString() const
{
std::ostringstream stream;
- stream << "Battlenet::WoWRealm::JoinRequestV2 ClientSeed " << ClientSeed << " Region " << uint32(Realm.Region) << " Battlegroup " << uint32(Realm.Battlegroup) << " Index " << Realm.Index;
+ stream << "Battlenet::WoWRealm::ToonReady" << " Game: " << Game
+ << ", Region: " << uint32(Realm.Region) << ", Battlegroup: " << uint32(Realm.Battlegroup) << ", Index: " << Realm.Index
+ << ", Guid: " << Guid << ", Name: " << Name;
+
return stream.str().c_str();
}
diff --git a/src/server/authserver/Server/BattlenetPackets/WoWRealmPackets.h b/src/server/bnetserver/Packets/WoWRealmPackets.h
index 881ddd3186a..b411c63100a 100644
--- a/src/server/authserver/Server/BattlenetPackets/WoWRealmPackets.h
+++ b/src/server/bnetserver/Packets/WoWRealmPackets.h
@@ -18,7 +18,8 @@
#ifndef WoWRealmPackets_h__
#define WoWRealmPackets_h__
-#include "BattlenetPacketsBase.h"
+#include "PacketsBase.h"
+#include "RealmList.h"
namespace Battlenet
{
@@ -27,7 +28,7 @@ namespace Battlenet
enum Opcode
{
CMSG_LIST_SUBSCRIBE_REQUEST = 0x0,
- CMSG_LIST_UNSUBSCRIBE = 0x1, // Not implemented
+ CMSG_LIST_UNSUBSCRIBE = 0x1,
CMSG_JOIN_REQUEST_V2 = 0x8,
CMSG_MULTI_LOGON_REQUEST_V2 = 0x9, // Not implemented
@@ -39,6 +40,32 @@ namespace Battlenet
SMSG_JOIN_RESPONSE_V2 = 0x8
};
+ class ListSubscribeRequest final : public ClientPacket
+ {
+ public:
+ ListSubscribeRequest(PacketHeader const& header, BitStream& stream) : ClientPacket(header, stream)
+ {
+ ASSERT(header == PacketHeader(CMSG_LIST_SUBSCRIBE_REQUEST, WOWREALM) && "Invalid packet header for ListSubscribeRequest");
+ }
+
+ void Read() override { }
+ std::string ToString() const override;
+ void CallHandler(Session* session) override;
+ };
+
+ class ListUnsubscribe final : public ClientPacket
+ {
+ public:
+ ListUnsubscribe(PacketHeader const& header, BitStream& stream) : ClientPacket(header, stream)
+ {
+ ASSERT(header == PacketHeader(CMSG_LIST_UNSUBSCRIBE, WOWREALM) && "Invalid packet header for ListUnsubscribe");
+ }
+
+ void Read() override { }
+ std::string ToString() const override;
+ void CallHandler(Session* session) override;
+ };
+
class JoinRequestV2 final : public ClientPacket
{
public:
@@ -49,6 +76,7 @@ namespace Battlenet
void Read() override;
std::string ToString() const override;
+ void CallHandler(Session* session) override;
uint32 ClientSeed;
RealmId Realm;
@@ -95,8 +123,7 @@ namespace Battlenet
};
ListUpdate() : ServerPacket(PacketHeader(SMSG_LIST_UPDATE, WOWREALM)), UpdateState(UPDATE),
- Timezone(0), Population(0.0f), Lock(0), Type(0), Name(""), Version(""),
- Flags(0), Region(0), Battlegroup(0), Index(0), Build(0)
+ Timezone(0), Population(0.0f), Lock(0), Type(0), Name(""), Version(""), Flags(0)
{
}
@@ -112,10 +139,7 @@ namespace Battlenet
std::string Version;
tcp::endpoint Address;
uint8 Flags;
- uint8 Region;
- uint8 Battlegroup;
- uint32 Index;
- uint32 Build;
+ RealmId Id;
};
class ListComplete final : public ServerPacket
@@ -129,6 +153,33 @@ namespace Battlenet
std::string ToString() const override { return "Battlenet::WoWRealm::ListComplete"; }
};
+ class ToonReady final : public ServerPacket
+ {
+ public:
+ ToonReady() : ServerPacket(PacketHeader(SMSG_TOON_READY, WOWREALM)), Game("WoW"), Guid(0)
+ {
+ }
+
+ void Write() override;
+ std::string ToString() const override;
+
+ std::string Game;
+ RealmId Realm;
+ uint64 Guid;
+ std::string Name;
+ };
+
+ class ToonLoggedOut final : public ServerPacket
+ {
+ public:
+ ToonLoggedOut() : ServerPacket(PacketHeader(SMSG_TOON_LOGGED_OUT, WOWREALM))
+ {
+ }
+
+ void Write() override { }
+ std::string ToString() const override { return "Battlenet::WoWRealm::ToonLoggedOut"; }
+ };
+
class JoinResponseV2 final : public ServerPacket
{
public:
@@ -139,7 +190,7 @@ namespace Battlenet
};
JoinResponseV2() : ServerPacket(PacketHeader(SMSG_JOIN_RESPONSE_V2, WOWREALM)),
- ServerSeed(0), Response(SUCCESS), ResponseCode(26)
+ Response(SUCCESS), ResponseCode(26), ServerSeed(0)
{
}
diff --git a/src/server/bnetserver/PrecompiledHeaders/bnetPCH.cpp b/src/server/bnetserver/PrecompiledHeaders/bnetPCH.cpp
new file mode 100644
index 00000000000..60b1d41a1a8
--- /dev/null
+++ b/src/server/bnetserver/PrecompiledHeaders/bnetPCH.cpp
@@ -0,0 +1 @@
+#include "bnetPCH.h"
diff --git a/src/server/bnetserver/PrecompiledHeaders/bnetPCH.h b/src/server/bnetserver/PrecompiledHeaders/bnetPCH.h
new file mode 100644
index 00000000000..82cd5393489
--- /dev/null
+++ b/src/server/bnetserver/PrecompiledHeaders/bnetPCH.h
@@ -0,0 +1,10 @@
+#include "Common.h"
+#include "Configuration/Config.h"
+#include "Database/DatabaseEnv.h"
+#include "Log.h"
+#include "ComponentManager.h"
+#include "ModuleManager.h"
+#include "RealmList.h"
+#include "ByteBuffer.h"
+#include "Packets.h"
+#include "Session.h"
diff --git a/src/server/bnetserver/Realms/RealmList.cpp b/src/server/bnetserver/Realms/RealmList.cpp
new file mode 100644
index 00000000000..cc7e1d492a8
--- /dev/null
+++ b/src/server/bnetserver/Realms/RealmList.cpp
@@ -0,0 +1,252 @@
+/*
+ * Copyright (C) 2008-2014 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/>.
+ */
+
+#include "Common.h"
+#include "Database/DatabaseEnv.h"
+#include "SessionManager.h"
+#include "Util.h"
+#include "Commands.h"
+#include "RealmList.h"
+#include <boost/asio/ip/tcp.hpp>
+
+Battlenet::RealmId& Battlenet::RealmId::operator=(Battlenet::RealmHandle const& handle)
+{
+ Region = handle.Region;
+ Battlegroup = handle.Battlegroup;
+ Index = handle.Index;
+ return *this;
+}
+
+ip::tcp::endpoint Realm::GetAddressForClient(ip::address const& clientAddr) const
+{
+ ip::address realmIp;
+
+ // Attempt to send best address for client
+ if (clientAddr.is_loopback())
+ {
+ // Try guessing if realm is also connected locally
+ if (LocalAddress.is_loopback() || ExternalAddress.is_loopback())
+ realmIp = clientAddr;
+ else
+ {
+ // Assume that user connecting from the machine that bnetserver is located on
+ // has all realms available in his local network
+ realmIp = LocalAddress;
+ }
+ }
+ else
+ {
+ if (clientAddr.is_v4() &&
+ (clientAddr.to_v4().to_ulong() & LocalSubnetMask.to_v4().to_ulong()) ==
+ (LocalAddress.to_v4().to_ulong() & LocalSubnetMask.to_v4().to_ulong()))
+ {
+ realmIp = LocalAddress;
+ }
+ else
+ realmIp = ExternalAddress;
+ }
+
+ ip::tcp::endpoint endpoint(realmIp, Port);
+
+ // Return external IP
+ return endpoint;
+}
+
+RealmList::RealmList() : _updateInterval(0), _updateTimer(nullptr), _resolver(nullptr), _worldListener(nullptr)
+{
+}
+
+RealmList::~RealmList()
+{
+ delete _updateTimer;
+ delete _resolver;
+ delete _worldListener;
+}
+
+// Load the realm list from the database
+void RealmList::Initialize(boost::asio::io_service& ioService, uint32 updateInterval, uint16 worldListenPort)
+{
+ _updateInterval = updateInterval;
+ _updateTimer = new boost::asio::deadline_timer(ioService);
+ _resolver = new boost::asio::ip::tcp::resolver(ioService);
+
+ // Get the content of the realmlist table in the database
+ UpdateRealms(boost::system::error_code());
+
+ _worldListener = new WorldListener(worldListenPort);
+ _worldListener->Start();
+}
+
+void RealmList::Close()
+{
+ _worldListener->End();
+}
+
+template<typename FieldType>
+inline void UpdateField(FieldType& out, FieldType const& in, bool& changed)
+{
+ if (out != in)
+ {
+ out = in;
+ changed = true;
+ }
+}
+
+void RealmList::UpdateRealm(Battlenet::RealmId const& id, const std::string& name, ip::address const& address, ip::address const& localAddr,
+ ip::address const& localSubmask, uint16 port, uint8 icon, RealmFlags flag, uint8 timezone, AccountTypes allowedSecurityLevel,
+ float population)
+{
+ // Create new if not exist or update existed
+ Realm& realm = _realms[id];
+
+ realm.Keep = true;
+
+ realm.Id = id;
+ UpdateField(realm.Name, name, realm.Updated);
+ UpdateField(realm.Type, icon, realm.Updated);
+ UpdateField(realm.Flags, flag, realm.Updated);
+ UpdateField(realm.Timezone, timezone, realm.Updated);
+ UpdateField(realm.AllowedSecurityLevel, allowedSecurityLevel, realm.Updated);
+ UpdateField(realm.PopulationLevel, population, realm.Updated);
+ UpdateField(realm.ExternalAddress, address, realm.Updated);
+ UpdateField(realm.LocalAddress, localAddr, realm.Updated);
+ UpdateField(realm.LocalSubnetMask, localSubmask, realm.Updated);
+ UpdateField(realm.Port, port, realm.Updated);
+}
+
+void RealmList::UpdateRealms(boost::system::error_code const& error)
+{
+ if (error)
+ return;
+
+ TC_LOG_DEBUG("realmlist", "Updating Realm List...");
+
+ PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_REALMLIST);
+ PreparedQueryResult result = LoginDatabase.Query(stmt);
+
+ // Circle through results and add them to the realm map
+ if (result)
+ {
+ do
+ {
+ try
+ {
+ boost::asio::ip::tcp::resolver::iterator end;
+
+ Field* fields = result->Fetch();
+ std::string name = fields[1].GetString();
+ boost::asio::ip::tcp::resolver::query externalAddressQuery(ip::tcp::v4(), fields[2].GetString(), "");
+
+ boost::system::error_code ec;
+ boost::asio::ip::tcp::resolver::iterator endPoint = _resolver->resolve(externalAddressQuery, ec);
+ if (endPoint == end || ec)
+ {
+ TC_LOG_ERROR("realmlist", "Could not resolve address %s", fields[2].GetString().c_str());
+ continue;
+ }
+
+ ip::address externalAddress = (*endPoint).endpoint().address();
+
+ boost::asio::ip::tcp::resolver::query localAddressQuery(ip::tcp::v4(), fields[3].GetString(), "");
+ endPoint = _resolver->resolve(localAddressQuery, ec);
+ if (endPoint == end || ec)
+ {
+ TC_LOG_ERROR("realmlist", "Could not resolve address %s", fields[3].GetString().c_str());
+ continue;
+ }
+
+ ip::address localAddress = (*endPoint).endpoint().address();
+
+ boost::asio::ip::tcp::resolver::query localSubmaskQuery(ip::tcp::v4(), fields[4].GetString(), "");
+ endPoint = _resolver->resolve(localSubmaskQuery, ec);
+ if (endPoint == end || ec)
+ {
+ TC_LOG_ERROR("realmlist", "Could not resolve address %s", fields[4].GetString().c_str());
+ continue;
+ }
+
+ ip::address localSubmask = (*endPoint).endpoint().address();
+
+ uint16 port = fields[5].GetUInt16();
+ uint8 icon = fields[6].GetUInt8();
+ RealmFlags flag = RealmFlags(fields[7].GetUInt8());
+ uint8 timezone = fields[8].GetUInt8();
+ uint8 allowedSecurityLevel = fields[9].GetUInt8();
+ float pop = fields[10].GetFloat();
+ uint32 realmId = fields[0].GetUInt32();
+ uint32 build = fields[11].GetUInt32();
+ uint8 region = fields[12].GetUInt8();
+ uint8 battlegroup = fields[13].GetUInt8();
+
+ Battlenet::RealmId id{ region, battlegroup, realmId, build };
+
+ UpdateRealm(id, name, externalAddress, localAddress, localSubmask, port, icon, flag, timezone,
+ (allowedSecurityLevel <= SEC_ADMINISTRATOR ? AccountTypes(allowedSecurityLevel) : SEC_ADMINISTRATOR), pop);
+
+ TC_LOG_TRACE("realmlist", "Realm \"%s\" at %s:%u.", name.c_str(), externalAddress.to_string().c_str(), port);
+ }
+ catch (std::exception& ex)
+ {
+ TC_LOG_ERROR("realmlist", "Realmlist::UpdateRealms has thrown an exception: %s", ex.what());
+ ASSERT(false);
+ }
+ }
+ while (result->NextRow());
+ }
+
+ std::vector<Realm const*> updatedRealms;
+ std::vector<Battlenet::RealmId> deletedRealms;
+
+ for (RealmMap::value_type& pair : _realms)
+ {
+ if (pair.second.Updated)
+ updatedRealms.push_back(&pair.second);
+ else if (!pair.second.Keep)
+ deletedRealms.push_back(pair.first);
+
+ pair.second.Updated = false;
+ pair.second.Keep = false;
+ }
+
+ for (Battlenet::RealmId const& deleted : deletedRealms)
+ _realms.erase(deleted);
+
+ if (!updatedRealms.empty() || !deletedRealms.empty())
+ {
+ sSessionMgr.LockedForEach([&updatedRealms, &deletedRealms](Battlenet::Session* session)
+ {
+ if (session->IsSubscribedToRealmListUpdates())
+ session->UpdateRealms(updatedRealms, deletedRealms);
+ });
+ }
+
+ if (_updateInterval)
+ {
+ _updateTimer->expires_from_now(boost::posix_time::seconds(_updateInterval));
+ _updateTimer->async_wait(std::bind(&RealmList::UpdateRealms, this, std::placeholders::_1));
+ }
+}
+
+Realm const* RealmList::GetRealm(Battlenet::RealmId const& id) const
+{
+ auto itr = _realms.find(id);
+ if (itr != _realms.end())
+ return &itr->second;
+
+ return NULL;
+}
diff --git a/src/server/bnetserver/Realms/RealmList.h b/src/server/bnetserver/Realms/RealmList.h
new file mode 100644
index 00000000000..dc78a00dfdd
--- /dev/null
+++ b/src/server/bnetserver/Realms/RealmList.h
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2008-2014 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 _REALMLIST_H
+#define _REALMLIST_H
+
+#include "Common.h"
+#include "WorldListener.h"
+#include <boost/asio/ip/address.hpp>
+#include <boost/asio/ip/tcp.hpp>
+#include <boost/asio/io_service.hpp>
+#include <boost/asio/deadline_timer.hpp>
+
+using namespace boost::asio;
+
+enum RealmFlags
+{
+ REALM_FLAG_NONE = 0x00,
+ REALM_FLAG_INVALID = 0x01,
+ REALM_FLAG_OFFLINE = 0x02,
+ REALM_FLAG_SPECIFYBUILD = 0x04,
+ REALM_FLAG_UNK1 = 0x08,
+ REALM_FLAG_UNK2 = 0x10,
+ REALM_FLAG_RECOMMENDED = 0x20,
+ REALM_FLAG_NEW = 0x40,
+ REALM_FLAG_FULL = 0x80
+};
+
+#pragma pack(push, 1)
+
+namespace Battlenet
+{
+ struct RealmHandle;
+
+ struct RealmId
+ {
+ RealmId() : Region(0), Battlegroup(0), Index(0), Build(0) { }
+ RealmId(uint8 region, uint8 battlegroup, uint32 index, uint32 build)
+ : Region(region), Battlegroup(battlegroup), Index(index), Build(build) { }
+
+ uint8 Region;
+ uint8 Battlegroup;
+ uint32 Index;
+ uint32 Build;
+
+ bool operator<(RealmId const& r) const
+ {
+ return memcmp(this, &r, sizeof(RealmId) - sizeof(Build)) < 0;
+ }
+
+ RealmId& operator=(RealmHandle const& handle);
+ };
+}
+
+#pragma pack(pop)
+
+// Storage object for a realm
+struct Realm
+{
+ Battlenet::RealmId Id;
+ ip::address ExternalAddress;
+ ip::address LocalAddress;
+ ip::address LocalSubnetMask;
+ uint16 Port;
+ std::string Name;
+ uint8 Type;
+ RealmFlags Flags;
+ uint8 Timezone;
+ AccountTypes AllowedSecurityLevel;
+ float PopulationLevel;
+ bool Updated;
+ bool Keep;
+
+ ip::tcp::endpoint GetAddressForClient(ip::address const& clientAddr) const;
+};
+
+/// Storage object for the list of realms on the server
+class RealmList
+{
+public:
+ typedef std::map<Battlenet::RealmId, Realm> RealmMap;
+
+ static RealmList* instance()
+ {
+ static RealmList instance;
+ return &instance;
+ }
+
+ ~RealmList();
+
+ void Initialize(boost::asio::io_service& ioService, uint32 updateInterval, uint16 worldListenPort);
+ void Close();
+
+ RealmMap const& GetRealms() const { return _realms; }
+ Realm const* GetRealm(Battlenet::RealmId const& id) const;
+
+private:
+ RealmList();
+
+ void UpdateRealms(boost::system::error_code const& error);
+ void UpdateRealm(Battlenet::RealmId const& id, const std::string& name, ip::address const& address, ip::address const& localAddr,
+ ip::address const& localSubmask, uint16 port, uint8 icon, RealmFlags flag, uint8 timezone, AccountTypes allowedSecurityLevel, float population);
+
+ RealmMap _realms;
+ uint32 _updateInterval;
+ boost::asio::deadline_timer* _updateTimer;
+ boost::asio::ip::tcp::resolver* _resolver;
+ WorldListener* _worldListener;
+};
+
+#define sRealmList RealmList::instance()
+#endif
diff --git a/src/server/bnetserver/Realms/WorldListener.cpp b/src/server/bnetserver/Realms/WorldListener.cpp
new file mode 100644
index 00000000000..30886a67310
--- /dev/null
+++ b/src/server/bnetserver/Realms/WorldListener.cpp
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2008-2014 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 "Log.h"
+#include "SessionManager.h"
+#include "WoWRealmPackets.h"
+#include "ZmqContext.h"
+#include "WorldListener.h"
+
+WorldListener::HandlerTable const WorldListener::_handlers;
+
+WorldListener::HandlerTable::HandlerTable()
+{
+#define DEFINE_HANDLER(opc, func) _handlers[opc] = { func, #opc }
+
+ DEFINE_HANDLER(BNET_CHANGE_TOON_ONLINE_STATE, &WorldListener::HandleToonOnlineStatusChange);
+
+#undef DEFINE_HANDLER
+}
+
+WorldListener::WorldListener(uint16 worldListenPort) : _worldListenPort(worldListenPort)
+{
+ _worldSocket = sIpcContext->CreateNewSocket(zmqpp::socket_type::pull);
+}
+
+WorldListener::~WorldListener()
+{
+ delete _worldSocket;
+}
+
+void WorldListener::Run()
+{
+ while (!ProcessExit())
+ {
+ _poller->poll();
+ if (_poller->events(*_worldSocket) & zmqpp::poller::poll_in)
+ {
+ int32 op1;
+ do
+ {
+ zmqpp::message msg;
+ _worldSocket->receive(msg);
+ Dispatch(msg);
+ _worldSocket->get(zmqpp::socket_option::events, op1);
+ } while (op1 & zmqpp::poller::poll_in);
+ }
+ }
+}
+
+void WorldListener::HandleOpen()
+{
+ _worldSocket->bind(std::string("tcp://*:") + std::to_string(_worldListenPort));
+ _poller->add(*_worldSocket);
+ TC_LOG_INFO("server.ipc", "Listening on connections from worldservers...");
+}
+
+void WorldListener::HandleClose()
+{
+ _worldSocket->close();
+ TC_LOG_INFO("server.ipc", "Shutting down connections from worldservers...");
+}
+
+void WorldListener::Dispatch(zmqpp::message& msg) const
+{
+ Battlenet::Header ipcHeader;
+ msg >> ipcHeader;
+
+ if (ipcHeader.Ipc.Channel != IPC_CHANNEL_BNET)
+ return;
+
+ if (ipcHeader.Ipc.Command < IPC_BNET_MAX_COMMAND)
+ (this->*_handlers[ipcHeader.Ipc.Command].Handler)(ipcHeader.Realm, msg);
+}
+
+void WorldListener::HandleToonOnlineStatusChange(Battlenet::RealmHandle const& realm, zmqpp::message& msg) const
+{
+ Battlenet::ToonHandle toonHandle;
+ bool online;
+ msg >> toonHandle;
+ msg >> online;
+
+ if (Battlenet::Session* session = sSessionMgr.GetSession(toonHandle.AccountId, toonHandle.GameAccountId))
+ {
+ if (online)
+ {
+ Battlenet::WoWRealm::ToonReady* toonReady = new Battlenet::WoWRealm::ToonReady();
+ toonReady->Realm = realm;
+ toonReady->Guid = toonHandle.Guid;
+ toonReady->Name = toonHandle.Name;
+ session->AsyncWrite(toonReady);
+ }
+ else
+ session->AsyncWrite(new Battlenet::WoWRealm::ToonLoggedOut());
+ }
+}
diff --git a/src/server/bnetserver/Realms/WorldListener.h b/src/server/bnetserver/Realms/WorldListener.h
new file mode 100644
index 00000000000..04d5342449c
--- /dev/null
+++ b/src/server/bnetserver/Realms/WorldListener.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2008-2014 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 WorldListener_h__
+#define WorldListener_h__
+
+#include "ZMQTask.h"
+#include "Commands.h"
+
+class WorldListener : public ZMQTask
+{
+public:
+ explicit WorldListener(uint16 worldListenPort);
+ ~WorldListener();
+ void Run() override;
+
+protected:
+ void HandleOpen() override;
+ void HandleClose() override;
+
+private:
+ void Dispatch(zmqpp::message& msg) const;
+
+ typedef void(WorldListener::*PacketHandler)(Battlenet::RealmHandle const& realm, zmqpp::message& msg) const;
+ class HandlerTable
+ {
+ public:
+ HandlerTable();
+
+ struct HandlerInfo
+ {
+ PacketHandler Handler;
+ char const* Name;
+ };
+
+ HandlerInfo const& operator[](uint8 opcode) const { return _handlers[opcode]; }
+
+ private:
+ HandlerInfo _handlers[IPC_BNET_MAX_COMMAND];
+ };
+
+ void HandleToonOnlineStatusChange(Battlenet::RealmHandle const& realm, zmqpp::message& msg) const;
+
+ zmqpp::socket* _worldSocket;
+ uint16 _worldListenPort;
+ static HandlerTable const _handlers;
+};
+
+#endif // WorldListener_h__
diff --git a/src/server/bnetserver/Server/ComponentManager.cpp b/src/server/bnetserver/Server/ComponentManager.cpp
new file mode 100644
index 00000000000..be1f22022f4
--- /dev/null
+++ b/src/server/bnetserver/Server/ComponentManager.cpp
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2008-2014 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 "ComponentManager.h"
+#include "DatabaseEnv.h"
+
+Battlenet::ComponentMgr::~ComponentMgr()
+{
+ for (Component* component : _components)
+ delete component;
+}
+
+void Battlenet::ComponentMgr::Load()
+{
+ QueryResult result = LoginDatabase.Query("SELECT Program, Platform, Build FROM battlenet_components");
+ if (result)
+ {
+ do
+ {
+ Field* fields = result->Fetch();
+ Component* component = new Component();
+ component->Program = fields[0].GetString();
+ component->Platform = fields[1].GetString();
+ component->Build = fields[2].GetUInt32();
+
+ _components.insert(component);
+ _programs.insert(component->Program);
+ _platforms.insert(component->Platform);
+
+ } while (result->NextRow());
+ }
+}
+
+bool Battlenet::ComponentMgr::HasComponent(Battlenet::Component const* component) const
+{
+ for (Component const* c : _components)
+ if (component->Program == c->Program && component->Platform == c->Platform && component->Build == c->Build)
+ return true;
+
+ return false;
+}
diff --git a/src/server/bnetserver/Server/ComponentManager.h b/src/server/bnetserver/Server/ComponentManager.h
new file mode 100644
index 00000000000..865cfca7f62
--- /dev/null
+++ b/src/server/bnetserver/Server/ComponentManager.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2008-2014 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 ComponentManager_h__
+#define ComponentManager_h__
+
+#include "Define.h"
+#include <cstring>
+#include <string>
+#include <set>
+
+namespace Battlenet
+{
+ struct Component
+ {
+ std::string Program;
+ std::string Platform;
+ uint32 Build;
+ };
+
+ class ComponentMgr
+ {
+ ComponentMgr() { }
+ ~ComponentMgr();
+
+ public:
+ void Load();
+ bool HasComponent(Component const* component) const;
+ bool HasProgram(std::string const& program) const { return _programs.count(program) != 0; }
+ bool HasPlatform(std::string const& platform) const { return _platforms.count(platform) != 0; }
+
+ static ComponentMgr* instance()
+ {
+ static ComponentMgr instance;
+ return &instance;
+ }
+
+ private:
+ std::set<Component*> _components;
+ std::set<std::string> _programs;
+ std::set<std::string> _platforms;
+ };
+}
+
+#define sComponentMgr Battlenet::ComponentMgr::instance()
+
+#endif // ComponentManager_h__
diff --git a/src/server/authserver/Server/BattlenetManager.cpp b/src/server/bnetserver/Server/ModuleManager.cpp
index f470c365b56..05cee2ff42e 100644
--- a/src/server/authserver/Server/BattlenetManager.cpp
+++ b/src/server/bnetserver/Server/ModuleManager.cpp
@@ -15,46 +15,16 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "BattlenetManager.h"
+#include "ModuleManager.h"
#include "DatabaseEnv.h"
-BattlenetMgr::~BattlenetMgr()
+Battlenet::ModuleManager::~ModuleManager()
{
- for (Battlenet::Component* component : _components)
- delete component;
-
for (auto const& m : _modules)
delete m.second;
}
-void BattlenetMgr::Load()
-{
- LoadComponents();
- LoadModules();
-}
-
-void BattlenetMgr::LoadComponents()
-{
- QueryResult result = LoginDatabase.Query("SELECT Program, Platform, Build FROM battlenet_components");
- if (result)
- {
- do
- {
- Field* fields = result->Fetch();
- Battlenet::Component* component = new Battlenet::Component();
- component->Program = fields[0].GetString();
- component->Platform = fields[1].GetString();
- component->Build = fields[2].GetUInt32();
-
- _components.insert(component);
- _programs.insert(component->Program);
- _platforms.insert(component->Platform);
-
- } while (result->NextRow());
- }
-}
-
-void BattlenetMgr::LoadModules()
+void Battlenet::ModuleManager::Load()
{
QueryResult result = LoginDatabase.Query("SELECT `Hash`, `Name`, `Type`, `System`, `Data` FROM battlenet_modules");
if (result)
@@ -62,7 +32,7 @@ void BattlenetMgr::LoadModules()
do
{
Field* fields = result->Fetch();
- Battlenet::ModuleInfo* module = new Battlenet::ModuleInfo();
+ ModuleInfo* module = new ModuleInfo();
module->Type = fields[2].GetString();
HexStrToByteArray(fields[0].GetString(), module->ModuleId);
std::string data = fields[4].GetString();
@@ -78,19 +48,11 @@ void BattlenetMgr::LoadModules()
}
}
-bool BattlenetMgr::HasComponent(Battlenet::Component const* component) const
-{
- for (Battlenet::Component const* c : _components)
- if (component->Program == c->Program && component->Platform == c->Platform && component->Build == c->Build)
- return true;
-
- return false;
-}
-
-Battlenet::ModuleInfo* BattlenetMgr::CreateModule(std::string const& os, std::string const& name) const
+Battlenet::ModuleInfo* Battlenet::ModuleManager::CreateModule(std::string const& os, std::string const& name) const
{
- Battlenet::ModuleKey key { os, name };
- ASSERT(_modules.count(key));
+ ModuleKey key { os, name };
+ if (!_modules.count(key))
+ return nullptr;
- return new Battlenet::ModuleInfo(*_modules.at(key));
+ return new ModuleInfo(*_modules.at(key));
}
diff --git a/src/server/authserver/Server/BattlenetManager.h b/src/server/bnetserver/Server/ModuleManager.h
index bd01619ef06..36ffb2fec3f 100644
--- a/src/server/authserver/Server/BattlenetManager.h
+++ b/src/server/bnetserver/Server/ModuleManager.h
@@ -15,24 +15,16 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef __BATTLENETMANAGER_H__
-#define __BATTLENETMANAGER_H__
+#ifndef ModuleManager_h__
+#define ModuleManager_h__
#include "Define.h"
#include <cstring>
#include <string>
-#include <set>
#include <map>
namespace Battlenet
{
- struct Component
- {
- std::string Program;
- std::string Platform;
- uint32 Build;
- };
-
struct ModuleKey
{
std::string Platform;
@@ -74,43 +66,29 @@ namespace Battlenet
uint8* Data;
};
- struct RealmId
+ class ModuleManager
{
- uint8 Region;
- uint8 Battlegroup;
- uint32 Index;
- uint32 Build;
- };
-}
+ ModuleManager() { }
+ ~ModuleManager();
-class BattlenetMgr
-{
- BattlenetMgr() { }
- ~BattlenetMgr();
+ public:
+ void Load();
+ ModuleInfo* CreateModule(std::string const& os, std::string const& name) const;
-public:
- void Load();
- bool HasComponent(Battlenet::Component const* component) const;
- bool HasProgram(std::string const& program) const { return _programs.count(program) != 0; }
- bool HasPlatform(std::string const& platform) const { return _platforms.count(platform) != 0; }
- Battlenet::ModuleInfo* CreateModule(std::string const& os, std::string const& name) const;
-
- static BattlenetMgr* instance()
- {
- static BattlenetMgr instance;
- return &instance;
- }
+ static ModuleManager* instance()
+ {
+ static ModuleManager instance;
+ return &instance;
+ }
-private:
- void LoadComponents();
- void LoadModules();
+ private:
+ void LoadComponents();
+ void LoadModules();
- std::set<Battlenet::Component*> _components;
- std::set<std::string> _programs;
- std::set<std::string> _platforms;
- std::map<Battlenet::ModuleKey, Battlenet::ModuleInfo*> _modules;
-};
+ std::map<ModuleKey, ModuleInfo*> _modules;
+ };
+}
-#define sBattlenetMgr BattlenetMgr::instance()
+#define sModuleMgr Battlenet::ModuleManager::instance()
-#endif // __BATTLENETMANAGER_H__
+#endif // ModuleManager_h__
diff --git a/src/server/authserver/Server/BattlenetSession.cpp b/src/server/bnetserver/Server/Session.cpp
index 860c557b46a..edd00e5db2d 100644
--- a/src/server/authserver/Server/BattlenetSession.cpp
+++ b/src/server/bnetserver/Server/Session.cpp
@@ -16,35 +16,15 @@
*/
#include "AuthCodes.h"
-#include "BattlenetBitStream.h"
-#include "BattlenetSessionManager.h"
+#include "BitStream.h"
+#include "PacketManager.h"
+#include "SessionManager.h"
#include "Database/DatabaseEnv.h"
#include "HmacHash.h"
#include "Log.h"
#include "RealmList.h"
#include "SHA256.h"
#include <map>
-#include <boost/asio/write.hpp>
-
-std::map<Battlenet::PacketHeader, Battlenet::Session::PacketHandler> InitHandlers()
-{
- std::map<Battlenet::PacketHeader, Battlenet::Session::PacketHandler> handlers;
-
- handlers[Battlenet::PacketHeader(Battlenet::Authentication::CMSG_LOGON_REQUEST_3, Battlenet::AUTHENTICATION)] = &Battlenet::Session::HandleLogonRequest;
- handlers[Battlenet::PacketHeader(Battlenet::Authentication::CMSG_RESUME_REQUEST, Battlenet::AUTHENTICATION)] = &Battlenet::Session::HandleResumeRequest;
- handlers[Battlenet::PacketHeader(Battlenet::Authentication::CMSG_PROOF_RESPONSE, Battlenet::AUTHENTICATION)] = &Battlenet::Session::HandleProofResponse;
-
- handlers[Battlenet::PacketHeader(Battlenet::Connection::CMSG_PING, Battlenet::CONNECTION)] = &Battlenet::Session::HandlePing;
- handlers[Battlenet::PacketHeader(Battlenet::Connection::CMSG_ENABLE_ENCRYPTION, Battlenet::CONNECTION)] = &Battlenet::Session::HandleEnableEncryption;
- handlers[Battlenet::PacketHeader(Battlenet::Connection::CMSG_LOGOUT_REQUEST, Battlenet::CONNECTION)] = &Battlenet::Session::HandleLogoutRequest;
-
- handlers[Battlenet::PacketHeader(Battlenet::WoWRealm::CMSG_LIST_SUBSCRIBE_REQUEST, Battlenet::WOWREALM)] = &Battlenet::Session::HandleListSubscribeRequest;
- handlers[Battlenet::PacketHeader(Battlenet::WoWRealm::CMSG_JOIN_REQUEST_V2, Battlenet::WOWREALM)] = &Battlenet::Session::HandleJoinRequestV2;
-
- return handlers;
-}
-
-std::map<Battlenet::PacketHeader, Battlenet::Session::PacketHandler> Handlers = InitHandlers();
Battlenet::Session::ModuleHandler const Battlenet::Session::ModuleHandlers[MODULE_COUNT] =
{
@@ -58,7 +38,7 @@ Battlenet::Session::ModuleHandler const Battlenet::Session::ModuleHandlers[MODUL
Battlenet::Session::Session(tcp::socket&& socket) : Socket(std::move(socket)), _accountId(0), _accountName(), _locale(),
_os(), _build(0), _gameAccountId(0), _gameAccountName(), _accountSecurityLevel(SEC_PLAYER), I(), s(), v(), b(), B(), K(),
- _reconnectProof(), _crypt(), _authed(false)
+ _reconnectProof(), _crypt(), _authed(false), _subscribedToRealmListUpdates(false)
{
static uint8 const N_Bytes[] =
{
@@ -83,8 +63,7 @@ Battlenet::Session::Session(tcp::socket&& socket) : Socket(std::move(socket)), _
Battlenet::Session::~Session()
{
- sBattlenetSessionMgr.RemoveSession(this);
- TC_LOG_TRACE("server.battlenet", "Battlenet::Session::OnClose");
+ sSessionMgr.RemoveSession(this);
}
void Battlenet::Session::_SetVSFields(std::string const& pstr)
@@ -109,7 +88,12 @@ void Battlenet::Session::_SetVSFields(std::string const& pstr)
LoginDatabase.Execute(stmt);
}
-bool Battlenet::Session::HandleLogonRequest(PacketHeader& header, BitStream& packet)
+void Battlenet::Session::LogUnhandledPacket(PacketHeader const& header)
+{
+ TC_LOG_DEBUG("session.packets", "%s Received unhandled packet %s", GetClientInfo().c_str(), sPacketManager.GetClientPacketName(header));
+}
+
+void Battlenet::Session::HandleLogonRequest(Authentication::LogonRequest3 const& logonRequest)
{
// Verify that this IP is not in the ip_banned table
LoginDatabase.Execute(LoginDatabase.GetPreparedStatement(LOGIN_DEL_EXPIRED_IP_BANS));
@@ -119,68 +103,65 @@ bool Battlenet::Session::HandleLogonRequest(PacketHeader& header, BitStream& pac
stmt->setString(0, ip_address);
if (PreparedQueryResult result = LoginDatabase.Query(stmt))
{
- Authentication::LogonResponse* complete = new Authentication::LogonResponse();
- complete->SetAuthResult(LOGIN_BANNED);
- AsyncWrite(complete);
- TC_LOG_DEBUG("server.battlenet", "[Battlenet::AuthChallenge] Banned ip '%s:%d' tries to login!", ip_address.c_str(), GetRemotePort());
- return true;
+ Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse();
+ logonResponse->SetAuthResult(LOGIN_BANNED);
+ AsyncWrite(logonResponse);
+ TC_LOG_DEBUG("session", "[Battlenet::LogonRequest] Banned ip '%s:%d' tries to login!", ip_address.c_str(), GetRemotePort());
+ return;
}
- Authentication::LogonRequest3 info(header, packet);
- info.Read();
-
- if (info.Program != "WoW")
+ if (logonRequest.Program != "WoW")
{
- Authentication::LogonResponse* complete = new Authentication::LogonResponse();
- complete->SetAuthResult(AUTH_INVALID_PROGRAM);
- AsyncWrite(complete);
- return true;
+ Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse();
+ logonResponse->SetAuthResult(AUTH_INVALID_PROGRAM);
+ AsyncWrite(logonResponse);
+ return;
}
- if (!sBattlenetMgr->HasPlatform(info.Platform))
+ if (!sComponentMgr->HasPlatform(logonRequest.Platform))
{
- Authentication::LogonResponse* complete = new Authentication::LogonResponse();
- complete->SetAuthResult(AUTH_INVALID_OS);
- AsyncWrite(complete);
- return true;
+ Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse();
+ logonResponse->SetAuthResult(AUTH_INVALID_OS);
+ AsyncWrite(logonResponse);
+ return;
}
- if (!sBattlenetMgr->HasPlatform(info.Locale))
+ if (!sComponentMgr->HasPlatform(logonRequest.Locale))
{
- Authentication::LogonResponse* complete = new Authentication::LogonResponse();
- complete->SetAuthResult(AUTH_UNSUPPORTED_LANGUAGE);
- AsyncWrite(complete);
- return true;
+ Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse();
+ logonResponse->SetAuthResult(AUTH_UNSUPPORTED_LANGUAGE);
+ AsyncWrite(logonResponse);
+ return;
}
- for (Component const& component : info.Components)
+ for (Component const& component : logonRequest.Components)
{
- if (!sBattlenetMgr->HasComponent(&component))
+ if (!sComponentMgr->HasComponent(&component))
{
- Authentication::LogonResponse* complete = new Authentication::LogonResponse();
- if (!sBattlenetMgr->HasProgram(component.Program))
- complete->SetAuthResult(AUTH_INVALID_PROGRAM);
- else if (!sBattlenetMgr->HasPlatform(component.Platform))
- complete->SetAuthResult(AUTH_INVALID_OS);
+ Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse();
+ if (!sComponentMgr->HasProgram(component.Program))
+ logonResponse->SetAuthResult(AUTH_INVALID_PROGRAM);
+ else if (!sComponentMgr->HasPlatform(component.Platform))
+ logonResponse->SetAuthResult(AUTH_INVALID_OS);
else
{
if (component.Program != "WoW" || AuthHelper::IsBuildSupportingBattlenet(component.Build))
- complete->SetAuthResult(AUTH_REGION_BAD_VERSION);
+ logonResponse->SetAuthResult(AUTH_REGION_BAD_VERSION);
else
- complete->SetAuthResult(AUTH_USE_GRUNT_LOGON);
+ logonResponse->SetAuthResult(AUTH_USE_GRUNT_LOGON);
}
- AsyncWrite(complete);
- return true;
+ AsyncWrite(logonResponse);
+ return;
}
if (component.Platform == "base")
_build = component.Build;
}
- _accountName = info.Login;
- _locale = info.Locale;
- _os = info.Platform;
+ _accountName = logonRequest.Login;
+ _locale = logonRequest.Locale;
+ _os = logonRequest.Platform;
Utf8ToUpperOnlyLatin(_accountName);
stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_BNET_ACCOUNT_INFO);
@@ -189,10 +170,10 @@ bool Battlenet::Session::HandleLogonRequest(PacketHeader& header, BitStream& pac
PreparedQueryResult result = LoginDatabase.Query(stmt);
if (!result)
{
- Authentication::LogonResponse* complete = new Authentication::LogonResponse();
- complete->SetAuthResult(AUTH_UNKNOWN_ACCOUNT);
- AsyncWrite(complete);
- return true;
+ Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse();
+ logonResponse->SetAuthResult(AUTH_UNKNOWN_ACCOUNT);
+ AsyncWrite(logonResponse);
+ return;
}
Field* fields = result->Fetch();
@@ -202,22 +183,22 @@ bool Battlenet::Session::HandleLogonRequest(PacketHeader& header, BitStream& pac
// If the IP is 'locked', check that the player comes indeed from the correct IP address
if (fields[2].GetUInt8() == 1) // if ip is locked
{
- TC_LOG_DEBUG("server.battlenet", "[Battlenet::AuthChallenge] Account '%s' is locked to IP - '%s' is logging in from '%s'", _accountName.c_str(), fields[4].GetCString(), ip_address.c_str());
+ TC_LOG_DEBUG("session", "[Battlenet::LogonRequest] Account '%s' is locked to IP - '%s' is logging in from '%s'", _accountName.c_str(), fields[4].GetCString(), ip_address.c_str());
if (strcmp(fields[4].GetCString(), ip_address.c_str()) != 0)
{
- Authentication::LogonResponse* complete = new Authentication::LogonResponse();
- complete->SetAuthResult(AUTH_ACCOUNT_LOCKED);
- AsyncWrite(complete);
- return true;
+ Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse();
+ logonResponse->SetAuthResult(AUTH_ACCOUNT_LOCKED);
+ AsyncWrite(logonResponse);
+ return;
}
}
else
{
- TC_LOG_DEBUG("server.battlenet", "[Battlenet::AuthChallenge] Account '%s' is not locked to ip", _accountName.c_str());
+ TC_LOG_DEBUG("session", "[Battlenet::LogonRequest] Account '%s' is not locked to ip", _accountName.c_str());
std::string accountCountry = fields[3].GetString();
if (accountCountry.empty() || accountCountry == "00")
- TC_LOG_DEBUG("server.battlenet", "[Battlenet::AuthChallenge] Account '%s' is not locked to country", _accountName.c_str());
+ TC_LOG_DEBUG("session", "[Battlenet::LogonRequest] Account '%s' is not locked to country", _accountName.c_str());
else if (!accountCountry.empty())
{
uint32 ip = inet_addr(ip_address.c_str());
@@ -228,13 +209,13 @@ bool Battlenet::Session::HandleLogonRequest(PacketHeader& header, BitStream& pac
if (PreparedQueryResult sessionCountryQuery = LoginDatabase.Query(stmt))
{
std::string loginCountry = (*sessionCountryQuery)[0].GetString();
- TC_LOG_DEBUG("server.battlenet", "[Battlenet::AuthChallenge] Account '%s' is locked to country: '%s' Player country is '%s'", _accountName.c_str(), accountCountry.c_str(), loginCountry.c_str());
+ TC_LOG_DEBUG("session", "[Battlenet::LogonRequest] Account '%s' is locked to country: '%s' Player country is '%s'", _accountName.c_str(), accountCountry.c_str(), loginCountry.c_str());
if (loginCountry != accountCountry)
{
- Authentication::LogonResponse* complete = new Authentication::LogonResponse();
- complete->SetAuthResult(AUTH_ACCOUNT_LOCKED);
- AsyncWrite(complete);
- return true;
+ Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse();
+ logonResponse->SetAuthResult(AUTH_ACCOUNT_LOCKED);
+ AsyncWrite(logonResponse);
+ return;
}
}
}
@@ -252,19 +233,19 @@ bool Battlenet::Session::HandleLogonRequest(PacketHeader& header, BitStream& pac
Field* fields = banresult->Fetch();
if (fields[0].GetUInt32() == fields[1].GetUInt32())
{
- Authentication::LogonResponse* complete = new Authentication::LogonResponse();
- complete->SetAuthResult(LOGIN_BANNED);
- AsyncWrite(complete);
- TC_LOG_DEBUG("server.battlenet", "'%s:%d' [Battlenet::AuthChallenge] Banned account %s tried to login!", ip_address.c_str(), GetRemotePort(), _accountName.c_str());
- return true;
+ Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse();
+ logonResponse->SetAuthResult(LOGIN_BANNED);
+ AsyncWrite(logonResponse);
+ TC_LOG_DEBUG("session", "'%s:%d' [Battlenet::LogonRequest] Banned account %s tried to login!", ip_address.c_str(), GetRemotePort(), _accountName.c_str());
+ return;
}
else
{
- Authentication::LogonResponse* complete = new Authentication::LogonResponse();
- complete->SetAuthResult(LOGIN_SUSPENDED);
- AsyncWrite(complete);
- TC_LOG_DEBUG("server.battlenet", "'%s:%d' [Battlenet::AuthChallenge] Temporarily banned account %s tried to login!", ip_address.c_str(), GetRemotePort(), _accountName.c_str());
- return true;
+ Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse();
+ logonResponse->SetAuthResult(LOGIN_SUSPENDED);
+ AsyncWrite(logonResponse);
+ TC_LOG_DEBUG("session", "'%s:%d' [Battlenet::LogonRequest] Temporarily banned account %s tried to login!", ip_address.c_str(), GetRemotePort(), _accountName.c_str());
+ return;
}
}
@@ -274,8 +255,8 @@ bool Battlenet::Session::HandleLogonRequest(PacketHeader& header, BitStream& pac
I.SetBinary(sha.GetDigest(), sha.GetLength());
- ModuleInfo* password = sBattlenetMgr->CreateModule(_os, "Password");
- ModuleInfo* thumbprint = sBattlenetMgr->CreateModule(_os, "Thumbprint");
+ ModuleInfo* password = sModuleMgr->CreateModule(_os, "Password");
+ ModuleInfo* thumbprint = sModuleMgr->CreateModule(_os, "Thumbprint");
std::string pStr = fields[0].GetString();
@@ -309,39 +290,33 @@ bool Battlenet::Session::HandleLogonRequest(PacketHeader& header, BitStream& pac
_modulesWaitingForData.push(MODULE_PASSWORD);
- Authentication::ProofRequest* request = new Authentication::ProofRequest();
- request->Modules.push_back(password);
+ Authentication::ProofRequest* proofRequest = new Authentication::ProofRequest();
+ proofRequest->Modules.push_back(password);
// if has authenticator, send Token module
- request->Modules.push_back(thumbprint);
- AsyncWrite(request);
- return true;
+ proofRequest->Modules.push_back(thumbprint);
+ AsyncWrite(proofRequest);
}
-bool Battlenet::Session::HandleResumeRequest(PacketHeader& header, BitStream& packet)
+void Battlenet::Session::HandleResumeRequest(Authentication::ResumeRequest const& resumeRequest)
{
- Authentication::ResumeRequest reconnect(header, packet);
- reconnect.Read();
-
- TC_LOG_DEBUG("server.battlenet", "%s", reconnect.ToString().c_str());
-
- _accountName = reconnect.Login;
- _locale = reconnect.Locale;
- _os = reconnect.Platform;
- auto baseComponent = std::find_if(reconnect.Components.begin(), reconnect.Components.end(), [](Component const& c) { return c.Program == "base"; });
- if (baseComponent != reconnect.Components.end())
+ _accountName = resumeRequest.Login;
+ _locale = resumeRequest.Locale;
+ _os = resumeRequest.Platform;
+ auto baseComponent = std::find_if(resumeRequest.Components.begin(), resumeRequest.Components.end(), [](Component const& c) { return c.Program == "base"; });
+ if (baseComponent != resumeRequest.Components.end())
_build = baseComponent->Build;
Utf8ToUpperOnlyLatin(_accountName);
PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_BNET_RECONNECT_INFO);
stmt->setString(0, _accountName);
- stmt->setString(1, reconnect.GameAccountName);
+ stmt->setString(1, resumeRequest.GameAccountName);
PreparedQueryResult result = LoginDatabase.Query(stmt);
if (!result)
{
- Authentication::ResumeResponse* resume = new Authentication::ResumeResponse();
- resume->SetAuthResult(AUTH_UNKNOWN_ACCOUNT);
- AsyncWrite(resume);
- return false;
+ Authentication::ResumeResponse* resumeResponse = new Authentication::ResumeResponse();
+ resumeResponse->SetAuthResult(AUTH_UNKNOWN_ACCOUNT);
+ AsyncWrite(resumeResponse);
+ return;
}
Field* fields = result->Fetch();
@@ -349,10 +324,10 @@ bool Battlenet::Session::HandleResumeRequest(PacketHeader& header, BitStream& pa
_accountId = fields[0].GetUInt32();
K.SetHexStr(fields[1].GetString().c_str());
_gameAccountId = fields[2].GetUInt32();
- _gameAccountName = reconnect.GameAccountName;
+ _gameAccountName = resumeRequest.GameAccountName;
- ModuleInfo* thumbprint = sBattlenetMgr->CreateModule(_os, "Thumbprint");
- ModuleInfo* resume = sBattlenetMgr->CreateModule(_os, "Resume");
+ ModuleInfo* thumbprint = sModuleMgr->CreateModule(_os, "Thumbprint");
+ ModuleInfo* resume = sModuleMgr->CreateModule(_os, "Resume");
BitStream resumeData;
uint8 state = 0;
_reconnectProof.SetRand(16 * 8);
@@ -366,30 +341,26 @@ bool Battlenet::Session::HandleResumeRequest(PacketHeader& header, BitStream& pa
_modulesWaitingForData.push(MODULE_RESUME);
- Authentication::ProofRequest* request = new Authentication::ProofRequest();
- request->Modules.push_back(thumbprint);
- request->Modules.push_back(resume);
- AsyncWrite(request);
- return true;
+ Authentication::ProofRequest* proofRequest = new Authentication::ProofRequest();
+ proofRequest->Modules.push_back(thumbprint);
+ proofRequest->Modules.push_back(resume);
+ AsyncWrite(proofRequest);
}
-bool Battlenet::Session::HandleProofResponse(PacketHeader& header, BitStream& packet)
+void Battlenet::Session::HandleProofResponse(Authentication::ProofResponse const& proofResponse)
{
- Authentication::ProofResponse proof(header, packet);
- proof.Read();
-
- if (_modulesWaitingForData.size() < proof.Modules.size())
+ if (_modulesWaitingForData.size() < proofResponse.Modules.size())
{
Authentication::LogonResponse* complete = new Authentication::LogonResponse();
complete->SetAuthResult(AUTH_CORRUPTED_MODULE);
AsyncWrite(complete);
- return true;
+ return;
}
ServerPacket* response = nullptr;
- for (size_t i = 0; i < proof.Modules.size(); ++i)
+ for (size_t i = 0; i < proofResponse.Modules.size(); ++i)
{
- if (!(this->*(ModuleHandlers[_modulesWaitingForData.front()]))(proof.Modules[i], &response))
+ if (!(this->*(ModuleHandlers[_modulesWaitingForData.front()]))(proofResponse.Modules[i], &response))
break;
_modulesWaitingForData.pop();
@@ -402,36 +373,35 @@ bool Battlenet::Session::HandleProofResponse(PacketHeader& header, BitStream& pa
}
AsyncWrite(response);
- return true;
+ return;
}
-bool Battlenet::Session::HandlePing(PacketHeader& /*header*/, BitStream& /*packet*/)
+void Battlenet::Session::HandlePing(Connection::Ping const& /*ping*/)
{
AsyncWrite(new Connection::Pong());
- return true;
}
-bool Battlenet::Session::HandleEnableEncryption(PacketHeader& /*header*/, BitStream& /*packet*/)
+void Battlenet::Session::HandleEnableEncryption(Connection::EnableEncryption const& /*enableEncryption*/)
{
_crypt.Init(&K);
- return true;
}
-bool Battlenet::Session::HandleLogoutRequest(PacketHeader& /*header*/, BitStream& /*packet*/)
+void Battlenet::Session::HandleLogoutRequest(Connection::LogoutRequest const& /*logoutRequest*/)
{
PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_BNET_SESSION_KEY);
stmt->setString(0, "");
stmt->setBool(1, false);
stmt->setUInt32(2, _accountId);
LoginDatabase.Execute(stmt);
- return true;
}
-bool Battlenet::Session::HandleListSubscribeRequest(PacketHeader& /*header*/, BitStream& /*packet*/)
+void Battlenet::Session::HandleConnectionClosing(Connection::ConnectionClosing const& /*connectionClosing*/)
{
- sRealmList->UpdateIfNeed();
+}
- WoWRealm::ListSubscribeResponse* counts = new WoWRealm::ListSubscribeResponse();
+void Battlenet::Session::HandleListSubscribeRequest(WoWRealm::ListSubscribeRequest const& /*listSubscribeRequest*/)
+{
+ WoWRealm::ListSubscribeResponse* listSubscribeResponse = new WoWRealm::ListSubscribeResponse();
PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_BNET_CHARACTER_COUNTS);
stmt->setUInt32(0, _gameAccountId);
@@ -442,87 +412,50 @@ bool Battlenet::Session::HandleListSubscribeRequest(PacketHeader& /*header*/, Bi
{
Field* fields = countResult->Fetch();
uint32 build = fields[4].GetUInt32();
- counts->CharacterCounts.push_back({ { fields[2].GetUInt8(), fields[3].GetUInt8(), fields[1].GetUInt32(), (_build != build ? build : 0) }, fields[0].GetUInt8() });
+ listSubscribeResponse->CharacterCounts.push_back({ RealmId(fields[2].GetUInt8(), fields[3].GetUInt8(), fields[1].GetUInt32(), (_build != build ? build : 0)), fields[0].GetUInt8() });
} while (countResult->NextRow());
}
- for (RealmList::RealmMap::const_iterator i = sRealmList->begin(); i != sRealmList->end(); ++i)
- {
- Realm const& realm = i->second;
-
- uint32 flag = realm.flag;
- RealmBuildInfo const* buildInfo = AuthHelper::GetBuildInfo(realm.gamebuild);
- if (realm.gamebuild != _build)
- {
- if (!buildInfo)
- continue;
-
- flag |= REALM_FLAG_OFFLINE | REALM_FLAG_SPECIFYBUILD; // tell the client what build the realm is for
- }
-
- if (!buildInfo)
- flag &= ~REALM_FLAG_SPECIFYBUILD;
-
- WoWRealm::ListUpdate* update = new WoWRealm::ListUpdate();
- update->Timezone = realm.timezone;
- update->Population = realm.populationLevel;
- update->Lock = (realm.allowedSecurityLevel > _accountSecurityLevel) ? 1 : 0;
- update->Type = realm.icon;
- update->Name = realm.name;
-
- if (flag & REALM_FLAG_SPECIFYBUILD)
- {
- std::ostringstream version;
- version << buildInfo->MajorVersion << '.' << buildInfo->MinorVersion << '.' << buildInfo->BugfixVersion << '.' << buildInfo->Build;
-
- update->Version = version.str();
- update->Address = realm.GetAddressForClient(GetRemoteIpAddress());
- update->Build = buildInfo->Build;
- }
-
- update->Flags = flag;
- update->Region = realm.Region;
- update->Battlegroup = realm.Battlegroup;
- update->Index = realm.m_ID;
-
- counts->RealmData.push_back(update);
- }
+ for (RealmList::RealmMap::value_type const& i : sRealmList->GetRealms())
+ listSubscribeResponse->RealmData.push_back(BuildListUpdate(&i.second));
- counts->RealmData.push_back(new WoWRealm::ListComplete());
+ listSubscribeResponse->RealmData.push_back(new WoWRealm::ListComplete());
- AsyncWrite(counts);
- return true;
+ AsyncWrite(listSubscribeResponse);
+ _subscribedToRealmListUpdates = true;
}
-bool Battlenet::Session::HandleJoinRequestV2(PacketHeader& header, BitStream& packet)
+void Battlenet::Session::HandleListUnsubscribe(WoWRealm::ListUnsubscribe const& /*listUnsubscribe*/)
{
- WoWRealm::JoinRequestV2 join(header, packet);
- join.Read();
+ _subscribedToRealmListUpdates = false;
+}
- WoWRealm::JoinResponseV2* result = new WoWRealm::JoinResponseV2();
- Realm const* realm = sRealmList->GetRealm(join.Realm);
- if (!realm || realm->flag & (REALM_FLAG_INVALID | REALM_FLAG_OFFLINE))
+void Battlenet::Session::HandleJoinRequestV2(WoWRealm::JoinRequestV2 const& joinRequest)
+{
+ WoWRealm::JoinResponseV2* joinResponse = new WoWRealm::JoinResponseV2();
+ Realm const* realm = sRealmList->GetRealm(joinRequest.Realm);
+ if (!realm || realm->Flags & (REALM_FLAG_INVALID | REALM_FLAG_OFFLINE))
{
- result->Response = WoWRealm::JoinResponseV2::FAILURE;
- AsyncWrite(result);
- return true;
+ joinResponse->Response = WoWRealm::JoinResponseV2::FAILURE;
+ AsyncWrite(joinResponse);
+ return;
}
- result->ServerSeed = uint32(rand32());
+ joinResponse->ServerSeed = uint32(rand32());
uint8 sessionKey[40];
HmacSha1 hmac(K.GetNumBytes(), K.AsByteArray().get());
hmac.UpdateData((uint8*)"WoW\0", 4);
- hmac.UpdateData((uint8*)&join.ClientSeed, 4);
- hmac.UpdateData((uint8*)&result->ServerSeed, 4);
+ hmac.UpdateData((uint8*)&joinRequest.ClientSeed, 4);
+ hmac.UpdateData((uint8*)&joinResponse->ServerSeed, 4);
hmac.Finalize();
memcpy(sessionKey, hmac.GetDigest(), hmac.GetLength());
HmacSha1 hmac2(K.GetNumBytes(), K.AsByteArray().get());
hmac2.UpdateData((uint8*)"WoW\0", 4);
- hmac2.UpdateData((uint8*)&result->ServerSeed, 4);
- hmac2.UpdateData((uint8*)&join.ClientSeed, 4);
+ hmac2.UpdateData((uint8*)&joinResponse->ServerSeed, 4);
+ hmac2.UpdateData((uint8*)&joinRequest.ClientSeed, 4);
hmac2.Finalize();
memcpy(sessionKey + hmac.GetLength(), hmac2.GetDigest(), hmac2.GetLength());
@@ -530,53 +463,92 @@ bool Battlenet::Session::HandleJoinRequestV2(PacketHeader& header, BitStream& pa
LoginDatabase.DirectPExecute("UPDATE account SET sessionkey = '%s', last_ip = '%s', last_login = NOW(), locale = %u, failed_logins = 0, os = '%s' WHERE id = %u",
ByteArrayToHexStr(sessionKey, 40, true).c_str(), GetRemoteIpAddress().to_string().c_str(), GetLocaleByName(_locale), _os.c_str(), _gameAccountId);
- result->IPv4.emplace_back(realm->ExternalAddress, realm->port);
+ joinResponse->IPv4.emplace_back(realm->ExternalAddress, realm->Port);
if (realm->ExternalAddress != realm->LocalAddress)
- result->IPv4.emplace_back(realm->LocalAddress, realm->port);
+ joinResponse->IPv4.emplace_back(realm->LocalAddress, realm->Port);
- AsyncWrite(result);
- return true;
+ AsyncWrite(joinResponse);
+}
+
+void Battlenet::Session::HandleSocialNetworkCheckConnected(Friends::SocialNetworkCheckConnected const& socialNetworkCheckConnected)
+{
+ Friends::SocialNetworkCheckConnectedResult* socialNetworkCheckConnectedResult = new Friends::SocialNetworkCheckConnectedResult();
+ socialNetworkCheckConnectedResult->SocialNetworkId = socialNetworkCheckConnected.SocialNetworkId;
+ AsyncWrite(socialNetworkCheckConnectedResult);
+}
+
+void Battlenet::Session::HandleGetStreamItemsRequest(Cache::GetStreamItemsRequest const& getStreamItemsRequest)
+{
+ if (ModuleInfo* module = sModuleMgr->CreateModule(getStreamItemsRequest.Locale, getStreamItemsRequest.ItemName))
+ {
+ Cache::GetStreamItemsResponse* getStreamItemsResponse = new Cache::GetStreamItemsResponse();
+ getStreamItemsResponse->Index = getStreamItemsRequest.Index;
+ getStreamItemsResponse->Modules.push_back(module);
+ AsyncWrite(getStreamItemsResponse);
+ }
+}
+
+inline std::string PacketToStringHelper(Battlenet::ClientPacket const* packet)
+{
+ if (sLog->ShouldLog("session.packets", LOG_LEVEL_TRACE))
+ return packet->ToString();
+
+ return sPacketManager.GetClientPacketName(packet->GetHeader());
+}
+
+inline std::string PacketToStringHelper(Battlenet::ServerPacket const* packet)
+{
+ if (sLog->ShouldLog("session.packets", LOG_LEVEL_TRACE))
+ return packet->ToString();
+
+ return sPacketManager.GetServerPacketName(packet->GetHeader());
}
void Battlenet::Session::ReadHandler()
{
- BitStream packet(std::move(GetReadBuffer()));
- _crypt.DecryptRecv(packet.GetBuffer(), packet.GetSize());
+ BitStream stream(std::move(GetReadBuffer()));
+ _crypt.DecryptRecv(stream.GetBuffer(), stream.GetSize());
- while (!packet.IsRead())
+ while (!stream.IsRead())
{
try
{
PacketHeader header;
- header.Opcode = packet.Read<uint32>(6);
- if (packet.Read<bool>(1))
- header.Channel = packet.Read<int32>(4);
+ header.Opcode = stream.Read<uint32>(6);
+ if (stream.Read<bool>(1))
+ header.Channel = stream.Read<int32>(4);
if (header.Channel != AUTHENTICATION && !_authed)
{
- TC_LOG_DEBUG("server.battlenet", "Battlenet::Session::ReadDataHandler Received not allowed packet %s", header.ToString().c_str());
+ TC_LOG_DEBUG("session.packets", "%s Received not allowed %s. Client has not authed yet.", GetClientInfo().c_str(), header.ToString().c_str());
CloseSocket();
return;
}
- TC_LOG_TRACE("server.battlenet", "Battlenet::Session::ReadDataHandler %s", header.ToString().c_str());
- std::map<PacketHeader, PacketHandler>::const_iterator itr = Handlers.find(header);
- if (itr != Handlers.end())
+ if (ClientPacket* packet = sPacketManager.CreateClientPacket(header, stream))
{
- if ((this->*(itr->second))(header, packet))
- break;
+ if (sPacketManager.IsHandled(header))
+ TC_LOG_DEBUG("session.packets", "%s Received %s", GetClientInfo().c_str(), PacketToStringHelper(packet).c_str());
+
+ packet->CallHandler(this);
+ delete packet;
+ }
+ else if (sPacketManager.GetClientPacketName(header))
+ {
+ LogUnhandledPacket(header);
+ break;
}
else
{
- TC_LOG_DEBUG("server.battlenet", "Battlenet::Session::ReadDataHandler Unhandled opcode %s", header.ToString().c_str());
+ TC_LOG_DEBUG("session.packets", "%s Received unknown %s", GetClientInfo().c_str(), header.ToString().c_str());
break;
}
- packet.AlignToNextByte();
+ stream.AlignToNextByte();
}
catch (BitStreamPositionException const& e)
{
- TC_LOG_ERROR("server.battlenet", "Battlenet::Session::ReadDataHandler Exception: %s", e.what());
+ TC_LOG_ERROR("session.packets", "%s Exception thrown during packet processing %s", GetClientInfo().c_str(), e.what());
CloseSocket();
return;
}
@@ -588,7 +560,7 @@ void Battlenet::Session::ReadHandler()
void Battlenet::Session::Start()
{
- TC_LOG_TRACE("server.battlenet", "Battlenet::Session::Start");
+ TC_LOG_TRACE("session", "Accepted connection from %s", GetRemoteIpAddress().to_string().c_str());
AsyncRead();
}
@@ -600,7 +572,7 @@ void Battlenet::Session::AsyncWrite(ServerPacket* packet)
return;
}
- TC_LOG_TRACE("server.battlenet", "Battlenet::Session::AsyncWrite %s", packet->ToString().c_str());
+ TC_LOG_DEBUG("session.packets", "%s Sending %s", GetClientInfo().c_str(), PacketToStringHelper(packet).c_str());
packet->Write();
@@ -627,17 +599,17 @@ bool Battlenet::Session::HandlePasswordModule(BitStream* dataStream, ServerPacke
{
if (dataStream->GetSize() != 1 + 128 + 32 + 128)
{
- Authentication::LogonResponse* complete = new Authentication::LogonResponse();
- complete->SetAuthResult(AUTH_CORRUPTED_MODULE);
- ReplaceResponse(response, complete);
+ Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse();
+ logonResponse->SetAuthResult(AUTH_CORRUPTED_MODULE);
+ ReplaceResponse(response, logonResponse);
return false;
}
if (dataStream->Read<uint8>(8) != 2) // State
{
- Authentication::LogonResponse* complete = new Authentication::LogonResponse();
- complete->SetAuthResult(AUTH_CORRUPTED_MODULE);
- ReplaceResponse(response, complete);
+ Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse();
+ logonResponse->SetAuthResult(AUTH_CORRUPTED_MODULE);
+ ReplaceResponse(response, logonResponse);
return false;
}
@@ -649,9 +621,9 @@ bool Battlenet::Session::HandlePasswordModule(BitStream* dataStream, ServerPacke
if (A.isZero())
{
- Authentication::LogonResponse* complete = new Authentication::LogonResponse();
- complete->SetAuthResult(AUTH_CORRUPTED_MODULE);
- ReplaceResponse(response, complete);
+ Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse();
+ logonResponse->SetAuthResult(AUTH_CORRUPTED_MODULE);
+ ReplaceResponse(response, logonResponse);
return false;
}
@@ -725,9 +697,9 @@ bool Battlenet::Session::HandlePasswordModule(BitStream* dataStream, ServerPacke
stmt->setString(0, _accountName);
LoginDatabase.Execute(stmt);
- Authentication::LogonResponse* complete = new Authentication::LogonResponse();
- complete->SetAuthResult(AUTH_UNKNOWN_ACCOUNT);
- ReplaceResponse(response, complete);
+ Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse();
+ logonResponse->SetAuthResult(AUTH_UNKNOWN_ACCOUNT);
+ ReplaceResponse(response, logonResponse);
return false;
}
@@ -740,9 +712,9 @@ bool Battlenet::Session::HandlePasswordModule(BitStream* dataStream, ServerPacke
if (!numAccounts)
{
- Authentication::LogonResponse* noAccounts = new Authentication::LogonResponse();
- noAccounts->SetAuthResult(LOGIN_NO_GAME_ACCOUNT);
- ReplaceResponse(response, noAccounts);
+ Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse();
+ logonResponse->SetAuthResult(LOGIN_NO_GAME_ACCOUNT);
+ ReplaceResponse(response, logonResponse);
return false;
}
@@ -761,7 +733,7 @@ bool Battlenet::Session::HandlePasswordModule(BitStream* dataStream, ServerPacke
serverProof.SetRand(128 * 8); // just send garbage, server signature check is patched out in client
BitStream stream;
- ModuleInfo* password = sBattlenetMgr->CreateModule(_os, "Password");
+ ModuleInfo* password = sModuleMgr->CreateModule(_os, "Password");
uint8 state = 3;
stream.WriteBytes(&state, 1);
@@ -772,8 +744,8 @@ bool Battlenet::Session::HandlePasswordModule(BitStream* dataStream, ServerPacke
password->Data = new uint8[password->DataSize];
memcpy(password->Data, stream.GetBuffer(), password->DataSize);
- Authentication::ProofRequest* request = new Authentication::ProofRequest();
- request->Modules.push_back(password);
+ Authentication::ProofRequest* proofRequest = new Authentication::ProofRequest();
+ proofRequest->Modules.push_back(password);
if (numAccounts > 1)
{
BitStream accounts;
@@ -794,43 +766,43 @@ bool Battlenet::Session::HandlePasswordModule(BitStream* dataStream, ServerPacke
accounts.WriteString(name.str(), 8);
} while (result->NextRow());
- ModuleInfo* selectGameAccount = sBattlenetMgr->CreateModule(_os, "SelectGameAccount");
+ ModuleInfo* selectGameAccount = sModuleMgr->CreateModule(_os, "SelectGameAccount");
selectGameAccount->DataSize = accounts.GetSize();
selectGameAccount->Data = new uint8[selectGameAccount->DataSize];
memcpy(selectGameAccount->Data, accounts.GetBuffer(), selectGameAccount->DataSize);
- request->Modules.push_back(selectGameAccount);
+ proofRequest->Modules.push_back(selectGameAccount);
_modulesWaitingForData.push(MODULE_SELECT_GAME_ACCOUNT);
}
else
{
if (fields[4].GetBool())
{
- delete request;
+ delete proofRequest;
- Authentication::LogonResponse* complete = new Authentication::LogonResponse();
+ Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse();
if (fields[2].GetUInt32() == fields[3].GetUInt32())
{
- complete->SetAuthResult(LOGIN_BANNED);
- TC_LOG_DEBUG("server.battlenet", "'%s:%d' [Battlenet::AuthChallenge] Banned account %s tried to login!", GetRemoteIpAddress().to_string().c_str(), GetRemotePort(), _accountName.c_str());
+ logonResponse->SetAuthResult(LOGIN_BANNED);
+ TC_LOG_DEBUG("session", "'%s:%d' [Battlenet::Password] Banned account %s tried to login!", GetRemoteIpAddress().to_string().c_str(), GetRemotePort(), _accountName.c_str());
}
else
{
- complete->SetAuthResult(LOGIN_SUSPENDED);
- TC_LOG_DEBUG("server.battlenet", "'%s:%d' [Battlenet::AuthChallenge] Temporarily banned account %s tried to login!", GetRemoteIpAddress().to_string().c_str(), GetRemotePort(), _accountName.c_str());
+ logonResponse->SetAuthResult(LOGIN_SUSPENDED);
+ TC_LOG_DEBUG("session", "'%s:%d' [Battlenet::Password] Temporarily banned account %s tried to login!", GetRemoteIpAddress().to_string().c_str(), GetRemotePort(), _accountName.c_str());
}
- ReplaceResponse(response, complete);
+ ReplaceResponse(response, logonResponse);
return false;
}
_gameAccountId = fields[0].GetUInt32();
_gameAccountName = fields[1].GetString();
- request->Modules.push_back(sBattlenetMgr->CreateModule(_os, "RiskFingerprint"));
+ proofRequest->Modules.push_back(sModuleMgr->CreateModule(_os, "RiskFingerprint"));
_modulesWaitingForData.push(MODULE_RISK_FINGERPRINT);
}
- ReplaceResponse(response, request);
+ ReplaceResponse(response, proofRequest);
return true;
}
@@ -838,9 +810,9 @@ bool Battlenet::Session::HandleSelectGameAccountModule(BitStream* dataStream, Se
{
if (dataStream->Read<uint8>(8) != 1)
{
- Authentication::LogonResponse* complete = new Authentication::LogonResponse();
- complete->SetAuthResult(AUTH_CORRUPTED_MODULE);
- ReplaceResponse(response, complete);
+ Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse();
+ logonResponse->SetAuthResult(AUTH_CORRUPTED_MODULE);
+ ReplaceResponse(response, logonResponse);
return false;
}
@@ -848,9 +820,9 @@ bool Battlenet::Session::HandleSelectGameAccountModule(BitStream* dataStream, Se
std::string account = dataStream->ReadString(8);
if (account.empty())
{
- Authentication::LogonResponse* complete = new Authentication::LogonResponse();
- complete->SetAuthResult(LOGIN_NO_GAME_ACCOUNT);
- ReplaceResponse(response, complete);
+ Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse();
+ logonResponse->SetAuthResult(LOGIN_NO_GAME_ACCOUNT);
+ ReplaceResponse(response, logonResponse);
return false;
}
@@ -879,28 +851,28 @@ bool Battlenet::Session::HandleSelectGameAccountModule(BitStream* dataStream, Se
Field* fields = result->Fetch();
if (fields[4].GetBool())
{
- Authentication::LogonResponse* complete = new Authentication::LogonResponse();
+ Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse();
if (fields[2].GetUInt32() == fields[3].GetUInt32())
{
- complete->SetAuthResult(LOGIN_BANNED);
- TC_LOG_DEBUG("server.battlenet", "'%s:%d' [Battlenet::SelectGameAccount] Banned account %s tried to login!", GetRemoteIpAddress().to_string().c_str(), GetRemotePort(), _accountName.c_str());
+ logonResponse->SetAuthResult(LOGIN_BANNED);
+ TC_LOG_DEBUG("session", "'%s:%d' [Battlenet::SelectGameAccount] Banned account %s tried to login!", GetRemoteIpAddress().to_string().c_str(), GetRemotePort(), _accountName.c_str());
}
else
{
- complete->SetAuthResult(LOGIN_SUSPENDED);
- TC_LOG_DEBUG("server.battlenet", "'%s:%d' [Battlenet::SelectGameAccount] Temporarily banned account %s tried to login!", GetRemoteIpAddress().to_string().c_str(), GetRemotePort(), _accountName.c_str());
+ logonResponse->SetAuthResult(LOGIN_SUSPENDED);
+ TC_LOG_DEBUG("session", "'%s:%d' [Battlenet::SelectGameAccount] Temporarily banned account %s tried to login!", GetRemoteIpAddress().to_string().c_str(), GetRemotePort(), _accountName.c_str());
}
- ReplaceResponse(response, complete);
+ ReplaceResponse(response, logonResponse);
return false;
}
_gameAccountId = fields[0].GetUInt32();
_gameAccountName = fields[1].GetString();
- Authentication::ProofRequest* request = new Authentication::ProofRequest();
- request->Modules.push_back(sBattlenetMgr->CreateModule(_os, "RiskFingerprint"));
- ReplaceResponse(response, request);
+ Authentication::ProofRequest* proofRequest = new Authentication::ProofRequest();
+ proofRequest->Modules.push_back(sModuleMgr->CreateModule(_os, "RiskFingerprint"));
+ ReplaceResponse(response, proofRequest);
_modulesWaitingForData.push(MODULE_RISK_FINGERPRINT);
return true;
@@ -908,16 +880,16 @@ bool Battlenet::Session::HandleSelectGameAccountModule(BitStream* dataStream, Se
bool Battlenet::Session::HandleRiskFingerprintModule(BitStream* dataStream, ServerPacket** response)
{
- Authentication::LogonResponse* complete = new Authentication::LogonResponse();
+ Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse();
if (dataStream->Read<uint8>(8) == 1)
{
- complete->AccountId = _accountId;
- complete->GameAccountName = _gameAccountName;
- complete->GameAccountFlags = GAMEACCOUNT_FLAG_PROPASS_LOCK;
+ logonResponse->AccountId = _accountId;
+ logonResponse->GameAccountName = _gameAccountName;
+ logonResponse->GameAccountFlags = GAMEACCOUNT_FLAG_PROPASS_LOCK;
PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_BNET_FAILED_LOGINS);
stmt->setUInt32(0, _accountId);
if (PreparedQueryResult failedLoginsResult = LoginDatabase.Query(stmt))
- complete->FailedLogins = (*failedLoginsResult)[0].GetUInt32();
+ logonResponse->FailedLogins = (*failedLoginsResult)[0].GetUInt32();
SQLTransaction trans = LoginDatabase.BeginTransaction();
@@ -937,12 +909,12 @@ bool Battlenet::Session::HandleRiskFingerprintModule(BitStream* dataStream, Serv
LoginDatabase.CommitTransaction(trans);
_authed = true;
- sBattlenetSessionMgr.AddSession(this);
+ sSessionMgr.AddSession(this);
}
else
- complete->SetAuthResult(AUTH_BAD_VERSION_HASH);
+ logonResponse->SetAuthResult(AUTH_BAD_VERSION_HASH);
- ReplaceResponse(response, complete);
+ ReplaceResponse(response, logonResponse);
return true;
}
@@ -950,9 +922,9 @@ bool Battlenet::Session::HandleResumeModule(BitStream* dataStream, ServerPacket*
{
if (dataStream->Read<uint8>(8) != 1)
{
- Authentication::ResumeResponse* complete = new Authentication::ResumeResponse();
- complete->SetAuthResult(AUTH_CORRUPTED_MODULE);
- ReplaceResponse(response, complete);
+ Authentication::ResumeResponse* resumeResponse = new Authentication::ResumeResponse();
+ resumeResponse->SetAuthResult(AUTH_CORRUPTED_MODULE);
+ ReplaceResponse(response, resumeResponse);
return false;
}
@@ -994,10 +966,10 @@ bool Battlenet::Session::HandleResumeModule(BitStream* dataStream, ServerPacket*
stmt->setString(0, _accountName);
LoginDatabase.Execute(stmt);
- TC_LOG_DEBUG("server.battlenet", "[Battlenet::Resume] Invalid proof!");
- Authentication::ResumeResponse* result = new Authentication::ResumeResponse();
- result->SetAuthResult(AUTH_UNKNOWN_ACCOUNT);
- ReplaceResponse(response, result);
+ TC_LOG_DEBUG("session", "[Battlenet::Resume] Invalid proof!");
+ Authentication::ResumeResponse* resumeResponse = new Authentication::ResumeResponse();
+ resumeResponse->SetAuthResult(AUTH_UNKNOWN_ACCOUNT);
+ ReplaceResponse(response, resumeResponse);
return false;
}
@@ -1013,7 +985,7 @@ bool Battlenet::Session::HandleResumeModule(BitStream* dataStream, ServerPacket*
serverProof.UpdateData(clientChallenge.get(), 16);
serverProof.Finalize();
- ModuleInfo* resume = sBattlenetMgr->CreateModule(_os, "Resume");
+ ModuleInfo* resume = sModuleMgr->CreateModule(_os, "Resume");
BitStream resumeData;
uint8 state = 2;
@@ -1024,18 +996,80 @@ bool Battlenet::Session::HandleResumeModule(BitStream* dataStream, ServerPacket*
resume->Data = new uint8[resume->DataSize];
memcpy(resume->Data, resumeData.GetBuffer(), resume->DataSize);
- Authentication::ResumeResponse* result = new Authentication::ResumeResponse();
- result->Modules.push_back(resume);
- ReplaceResponse(response, result);
+ Authentication::ResumeResponse* resumeResponse = new Authentication::ResumeResponse();
+ resumeResponse->Modules.push_back(resume);
+ ReplaceResponse(response, resumeResponse);
_authed = true;
- sBattlenetSessionMgr.AddSession(this);
+ sSessionMgr.AddSession(this);
return true;
}
bool Battlenet::Session::UnhandledModule(BitStream* /*dataStream*/, ServerPacket** response)
{
- Authentication::LogonResponse* complete = new Authentication::LogonResponse();
- complete->SetAuthResult(AUTH_CORRUPTED_MODULE);
- ReplaceResponse(response, complete);
+ TC_LOG_ERROR("session.packets", "Unhandled module.");
+ Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse();
+ logonResponse->SetAuthResult(AUTH_CORRUPTED_MODULE);
+ ReplaceResponse(response, logonResponse);
return false;
}
+
+void Battlenet::Session::UpdateRealms(std::vector<Realm const*>& realms, std::vector<RealmId>& deletedRealms)
+{
+ for (Realm const* realm : realms)
+ AsyncWrite(BuildListUpdate(realm));
+
+ for (RealmId& deleted : deletedRealms)
+ {
+ WoWRealm::ListUpdate* listUpdate = new WoWRealm::ListUpdate();
+ listUpdate->UpdateState = WoWRealm::ListUpdate::DELETED;
+ listUpdate->Id = deleted;
+ AsyncWrite(listUpdate);
+ }
+}
+
+Battlenet::WoWRealm::ListUpdate* Battlenet::Session::BuildListUpdate(Realm const* realm) const
+{
+ uint32 flag = realm->Flags & ~REALM_FLAG_SPECIFYBUILD;
+ RealmBuildInfo const* buildInfo = AuthHelper::GetBuildInfo(realm->Id.Build);
+ if (realm->Id.Build != _build)
+ {
+ flag |= REALM_FLAG_INVALID;
+ if (buildInfo)
+ flag |= REALM_FLAG_SPECIFYBUILD; // tell the client what build the realm is for
+ }
+
+ WoWRealm::ListUpdate* listUpdate = new WoWRealm::ListUpdate();
+ listUpdate->Timezone = realm->Timezone;
+ listUpdate->Population = realm->PopulationLevel;
+ listUpdate->Lock = (realm->AllowedSecurityLevel > _accountSecurityLevel) ? 1 : 0;
+ listUpdate->Type = realm->Type;
+ listUpdate->Name = realm->Name;
+
+ if (flag & REALM_FLAG_SPECIFYBUILD)
+ {
+ std::ostringstream version;
+ version << buildInfo->MajorVersion << '.' << buildInfo->MinorVersion << '.' << buildInfo->BugfixVersion << '.' << buildInfo->Build;
+
+ listUpdate->Version = version.str();
+ listUpdate->Address = realm->GetAddressForClient(GetRemoteIpAddress());
+ }
+
+ listUpdate->Flags = flag;
+ listUpdate->Id = realm->Id;
+ return listUpdate;
+}
+
+std::string Battlenet::Session::GetClientInfo() const
+{
+ std::ostringstream stream;
+ stream << '[' << GetRemoteIpAddress() << ':' << GetRemotePort();
+ if (!_accountName.empty())
+ stream << ", Account: " << _accountName;
+
+ if (!_gameAccountName.empty())
+ stream << ", Game account: " << _gameAccountName;
+
+ stream << ']';
+
+ return stream.str();
+}
diff --git a/src/server/authserver/Server/BattlenetSession.h b/src/server/bnetserver/Server/Session.h
index c3e4afee19b..ded5170ae32 100644
--- a/src/server/authserver/Server/BattlenetSession.h
+++ b/src/server/bnetserver/Server/Session.h
@@ -15,16 +15,17 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef _BATTLENETSOCKET_H
-#define _BATTLENETSOCKET_H
+#ifndef Session_h__
+#define Session_h__
-#include "BattlenetPackets.h"
+#include "Packets.h"
#include "BattlenetPacketCrypt.h"
#include "Socket.h"
#include "BigNumber.h"
#include <memory>
#include <boost/asio/ip/tcp.hpp>
+struct Realm;
using boost::asio::ip::tcp;
namespace Battlenet
@@ -59,24 +60,39 @@ namespace Battlenet
explicit Session(tcp::socket&& socket);
~Session();
- typedef bool(Session::*PacketHandler)(PacketHeader& socket, BitStream& packet);
+ void LogUnhandledPacket(PacketHeader const& header);
// Authentication
- bool HandleLogonRequest(PacketHeader& header, BitStream& packet);
- bool HandleResumeRequest(PacketHeader& header, BitStream& packet);
- bool HandleProofResponse(PacketHeader& header, BitStream& packet);
+ void HandleLogonRequest(Authentication::LogonRequest3 const& logonRequest);
+ void HandleResumeRequest(Authentication::ResumeRequest const& resumeRequest);
+ void HandleProofResponse(Authentication::ProofResponse const& proofResponse);
// Connection
- bool HandlePing(PacketHeader& header, BitStream& packet);
- bool HandleEnableEncryption(PacketHeader& header, BitStream& packet);
- bool HandleLogoutRequest(PacketHeader& header, BitStream& packet);
+ void HandlePing(Connection::Ping const& ping);
+ void HandleEnableEncryption(Connection::EnableEncryption const& enableEncryption);
+ void HandleLogoutRequest(Connection::LogoutRequest const& logoutRequest);
+ void HandleConnectionClosing(Connection::ConnectionClosing const& connectionClosing);
// WoWRealm
- bool HandleListSubscribeRequest(PacketHeader& header, BitStream& packet);
- bool HandleJoinRequestV2(PacketHeader& header, BitStream& packet);
+ void HandleListSubscribeRequest(WoWRealm::ListSubscribeRequest const& listSubscribeRequest);
+ void HandleListUnsubscribe(WoWRealm::ListUnsubscribe const& listUnsubscribe);
+ void HandleJoinRequestV2(WoWRealm::JoinRequestV2 const& joinRequest);
+
+ // Friends
+ void HandleSocialNetworkCheckConnected(Friends::SocialNetworkCheckConnected const& socialNetworkCheckConnected);
+
+ // Cache
+ void HandleGetStreamItemsRequest(Cache::GetStreamItemsRequest const& getStreamItemsRequest);
void Start() override;
+ void UpdateRealms(std::vector<Realm const*>& realms, std::vector<RealmId>& deletedRealms);
+
+ uint32 GetAccountId() const { return _accountId; }
+ uint32 GetGameAccountId() const { return _gameAccountId; }
+
+ bool IsSubscribedToRealmListUpdates() const { return _subscribedToRealmListUpdates; }
+
void AsyncWrite(ServerPacket* packet);
protected:
@@ -94,6 +110,9 @@ namespace Battlenet
bool HandleResumeModule(BitStream* dataStream, ServerPacket** response);
bool UnhandledModule(BitStream* dataStream, ServerPacket** response);
+ WoWRealm::ListUpdate* BuildListUpdate(Realm const* realm) const;
+ std::string GetClientInfo() const;
+
uint32 _accountId;
std::string _accountName;
std::string _locale;
@@ -121,8 +140,9 @@ namespace Battlenet
PacketCrypt _crypt;
bool _authed;
+ bool _subscribedToRealmListUpdates;
};
}
-#endif // _BATTLENETSOCKET_H
+#endif // Session_h__
diff --git a/src/server/bnetserver/Server/SessionManager.cpp b/src/server/bnetserver/Server/SessionManager.cpp
new file mode 100644
index 00000000000..9e5836dab8d
--- /dev/null
+++ b/src/server/bnetserver/Server/SessionManager.cpp
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2008-2014 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 "SessionManager.h"
+
+bool Battlenet::SessionManager::StartNetwork(boost::asio::io_service& service, std::string const& bindIp, uint16 port)
+{
+ if (!BaseSocketMgr::StartNetwork(service, bindIp, port))
+ return false;
+
+ _acceptor->AsyncAcceptManaged(&OnSocketAccept);
+ return true;
+}
+
+NetworkThread<Battlenet::Session>* Battlenet::SessionManager::CreateThreads() const
+{
+ return new NetworkThread<Session>[GetNetworkThreadCount()];
+}
+
+void Battlenet::SessionManager::OnSocketAccept(tcp::socket&& sock)
+{
+ sSessionMgr.OnSocketOpen(std::forward<tcp::socket>(sock));
+}
+
+void Battlenet::SessionManager::AddSession(Session* session)
+{
+ std::unique_lock<boost::shared_mutex> lock(_sessionMutex);
+ _sessions[{ session->GetAccountId(), session->GetGameAccountId() }] = session;
+ _sessionsByAccountId[session->GetAccountId()].push_back(session);
+}
+
+void Battlenet::SessionManager::RemoveSession(Session* session)
+{
+ std::unique_lock<boost::shared_mutex> lock(_sessionMutex);
+ _sessions.erase({ session->GetAccountId(), session->GetGameAccountId() });
+ _sessionsByAccountId[session->GetAccountId()].remove(session);
+}
+
+Battlenet::Session* Battlenet::SessionManager::GetSession(uint32 accountId, uint32 gameAccountId) const
+{
+ auto itr = _sessions.find({ accountId, gameAccountId });
+ if (itr != _sessions.end())
+ return itr->second;
+
+ return nullptr;
+}
+
+std::list<Battlenet::Session*> Battlenet::SessionManager::GetSessions(uint32 accountId) const
+{
+ std::list<Session*> sessions;
+ auto itr = _sessionsByAccountId.find(accountId);
+ if (itr != _sessionsByAccountId.end())
+ sessions = itr->second;
+
+ return sessions;
+}
diff --git a/src/server/authserver/Server/BattlenetSessionManager.h b/src/server/bnetserver/Server/SessionManager.h
index b5a54438ef1..08ca5ce2b4e 100644
--- a/src/server/authserver/Server/BattlenetSessionManager.h
+++ b/src/server/bnetserver/Server/SessionManager.h
@@ -15,11 +15,13 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef BattlenetSessionManager_h__
-#define BattlenetSessionManager_h__
+#ifndef SessionManager_h__
+#define SessionManager_h__
-#include "BattlenetSession.h"
+#include "Session.h"
#include "SocketMgr.h"
+#include <boost/thread/locks.hpp>
+#include <boost/thread/shared_mutex.hpp>
namespace Battlenet
{
@@ -28,7 +30,7 @@ namespace Battlenet
struct SessionInfo
{
uint32 AccountId;
- uint32 GameAccountIndex;
+ uint32 GameAccountId;
bool operator<(SessionInfo const& right) const
{
@@ -41,6 +43,8 @@ namespace Battlenet
class SessionManager : SocketMgr<Session>
{
typedef SocketMgr<Session> BaseSocketMgr;
+ typedef std::map<SessionInfo, Session*> SessionMap;
+ typedef std::map<uint32, std::list<Session*>> SessionByAccountMap;
public:
static SessionManager& Instance()
@@ -52,9 +56,20 @@ namespace Battlenet
bool StartNetwork(boost::asio::io_service& service, std::string const& bindIp, uint16 port) override;
// noop for now, will be needed later to broadcast realmlist updates for example
- void AddSession(Session* /*session*/) { }
+ void AddSession(Session* /*session*/);
- void RemoveSession(Session* /*session*/) { }
+ void RemoveSession(Session* /*session*/);
+
+ Session* GetSession(uint32 accountId, uint32 gameAccountId) const;
+ std::list<Session*> GetSessions(uint32 accountId) const;
+
+ template<typename Iterator>
+ void LockedForEach(Iterator iterator)
+ {
+ boost::shared_lock<boost::shared_mutex> lock(_sessionMutex);
+ for (SessionMap::value_type const& pair : _sessions)
+ iterator(pair.second);
+ }
protected:
NetworkThread<Session>* CreateThreads() const override;
@@ -62,10 +77,12 @@ namespace Battlenet
private:
static void OnSocketAccept(tcp::socket&& sock);
- std::map<SessionInfo, Session> _sessions;
+ SessionMap _sessions;
+ SessionByAccountMap _sessionsByAccountId;
+ boost::shared_mutex _sessionMutex;
};
}
-#define sBattlenetSessionMgr Battlenet::SessionManager::Instance()
+#define sSessionMgr Battlenet::SessionManager::Instance()
-#endif // BattlenetSessionManager_h__
+#endif // SessionManager_h__
diff --git a/src/server/bnetserver/bnetserver.conf.dist b/src/server/bnetserver/bnetserver.conf.dist
new file mode 100644
index 00000000000..102ddb9906a
--- /dev/null
+++ b/src/server/bnetserver/bnetserver.conf.dist
@@ -0,0 +1,260 @@
+###############################################
+# Trinity Core Auth Server configuration file #
+###############################################
+[authserver]
+
+###################################################################################################
+# SECTION INDEX
+#
+# EXAMPLE CONFIG
+# AUTH SERVER SETTINGS
+# MYSQL SETTINGS
+# LOGGING SYSTEM SETTINGS
+#
+###################################################################################################
+
+###################################################################################################
+# EXAMPLE CONFIG
+#
+# Variable
+# Description: Brief description what the variable is doing.
+# Important: Annotation for important things about this variable.
+# Example: "Example, i.e. if the value is a string"
+# Default: 10 - (Enabled|Comment|Variable name in case of grouped config options)
+# 0 - (Disabled|Comment|Variable name in case of grouped config options)
+#
+# Note to developers:
+# - Copy this example to keep the formatting.
+# - Line breaks should be at column 100.
+###################################################################################################
+
+###################################################################################################
+# AUTH SERVER SETTINGS
+#
+# LogsDir
+# Description: Logs directory setting.
+# Important: LogsDir needs to be quoted, as the string might contain space characters.
+# Logs directory must exists, or log file creation will be disabled.
+# Default: "" - (Log files will be stored in the current path)
+
+LogsDir = ""
+
+#
+# MaxPingTime
+# Description: Time (in minutes) between database pings.
+# Default: 30
+
+MaxPingTime = 30
+
+#
+# WorldserverListenPort
+# Description: TCP port to listen on for incoming worldserver IPC.
+# Default: 1118
+
+WorldserverListenPort = 1118
+
+#
+# BattlenetPort
+# Description: TCP port to reach the auth server for battle.net connections.
+# Default: 1119
+
+BattlenetPort = 1119
+
+#
+#
+# BindIP
+# Description: Bind auth server to IP/hostname
+# Default: "0.0.0.0" - (Bind to all IPs on the system)
+
+BindIP = "0.0.0.0"
+
+#
+# PidFile
+# Description: Auth server PID file.
+# Example: "./authserver.pid" - (Enabled)
+# Default: "" - (Disabled)
+
+PidFile = ""
+
+#
+# UseProcessors
+# Description: Processors mask for Windows and Linux based multi-processor systems.
+# Example: A computer with 2 CPUs:
+# 1 - 1st CPU only, 2 - 2nd CPU only, 3 - 1st and 2nd CPU, because 1 | 2 is 3
+# Default: 0 - (Selected by OS)
+# 1+ - (Bit mask value of selected processors)
+
+UseProcessors = 0
+
+#
+# ProcessPriority
+# Description: Process priority setting for Windows and Linux based systems.
+# Details: On Linux, a nice value of -15 is used. (requires superuser). On Windows, process is set to HIGH class.
+# Default: 0 - (Normal)
+# 1 - (High)
+
+ProcessPriority = 0
+
+#
+# RealmsStateUpdateDelay
+# Description: Time (in seconds) between realm list updates.
+# Default: 10
+# 0 - (Disabled)
+
+RealmsStateUpdateDelay = 10
+
+#
+# WrongPass.MaxCount
+# Description: Number of login attemps with wrong password before the account or IP will be
+# banned.
+# Default: 0 - (Disabled)
+# 1+ - (Enabled)
+
+WrongPass.MaxCount = 0
+
+#
+# WrongPass.BanTime
+# Description: Time (in seconds) for banning account or IP for invalid login attempts.
+# Default: 600 - (10 minutes)
+# 0 - (Permanent ban)
+
+WrongPass.BanTime = 600
+
+#
+# WrongPass.BanType
+# Description: Ban type for invalid login attempts.
+# Default: 0 - (Ban IP)
+# 1 - (Ban Account)
+
+WrongPass.BanType = 0
+
+#
+###################################################################################################
+
+###################################################################################################
+# MYSQL SETTINGS
+#
+# LoginDatabaseInfo
+# Description: Database connection settings for the realm server.
+# Example: "hostname;port;username;password;database"
+# ".;somenumber;username;password;database" - (Use named pipes on Windows
+# "enable-named-pipe" to [mysqld]
+# section my.ini)
+# ".;/path/to/unix_socket;username;password;database" - (use Unix sockets on
+# Unix/Linux)
+# Default: "127.0.0.1;3306;trinity;trinity;auth"
+
+LoginDatabaseInfo = "127.0.0.1;3306;trinity;trinity;auth"
+
+#
+# LoginDatabase.WorkerThreads
+# Description: The amount of worker threads spawned to handle asynchronous (delayed) MySQL
+# statements. Each worker thread is mirrored with its own connection to the
+# Default: 1
+
+LoginDatabase.WorkerThreads = 1
+
+#
+# Wrong.Password.Login.Logging
+# Description: Additionally log attempted wrong password logging
+# Default: 0 - (Disabled)
+# 1 - (Enabled)
+
+Wrong.Password.Login.Logging = 0
+#
+###################################################################################################
+
+###################################################################################################
+#
+# LOGGING SYSTEM SETTINGS
+#
+# Appender config values: Given a appender "name"
+# Appender.name
+# Description: Defines 'where to log'
+# Format: Type,LogLevel,Flags,optional1,optional2,optional3
+#
+# Type
+# 0 - (None)
+# 1 - (Console)
+# 2 - (File)
+# 3 - (DB)
+#
+# LogLevel
+# 0 - (Disabled)
+# 1 - (Trace)
+# 2 - (Debug)
+# 3 - (Info)
+# 4 - (Warn)
+# 5 - (Error)
+# 6 - (Fatal)
+#
+# Flags:
+# 0 - None
+# 1 - Prefix Timestamp to the text
+# 2 - Prefix Log Level to the text
+# 4 - Prefix Log Filter type to the text
+# 8 - Append timestamp to the log file name. Format: YYYY-MM-DD_HH-MM-SS (Only used with Type = 2)
+# 16 - Make a backup of existing file before overwrite (Only used with Mode = w)
+#
+# Colors (read as optional1 if Type = Console)
+# Format: "fatal error warn info debug trace"
+# 0 - BLACK
+# 1 - RED
+# 2 - GREEN
+# 3 - BROWN
+# 4 - BLUE
+# 5 - MAGENTA
+# 6 - CYAN
+# 7 - GREY
+# 8 - YELLOW
+# 9 - LRED
+# 10 - LGREEN
+# 11 - LBLUE
+# 12 - LMAGENTA
+# 13 - LCYAN
+# 14 - WHITE
+# Example: "13 11 9 5 3 1"
+#
+# File: Name of the file (read as optional1 if Type = File)
+# Allows to use one "%s" to create dynamic files
+#
+# Mode: Mode to open the file (read as optional2 if Type = File)
+# a - (Append)
+# w - (Overwrite)
+#
+# MaxFileSize: Maximum file size of the log file before creating a new log file
+# (read as optional3 if Type = File)
+# Size is measured in bytes expressed in a 64-bit unsigned integer.
+# Maximum value is 4294967295 (4 gb). Leave blank for no limit.
+# NOTE: Does not work with dynamic filenames.
+# Example: 536870912 (512 mb)
+#
+
+Appender.Console=1,2,0
+Appender.Bnet=2,2,0,Bnet.log,w
+
+# Logger config values: Given a logger "name"
+# Logger.name
+# Description: Defines 'What to log'
+# Format: LogLevel,AppenderList
+#
+# LogLevel
+# 0 - (Disabled)
+# 1 - (Trace)
+# 2 - (Debug)
+# 3 - (Info)
+# 4 - (Warn)
+# 5 - (Error)
+# 6 - (Fatal)
+#
+# AppenderList: List of appenders linked to logger
+# (Using spaces as separator).
+#
+
+Logger.root=3,Console Bnet
+Logger.realmlist=3,Console Bnet
+Logger.session=3,Console Bnet
+Logger.session.packets=3,Console Bnet
+
+#
+###################################################################################################
diff --git a/src/server/bnetserver/bnetserver.ico b/src/server/bnetserver/bnetserver.ico
new file mode 100644
index 00000000000..da318f48a8c
--- /dev/null
+++ b/src/server/bnetserver/bnetserver.ico
Binary files differ
diff --git a/src/server/bnetserver/bnetserver.rc b/src/server/bnetserver/bnetserver.rc
new file mode 100644
index 00000000000..f030203fdcd
--- /dev/null
+++ b/src/server/bnetserver/bnetserver.rc
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2008-2014 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/>.
+ */
+
+#include "resource.h"
+#include "revision.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "windows.h" //"afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Icon
+//
+
+// Icon with lowest ID value placed first to ensure application icon
+// remains consistent on all systems.
+IDI_APPICON ICON "bnetserver.ico"
+
+/////////////////////////////////////////////////////////////////////////////
+// Neutre (Par défaut système) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_NEUSD)
+#ifdef _WIN32
+LANGUAGE LANG_NEUTRAL, SUBLANG_SYS_DEFAULT
+#pragma code_page(1252)
+#endif //_WIN32
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+FILEVERSION VER_FILEVERSION
+PRODUCTVERSION VER_PRODUCTVERSION
+
+FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
+
+#ifndef _DEBUG
+ FILEFLAGS 0
+#else
+ #define VER_PRERELEASE VS_FF_PRERELEASE
+ #define VER_PRIVATEBUILD VS_FF_PRIVATEBUILD
+ #define VER_DEBUG 0
+ FILEFLAGS (VER_PRIVATEBUILD|VER_PRERELEASE|VER_DEBUG)
+#endif
+
+FILEOS VOS_NT_WINDOWS32
+FILETYPE VFT_APP
+
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "080004b0"
+ BEGIN
+ VALUE "CompanyName", VER_COMPANYNAME_STR
+ VALUE "FileDescription", "TrinityCore Battle.net Server Daemon"
+ VALUE "FileVersion", VER_FILEVERSION_STR
+ VALUE "InternalName", "bnetserver"
+ VALUE "LegalCopyright", VER_LEGALCOPYRIGHT_STR
+ VALUE "OriginalFilename", "bnetserver.exe"
+ VALUE "ProductName", "TrinityCore Battle.net Server"
+ VALUE "ProductVersion", VER_PRODUCTVERSION_STR
+ END
+ END
+
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x800, 1200
+ END
+END
+#endif
diff --git a/src/server/bnetserver/resource.h b/src/server/bnetserver/resource.h
new file mode 100644
index 00000000000..7dc5cb9ef7b
--- /dev/null
+++ b/src/server/bnetserver/resource.h
@@ -0,0 +1,15 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by TrinityCore.rc
+//
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 101
+#define _APS_NEXT_COMMAND_VALUE 40001
+#define _APS_NEXT_CONTROL_VALUE 1000
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/src/server/collision/CMakeLists.txt b/src/server/collision/CMakeLists.txt
index 1c5fcbee52e..3aac255be29 100644
--- a/src/server/collision/CMakeLists.txt
+++ b/src/server/collision/CMakeLists.txt
@@ -47,6 +47,7 @@ include_directories(
${CMAKE_SOURCE_DIR}/src/server/shared/Packets
${CMAKE_SOURCE_DIR}/src/server/shared/Utilities
${CMAKE_SOURCE_DIR}/src/server/shared/DataStores
+ ${CMAKE_SOURCE_DIR}/src/server/ipc
${CMAKE_SOURCE_DIR}/src/server/game/Addons
${CMAKE_SOURCE_DIR}/src/server/game/Conditions
${CMAKE_SOURCE_DIR}/src/server/game/Entities/Item
diff --git a/src/server/collision/Management/MMapFactory.cpp b/src/server/collision/Management/MMapFactory.cpp
index b08cd92d638..51f016f6e96 100644
--- a/src/server/collision/Management/MMapFactory.cpp
+++ b/src/server/collision/Management/MMapFactory.cpp
@@ -17,9 +17,7 @@
*/
#include "MMapFactory.h"
-#include "World.h"
#include "Config.h"
-#include "DisableMgr.h"
namespace MMAP
{
@@ -35,12 +33,6 @@ namespace MMAP
return g_MMapManager;
}
- bool MMapFactory::IsPathfindingEnabled(uint32 mapId)
- {
- return sWorld->getBoolConfig(CONFIG_ENABLE_MMAPS)
- && !DisableMgr::IsDisabledFor(DISABLE_TYPE_MMAP, mapId, NULL, MMAP_DISABLE_PATHFINDING);
- }
-
void MMapFactory::clear()
{
if (g_MMapManager)
diff --git a/src/server/collision/Management/VMapManager2.cpp b/src/server/collision/Management/VMapManager2.cpp
index 484fdcd8ea4..b9ac7e204da 100644
--- a/src/server/collision/Management/VMapManager2.cpp
+++ b/src/server/collision/Management/VMapManager2.cpp
@@ -25,10 +25,9 @@
#include "ModelInstance.h"
#include "WorldModel.h"
#include <G3D/Vector3.h>
-#include "DisableMgr.h"
-#include "DBCStores.h"
#include "Log.h"
#include "VMapDefinitions.h"
+#include "Errors.h"
using G3D::Vector3;
@@ -36,6 +35,8 @@ namespace VMAP
{
VMapManager2::VMapManager2()
{
+ GetLiquidFlagsPtr = &GetLiquidFlagsDummy;
+ IsVMAPDisabledForPtr = &IsVMAPDisabledForDummy;
}
VMapManager2::~VMapManager2(void)
@@ -134,7 +135,7 @@ namespace VMAP
bool VMapManager2::isInLineOfSight(unsigned int mapId, float x1, float y1, float z1, float x2, float y2, float z2)
{
- if (!isLineOfSightCalcEnabled() || DisableMgr::IsDisabledFor(DISABLE_TYPE_VMAP, mapId, NULL, VMAP_DISABLE_LOS))
+ if (!isLineOfSightCalcEnabled() || IsVMAPDisabledForPtr(mapId, VMAP_DISABLE_LOS))
return true;
InstanceTreeMap::iterator instanceTree = iInstanceMapTrees.find(mapId);
@@ -157,7 +158,7 @@ namespace VMAP
*/
bool VMapManager2::getObjectHitPos(unsigned int mapId, float x1, float y1, float z1, float x2, float y2, float z2, float& rx, float &ry, float& rz, float modifyDist)
{
- if (isLineOfSightCalcEnabled() && !DisableMgr::IsDisabledFor(DISABLE_TYPE_VMAP, mapId, NULL, VMAP_DISABLE_LOS))
+ if (isLineOfSightCalcEnabled() && !IsVMAPDisabledForPtr(mapId, VMAP_DISABLE_LOS))
{
InstanceTreeMap::iterator instanceTree = iInstanceMapTrees.find(mapId);
if (instanceTree != iInstanceMapTrees.end())
@@ -187,7 +188,7 @@ namespace VMAP
float VMapManager2::getHeight(unsigned int mapId, float x, float y, float z, float maxSearchDist)
{
- if (isHeightCalcEnabled() && !DisableMgr::IsDisabledFor(DISABLE_TYPE_VMAP, mapId, NULL, VMAP_DISABLE_HEIGHT))
+ if (isHeightCalcEnabled() && !IsVMAPDisabledForPtr(mapId, VMAP_DISABLE_HEIGHT))
{
InstanceTreeMap::iterator instanceTree = iInstanceMapTrees.find(mapId);
if (instanceTree != iInstanceMapTrees.end())
@@ -206,7 +207,7 @@ namespace VMAP
bool VMapManager2::getAreaInfo(unsigned int mapId, float x, float y, float& z, uint32& flags, int32& adtId, int32& rootId, int32& groupId) const
{
- if (!DisableMgr::IsDisabledFor(DISABLE_TYPE_VMAP, mapId, NULL, VMAP_DISABLE_AREAFLAG))
+ if (!IsVMAPDisabledForPtr(mapId, VMAP_DISABLE_AREAFLAG))
{
InstanceTreeMap::const_iterator instanceTree = iInstanceMapTrees.find(mapId);
if (instanceTree != iInstanceMapTrees.end())
@@ -224,7 +225,7 @@ namespace VMAP
bool VMapManager2::GetLiquidLevel(uint32 mapId, float x, float y, float z, uint8 reqLiquidType, float& level, float& floor, uint32& type) const
{
- if (!DisableMgr::IsDisabledFor(DISABLE_TYPE_VMAP, mapId, NULL, VMAP_DISABLE_LIQUIDSTATUS))
+ if (!IsVMAPDisabledForPtr(mapId, VMAP_DISABLE_LIQUIDSTATUS))
{
InstanceTreeMap::const_iterator instanceTree = iInstanceMapTrees.find(mapId);
if (instanceTree != iInstanceMapTrees.end())
@@ -236,7 +237,7 @@ namespace VMAP
floor = info.ground_Z;
ASSERT(floor < std::numeric_limits<float>::max());
type = info.hitModel->GetLiquidType(); // entry from LiquidType.dbc
- if (reqLiquidType && !(GetLiquidFlags(type) & reqLiquidType))
+ if (reqLiquidType && !(GetLiquidFlagsPtr(type) & reqLiquidType))
return false;
if (info.hitInstance->GetLiquidLevel(pos, info, level))
return true;
diff --git a/src/server/collision/Management/VMapManager2.h b/src/server/collision/Management/VMapManager2.h
index 04292e7d8e4..9c419270b5a 100644
--- a/src/server/collision/Management/VMapManager2.h
+++ b/src/server/collision/Management/VMapManager2.h
@@ -66,6 +66,14 @@ namespace VMAP
typedef std::unordered_map<uint32, StaticMapTree*> InstanceTreeMap;
typedef std::unordered_map<std::string, ManagedModel> ModelFileMap;
+ enum DisableTypes
+ {
+ VMAP_DISABLE_AREAFLAG = 0x1,
+ VMAP_DISABLE_HEIGHT = 0x2,
+ VMAP_DISABLE_LOS = 0x4,
+ VMAP_DISABLE_LIQUIDSTATUS = 0x8
+ };
+
class VMapManager2 : public IVMapManager
{
protected:
@@ -78,6 +86,9 @@ namespace VMAP
bool _loadMap(uint32 mapId, const std::string& basePath, uint32 tileX, uint32 tileY);
/* void _unloadMap(uint32 pMapId, uint32 x, uint32 y); */
+ static uint32 GetLiquidFlagsDummy(uint32) { return 0; }
+ static bool IsVMAPDisabledForDummy(uint32 /*entry*/, uint8 /*flags*/) { return false; }
+
public:
// public for debug
G3D::Vector3 convertPositionToInternalRep(float x, float y, float z) const;
@@ -114,6 +125,12 @@ namespace VMAP
virtual bool existsMap(const char* basePath, unsigned int mapId, int x, int y) override;
public:
void getInstanceMapTree(InstanceTreeMap &instanceMapTree);
+
+ typedef uint32(*GetLiquidFlagsFn)(uint32 liquidType);
+ GetLiquidFlagsFn GetLiquidFlagsPtr;
+
+ typedef bool(*IsVMAPDisabledForFn)(uint32 entry, uint8 flags);
+ IsVMAPDisabledForFn IsVMAPDisabledForPtr;
};
}
diff --git a/src/server/game/AI/SmartScripts/SmartScript.cpp b/src/server/game/AI/SmartScripts/SmartScript.cpp
index fb3bbd17a69..ccfeb61206f 100644
--- a/src/server/game/AI/SmartScripts/SmartScript.cpp
+++ b/src/server/game/AI/SmartScripts/SmartScript.cpp
@@ -83,13 +83,13 @@ void SmartScript::ProcessEventsFor(SMART_EVENT e, Unit* unit, uint32 var0, uint3
{
for (SmartAIEventList::iterator i = mEvents.begin(); i != mEvents.end(); ++i)
{
- SMART_EVENT eventType = SMART_EVENT((*i).GetEventType());
+ SMART_EVENT eventType = SMART_EVENT(i->GetEventType());
if (eventType == SMART_EVENT_LINK)//special handling
continue;
- if (eventType == e/* && (!(*i).event.event_phase_mask || IsInPhase((*i).event.event_phase_mask)) && !((*i).event.event_flags & SMART_EVENT_FLAG_NOT_REPEATABLE && (*i).runOnce)*/)
+ if (eventType == e /*&& (!i->event.event_phase_mask || IsInPhase(i->event.event_phase_mask)) && !(i->event.event_flags & SMART_EVENT_FLAG_NOT_REPEATABLE && i->runOnce)*/)
{
- ConditionList conds = sConditionMgr->GetConditionsForSmartEvent((*i).entryOrGuid, (*i).event_id, (*i).source_type);
+ ConditionList conds = sConditionMgr->GetConditionsForSmartEvent(i->entryOrGuid, i->event_id, i->source_type);
ConditionSourceInfo info = ConditionSourceInfo(unit, GetBaseObject());
if (sConditionMgr->IsObjectMeetToConditions(info, conds))
@@ -167,7 +167,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
{
if (IsCreature(*itr))
- sCreatureTextMgr->SendChat((*itr)->ToCreature(), uint8(e.action.talk.textGroupID), IsPlayer(GetLastInvoker())? GetLastInvoker() : 0);
+ sCreatureTextMgr->SendChat((*itr)->ToCreature(), uint8(e.action.talk.textGroupID), IsPlayer(GetLastInvoker()) ? GetLastInvoker() : 0);
else if (IsPlayer(*itr) && me)
{
Unit* templastInvoker = GetLastInvoker();
@@ -2262,8 +2262,8 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
if (e.link && e.link != e.event_id)
{
- SmartScriptHolder linked = FindLinkedEvent(e.link);
- if (linked.GetActionType() && linked.GetEventType() == SMART_EVENT_LINK)
+ SmartScriptHolder& linked = SmartAIMgr::FindLinkedEvent(mEvents, e.link);
+ if (linked)
ProcessEvent(linked, unit, var0, var1, bvar, spell, gob);
else
TC_LOG_ERROR("sql.sql", "SmartScript::ProcessAction: Entry %d SourceType %u, Event %u, Link Event %u not found or invalid, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.link);
@@ -2468,10 +2468,10 @@ ObjectList* SmartScript::GetTargets(SmartScriptHolder const& e, Unit* invoker /*
if (!IsCreature(*itr))
continue;
- if (me && me == *itr)
+ if (me && me->GetGUID() == (*itr)->GetGUID())
continue;
- if (((e.target.unitRange.creature && (*itr)->ToCreature()->GetEntry() == e.target.unitRange.creature) || !e.target.unitRange.creature) && baseObject->IsInRange(*itr, (float)e.target.unitRange.minDist, (float)e.target.unitRange.maxDist))
+ if ((!e.target.unitRange.creature || (*itr)->ToCreature()->GetEntry() == e.target.unitRange.creature) && baseObject->IsInRange(*itr, float(e.target.unitRange.minDist), float(e.target.unitRange.maxDist)))
l->push_back(*itr);
}
@@ -2487,10 +2487,10 @@ ObjectList* SmartScript::GetTargets(SmartScriptHolder const& e, Unit* invoker /*
if (!IsCreature(*itr))
continue;
- if (me && me == *itr)
+ if (me && me->GetGUID() == (*itr)->GetGUID())
continue;
- if ((e.target.unitDistance.creature && (*itr)->ToCreature()->GetEntry() == e.target.unitDistance.creature) || !e.target.unitDistance.creature)
+ if (!e.target.unitDistance.creature || (*itr)->ToCreature()->GetEntry() == e.target.unitDistance.creature)
l->push_back(*itr);
}
@@ -2506,10 +2506,10 @@ ObjectList* SmartScript::GetTargets(SmartScriptHolder const& e, Unit* invoker /*
if (!IsGameObject(*itr))
continue;
- if (go && go == *itr)
+ if (go && go->GetGUID() == (*itr)->GetGUID())
continue;
- if ((e.target.goDistance.entry && (*itr)->ToGameObject()->GetEntry() == e.target.goDistance.entry) || !e.target.goDistance.entry)
+ if (!e.target.goDistance.entry || (*itr)->ToGameObject()->GetEntry() == e.target.goDistance.entry)
l->push_back(*itr);
}
@@ -2525,10 +2525,10 @@ ObjectList* SmartScript::GetTargets(SmartScriptHolder const& e, Unit* invoker /*
if (!IsGameObject(*itr))
continue;
- if (go && go == *itr)
+ if (go && go->GetGUID() == (*itr)->GetGUID())
continue;
- if (((e.target.goRange.entry && IsGameObject(*itr) && (*itr)->ToGameObject()->GetEntry() == e.target.goRange.entry) || !e.target.goRange.entry) && baseObject->IsInRange((*itr), (float)e.target.goRange.minDist, (float)e.target.goRange.maxDist))
+ if ((!e.target.goRange.entry && (*itr)->ToGameObject()->GetEntry() == e.target.goRange.entry) && baseObject->IsInRange(*itr, float(e.target.goRange.minDist), float(e.target.goRange.maxDist)))
l->push_back(*itr);
}
@@ -2537,32 +2537,28 @@ ObjectList* SmartScript::GetTargets(SmartScriptHolder const& e, Unit* invoker /*
}
case SMART_TARGET_CREATURE_GUID:
{
- Creature* target = NULL;
if (!scriptTrigger && !baseObject)
{
TC_LOG_ERROR("sql.sql", "SMART_TARGET_CREATURE_GUID can not be used without invoker");
break;
}
- target = FindCreatureNear(scriptTrigger ? scriptTrigger : baseObject, e.target.unitGUID.dbGuid);
-
- if (target && (!e.target.unitGUID.entry || target->GetEntry() == e.target.unitGUID.entry))
- l->push_back(target);
+ if (Creature* target = FindCreatureNear(scriptTrigger ? scriptTrigger : baseObject, e.target.unitGUID.dbGuid))
+ if (!e.target.unitGUID.entry || target->GetEntry() == e.target.unitGUID.entry)
+ l->push_back(target);
break;
}
case SMART_TARGET_GAMEOBJECT_GUID:
{
- GameObject* target = NULL;
if (!scriptTrigger && !baseObject)
{
TC_LOG_ERROR("sql.sql", "SMART_TARGET_GAMEOBJECT_GUID can not be used without invoker");
break;
}
- target = FindGameObjectNear(scriptTrigger ? scriptTrigger : baseObject, e.target.goGUID.dbGuid);
-
- if (target && (!e.target.goGUID.entry || target->GetEntry() == e.target.goGUID.entry))
- l->push_back(target);
+ if (GameObject* target = FindGameObjectNear(scriptTrigger ? scriptTrigger : baseObject, e.target.goGUID.dbGuid))
+ if (!e.target.goGUID.entry || target->GetEntry() == e.target.goGUID.entry)
+ l->push_back(target);
break;
}
case SMART_TARGET_PLAYER_RANGE:
@@ -2601,26 +2597,21 @@ ObjectList* SmartScript::GetTargets(SmartScriptHolder const& e, Unit* invoker /*
}
case SMART_TARGET_CLOSEST_CREATURE:
{
- Creature* target = GetClosestCreatureWithEntry(baseObject, e.target.closest.entry, (float)(e.target.closest.dist ? e.target.closest.dist : 100), !e.target.closest.dead);
- if (target)
+ if (Creature* target = GetClosestCreatureWithEntry(baseObject, e.target.closest.entry, float(e.target.closest.dist ? e.target.closest.dist : 100), !e.target.closest.dead))
l->push_back(target);
break;
}
case SMART_TARGET_CLOSEST_GAMEOBJECT:
{
- GameObject* target = GetClosestGameObjectWithEntry(baseObject, e.target.closest.entry, (float)(e.target.closest.dist ? e.target.closest.dist : 100));
- if (target)
+ if (GameObject* target = GetClosestGameObjectWithEntry(baseObject, e.target.closest.entry, float(e.target.closest.dist ? e.target.closest.dist : 100)))
l->push_back(target);
break;
}
case SMART_TARGET_CLOSEST_PLAYER:
{
if (me)
- {
- Player* target = me->SelectNearestPlayer((float)e.target.playerDistance.dist);
- if (target)
+ if (Player* target = me->SelectNearestPlayer(float(e.target.playerDistance.dist)))
l->push_back(target);
- }
break;
}
case SMART_TARGET_OWNER_OR_SUMMONER:
@@ -2653,7 +2644,6 @@ ObjectList* SmartScript::GetTargets(SmartScriptHolder const& e, Unit* invoker /*
if (me)
if (Unit* target = me->SelectNearestTarget(e.target.closestAttackable.maxDist, e.target.closestAttackable.playerOnly != 0))
l->push_back(target);
-
break;
}
case SMART_TARGET_CLOSEST_FRIENDLY:
@@ -2661,7 +2651,6 @@ ObjectList* SmartScript::GetTargets(SmartScriptHolder const& e, Unit* invoker /*
if (me)
if (Unit* target = DoFindClosestFriendlyInRange(e.target.closestFriendly.maxDist, e.target.closestFriendly.playerOnly != 0))
l->push_back(target);
-
break;
}
case SMART_TARGET_POSITION:
diff --git a/src/server/game/AI/SmartScripts/SmartScript.h b/src/server/game/AI/SmartScripts/SmartScript.h
index 02bc1a2b487..b59b62c5697 100644
--- a/src/server/game/AI/SmartScripts/SmartScript.h
+++ b/src/server/game/AI/SmartScripts/SmartScript.h
@@ -257,21 +257,6 @@ class SmartScript
}
}
}
- SmartScriptHolder FindLinkedEvent(uint32 link)
- {
- if (!mEvents.empty())
- {
- for (SmartAIEventList::iterator i = mEvents.begin(); i != mEvents.end(); ++i)
- {
- if (i->event_id == link)
- {
- return (*i);
- }
- }
- }
- SmartScriptHolder s;
- return s;
- }
};
#endif
diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp
index 2a7fd1369e2..0b2fdfc6bee 100644
--- a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp
+++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp
@@ -91,7 +91,6 @@ void SmartWaypointMgr::LoadFromDB()
while (result->NextRow());
TC_LOG_INFO("server.loading", ">> Loaded %u SmartAI waypoint paths (total %u waypoints) in %u ms", count, total, GetMSTimeDiffToNow(oldMSTime));
-
}
SmartWaypointMgr::~SmartWaypointMgr()
@@ -192,23 +191,23 @@ void SmartAIMgr::LoadSmartAIFromDB()
}
else
{
- CreatureData const* creature = sObjectMgr->GetCreatureData(uint32(abs(temp.entryOrGuid)));
+ CreatureData const* creature = sObjectMgr->GetCreatureData(uint32(std::abs(temp.entryOrGuid)));
if (!creature)
{
- TC_LOG_ERROR("sql.sql", "SmartAIMgr::LoadSmartAIFromDB: Creature guid (%u) does not exist, skipped loading.", uint32(abs(temp.entryOrGuid)));
+ TC_LOG_ERROR("sql.sql", "SmartAIMgr::LoadSmartAIFromDB: Creature guid (%u) does not exist, skipped loading.", uint32(std::abs(temp.entryOrGuid)));
continue;
}
CreatureTemplate const* creatureInfo = sObjectMgr->GetCreatureTemplate(creature->id);
if (!creatureInfo)
{
- TC_LOG_ERROR("sql.sql", "SmartAIMgr::LoadSmartAIFromDB: Creature entry (%u) does not exist, skipped loading.", uint32(temp.entryOrGuid));
+ TC_LOG_ERROR("sql.sql", "SmartAIMgr::LoadSmartAIFromDB: Creature entry (%u) guid (%u) does not exist, skipped loading.", creature->id, uint32(std::abs(temp.entryOrGuid)));
continue;
}
if (creatureInfo->AIName != "SmartAI")
{
- TC_LOG_ERROR("sql.sql", "SmartAIMgr::LoadSmartAIFromDB: Creature entry (%u) is not using SmartAI, skipped loading.", uint32(temp.entryOrGuid));
+ TC_LOG_ERROR("sql.sql", "SmartAIMgr::LoadSmartAIFromDB: Creature entry (%u) guid (%u) is not using SmartAI, skipped loading.", creature->id, uint32(std::abs(temp.entryOrGuid)));
continue;
}
}
@@ -263,26 +262,29 @@ void SmartAIMgr::LoadSmartAIFromDB()
}
while (result->NextRow());
- // TO-DO: Find better way
- for (uint8 i = 0; i < SMART_SCRIPT_TYPE_MAX; i++)
+ // Post Loading Validation
+ for (uint8 i = 0; i < SMART_SCRIPT_TYPE_MAX; ++i)
{
- for (auto itr = mEventMap[i].begin(); itr != mEventMap[i].end(); ++itr)
+ for (SmartAIEventMap::iterator itr = mEventMap[i].begin(); itr != mEventMap[i].end(); ++itr)
{
- for (auto e : mEventMap[i][itr->first])
+ for (SmartScriptHolder const& e : itr->second)
{
- bool found = false;
- if (e.link && e.link != e.event_id)
+ if (e.link)
{
- for (auto linked : mEventMap[i][itr->first])
+ if (!FindLinkedEvent(itr->second, e.link))
{
- if (linked.event_id == e.link)
- if (linked.GetActionType() && linked.GetEventType() == SMART_EVENT_LINK)
- found = true;
+ TC_LOG_ERROR("sql.sql", "SmartAIMgr::LoadSmartAIFromDB: Entry %d SourceType %u, Event %u, Link Event %u not found or invalid.",
+ e.entryOrGuid, e.GetScriptType(), e.event_id, e.link);
}
+ }
- if (!found)
- TC_LOG_ERROR("sql.sql", "SmartAIMgr::LoadSmartAIFromDB: Entry %d SourceType %u, Event %u, Link Event %u not found or invalid",
- e.entryOrGuid, e.GetScriptType(), e.event_id, e.link);
+ if (e.GetEventType() == SMART_EVENT_LINK)
+ {
+ if (!FindLinkedSourceEvent(itr->second, e.event_id))
+ {
+ TC_LOG_ERROR("sql.sql", "SmartAIMgr::LoadSmartAIFromDB: Entry %d SourceType %u, Event %u, Link Source Event not found or invalid. Event will never trigger.",
+ e.entryOrGuid, e.GetScriptType(), e.event_id);
+ }
}
}
}
@@ -295,8 +297,13 @@ void SmartAIMgr::LoadSmartAIFromDB()
bool SmartAIMgr::IsTargetValid(SmartScriptHolder const& e)
{
+ if (std::abs(e.target.o) > 2 * float(M_PI))
+ TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry %d SourceType %u Event %u Action %u has abs(`target.o` = %f) > 2*PI (orientation is expressed in radians)",
+ e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), e.target.o);
+
if (e.GetActionType() == SMART_ACTION_INSTALL_AI_TEMPLATE)
return true; // AI template has special handling
+
switch (e.GetTargetType())
{
case SMART_TARGET_CREATURE_DISTANCE:
@@ -375,27 +382,38 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e)
TC_LOG_ERROR("sql.sql", "SmartAIMgr: EntryOrGuid %d using event(%u) has invalid event type (%u), skipped.", e.entryOrGuid, e.event_id, e.GetEventType());
return false;
}
+
// in SMART_SCRIPT_TYPE_TIMED_ACTIONLIST all event types are overriden by core
if (e.GetScriptType() != SMART_SCRIPT_TYPE_TIMED_ACTIONLIST && !(SmartAIEventMask[e.event.type][1] & SmartAITypeMask[e.GetScriptType()][1]))
{
TC_LOG_ERROR("sql.sql", "SmartAIMgr: EntryOrGuid %d, event type %u can not be used for Script type %u", e.entryOrGuid, e.GetEventType(), e.GetScriptType());
return false;
}
+
if (e.action.type <= 0 || e.action.type >= SMART_ACTION_END)
{
TC_LOG_ERROR("sql.sql", "SmartAIMgr: EntryOrGuid %d using event(%u) has invalid action type (%u), skipped.", e.entryOrGuid, e.event_id, e.GetActionType());
return false;
}
+
if (e.event.event_phase_mask > SMART_EVENT_PHASE_ALL)
{
TC_LOG_ERROR("sql.sql", "SmartAIMgr: EntryOrGuid %d using event(%u) has invalid phase mask (%u), skipped.", e.entryOrGuid, e.event_id, e.event.event_phase_mask);
return false;
}
+
if (e.event.event_flags > SMART_EVENT_FLAGS_ALL)
{
TC_LOG_ERROR("sql.sql", "SmartAIMgr: EntryOrGuid %d using event(%u) has invalid event flags (%u), skipped.", e.entryOrGuid, e.event_id, e.event.event_flags);
return false;
}
+
+ if (e.link && e.link == e.event_id)
+ {
+ TC_LOG_ERROR("sql.sql", "SmartAIMgr: EntryOrGuid %d SourceType %u, Event %u, Event is linking self (infinite loop), skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id);
+ return false;
+ }
+
if (e.GetScriptType() == SMART_SCRIPT_TYPE_TIMED_ACTIONLIST)
{
e.event.type = SMART_EVENT_UPDATE_OOC;//force default OOC, can change when calling the script!
@@ -407,8 +425,7 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e)
}
else
{
- uint32 type = e.event.type;
- switch (type)
+ switch (e.GetEventType())
{
case SMART_EVENT_UPDATE:
case SMART_EVENT_UPDATE_IC:
@@ -568,17 +585,9 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e)
break;
}
case SMART_EVENT_TEXT_OVER:
- //if (e.event.textOver.textGroupID && !IsTextValid(e, e.event.textOver.textGroupID)) return false;// 0 is a valid text group!
- break;
- case SMART_EVENT_LINK:
- {
- if (e.link && e.link == e.event_id)
- {
- TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry %d SourceType %u, Event %u, Link Event is linking self (infinite loop), skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id);
+ if (!IsTextValid(e, e.event.textOver.textGroupID))
return false;
- }
break;
- }
case SMART_EVENT_DUMMY_EFFECT:
{
if (!IsSpellValid(e, e.event.dummy.spell))
@@ -686,6 +695,7 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e)
return false;
}
break;
+ case SMART_EVENT_LINK:
case SMART_EVENT_GO_STATE_CHANGED:
case SMART_EVENT_GO_EVENT_INFORM:
case SMART_EVENT_TIMED_EVENT_TRIGGERED:
@@ -729,14 +739,10 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e)
switch (e.GetActionType())
{
case SMART_ACTION_TALK:
- {
- if (e.GetScriptType() == SMART_SCRIPT_TYPE_CREATURE)
- {
- if (!IsTextValid(e, e.action.talk.textGroupID))
- return false;
- }
+ case SMART_ACTION_SIMPLE_TALK:
+ if (!IsTextValid(e, e.action.talk.textGroupID))
+ return false;
break;
- }
case SMART_ACTION_SET_FACTION:
if (e.action.faction.factionID && !sFactionTemplateStore.LookupEntry(e.action.faction.factionID))
{
@@ -816,7 +822,7 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e)
if (!IsSpellValid(e, e.action.cast.spell))
return false;
- SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(e.action.cast.spell);
+ SpellInfo const* spellInfo = sSpellMgr->EnsureSpellInfo(e.action.cast.spell);
for (uint32 j = 0; j < MAX_SPELL_EFFECTS; ++j)
{
if (spellInfo->Effects[j].IsEffect(SPELL_EFFECT_KILL_CREDIT) || spellInfo->Effects[j].IsEffect(SPELL_EFFECT_KILL_CREDIT2))
@@ -979,10 +985,10 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e)
if (!NotNULL(e, e.action.item.count))
return false;
- CacheSpellContainerBounds sBounds = GetCreditItemSpellContainerBounds(e.action.item.entry);
+ CacheSpellContainerBounds sBounds = GetCreateItemSpellContainerBounds(e.action.item.entry);
for (CacheSpellContainer::const_iterator itr = sBounds.first; itr != sBounds.second; ++itr)
TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry %d SourceType %u Event %u Action %u Create Item: There is a create item spell for item %u (SpellId: %u effect: %u)",
- e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), e.action.item.entry, itr->second.first, itr->second.second);
+ e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), e.action.item.entry, itr->second.first, itr->second.second);
break;
}
case SMART_ACTION_TELEPORT:
@@ -1183,7 +1189,6 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e)
case SMART_ACTION_SET_NPC_FLAG:
case SMART_ACTION_ADD_NPC_FLAG:
case SMART_ACTION_REMOVE_NPC_FLAG:
- case SMART_ACTION_SIMPLE_TALK:
case SMART_ACTION_CROSS_CAST:
case SMART_ACTION_CALL_RANDOM_TIMED_ACTIONLIST:
case SMART_ACTION_RANDOM_MOVE:
@@ -1214,32 +1219,47 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e)
return true;
}
-bool SmartAIMgr::IsTextValid(SmartScriptHolder const& e, uint32 id) // unused
+bool SmartAIMgr::IsTextValid(SmartScriptHolder const& e, uint32 id)
{
- bool error = false;
+ if (e.GetScriptType() != SMART_SCRIPT_TYPE_CREATURE)
+ return true;
+
uint32 entry = 0;
- if (e.entryOrGuid >= 0)
- entry = uint32(e.entryOrGuid);
+ if (e.GetEventType() == SMART_EVENT_TEXT_OVER)
+ {
+ entry = e.event.textOver.creatureEntry;
+ }
else
{
- entry = uint32(abs(e.entryOrGuid));
- CreatureData const* data = sObjectMgr->GetCreatureData(entry);
- if (!data)
+ switch (e.GetTargetType())
{
- TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry %d SourceType %u Event %u Action %u using non-existent Creature guid %d, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), entry);
- return false;
+ case SMART_TARGET_CREATURE_DISTANCE:
+ case SMART_TARGET_CREATURE_RANGE:
+ case SMART_TARGET_CLOSEST_CREATURE:
+ return true; // ignore
+ default:
+ if (e.entryOrGuid < 0)
+ {
+ entry = uint32(std::abs(e.entryOrGuid));
+ CreatureData const* data = sObjectMgr->GetCreatureData(entry);
+ if (!data)
+ {
+ TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry %d SourceType %u Event %u Action %u using non-existent Creature guid %d, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), entry);
+ return false;
+ }
+ else
+ entry = data->id;
+ }
+ else
+ entry = uint32(e.entryOrGuid);
+ break;
}
- else
- entry = data->id;
}
if (!entry || !sCreatureTextMgr->TextExist(entry, uint8(id)))
- error = true;
-
- if (error)
{
- TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry %d SourceType %u Event %u Action %u using non-existent Text id %d, skipped.", e.entryOrGuid, e.GetScriptType(), e.source_type, e.GetActionType(), id);
+ TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry %d SourceType %u Event %u Action %u using non-existent Text id %d, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), id);
return false;
}
@@ -1299,7 +1319,7 @@ CacheSpellContainerBounds SmartAIMgr::GetKillCreditSpellContainerBounds(uint32 k
return KillCreditSpellStore.equal_range(killCredit);
}
-CacheSpellContainerBounds SmartAIMgr::GetCreditItemSpellContainerBounds(uint32 itemId) const
+CacheSpellContainerBounds SmartAIMgr::GetCreateItemSpellContainerBounds(uint32 itemId) const
{
return CreateItemSpellStore.equal_range(itemId);
}
diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.h b/src/server/game/AI/SmartScripts/SmartScriptMgr.h
index bdd1dfc6ae0..a567a4be35e 100644
--- a/src/server/game/AI/SmartScripts/SmartScriptMgr.h
+++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.h
@@ -1355,6 +1355,8 @@ struct SmartScriptHolder
bool active;
bool runOnce;
bool enableTimed;
+
+ operator bool() const { return entryOrGuid != 0; }
};
typedef std::unordered_map<uint32, WayPoint*> WPPath;
@@ -1477,6 +1479,30 @@ class SmartAIMgr
}
}
+ static SmartScriptHolder& FindLinkedSourceEvent(SmartAIEventList& list, uint32 eventId)
+ {
+ SmartAIEventList::iterator itr = std::find_if(list.begin(), list.end(),
+ [eventId](SmartScriptHolder& source) { return source.link == eventId; });
+
+ if (itr != list.end())
+ return *itr;
+
+ static SmartScriptHolder SmartScriptHolderDummy;
+ return SmartScriptHolderDummy;
+ }
+
+ static SmartScriptHolder& FindLinkedEvent(SmartAIEventList& list, uint32 link)
+ {
+ SmartAIEventList::iterator itr = std::find_if(list.begin(), list.end(),
+ [link](SmartScriptHolder& linked) { return linked.event_id == link && linked.GetEventType() == SMART_EVENT_LINK; });
+
+ if (itr != list.end())
+ return *itr;
+
+ static SmartScriptHolder SmartScriptHolderDummy;
+ return SmartScriptHolderDummy;
+ }
+
private:
//event stores
SmartAIEventMap mEventMap[SMART_SCRIPT_TYPE_MAX];
@@ -1484,16 +1510,6 @@ class SmartAIMgr
bool IsEventValid(SmartScriptHolder& e);
bool IsTargetValid(SmartScriptHolder const& e);
- /*inline bool IsTargetValid(SmartScriptHolder e, int32 target)
- {
- if (target < SMART_TARGET_NONE || target >= SMART_TARGET_END)
- {
- TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry %d SourceType %u Event %u Action %u uses invalid Target type %d, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), target);
- return false;
- }
- return true;
- }*/
-
bool IsMinMaxValid(SmartScriptHolder const& e, uint32 min, uint32 max)
{
if (max < min)
@@ -1623,7 +1639,7 @@ class SmartAIMgr
CacheSpellContainerBounds GetSummonCreatureSpellContainerBounds(uint32 creatureEntry) const;
CacheSpellContainerBounds GetSummonGameObjectSpellContainerBounds(uint32 gameObjectEntry) const;
CacheSpellContainerBounds GetKillCreditSpellContainerBounds(uint32 killCredit) const;
- CacheSpellContainerBounds GetCreditItemSpellContainerBounds(uint32 itemId) const;
+ CacheSpellContainerBounds GetCreateItemSpellContainerBounds(uint32 itemId) const;
CacheSpellContainer SummonCreatureSpellStore;
CacheSpellContainer SummonGameObjectSpellStore;
diff --git a/src/server/game/Accounts/AccountMgr.cpp b/src/server/game/Accounts/AccountMgr.cpp
index 682df18b2d1..4abcf35fe57 100644
--- a/src/server/game/Accounts/AccountMgr.cpp
+++ b/src/server/game/Accounts/AccountMgr.cpp
@@ -84,7 +84,7 @@ AccountOpResult AccountMgr::DeleteAccount(uint32 accountId)
ObjectGuid guid(HIGHGUID_PLAYER, (*result)[0].GetUInt32());
// Kick if player is online
- if (Player* p = ObjectAccessor::FindPlayer(guid))
+ if (Player* p = ObjectAccessor::FindConnectedPlayer(guid))
{
WorldSession* s = p->GetSession();
s->KickPlayer(); // mark session to remove at next session list update
diff --git a/src/server/game/AuctionHouse/AuctionHouseMgr.cpp b/src/server/game/AuctionHouse/AuctionHouseMgr.cpp
index 79512e57fe3..9390ec80208 100644
--- a/src/server/game/AuctionHouse/AuctionHouseMgr.cpp
+++ b/src/server/game/AuctionHouse/AuctionHouseMgr.cpp
@@ -93,7 +93,7 @@ void AuctionHouseMgr::SendAuctionWonMail(AuctionEntry* auction, SQLTransaction&
uint32 bidderAccId = 0;
ObjectGuid bidderGuid(HIGHGUID_PLAYER, auction->bidder);
- Player* bidder = ObjectAccessor::FindPlayer(bidderGuid);
+ Player* bidder = ObjectAccessor::FindConnectedPlayer(bidderGuid);
// data for gm.log
std::string bidderName;
bool logGmTrade = false;
@@ -107,7 +107,7 @@ void AuctionHouseMgr::SendAuctionWonMail(AuctionEntry* auction, SQLTransaction&
else
{
bidderAccId = sObjectMgr->GetPlayerAccountIdByGUID(bidderGuid);
- logGmTrade = AccountMgr::HasPermission(bidderAccId, rbac::RBAC_PERM_LOG_GM_TRADE, realmID);
+ logGmTrade = AccountMgr::HasPermission(bidderAccId, rbac::RBAC_PERM_LOG_GM_TRADE, realmHandle.Index);
if (logGmTrade && !sObjectMgr->GetPlayerNameByGUID(bidderGuid, bidderName))
bidderName = sObjectMgr->GetTrinityStringForDBCLocale(LANG_UNKNOWN);
@@ -157,7 +157,7 @@ void AuctionHouseMgr::SendAuctionWonMail(AuctionEntry* auction, SQLTransaction&
void AuctionHouseMgr::SendAuctionSalePendingMail(AuctionEntry* auction, SQLTransaction& trans)
{
ObjectGuid owner_guid(HIGHGUID_PLAYER, auction->owner);
- Player* owner = ObjectAccessor::FindPlayer(owner_guid);
+ Player* owner = ObjectAccessor::FindConnectedPlayer(owner_guid);
uint32 owner_accId = sObjectMgr->GetPlayerAccountIdByGUID(owner_guid);
// owner exist (online or offline)
if (owner || owner_accId)
@@ -169,7 +169,7 @@ void AuctionHouseMgr::SendAuctionSalePendingMail(AuctionEntry* auction, SQLTrans
void AuctionHouseMgr::SendAuctionSuccessfulMail(AuctionEntry* auction, SQLTransaction& trans)
{
ObjectGuid owner_guid(HIGHGUID_PLAYER, auction->owner);
- Player* owner = ObjectAccessor::FindPlayer(owner_guid);
+ Player* owner = ObjectAccessor::FindConnectedPlayer(owner_guid);
uint32 owner_accId = sObjectMgr->GetPlayerAccountIdByGUID(owner_guid);
// owner exist
if (owner || owner_accId)
@@ -200,7 +200,7 @@ void AuctionHouseMgr::SendAuctionExpiredMail(AuctionEntry* auction, SQLTransacti
return;
ObjectGuid owner_guid(HIGHGUID_PLAYER, auction->owner);
- Player* owner = ObjectAccessor::FindPlayer(owner_guid);
+ Player* owner = ObjectAccessor::FindConnectedPlayer(owner_guid);
uint32 owner_accId = sObjectMgr->GetPlayerAccountIdByGUID(owner_guid);
// owner exist
if (owner || owner_accId)
@@ -223,7 +223,7 @@ void AuctionHouseMgr::SendAuctionExpiredMail(AuctionEntry* auction, SQLTransacti
void AuctionHouseMgr::SendAuctionOutbiddedMail(AuctionEntry* auction, uint32 newPrice, Player* newBidder, SQLTransaction& trans)
{
ObjectGuid oldBidder_guid(HIGHGUID_PLAYER, auction->bidder);
- Player* oldBidder = ObjectAccessor::FindPlayer(oldBidder_guid);
+ Player* oldBidder = ObjectAccessor::FindConnectedPlayer(oldBidder_guid);
uint32 oldBidder_accId = 0;
if (!oldBidder)
@@ -245,7 +245,7 @@ void AuctionHouseMgr::SendAuctionOutbiddedMail(AuctionEntry* auction, uint32 new
void AuctionHouseMgr::SendAuctionCancelledToBidderMail(AuctionEntry* auction, SQLTransaction& trans, Item* item)
{
ObjectGuid bidder_guid = ObjectGuid(HIGHGUID_PLAYER, auction->bidder);
- Player* bidder = ObjectAccessor::FindPlayer(bidder_guid);
+ Player* bidder = ObjectAccessor::FindConnectedPlayer(bidder_guid);
uint32 bidder_accId = 0;
if (!bidder)
diff --git a/src/server/game/Battlefield/Battlefield.cpp b/src/server/game/Battlefield/Battlefield.cpp
index ab90fca0115..3dcc126f872 100644
--- a/src/server/game/Battlefield/Battlefield.cpp
+++ b/src/server/game/Battlefield/Battlefield.cpp
@@ -422,7 +422,7 @@ void Battlefield::BroadcastPacketToQueue(WorldPacket& data) const
{
for (uint8 team = 0; team < BG_TEAMS_COUNT; ++team)
for (GuidSet::const_iterator itr = m_PlayersInQueue[team].begin(); itr != m_PlayersInQueue[team].end(); ++itr)
- if (Player* player = ObjectAccessor::FindPlayer(*itr))
+ if (Player* player = ObjectAccessor::FindConnectedPlayer(*itr))
player->SendDirectMessage(&data);
}
diff --git a/src/server/game/Battlefield/Zones/BattlefieldWG.cpp b/src/server/game/Battlefield/Zones/BattlefieldWG.cpp
index 4c5994f6b3a..326adb66c72 100644
--- a/src/server/game/Battlefield/Zones/BattlefieldWG.cpp
+++ b/src/server/game/Battlefield/Zones/BattlefieldWG.cpp
@@ -253,7 +253,7 @@ void BattlefieldWG::OnBattleStart()
for (GuidSet::const_iterator itr = m_players[team].begin(); itr != m_players[team].end(); ++itr)
{
// Kick player in orb room, TODO: offline player ?
- if (Player* player = sObjectAccessor->FindPlayer(*itr))
+ if (Player* player = ObjectAccessor::FindPlayer(*itr))
{
float x, y, z;
player->GetPosition(x, y, z);
@@ -356,7 +356,7 @@ void BattlefieldWG::OnBattleEnd(bool endByTimer)
for (GuidSet::const_iterator itr = m_PlayersInWar[GetDefenderTeam()].begin(); itr != m_PlayersInWar[GetDefenderTeam()].end(); ++itr)
{
- if (Player* player = sObjectAccessor->FindPlayer(*itr))
+ if (Player* player = ObjectAccessor::FindPlayer(*itr))
{
player->CastSpell(player, SPELL_ESSENCE_OF_WINTERGRASP, true);
player->CastSpell(player, SPELL_VICTORY_REWARD, true);
@@ -369,13 +369,13 @@ void BattlefieldWG::OnBattleEnd(bool endByTimer)
}
for (GuidSet::const_iterator itr = m_PlayersInWar[GetAttackerTeam()].begin(); itr != m_PlayersInWar[GetAttackerTeam()].end(); ++itr)
- if (Player* player = sObjectAccessor->FindPlayer(*itr))
+ if (Player* player = ObjectAccessor::FindPlayer(*itr))
player->CastSpell(player, SPELL_DEFEAT_REWARD, true);
for (uint8 team = 0; team < 2; ++team)
{
for (GuidSet::const_iterator itr = m_PlayersInWar[team].begin(); itr != m_PlayersInWar[team].end(); ++itr)
- if (Player* player = sObjectAccessor->FindPlayer(*itr))
+ if (Player* player = ObjectAccessor::FindPlayer(*itr))
RemoveAurasFromPlayer(player);
m_PlayersInWar[team].clear();
@@ -394,7 +394,7 @@ void BattlefieldWG::OnBattleEnd(bool endByTimer)
{
for (GuidSet::const_iterator itr = m_players[team].begin(); itr != m_players[team].end(); ++itr)
{
- if (Player* player = sObjectAccessor->FindPlayer(*itr))
+ if (Player* player = ObjectAccessor::FindPlayer(*itr))
{
player->RemoveAurasDueToSpell(m_DefenderTeam == TEAM_ALLIANCE ? SPELL_HORDE_CONTROL_PHASE_SHIFT : SPELL_ALLIANCE_CONTROL_PHASE_SHIFT, player->GetGUID());
player->AddAura(m_DefenderTeam == TEAM_HORDE ? SPELL_HORDE_CONTROL_PHASE_SHIFT : SPELL_ALLIANCE_CONTROL_PHASE_SHIFT, player);
@@ -620,7 +620,7 @@ void BattlefieldWG::HandleKill(Player* killer, Unit* victim)
if (victim->GetTypeId() == TYPEID_PLAYER)
{
for (GuidSet::const_iterator itr = m_PlayersInWar[killerTeam].begin(); itr != m_PlayersInWar[killerTeam].end(); ++itr)
- if (Player* player = sObjectAccessor->FindPlayer(*itr))
+ if (Player* player = ObjectAccessor::FindPlayer(*itr))
if (player->GetDistance2d(killer) < 40)
PromotePlayer(player);
return;
@@ -635,7 +635,7 @@ void BattlefieldWG::HandleKill(Player* killer, Unit* victim)
{
again = true;
for (GuidSet::const_iterator iter = m_PlayersInWar[killerTeam].begin(); iter != m_PlayersInWar[killerTeam].end(); ++iter)
- if (Player* player = sObjectAccessor->FindPlayer(*iter))
+ if (Player* player = ObjectAccessor::FindPlayer(*iter))
if (player->GetDistance2d(killer) < 40.0f)
PromotePlayer(player);
}
@@ -847,7 +847,7 @@ void BattlefieldWG::SendInitWorldStatesToAll()
{
for (uint8 team = 0; team < 2; team++)
for (GuidSet::iterator itr = m_players[team].begin(); itr != m_players[team].end(); ++itr)
- if (Player* player = sObjectAccessor->FindPlayer(*itr))
+ if (Player* player = ObjectAccessor::FindPlayer(*itr))
SendInitWorldStatesTo(player);
}
@@ -858,7 +858,7 @@ void BattlefieldWG::BrokenWallOrTower(TeamId /*team*/)
{
for (GuidSet::const_iterator itr = m_PlayersInWar[GetAttackerTeam()].begin(); itr != m_PlayersInWar[GetAttackerTeam()].end(); ++itr)
{
- if (Player* player = sObjectAccessor->FindPlayer(*itr))
+ if (Player* player = ObjectAccessor::FindPlayer(*itr))
IncrementQuest(player, WGQuest[player->GetTeamId()][2], true);
}
}*/
@@ -876,12 +876,12 @@ void BattlefieldWG::UpdatedDestroyedTowerCount(TeamId team)
// Remove buff stack on attackers
for (GuidSet::const_iterator itr = m_PlayersInWar[GetAttackerTeam()].begin(); itr != m_PlayersInWar[GetAttackerTeam()].end(); ++itr)
- if (Player* player = sObjectAccessor->FindPlayer(*itr))
+ if (Player* player = ObjectAccessor::FindPlayer(*itr))
player->RemoveAuraFromStack(SPELL_TOWER_CONTROL);
// Add buff stack to defenders
for (GuidSet::const_iterator itr = m_PlayersInWar[GetDefenderTeam()].begin(); itr != m_PlayersInWar[GetDefenderTeam()].end(); ++itr)
- if (Player* player = sObjectAccessor->FindPlayer(*itr))
+ if (Player* player = ObjectAccessor::FindPlayer(*itr))
{
player->CastSpell(player, SPELL_TOWER_CONTROL, true);
DoCompleteOrIncrementAchievement(ACHIEVEMENTS_WG_TOWER_DESTROY, player);
@@ -986,7 +986,7 @@ void BattlefieldWG::UpdateTenacity()
if (team != TEAM_NEUTRAL)
{
for (GuidSet::const_iterator itr = m_players[team].begin(); itr != m_players[team].end(); ++itr)
- if (Player* player = sObjectAccessor->FindPlayer(*itr))
+ if (Player* player = ObjectAccessor::FindPlayer(*itr))
if (player->getLevel() >= m_MinLevel)
player->RemoveAurasDueToSpell(SPELL_TENACITY);
@@ -1014,7 +1014,7 @@ void BattlefieldWG::UpdateTenacity()
buff_honor = 0;
for (GuidSet::const_iterator itr = m_PlayersInWar[team].begin(); itr != m_PlayersInWar[team].end(); ++itr)
- if (Player* player = sObjectAccessor->FindPlayer(*itr))
+ if (Player* player = ObjectAccessor::FindPlayer(*itr))
player->SetAuraStack(SPELL_TENACITY, player, newStack);
for (GuidSet::const_iterator itr = m_vehicles[team].begin(); itr != m_vehicles[team].end(); ++itr)
@@ -1024,7 +1024,7 @@ void BattlefieldWG::UpdateTenacity()
if (buff_honor != 0)
{
for (GuidSet::const_iterator itr = m_PlayersInWar[team].begin(); itr != m_PlayersInWar[team].end(); ++itr)
- if (Player* player = sObjectAccessor->FindPlayer(*itr))
+ if (Player* player = ObjectAccessor::FindPlayer(*itr))
player->CastSpell(player, buff_honor, true);
for (GuidSet::const_iterator itr = m_vehicles[team].begin(); itr != m_vehicles[team].end(); ++itr)
if (Creature* creature = GetCreature(*itr))
diff --git a/src/server/game/Battlegrounds/Arena.cpp b/src/server/game/Battlegrounds/Arena.cpp
index 39fff2529b9..b75a71f32b7 100644
--- a/src/server/game/Battlegrounds/Arena.cpp
+++ b/src/server/game/Battlegrounds/Arena.cpp
@@ -180,7 +180,7 @@ void Arena::EndBattleground(uint32 winner)
if (sWorld->getBoolConfig(CONFIG_ARENA_LOG_EXTENDED_INFO))
for (auto const& score : PlayerScores)
- if (Player* player = ObjectAccessor::FindPlayer(ObjectGuid(HIGHGUID_PLAYER, score.first)))
+ if (Player* player = ObjectAccessor::FindConnectedPlayer(ObjectGuid(HIGHGUID_PLAYER, score.first)))
{
TC_LOG_DEBUG("bg.arena", "Statistics match Type: %u for %s (GUID: %u, Team: %d, IP: %s): %s",
GetArenaType(), player->GetName().c_str(), score.first, player->GetArenaTeamId(GetArenaType() == 5 ? 2 : GetArenaType() == 3),
diff --git a/src/server/game/Battlegrounds/ArenaTeam.cpp b/src/server/game/Battlegrounds/ArenaTeam.cpp
index c26238cdc9c..8a0b0d04df6 100644
--- a/src/server/game/Battlegrounds/ArenaTeam.cpp
+++ b/src/server/game/Battlegrounds/ArenaTeam.cpp
@@ -120,7 +120,7 @@ bool ArenaTeam::AddMember(ObjectGuid playerGuid)
// Check if player is already in a similar arena team
if ((player && player->GetArenaTeamId(GetSlot())) || Player::GetArenaTeamIdFromDB(playerGuid, GetType()) != 0)
{
- TC_LOG_DEBUG("bg.arena", "Arena: Player %s (guid: %u) already has an arena team of type %u", playerName.c_str(), playerGuid.GetCounter(), GetType());
+ TC_LOG_DEBUG("bg.arena", "Arena: %s %s already has an arena team of type %u", playerGuid.ToString().c_str(), playerName.c_str(), GetType());
return false;
}
@@ -179,7 +179,7 @@ bool ArenaTeam::AddMember(ObjectGuid playerGuid)
player->SetArenaTeamInfoField(GetSlot(), ARENA_TEAM_MEMBER, 1);
}
- TC_LOG_INFO("bg.arena", "Player: %s [GUID: %u] joined arena team type: %u [Id: %u, Name: %s].", playerName.c_str(), playerGuid.GetCounter(), GetType(), GetId(), GetName().c_str());
+ 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());
return true;
}
@@ -245,7 +245,7 @@ bool ArenaTeam::LoadMembersFromDB(QueryResult result)
// Delete member if character information is missing
if (newMember.Name.empty())
{
- TC_LOG_ERROR("sql.sql", "ArenaTeam %u has member with empty name - probably player %u doesn't exist, deleting him from memberlist!", arenaTeamId, newMember.Guid.GetCounter());
+ TC_LOG_ERROR("sql.sql", "ArenaTeam %u has member with empty name - probably %s doesn't exist, deleting him from memberlist!", arenaTeamId, newMember.Guid.ToString().c_str());
DelMember(newMember.Guid, true);
continue;
}
@@ -408,7 +408,7 @@ void ArenaTeam::Roster(WorldSession* session)
for (MemberList::const_iterator itr = Members.begin(); itr != Members.end(); ++itr)
{
- player = ObjectAccessor::FindPlayer(itr->Guid);
+ player = ObjectAccessor::FindConnectedPlayer(itr->Guid);
data << uint64(itr->Guid); // guid
data << uint8((player ? 1 : 0)); // online flag
@@ -465,7 +465,7 @@ void ArenaTeam::NotifyStatsChanged()
// This is called after a rated match ended
// Updates arena team stats for every member of the team (not only the ones who participated!)
for (MemberList::const_iterator itr = Members.begin(); itr != Members.end(); ++itr)
- if (Player* player = ObjectAccessor::FindPlayer(itr->Guid))
+ if (Player* player = ObjectAccessor::FindConnectedPlayer(itr->Guid))
SendStats(player->GetSession());
}
@@ -512,7 +512,7 @@ void ArenaTeamMember::ModifyMatchmakerRating(int32 mod, uint32 /*slot*/)
void ArenaTeam::BroadcastPacket(WorldPacket* packet)
{
for (MemberList::const_iterator itr = Members.begin(); itr != Members.end(); ++itr)
- if (Player* player = ObjectAccessor::FindPlayer(itr->Guid))
+ if (Player* player = ObjectAccessor::FindConnectedPlayer(itr->Guid))
player->GetSession()->SendPacket(packet);
}
@@ -611,7 +611,7 @@ uint32 ArenaTeam::GetAverageMMR(Group* group) const
for (MemberList::const_iterator itr = Members.begin(); itr != Members.end(); ++itr)
{
// Skip if player is not online
- if (!ObjectAccessor::FindPlayer(itr->Guid))
+ if (!ObjectAccessor::FindConnectedPlayer(itr->Guid))
continue;
// Skip if player is not a member of group
@@ -699,7 +699,7 @@ void ArenaTeam::FinishGame(int32 mod)
// Check if rating related achivements are met
for (MemberList::iterator itr = Members.begin(); itr != Members.end(); ++itr)
- if (Player* member = ObjectAccessor::FindPlayer(itr->Guid))
+ if (Player* member = ObjectAccessor::FindConnectedPlayer(itr->Guid))
member->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_TEAM_RATING, Stats.Rating, Type);
}
diff --git a/src/server/game/Battlegrounds/Battleground.cpp b/src/server/game/Battlegrounds/Battleground.cpp
index b1189e6c03e..52843b97a51 100644
--- a/src/server/game/Battlegrounds/Battleground.cpp
+++ b/src/server/game/Battlegrounds/Battleground.cpp
@@ -598,10 +598,11 @@ Player* Battleground::_GetPlayer(ObjectGuid guid, bool offlineRemove, char const
Player* player = NULL;
if (!offlineRemove)
{
+ // should this be ObjectAccessor::FindConnectedPlayer() to return players teleporting ?
player = ObjectAccessor::FindPlayer(guid);
if (!player)
- TC_LOG_ERROR("bg.battleground", "Battleground::%s: player (GUID: %u) not found for BG (map: %u, instance id: %u)!",
- context, guid.GetCounter(), m_MapId, m_InstanceID);
+ TC_LOG_ERROR("bg.battleground", "Battleground::%s: player (%s) not found for BG (map: %u, instance id: %u)!",
+ context, guid.ToString().c_str(), m_MapId, m_InstanceID);
}
return player;
}
@@ -1478,8 +1479,8 @@ void Battleground::DoorClose(uint32 type)
}
}
else
- TC_LOG_ERROR("bg.battleground", "Battleground::DoorClose: door gameobject (type: %u, GUID: %u) not found for BG (map: %u, instance id: %u)!",
- type, BgObjects[type].GetCounter(), m_MapId, m_InstanceID);
+ TC_LOG_ERROR("bg.battleground", "Battleground::DoorClose: door gameobject (type: %u, %s) not found for BG (map: %u, instance id: %u)!",
+ type, BgObjects[type].ToString().c_str(), m_MapId, m_InstanceID);
}
void Battleground::DoorOpen(uint32 type)
@@ -1490,8 +1491,8 @@ void Battleground::DoorOpen(uint32 type)
obj->SetGoState(GO_STATE_ACTIVE);
}
else
- TC_LOG_ERROR("bg.battleground", "Battleground::DoorOpen: door gameobject (type: %u, GUID: %u) not found for BG (map: %u, instance id: %u)!",
- type, BgObjects[type].GetCounter(), m_MapId, m_InstanceID);
+ TC_LOG_ERROR("bg.battleground", "Battleground::DoorOpen: door gameobject (type: %u, %s) not found for BG (map: %u, instance id: %u)!",
+ type, BgObjects[type].ToString().c_str(), m_MapId, m_InstanceID);
}
GameObject* Battleground::GetBGObject(uint32 type, bool logError)
@@ -1500,11 +1501,11 @@ GameObject* Battleground::GetBGObject(uint32 type, bool logError)
if (!obj)
{
if (logError)
- TC_LOG_ERROR("bg.battleground", "Battleground::GetBGObject: gameobject (type: %u, GUID: %u) not found for BG (map: %u, instance id: %u)!",
- type, BgObjects[type].GetCounter(), m_MapId, m_InstanceID);
+ TC_LOG_ERROR("bg.battleground", "Battleground::GetBGObject: gameobject (type: %u, %s) not found for BG (map: %u, instance id: %u)!",
+ type, BgObjects[type].ToString().c_str(), m_MapId, m_InstanceID);
else
- TC_LOG_INFO("bg.battleground", "Battleground::GetBGObject: gameobject (type: %u, GUID: %u) not found for BG (map: %u, instance id: %u)!",
- type, BgObjects[type].GetCounter(), m_MapId, m_InstanceID);
+ TC_LOG_INFO("bg.battleground", "Battleground::GetBGObject: gameobject (type: %u, %s) not found for BG (map: %u, instance id: %u)!",
+ type, BgObjects[type].ToString().c_str(), m_MapId, m_InstanceID);
}
return obj;
}
@@ -1515,11 +1516,11 @@ Creature* Battleground::GetBGCreature(uint32 type, bool logError)
if (!creature)
{
if (logError)
- TC_LOG_ERROR("bg.battleground", "Battleground::GetBGCreature: creature (type: %u, GUID: %u) not found for BG (map: %u, instance id: %u)!",
- type, BgCreatures[type].GetCounter(), m_MapId, m_InstanceID);
+ TC_LOG_ERROR("bg.battleground", "Battleground::GetBGCreature: creature (type: %u, %s) not found for BG (map: %u, instance id: %u)!",
+ type, BgCreatures[type].ToString().c_str(), m_MapId, m_InstanceID);
else
- TC_LOG_INFO("bg.battleground", "Battleground::GetBGCreature: creature (type: %u, GUID: %u) not found for BG (map: %u, instance id: %u)!",
- type, BgCreatures[type].GetCounter(), m_MapId, m_InstanceID);
+ TC_LOG_INFO("bg.battleground", "Battleground::GetBGCreature: creature (type: %u, %s) not found for BG (map: %u, instance id: %u)!",
+ type, BgCreatures[type].ToString().c_str(), m_MapId, m_InstanceID);
}
return creature;
}
@@ -1600,8 +1601,8 @@ bool Battleground::DelCreature(uint32 type)
return true;
}
- TC_LOG_ERROR("bg.battleground", "Battleground::DelCreature: creature (type: %u, GUID: %u) not found for BG (map: %u, instance id: %u)!",
- type, BgCreatures[type].GetCounter(), m_MapId, m_InstanceID);
+ TC_LOG_ERROR("bg.battleground", "Battleground::DelCreature: creature (type: %u, %s) not found for BG (map: %u, instance id: %u)!",
+ type, BgCreatures[type].ToString().c_str(), m_MapId, m_InstanceID);
BgCreatures[type].Clear();
return false;
}
@@ -1618,8 +1619,8 @@ bool Battleground::DelObject(uint32 type)
BgObjects[type].Clear();
return true;
}
- TC_LOG_ERROR("bg.battleground", "Battleground::DelObject: gameobject (type: %u, GUID: %u) not found for BG (map: %u, instance id: %u)!",
- type, BgObjects[type].GetCounter(), m_MapId, m_InstanceID);
+ TC_LOG_ERROR("bg.battleground", "Battleground::DelObject: gameobject (type: %u, %s) not found for BG (map: %u, instance id: %u)!",
+ type, BgObjects[type].ToString().c_str(), m_MapId, m_InstanceID);
BgObjects[type].Clear();
return false;
}
@@ -1734,8 +1735,8 @@ void Battleground::HandleTriggerBuff(ObjectGuid go_guid)
index--;
if (index < 0)
{
- TC_LOG_ERROR("bg.battleground", "Battleground::HandleTriggerBuff: cannot find buff gameobject (GUID: %u, entry: %u, type: %u) in internal data for BG (map: %u, instance id: %u)!",
- go_guid.GetCounter(), obj->GetEntry(), obj->GetGoType(), m_MapId, m_InstanceID);
+ TC_LOG_ERROR("bg.battleground", "Battleground::HandleTriggerBuff: cannot find buff gameobject (%s, entry: %u, type: %u) in internal data for BG (map: %u, instance id: %u)!",
+ go_guid.ToString().c_str(), obj->GetEntry(), obj->GetGoType(), m_MapId, m_InstanceID);
return;
}
@@ -1858,8 +1859,8 @@ int32 Battleground::GetObjectType(ObjectGuid guid)
for (uint32 i = 0; i < BgObjects.size(); ++i)
if (BgObjects[i] == guid)
return i;
- TC_LOG_ERROR("bg.battleground", "Battleground::GetObjectType: player used gameobject (GUID: %u) which is not in internal data for BG (map: %u, instance id: %u), cheating?",
- guid.GetCounter(), m_MapId, m_InstanceID);
+ TC_LOG_ERROR("bg.battleground", "Battleground::GetObjectType: player used gameobject (%s) which is not in internal data for BG (map: %u, instance id: %u), cheating?",
+ guid.ToString().c_str(), m_MapId, m_InstanceID);
return -1;
}
diff --git a/src/server/game/Battlegrounds/BattlegroundQueue.cpp b/src/server/game/Battlegrounds/BattlegroundQueue.cpp
index 375c896fd39..8bc37e023e8 100644
--- a/src/server/game/Battlegrounds/BattlegroundQueue.cpp
+++ b/src/server/game/Battlegrounds/BattlegroundQueue.cpp
@@ -293,7 +293,7 @@ void BattlegroundQueue::RemovePlayer(ObjectGuid guid, bool decreaseInvitedCount)
std::string playerName = "Unknown";
if (Player* player = ObjectAccessor::FindPlayer(guid))
playerName = player->GetName();
- TC_LOG_ERROR("bg.battleground", "BattlegroundQueue: couldn't find player %s (GUID: %u)", playerName.c_str(), guid.GetCounter());
+ TC_LOG_ERROR("bg.battleground", "BattlegroundQueue: couldn't find player %s (%s)", playerName.c_str(), guid.ToString().c_str());
return;
}
@@ -328,10 +328,10 @@ void BattlegroundQueue::RemovePlayer(ObjectGuid guid, bool decreaseInvitedCount)
//player can't be in queue without group, but just in case
if (bracket_id == -1)
{
- TC_LOG_ERROR("bg.battleground", "BattlegroundQueue: ERROR Cannot find groupinfo for player GUID: %u", guid.GetCounter());
+ TC_LOG_ERROR("bg.battleground", "BattlegroundQueue: ERROR Cannot find groupinfo for %s", guid.ToString().c_str());
return;
}
- TC_LOG_DEBUG("bg.battleground", "BattlegroundQueue: Removing player GUID %u, from bracket_id %u", guid.GetCounter(), (uint32)bracket_id);
+ TC_LOG_DEBUG("bg.battleground", "BattlegroundQueue: Removing %s, from bracket_id %u", guid.ToString().c_str(), (uint32)bracket_id);
// ALL variables are correctly set
// We can ignore leveling up in queue - it should not cause crash
@@ -361,8 +361,8 @@ void BattlegroundQueue::RemovePlayer(ObjectGuid guid, bool decreaseInvitedCount)
{
if (ArenaTeam* at = sArenaTeamMgr->GetArenaTeamById(group->ArenaTeamId))
{
- TC_LOG_DEBUG("bg.battleground", "UPDATING memberLost's personal arena rating for %u by opponents rating: %u", guid.GetCounter(), group->OpponentsTeamRating);
- if (Player* player = ObjectAccessor::FindPlayer(guid))
+ TC_LOG_DEBUG("bg.battleground", "UPDATING memberLost's personal arena rating for %s by opponents rating: %u", guid.ToString().c_str(), group->OpponentsTeamRating);
+ if (Player* player = ObjectAccessor::FindConnectedPlayer(guid))
at->MemberLost(player, group->OpponentsMatchmakerRating);
else
at->OfflineMemberLost(guid, group->OpponentsMatchmakerRating);
@@ -385,7 +385,7 @@ void BattlegroundQueue::RemovePlayer(ObjectGuid guid, bool decreaseInvitedCount)
{
// remove next player, this is recursive
// first send removal information
- if (Player* plr2 = ObjectAccessor::FindPlayer(group->Players.begin()->first))
+ if (Player* plr2 = ObjectAccessor::FindConnectedPlayer(group->Players.begin()->first))
{
Battleground* bg = sBattlegroundMgr->GetBattlegroundTemplate(group->BgTypeId);
BattlegroundQueueTypeId bgQueueTypeId = BattlegroundMgr::BGQueueTypeId(group->BgTypeId, group->ArenaType);
@@ -450,7 +450,7 @@ bool BattlegroundQueue::InviteGroupToBG(GroupQueueInfo* ginfo, Battleground* bg,
for (std::map<ObjectGuid, PlayerQueueInfo*>::iterator itr = ginfo->Players.begin(); itr != ginfo->Players.end(); ++itr)
{
// get the player
- Player* player = ObjectAccessor::FindPlayer(itr->first);
+ Player* player = ObjectAccessor::FindConnectedPlayer(itr->first);
// if offline, skip him, this should not happen - player is removed from queue when he logs out
if (!player)
continue;
@@ -981,7 +981,7 @@ void BattlegroundQueue::BattlegroundQueueUpdate(uint32 /*diff*/, BattlegroundTyp
bool BGQueueInviteEvent::Execute(uint64 /*e_time*/, uint32 /*p_time*/)
{
- Player* player = ObjectAccessor::FindPlayer(m_PlayerGuid);
+ Player* player = ObjectAccessor::FindConnectedPlayer(m_PlayerGuid);
// player logged off (we should do nothing, he is correctly removed from queue in another procedure)
if (!player)
return true;
@@ -1024,7 +1024,7 @@ void BGQueueInviteEvent::Abort(uint64 /*e_time*/)
*/
bool BGQueueRemoveEvent::Execute(uint64 /*e_time*/, uint32 /*p_time*/)
{
- Player* player = ObjectAccessor::FindPlayer(m_PlayerGuid);
+ Player* player = ObjectAccessor::FindConnectedPlayer(m_PlayerGuid);
if (!player)
// player logged off (we should do nothing, he is correctly removed from queue in another procedure)
return true;
diff --git a/src/server/game/CMakeLists.txt b/src/server/game/CMakeLists.txt
index 0d1b460500e..27b3ea2c381 100644
--- a/src/server/game/CMakeLists.txt
+++ b/src/server/game/CMakeLists.txt
@@ -111,6 +111,7 @@ include_directories(
${CMAKE_SOURCE_DIR}/dep/g3dlite/include
${CMAKE_SOURCE_DIR}/dep/SFMT
${CMAKE_SOURCE_DIR}/dep/zlib
+ ${CMAKE_SOURCE_DIR}/dep/zmqpp
${CMAKE_SOURCE_DIR}/src/server/collision
${CMAKE_SOURCE_DIR}/src/server/collision/Management
${CMAKE_SOURCE_DIR}/src/server/collision/Models
@@ -129,6 +130,7 @@ include_directories(
${CMAKE_SOURCE_DIR}/src/server/shared/Packets
${CMAKE_SOURCE_DIR}/src/server/shared/Threading
${CMAKE_SOURCE_DIR}/src/server/shared/Utilities
+ ${CMAKE_SOURCE_DIR}/src/server/ipc
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/Accounts
${CMAKE_CURRENT_SOURCE_DIR}/Achievements
@@ -205,6 +207,7 @@ include_directories(
${MYSQL_INCLUDE_DIR}
${OPENSSL_INCLUDE_DIR}
${VALGRIND_INCLUDE_DIR}
+ ${ZMQ_INCLUDE_DIR}
)
add_library(game STATIC
diff --git a/src/server/game/Calendar/CalendarMgr.cpp b/src/server/game/Calendar/CalendarMgr.cpp
index 2e62e8514a0..5270e42d0b1 100644
--- a/src/server/game/Calendar/CalendarMgr.cpp
+++ b/src/server/game/Calendar/CalendarMgr.cpp
@@ -350,7 +350,7 @@ CalendarEventStore CalendarMgr::GetPlayerEvents(ObjectGuid guid)
if (CalendarEvent* event = GetEvent(itr->first)) // NULL check added as attempt to fix #11512
events.insert(event);
- if (Player* player = ObjectAccessor::FindPlayer(guid))
+ if (Player* player = ObjectAccessor::FindConnectedPlayer(guid))
for (CalendarEventStore::const_iterator itr = _events.begin(); itr != _events.end(); ++itr)
if ((*itr)->GetGuildId() == player->GetGuildId())
events.insert(*itr);
@@ -424,7 +424,7 @@ void CalendarMgr::SendCalendarEventInvite(CalendarInvite const& invite)
bool hasStatusTime = statusTime != 946684800; // 01/01/2000 00:00:00
ObjectGuid invitee = invite.GetInviteeGUID();
- Player* player = ObjectAccessor::FindPlayer(invitee);
+ Player* player = ObjectAccessor::FindConnectedPlayer(invitee);
uint8 level = player ? player->getLevel() : Player::GetLevelFromDB(invitee);
@@ -441,7 +441,7 @@ void CalendarMgr::SendCalendarEventInvite(CalendarInvite const& invite)
if (!calendarEvent) // Pre-invite
{
- if (Player* playerSender = ObjectAccessor::FindPlayer(invite.GetSenderGUID()))
+ if (Player* playerSender = ObjectAccessor::FindConnectedPlayer(invite.GetSenderGUID()))
playerSender->SendDirectMessage(&data);
}
else
@@ -542,13 +542,13 @@ void CalendarMgr::SendCalendarEventInviteAlert(CalendarEvent const& calendarEven
guild->BroadcastPacket(&data);
}
else
- if (Player* player = ObjectAccessor::FindPlayer(invite.GetInviteeGUID()))
+ if (Player* player = ObjectAccessor::FindConnectedPlayer(invite.GetInviteeGUID()))
player->SendDirectMessage(&data);
}
void CalendarMgr::SendCalendarEvent(ObjectGuid guid, CalendarEvent const& calendarEvent, CalendarSendEventType sendType)
{
- Player* player = ObjectAccessor::FindPlayer(guid);
+ Player* player = ObjectAccessor::FindConnectedPlayer(guid);
if (!player)
return;
@@ -596,7 +596,7 @@ void CalendarMgr::SendCalendarEvent(ObjectGuid guid, CalendarEvent const& calend
void CalendarMgr::SendCalendarEventInviteRemoveAlert(ObjectGuid guid, CalendarEvent const& calendarEvent, CalendarInviteStatus status)
{
- if (Player* player = ObjectAccessor::FindPlayer(guid))
+ if (Player* player = ObjectAccessor::FindConnectedPlayer(guid))
{
WorldPacket data(SMSG_CALENDAR_EVENT_INVITE_REMOVED_ALERT, 8 + 4 + 4 + 1);
data << uint64(calendarEvent.GetEventId());
@@ -610,7 +610,7 @@ void CalendarMgr::SendCalendarEventInviteRemoveAlert(ObjectGuid guid, CalendarEv
void CalendarMgr::SendCalendarClearPendingAction(ObjectGuid guid)
{
- if (Player* player = ObjectAccessor::FindPlayer(guid))
+ if (Player* player = ObjectAccessor::FindConnectedPlayer(guid))
{
WorldPacket data(SMSG_CALENDAR_CLEAR_PENDING_ACTION, 0);
player->SendDirectMessage(&data);
@@ -619,7 +619,7 @@ void CalendarMgr::SendCalendarClearPendingAction(ObjectGuid guid)
void CalendarMgr::SendCalendarCommandResult(ObjectGuid guid, CalendarError err, char const* param /*= NULL*/)
{
- if (Player* player = ObjectAccessor::FindPlayer(guid))
+ if (Player* player = ObjectAccessor::FindConnectedPlayer(guid))
{
WorldPacket data(SMSG_CALENDAR_COMMAND_RESULT, 0);
data << uint32(0);
@@ -652,7 +652,7 @@ void CalendarMgr::SendPacketToAllEventRelatives(WorldPacket& packet, CalendarEve
// Send packet to all invitees if event is non-guild, in other case only to non-guild invitees (packet was broadcasted for them)
CalendarInviteStore invites = _invites[calendarEvent.GetEventId()];
for (CalendarInviteStore::iterator itr = invites.begin(); itr != invites.end(); ++itr)
- if (Player* player = ObjectAccessor::FindPlayer((*itr)->GetInviteeGUID()))
+ if (Player* player = ObjectAccessor::FindConnectedPlayer((*itr)->GetInviteeGUID()))
if (!calendarEvent.IsGuildEvent() || (calendarEvent.IsGuildEvent() && player->GetGuildId() != calendarEvent.GetGuildId()))
player->SendDirectMessage(&packet);
}
diff --git a/src/server/game/Chat/Channels/Channel.cpp b/src/server/game/Chat/Channels/Channel.cpp
index 654ce8da2b9..6d984ab2e66 100644
--- a/src/server/game/Chat/Channels/Channel.cpp
+++ b/src/server/game/Chat/Channels/Channel.cpp
@@ -296,7 +296,7 @@ void Channel::KickOrBan(Player const* player, std::string const& badname, bool b
return;
}
- Player* bad = sObjectAccessor->FindPlayerByName(badname);
+ Player* bad = ObjectAccessor::FindConnectedPlayerByName(badname);
ObjectGuid victim = bad ? bad->GetGUID() : ObjectGuid::Empty;
if (!victim || !IsOn(victim))
{
@@ -366,7 +366,7 @@ void Channel::UnBan(Player const* player, std::string const& badname)
return;
}
- Player* bad = sObjectAccessor->FindPlayerByName(badname);
+ Player* bad = ObjectAccessor::FindConnectedPlayerByName(badname);
ObjectGuid victim = bad ? bad->GetGUID() : ObjectGuid::Empty;
if (!victim || !IsBanned(victim))
@@ -439,7 +439,7 @@ void Channel::SetMode(Player const* player, std::string const& p2n, bool mod, bo
if (guid == _ownerGUID && std::string(p2n) == player->GetName() && mod)
return;
- Player* newp = sObjectAccessor->FindPlayerByName(p2n);
+ Player* newp = ObjectAccessor::FindConnectedPlayerByName(p2n);
ObjectGuid victim = newp ? newp->GetGUID() : ObjectGuid::Empty;
if (!victim || !IsOn(victim) ||
@@ -487,7 +487,7 @@ void Channel::SetOwner(Player const* player, std::string const& newname)
return;
}
- Player* newp = sObjectAccessor->FindPlayerByName(newname);
+ Player* newp = ObjectAccessor::FindConnectedPlayerByName(newname);
ObjectGuid victim = newp ? newp->GetGUID() : ObjectGuid::Empty;
if (!victim || !IsOn(victim) ||
@@ -543,7 +543,7 @@ void Channel::List(Player const* player)
uint32 count = 0;
for (PlayerContainer::const_iterator i = playersStore.begin(); i != playersStore.end(); ++i)
{
- Player* member = ObjectAccessor::FindPlayer(i->first);
+ Player* member = ObjectAccessor::FindConnectedPlayer(i->first);
// PLAYER can't see MODERATOR, GAME MASTER, ADMINISTRATOR characters
// MODERATOR, GAME MASTER, ADMINISTRATOR can see all
@@ -621,7 +621,7 @@ void Channel::Say(ObjectGuid guid, std::string const& what, uint32 lang)
}
WorldPacket data;
- if (Player* player = ObjectAccessor::FindPlayer(guid))
+ if (Player* player = ObjectAccessor::FindConnectedPlayer(guid))
ChatHandler::BuildChatPacket(data, CHAT_MSG_CHANNEL, Language(lang), player, player, what, 0, _name);
else
ChatHandler::BuildChatPacket(data, CHAT_MSG_CHANNEL, Language(lang), guid, guid, what, 0, "", "", 0, false, _name);
@@ -641,7 +641,7 @@ void Channel::Invite(Player const* player, std::string const& newname)
return;
}
- Player* newp = sObjectAccessor->FindPlayerByName(newname);
+ Player* newp = ObjectAccessor::FindConnectedPlayerByName(newname);
if (!newp || !newp->isGMVisible())
{
WorldPacket data;
@@ -723,7 +723,7 @@ void Channel::SetOwner(ObjectGuid guid, bool exclaim)
void Channel::SendToAll(WorldPacket* data, ObjectGuid guid)
{
for (PlayerContainer::const_iterator i = playersStore.begin(); i != playersStore.end(); ++i)
- if (Player* player = ObjectAccessor::FindPlayer(i->first))
+ if (Player* player = ObjectAccessor::FindConnectedPlayer(i->first))
if (!guid || !player->GetSocial()->HasIgnore(guid.GetCounter()))
player->GetSession()->SendPacket(data);
}
@@ -732,13 +732,13 @@ void Channel::SendToAllButOne(WorldPacket* data, ObjectGuid who)
{
for (PlayerContainer::const_iterator i = playersStore.begin(); i != playersStore.end(); ++i)
if (i->first != who)
- if (Player* player = ObjectAccessor::FindPlayer(i->first))
+ if (Player* player = ObjectAccessor::FindConnectedPlayer(i->first))
player->GetSession()->SendPacket(data);
}
void Channel::SendToOne(WorldPacket* data, ObjectGuid who)
{
- if (Player* player = ObjectAccessor::FindPlayer(who))
+ if (Player* player = ObjectAccessor::FindConnectedPlayer(who))
player->GetSession()->SendPacket(data);
}
diff --git a/src/server/game/Chat/Chat.cpp b/src/server/game/Chat/Chat.cpp
index ace13989efb..501f73c460f 100644
--- a/src/server/game/Chat/Chat.cpp
+++ b/src/server/game/Chat/Chat.cpp
@@ -160,7 +160,7 @@ bool ChatHandler::HasLowerSecurityAccount(WorldSession* target, uint32 target_ac
if (target)
target_sec = target->GetSecurity();
else if (target_account)
- target_sec = AccountMgr::GetSecurity(target_account, realmID);
+ target_sec = AccountMgr::GetSecurity(target_account, realmHandle.Index);
else
return true; // caller must report error for (target == NULL && target_account == 0)
@@ -765,7 +765,7 @@ Player* ChatHandler::getSelectedPlayer()
if (!selected)
return m_session->GetPlayer();
- return ObjectAccessor::FindPlayer(selected);
+ return ObjectAccessor::FindConnectedPlayer(selected);
}
Unit* ChatHandler::getSelectedUnit()
@@ -810,7 +810,7 @@ Player* ChatHandler::getSelectedPlayerOrSelf()
return m_session->GetPlayer();
// first try with selected target
- Player* targetPlayer = ObjectAccessor::FindPlayer(selected);
+ Player* targetPlayer = ObjectAccessor::FindConnectedPlayer(selected);
// if the target is not a player, then return self
if (!targetPlayer)
targetPlayer = m_session->GetPlayer();
@@ -1090,7 +1090,7 @@ ObjectGuid ChatHandler::extractGuidFromLink(char* text)
if (!normalizePlayerName(name))
return ObjectGuid::Empty;
- if (Player* player = sObjectAccessor->FindPlayerByName(name))
+ if (Player* player = ObjectAccessor::FindPlayerByName(name))
return player->GetGUID();
if (ObjectGuid guid = sObjectMgr->GetPlayerGUIDByName(name))
@@ -1148,7 +1148,7 @@ bool ChatHandler::extractPlayerTarget(char* args, Player** player, ObjectGuid* p
return false;
}
- Player* pl = sObjectAccessor->FindPlayerByName(name);
+ Player* pl = ObjectAccessor::FindPlayerByName(name);
// if allowed player pointer
if (player)
@@ -1312,7 +1312,7 @@ bool ChatHandler::GetPlayerGroupAndGUIDByName(const char* cname, Player*& player
return false;
}
- player = sObjectAccessor->FindPlayerByName(name);
+ player = ObjectAccessor::FindPlayerByName(name);
if (offline)
guid = sObjectMgr->GetPlayerGUIDByName(name.c_str());
}
diff --git a/src/server/game/Conditions/DisableMgr.cpp b/src/server/game/Conditions/DisableMgr.cpp
index 3f325be1e83..eb50545b510 100644
--- a/src/server/game/Conditions/DisableMgr.cpp
+++ b/src/server/game/Conditions/DisableMgr.cpp
@@ -21,8 +21,8 @@
#include "ObjectMgr.h"
#include "OutdoorPvP.h"
#include "SpellMgr.h"
-#include "VMapManager2.h"
#include "Player.h"
+#include "World.h"
namespace DisableMgr
{
@@ -193,28 +193,28 @@ void LoadDisables()
switch (mapEntry->map_type)
{
case MAP_COMMON:
- if (flags & VMAP_DISABLE_AREAFLAG)
+ if (flags & VMAP::VMAP_DISABLE_AREAFLAG)
TC_LOG_INFO("misc", "Areaflag disabled for world map %u.", entry);
- if (flags & VMAP_DISABLE_LIQUIDSTATUS)
+ if (flags & VMAP::VMAP_DISABLE_LIQUIDSTATUS)
TC_LOG_INFO("misc", "Liquid status disabled for world map %u.", entry);
break;
case MAP_INSTANCE:
case MAP_RAID:
- if (flags & VMAP_DISABLE_HEIGHT)
+ if (flags & VMAP::VMAP_DISABLE_HEIGHT)
TC_LOG_INFO("misc", "Height disabled for instance map %u.", entry);
- if (flags & VMAP_DISABLE_LOS)
+ if (flags & VMAP::VMAP_DISABLE_LOS)
TC_LOG_INFO("misc", "LoS disabled for instance map %u.", entry);
break;
case MAP_BATTLEGROUND:
- if (flags & VMAP_DISABLE_HEIGHT)
+ if (flags & VMAP::VMAP_DISABLE_HEIGHT)
TC_LOG_INFO("misc", "Height disabled for battleground map %u.", entry);
- if (flags & VMAP_DISABLE_LOS)
+ if (flags & VMAP::VMAP_DISABLE_LOS)
TC_LOG_INFO("misc", "LoS disabled for battleground map %u.", entry);
break;
case MAP_ARENA:
- if (flags & VMAP_DISABLE_HEIGHT)
+ if (flags & VMAP::VMAP_DISABLE_HEIGHT)
TC_LOG_INFO("misc", "Height disabled for arena map %u.", entry);
- if (flags & VMAP_DISABLE_LOS)
+ if (flags & VMAP::VMAP_DISABLE_LOS)
TC_LOG_INFO("misc", "LoS disabled for arena map %u.", entry);
break;
default:
@@ -387,4 +387,15 @@ bool IsDisabledFor(DisableType type, uint32 entry, Unit const* unit, uint8 flags
return false;
}
+bool IsVMAPDisabledFor(uint32 entry, uint8 flags)
+{
+ return IsDisabledFor(DISABLE_TYPE_VMAP, entry, NULL, flags);
+}
+
+bool IsPathfindingEnabled(uint32 mapId)
+{
+ return sWorld->getBoolConfig(CONFIG_ENABLE_MMAPS)
+ && !IsDisabledFor(DISABLE_TYPE_MMAP, mapId, NULL, MMAP_DISABLE_PATHFINDING);
+}
+
} // Namespace
diff --git a/src/server/game/Conditions/DisableMgr.h b/src/server/game/Conditions/DisableMgr.h
index 0930da78547..f6c65abe90a 100644
--- a/src/server/game/Conditions/DisableMgr.h
+++ b/src/server/game/Conditions/DisableMgr.h
@@ -19,6 +19,7 @@
#ifndef TRINITY_DISABLEMGR_H
#define TRINITY_DISABLEMGR_H
+#include "VMapManager2.h"
#include "Define.h"
class Unit;
@@ -49,14 +50,6 @@ enum SpellDisableTypes
SPELL_DISABLE_LOS)
};
-enum VmapDisableTypes
-{
- VMAP_DISABLE_AREAFLAG = 0x1,
- VMAP_DISABLE_HEIGHT = 0x2,
- VMAP_DISABLE_LOS = 0x4,
- VMAP_DISABLE_LIQUIDSTATUS = 0x8
-};
-
enum MMapDisableTypes
{
MMAP_DISABLE_PATHFINDING = 0x0
@@ -67,6 +60,8 @@ namespace DisableMgr
void LoadDisables();
bool IsDisabledFor(DisableType type, uint32 entry, Unit const* unit, uint8 flags = 0);
void CheckQuestDisables();
+ bool IsVMAPDisabledFor(uint32 entry, uint8 flags);
+ bool IsPathfindingEnabled(uint32 mapId);
}
#endif //TRINITY_DISABLEMGR_H
diff --git a/src/server/game/DungeonFinding/LFGMgr.cpp b/src/server/game/DungeonFinding/LFGMgr.cpp
index 4bed997bced..3946d7b543f 100644
--- a/src/server/game/DungeonFinding/LFGMgr.cpp
+++ b/src/server/game/DungeonFinding/LFGMgr.cpp
@@ -490,8 +490,8 @@ void LFGMgr::JoinLfg(Player* player, uint8 roles, LfgDungeonSet& dungeons, const
// Can't join. Send result
if (joinData.result != LFG_JOIN_OK)
{
- TC_LOG_DEBUG("lfg.join", "%u joining with %u members. Result: %u, Dungeons: %s",
- guid.GetCounter(), grp ? grp->GetMembersCount() : 1, joinData.result, ConcatenateDungeons(dungeons).c_str());
+ TC_LOG_DEBUG("lfg.join", "%s joining with %u members. Result: %u, Dungeons: %s",
+ guid.ToString().c_str(), grp ? grp->GetMembersCount() : 1, joinData.result, ConcatenateDungeons(dungeons).c_str());
if (!dungeons.empty()) // Only should show lockmap when have no dungeons available
joinData.lockmap.clear();
@@ -503,7 +503,7 @@ void LFGMgr::JoinLfg(Player* player, uint8 roles, LfgDungeonSet& dungeons, const
if (isRaid)
{
- TC_LOG_DEBUG("lfg.join", "%u trying to join raid browser and it's disabled.", guid.GetCounter());
+ TC_LOG_DEBUG("lfg.join", "%s trying to join raid browser and it's disabled.", guid.ToString().c_str());
return;
}
@@ -569,7 +569,7 @@ void LFGMgr::JoinLfg(Player* player, uint8 roles, LfgDungeonSet& dungeons, const
debugNames.append(player->GetName());
}
- TC_LOG_DEBUG("lfg.join", "%u joined (%s), Members: %s. Dungeons (%u): %s", guid.GetCounter(),
+ TC_LOG_DEBUG("lfg.join", "%s joined (%s), Members: %s. Dungeons (%u): %s", guid.ToString().c_str(),
grp ? "group" : "player", debugNames.c_str(), uint32(dungeons.size()), ConcatenateDungeons(dungeons).c_str());
}
@@ -583,7 +583,7 @@ void LFGMgr::LeaveLfg(ObjectGuid guid)
{
ObjectGuid gguid = guid.IsGroup() ? guid : GetGroup(guid);
- TC_LOG_DEBUG("lfg.leave", "%u left (%s)", guid.GetCounter(), guid == gguid ? "group" : "player");
+ TC_LOG_DEBUG("lfg.leave", "%s left (%s)", guid.ToString().c_str(), guid == gguid ? "group" : "player");
LfgState state = GetState(guid);
switch (state)
@@ -772,10 +772,9 @@ void LFGMgr::GetCompatibleDungeons(LfgDungeonSet& dungeons, GuidSet const& playe
Check if a group can be formed with the given group roles
@param[in] groles Map of roles to check
- @param[in] removeLeaderFlag Determines if we have to remove leader flag (only used first call, Default = true)
@return True if roles are compatible
*/
-bool LFGMgr::CheckGroupRoles(LfgRolesMap& groles, bool removeLeaderFlag /*= true*/)
+bool LFGMgr::CheckGroupRoles(LfgRolesMap& groles)
{
if (groles.empty())
return false;
@@ -784,21 +783,18 @@ bool LFGMgr::CheckGroupRoles(LfgRolesMap& groles, bool removeLeaderFlag /*= true
uint8 tank = 0;
uint8 healer = 0;
- if (removeLeaderFlag)
- for (LfgRolesMap::iterator it = groles.begin(); it != groles.end(); ++it)
- it->second &= ~PLAYER_ROLE_LEADER;
-
for (LfgRolesMap::iterator it = groles.begin(); it != groles.end(); ++it)
{
- if (it->second == PLAYER_ROLE_NONE)
+ uint8 role = it->second & ~PLAYER_ROLE_LEADER;
+ if (role == PLAYER_ROLE_NONE)
return false;
- if (it->second & PLAYER_ROLE_DAMAGE)
+ if (role & PLAYER_ROLE_DAMAGE)
{
- if (it->second != PLAYER_ROLE_DAMAGE)
+ if (role != PLAYER_ROLE_DAMAGE)
{
it->second -= PLAYER_ROLE_DAMAGE;
- if (CheckGroupRoles(groles, false))
+ if (CheckGroupRoles(groles))
return true;
it->second += PLAYER_ROLE_DAMAGE;
}
@@ -808,12 +804,12 @@ bool LFGMgr::CheckGroupRoles(LfgRolesMap& groles, bool removeLeaderFlag /*= true
damage++;
}
- if (it->second & PLAYER_ROLE_HEALER)
+ if (role & PLAYER_ROLE_HEALER)
{
- if (it->second != PLAYER_ROLE_HEALER)
+ if (role != PLAYER_ROLE_HEALER)
{
it->second -= PLAYER_ROLE_HEALER;
- if (CheckGroupRoles(groles, false))
+ if (CheckGroupRoles(groles))
return true;
it->second += PLAYER_ROLE_HEALER;
}
@@ -823,12 +819,12 @@ bool LFGMgr::CheckGroupRoles(LfgRolesMap& groles, bool removeLeaderFlag /*= true
healer++;
}
- if (it->second & PLAYER_ROLE_TANK)
+ if (role & PLAYER_ROLE_TANK)
{
- if (it->second != PLAYER_ROLE_TANK)
+ if (role != PLAYER_ROLE_TANK)
{
it->second -= PLAYER_ROLE_TANK;
- if (CheckGroupRoles(groles, false))
+ if (CheckGroupRoles(groles))
return true;
it->second += PLAYER_ROLE_TANK;
}
@@ -945,7 +941,7 @@ void LFGMgr::UpdateProposal(uint32 proposalId, ObjectGuid guid, bool accept)
LfgProposalPlayer& player = itProposalPlayer->second;
player.accept = LfgAnswer(accept);
- TC_LOG_DEBUG("lfg.proposal.update", "Player %u, Proposal %u, Selection: %u", guid.GetCounter(), proposalId, accept);
+ TC_LOG_DEBUG("lfg.proposal.update", "%s, Proposal %u, Selection: %u", guid.ToString().c_str(), proposalId, accept);
if (!accept)
{
RemoveProposal(itProposal, LFG_UPDATETYPE_PROPOSAL_DECLINED);
@@ -1073,12 +1069,12 @@ void LFGMgr::RemoveProposal(LfgProposalContainer::iterator itProposal, LfgUpdate
if (it->second.accept == LFG_ANSWER_DENY)
{
updateData.updateType = type;
- TC_LOG_DEBUG("lfg.proposal.remove", "%u didn't accept. Removing from queue and compatible cache", guid.GetCounter());
+ TC_LOG_DEBUG("lfg.proposal.remove", "%s didn't accept. Removing from queue and compatible cache", guid.ToString().c_str());
}
else
{
updateData.updateType = LFG_UPDATETYPE_REMOVED_FROM_QUEUE;
- TC_LOG_DEBUG("lfg.proposal.remove", "%u in same group that someone that didn't accept. Removing from queue and compatible cache", guid.GetCounter());
+ TC_LOG_DEBUG("lfg.proposal.remove", "%s in same group that someone that didn't accept. Removing from queue and compatible cache", guid.ToString().c_str());
}
RestoreState(guid, "Proposal Fail (didn't accepted or in group with someone that didn't accept");
@@ -1092,7 +1088,7 @@ void LFGMgr::RemoveProposal(LfgProposalContainer::iterator itProposal, LfgUpdate
}
else
{
- TC_LOG_DEBUG("lfg.proposal.remove", "Readding %u to queue.", guid.GetCounter());
+ TC_LOG_DEBUG("lfg.proposal.remove", "Readding %s to queue.", guid.ToString().c_str());
SetState(guid, LFG_STATE_QUEUED);
if (gguid != guid)
{
@@ -1325,13 +1321,13 @@ void LFGMgr::FinishDungeon(ObjectGuid gguid, const uint32 dungeonId)
uint32 gDungeonId = GetDungeon(gguid);
if (gDungeonId != dungeonId)
{
- TC_LOG_DEBUG("lfg.dungeon.finish", "Group %u finished dungeon %u but queued for %u", gguid.GetCounter(), dungeonId, gDungeonId);
+ TC_LOG_DEBUG("lfg.dungeon.finish", "Group %s finished dungeon %u but queued for %u", gguid.ToString().c_str(), dungeonId, gDungeonId);
return;
}
if (GetState(gguid) == LFG_STATE_FINISHED_DUNGEON) // Shouldn't happen. Do not reward multiple times
{
- TC_LOG_DEBUG("lfg.dungeon.finish", "Group: %u already rewarded", gguid.GetCounter());
+ TC_LOG_DEBUG("lfg.dungeon.finish", "Group: %s already rewarded", gguid.ToString().c_str());
return;
}
@@ -1343,7 +1339,7 @@ void LFGMgr::FinishDungeon(ObjectGuid gguid, const uint32 dungeonId)
ObjectGuid guid = (*it);
if (GetState(guid) == LFG_STATE_FINISHED_DUNGEON)
{
- TC_LOG_DEBUG("lfg.dungeon.finish", "Group: %u, Player: %u already rewarded", gguid.GetCounter(), guid.GetCounter());
+ TC_LOG_DEBUG("lfg.dungeon.finish", "Group: %s, Player: %s already rewarded", gguid.ToString().c_str(), guid.ToString().c_str());
continue;
}
@@ -1359,14 +1355,14 @@ void LFGMgr::FinishDungeon(ObjectGuid gguid, const uint32 dungeonId)
if (!dungeon || (dungeon->type != LFG_TYPE_RANDOM && !dungeon->seasonal))
{
- TC_LOG_DEBUG("lfg.dungeon.finish", "Group: %u, Player: %u dungeon %u is not random or seasonal", gguid.GetCounter(), guid.GetCounter(), rDungeonId);
+ TC_LOG_DEBUG("lfg.dungeon.finish", "Group: %s, Player: %s dungeon %u is not random or seasonal", gguid.ToString().c_str(), guid.ToString().c_str(), rDungeonId);
continue;
}
Player* player = ObjectAccessor::FindPlayer(guid);
- if (!player || !player->IsInWorld())
+ if (!player)
{
- TC_LOG_DEBUG("lfg.dungeon.finish", "Group: %u, Player: %u not found in world", gguid.GetCounter(), guid.GetCounter());
+ TC_LOG_DEBUG("lfg.dungeon.finish", "Group: %s, Player: %s not found in world", gguid.ToString().c_str(), guid.ToString().c_str());
continue;
}
@@ -1375,7 +1371,7 @@ void LFGMgr::FinishDungeon(ObjectGuid gguid, const uint32 dungeonId)
if (player->GetMapId() != mapId)
{
- TC_LOG_DEBUG("lfg.dungeon.finish", "Group: %u, Player: %u is in map %u and should be in %u to get reward", gguid.GetCounter(), guid.GetCounter(), player->GetMapId(), mapId);
+ TC_LOG_DEBUG("lfg.dungeon.finish", "Group: %s, Player: %s is in map %u and should be in %u to get reward", gguid.ToString().c_str(), guid.ToString().c_str(), player->GetMapId(), mapId);
continue;
}
@@ -1406,7 +1402,7 @@ void LFGMgr::FinishDungeon(ObjectGuid gguid, const uint32 dungeonId)
}
// Give rewards
- TC_LOG_DEBUG("lfg.dungeon.finish", "Group: %u, Player: %u done dungeon %u, %s previously done.", gguid.GetCounter(), guid.GetCounter(), GetDungeon(gguid), done? " " : " not");
+ TC_LOG_DEBUG("lfg.dungeon.finish", "Group: %s, Player: %s done dungeon %u, %s previously done.", gguid.ToString().c_str(), guid.ToString().c_str(), GetDungeon(gguid), done ? " " : " not");
LfgPlayerRewardData data = LfgPlayerRewardData(dungeon->Entry(), GetDungeon(gguid, false), done, quest);
player->GetSession()->SendLfgPlayerReward(data);
}
@@ -1472,12 +1468,12 @@ LfgState LFGMgr::GetState(ObjectGuid guid)
if (guid.IsGroup())
{
state = GroupsStore[guid].GetState();
- TC_LOG_TRACE("lfg.data.group.state.get", "Group: %u, State: %u", guid.GetCounter(), state);
+ TC_LOG_TRACE("lfg.data.group.state.get", "Group: %s, State: %u", guid.ToString().c_str(), state);
}
else
{
state = PlayersStore[guid].GetState();
- TC_LOG_TRACE("lfg.data.player.state.get", "Player: %u, State: %u", guid.GetCounter(), state);
+ TC_LOG_TRACE("lfg.data.player.state.get", "Player: %s, State: %u", guid.ToString().c_str(), state);
}
return state;
@@ -1489,12 +1485,12 @@ LfgState LFGMgr::GetOldState(ObjectGuid guid)
if (guid.IsGroup())
{
state = GroupsStore[guid].GetOldState();
- TC_LOG_TRACE("lfg.data.group.oldstate.get", "Group: %u, Old state: %u", guid.GetCounter(), state);
+ TC_LOG_TRACE("lfg.data.group.oldstate.get", "Group: %s, Old state: %u", guid.ToString().c_str(), state);
}
else
{
state = PlayersStore[guid].GetOldState();
- TC_LOG_TRACE("lfg.data.player.oldstate.get", "Player: %u, Old state: %u", guid.GetCounter(), state);
+ TC_LOG_TRACE("lfg.data.player.oldstate.get", "Player: %s, Old state: %u", guid.ToString().c_str(), state);
}
return state;
@@ -1503,7 +1499,7 @@ LfgState LFGMgr::GetOldState(ObjectGuid guid)
uint32 LFGMgr::GetDungeon(ObjectGuid guid, bool asId /*= true */)
{
uint32 dungeon = GroupsStore[guid].GetDungeon(asId);
- TC_LOG_TRACE("lfg.data.group.dungeon.get", "Group: %u, asId: %u, Dungeon: %u", guid.GetCounter(), asId, dungeon);
+ TC_LOG_TRACE("lfg.data.group.dungeon.get", "Group: %s, asId: %u, Dungeon: %u", guid.ToString().c_str(), asId, dungeon);
return dungeon;
}
@@ -1515,7 +1511,7 @@ uint32 LFGMgr::GetDungeonMapId(ObjectGuid guid)
if (LFGDungeonData const* dungeon = GetLFGDungeon(dungeonId))
mapId = dungeon->map;
- TC_LOG_TRACE("lfg.data.group.dungeon.map", "Group: %u, MapId: %u (DungeonId: %u)", guid.GetCounter(), mapId, dungeonId);
+ TC_LOG_TRACE("lfg.data.group.dungeon.map", "Group: %s, MapId: %u (DungeonId: %u)", guid.ToString().c_str(), mapId, dungeonId);
return mapId;
}
@@ -1523,30 +1519,30 @@ uint32 LFGMgr::GetDungeonMapId(ObjectGuid guid)
uint8 LFGMgr::GetRoles(ObjectGuid guid)
{
uint8 roles = PlayersStore[guid].GetRoles();
- TC_LOG_TRACE("lfg.data.player.role.get", "Player: %u, Role: %u", guid.GetCounter(), roles);
+ TC_LOG_TRACE("lfg.data.player.role.get", "Player: %s, Role: %u", guid.ToString().c_str(), roles);
return roles;
}
const std::string& LFGMgr::GetComment(ObjectGuid guid)
{
- TC_LOG_TRACE("lfg.data.player.comment.get", "Player: %u, Comment: %s", guid.GetCounter(), PlayersStore[guid].GetComment().c_str());
+ TC_LOG_TRACE("lfg.data.player.comment.get", "Player: %s, Comment: %s", guid.ToString().c_str(), PlayersStore[guid].GetComment().c_str());
return PlayersStore[guid].GetComment();
}
LfgDungeonSet const& LFGMgr::GetSelectedDungeons(ObjectGuid guid)
{
- TC_LOG_TRACE("lfg.data.player.dungeons.selected.get", "Player: %u, Selected Dungeons: %s", guid.GetCounter(), ConcatenateDungeons(PlayersStore[guid].GetSelectedDungeons()).c_str());
+ TC_LOG_TRACE("lfg.data.player.dungeons.selected.get", "Player: %s, Selected Dungeons: %s", guid.ToString().c_str(), ConcatenateDungeons(PlayersStore[guid].GetSelectedDungeons()).c_str());
return PlayersStore[guid].GetSelectedDungeons();
}
LfgLockMap const LFGMgr::GetLockedDungeons(ObjectGuid guid)
{
- TC_LOG_TRACE("lfg.data.player.dungeons.locked.get", "Player: %u, LockedDungeons.", guid.GetCounter());
+ TC_LOG_TRACE("lfg.data.player.dungeons.locked.get", "Player: %s, LockedDungeons.", guid.ToString().c_str());
LfgLockMap lock;
Player* player = ObjectAccessor::FindPlayer(guid);
if (!player)
{
- TC_LOG_WARN("lfg.data.player.dungeons.locked.get", "Player: %u not ingame while retrieving his LockedDungeons.", guid.GetCounter());
+ TC_LOG_WARN("lfg.data.player.dungeons.locked.get", "Player: %s not ingame while retrieving his LockedDungeons.", guid.ToString().c_str());
return lock;
}
@@ -1612,7 +1608,7 @@ LfgLockMap const LFGMgr::GetLockedDungeons(ObjectGuid guid)
uint8 LFGMgr::GetKicksLeft(ObjectGuid guid)
{
uint8 kicks = GroupsStore[guid].GetKicksLeft();
- TC_LOG_TRACE("lfg.data.group.kickleft.get", "Group: %u, Kicks left: %u", guid.GetCounter(), kicks);
+ TC_LOG_TRACE("lfg.data.group.kickleft.get", "Group: %s, Kicks left: %u", guid.ToString().c_str(), kicks);
return kicks;
}
@@ -1621,8 +1617,8 @@ void LFGMgr::RestoreState(ObjectGuid guid, char const* debugMsg)
if (guid.IsGroup())
{
LfgGroupData& data = GroupsStore[guid];
- TC_LOG_TRACE("lfg.data.group.state.restore", "Group: %u (%s), State: %s, Old state: %s",
- guid.GetCounter(), debugMsg, GetStateString(data.GetState()).c_str(),
+ TC_LOG_TRACE("lfg.data.group.state.restore", "Group: %s (%s), State: %s, Old state: %s",
+ guid.ToString().c_str(), debugMsg, GetStateString(data.GetState()).c_str(),
GetStateString(data.GetOldState()).c_str());
data.RestoreState();
@@ -1630,8 +1626,8 @@ void LFGMgr::RestoreState(ObjectGuid guid, char const* debugMsg)
else
{
LfgPlayerData& data = PlayersStore[guid];
- TC_LOG_TRACE("lfg.data.player.state.restore", "Player: %u (%s), State: %s, Old state: %s",
- guid.GetCounter(), debugMsg, GetStateString(data.GetState()).c_str(),
+ TC_LOG_TRACE("lfg.data.player.state.restore", "Player: %s (%s), State: %s, Old state: %s",
+ guid.ToString().c_str(), debugMsg, GetStateString(data.GetState()).c_str(),
GetStateString(data.GetOldState()).c_str());
data.RestoreState();
@@ -1643,8 +1639,8 @@ void LFGMgr::SetState(ObjectGuid guid, LfgState state)
if (guid.IsGroup())
{
LfgGroupData& data = GroupsStore[guid];
- TC_LOG_TRACE("lfg.data.group.state.set", "Group: %u, New state: %s, Previous: %s, Old state: %s",
- guid.GetCounter(), GetStateString(state).c_str(), GetStateString(data.GetState()).c_str(),
+ TC_LOG_TRACE("lfg.data.group.state.set", "Group: %s, New state: %s, Previous: %s, Old state: %s",
+ guid.ToString().c_str(), GetStateString(state).c_str(), GetStateString(data.GetState()).c_str(),
GetStateString(data.GetOldState()).c_str());
data.SetState(state);
@@ -1652,8 +1648,8 @@ void LFGMgr::SetState(ObjectGuid guid, LfgState state)
else
{
LfgPlayerData& data = PlayersStore[guid];
- TC_LOG_TRACE("lfg.data.player.state.set", "Player: %u, New state: %s, Previous: %s, OldState: %s",
- guid.GetCounter(), GetStateString(state).c_str(), GetStateString(data.GetState()).c_str(),
+ TC_LOG_TRACE("lfg.data.player.state.set", "Player: %s, New state: %s, Previous: %s, OldState: %s",
+ guid.ToString().c_str(), GetStateString(state).c_str(), GetStateString(data.GetState()).c_str(),
GetStateString(data.GetOldState()).c_str());
data.SetState(state);
@@ -1662,37 +1658,37 @@ void LFGMgr::SetState(ObjectGuid guid, LfgState state)
void LFGMgr::SetDungeon(ObjectGuid guid, uint32 dungeon)
{
- TC_LOG_TRACE("lfg.data.group.dungeon.set", "Group: %u, Dungeon: %u", guid.GetCounter(), dungeon);
+ TC_LOG_TRACE("lfg.data.group.dungeon.set", "Group: %s, Dungeon: %u", guid.ToString().c_str(), dungeon);
GroupsStore[guid].SetDungeon(dungeon);
}
void LFGMgr::SetRoles(ObjectGuid guid, uint8 roles)
{
- TC_LOG_TRACE("lfg.data.player.role.set", "Player: %u, Roles: %u", guid.GetCounter(), roles);
+ TC_LOG_TRACE("lfg.data.player.role.set", "Player: %s, Roles: %u", guid.ToString().c_str(), roles);
PlayersStore[guid].SetRoles(roles);
}
void LFGMgr::SetComment(ObjectGuid guid, std::string const& comment)
{
- TC_LOG_TRACE("lfg.data.player.comment.set", "Player: %u, Comment: %s", guid.GetCounter(), comment.c_str());
+ TC_LOG_TRACE("lfg.data.player.comment.set", "Player: %s, Comment: %s", guid.ToString().c_str(), comment.c_str());
PlayersStore[guid].SetComment(comment);
}
void LFGMgr::SetSelectedDungeons(ObjectGuid guid, LfgDungeonSet const& dungeons)
{
- TC_LOG_TRACE("lfg.data.player.dungeon.selected.set", "Player: %u, Dungeons: %s", guid.GetCounter(), ConcatenateDungeons(dungeons).c_str());
+ TC_LOG_TRACE("lfg.data.player.dungeon.selected.set", "Player: %s, Dungeons: %s", guid.ToString().c_str(), ConcatenateDungeons(dungeons).c_str());
PlayersStore[guid].SetSelectedDungeons(dungeons);
}
void LFGMgr::DecreaseKicksLeft(ObjectGuid guid)
{
GroupsStore[guid].DecreaseKicksLeft();
- TC_LOG_TRACE("lfg.data.group.kicksleft.decrease", "Group: %u, Kicks: %u", guid.GetCounter(), GroupsStore[guid].GetKicksLeft());
+ TC_LOG_TRACE("lfg.data.group.kicksleft.decrease", "Group: %s, Kicks: %u", guid.ToString().c_str(), GroupsStore[guid].GetKicksLeft());
}
void LFGMgr::RemovePlayerData(ObjectGuid guid)
{
- TC_LOG_TRACE("lfg.data.player.remove", "Player: %u", guid.GetCounter());
+ TC_LOG_TRACE("lfg.data.player.remove", "Player: %s", guid.ToString().c_str());
LfgPlayerDataContainer::iterator it = PlayersStore.find(guid);
if (it != PlayersStore.end())
PlayersStore.erase(it);
@@ -1700,7 +1696,7 @@ void LFGMgr::RemovePlayerData(ObjectGuid guid)
void LFGMgr::RemoveGroupData(ObjectGuid guid)
{
- TC_LOG_TRACE("lfg.data.group.remove", "Group: %u", guid.GetCounter());
+ TC_LOG_TRACE("lfg.data.group.remove", "Group: %s", guid.ToString().c_str());
LfgGroupDataContainer::iterator it = GroupsStore.find(guid);
if (it == GroupsStore.end())
return;
@@ -1723,7 +1719,7 @@ void LFGMgr::RemoveGroupData(ObjectGuid guid)
uint8 LFGMgr::GetTeam(ObjectGuid guid)
{
uint8 team = PlayersStore[guid].GetTeam();
- TC_LOG_TRACE("lfg.data.player.team.get", "Player: %u, Team: %u", guid.GetCounter(), team);
+ TC_LOG_TRACE("lfg.data.player.team.get", "Player: %s, Team: %u", guid.ToString().c_str(), team);
return team;
}
@@ -1777,50 +1773,50 @@ ObjectGuid LFGMgr::GetLeader(ObjectGuid guid)
bool LFGMgr::HasIgnore(ObjectGuid guid1, ObjectGuid guid2)
{
- Player* plr1 = ObjectAccessor::FindPlayer(guid1);
- Player* plr2 = ObjectAccessor::FindPlayer(guid2);
+ Player* plr1 = ObjectAccessor::FindConnectedPlayer(guid1);
+ Player* plr2 = ObjectAccessor::FindConnectedPlayer(guid2);
return plr1 && plr2 && (plr1->GetSocial()->HasIgnore(guid2.GetCounter()) || plr2->GetSocial()->HasIgnore(guid1.GetCounter()));
}
void LFGMgr::SendLfgRoleChosen(ObjectGuid guid, ObjectGuid pguid, uint8 roles)
{
- if (Player* player = ObjectAccessor::FindPlayer(guid))
+ if (Player* player = ObjectAccessor::FindConnectedPlayer(guid))
player->GetSession()->SendLfgRoleChosen(pguid, roles);
}
void LFGMgr::SendLfgRoleCheckUpdate(ObjectGuid guid, LfgRoleCheck const& roleCheck)
{
- if (Player* player = ObjectAccessor::FindPlayer(guid))
+ if (Player* player = ObjectAccessor::FindConnectedPlayer(guid))
player->GetSession()->SendLfgRoleCheckUpdate(roleCheck);
}
void LFGMgr::SendLfgUpdateStatus(ObjectGuid guid, LfgUpdateData const& data, bool party)
{
- if (Player* player = ObjectAccessor::FindPlayer(guid))
+ if (Player* player = ObjectAccessor::FindConnectedPlayer(guid))
player->GetSession()->SendLfgUpdateStatus(data, party);
}
void LFGMgr::SendLfgJoinResult(ObjectGuid guid, LfgJoinResultData const& data)
{
- if (Player* player = ObjectAccessor::FindPlayer(guid))
+ if (Player* player = ObjectAccessor::FindConnectedPlayer(guid))
player->GetSession()->SendLfgJoinResult(data);
}
void LFGMgr::SendLfgBootProposalUpdate(ObjectGuid guid, LfgPlayerBoot const& boot)
{
- if (Player* player = ObjectAccessor::FindPlayer(guid))
+ if (Player* player = ObjectAccessor::FindConnectedPlayer(guid))
player->GetSession()->SendLfgBootProposalUpdate(boot);
}
void LFGMgr::SendLfgUpdateProposal(ObjectGuid guid, LfgProposal const& proposal)
{
- if (Player* player = ObjectAccessor::FindPlayer(guid))
+ if (Player* player = ObjectAccessor::FindConnectedPlayer(guid))
player->GetSession()->SendLfgUpdateProposal(proposal);
}
void LFGMgr::SendLfgQueueStatus(ObjectGuid guid, LfgQueueStatusData const& data)
{
- if (Player* player = ObjectAccessor::FindPlayer(guid))
+ if (Player* player = ObjectAccessor::FindConnectedPlayer(guid))
player->GetSession()->SendLfgQueueStatus(data);
}
diff --git a/src/server/game/DungeonFinding/LFGMgr.h b/src/server/game/DungeonFinding/LFGMgr.h
index 343705a58ab..9f990131a71 100644
--- a/src/server/game/DungeonFinding/LFGMgr.h
+++ b/src/server/game/DungeonFinding/LFGMgr.h
@@ -421,7 +421,7 @@ class LFGMgr
/// Gets queue join time
time_t GetQueueJoinTime(ObjectGuid guid);
/// Checks if given roles match, modifies given roles map with new roles
- static bool CheckGroupRoles(LfgRolesMap &groles, bool removeLeaderFlag = true);
+ static bool CheckGroupRoles(LfgRolesMap &groles);
/// Checks if given players are ignoring each other
static bool HasIgnore(ObjectGuid guid1, ObjectGuid guid2);
/// Sends queue status to player
diff --git a/src/server/game/DungeonFinding/LFGScripts.cpp b/src/server/game/DungeonFinding/LFGScripts.cpp
index bac1949d894..f9c059feea9 100644
--- a/src/server/game/DungeonFinding/LFGScripts.cpp
+++ b/src/server/game/DungeonFinding/LFGScripts.cpp
@@ -60,8 +60,8 @@ void LFGPlayerScript::OnLogin(Player* player, bool /*loginFirst*/)
ObjectGuid gguid2 = group->GetGUID();
if (gguid != gguid2)
{
- TC_LOG_ERROR("lfg", "%s on group %u but LFG has group %u saved... Fixing.",
- player->GetSession()->GetPlayerInfo().c_str(), gguid2.GetCounter(), gguid.GetCounter());
+ TC_LOG_ERROR("lfg", "%s on group %s but LFG has group %s saved... Fixing.",
+ player->GetSession()->GetPlayerInfo().c_str(), gguid2.ToString().c_str(), gguid.ToString().c_str());
sLFGMgr->SetupGroupMember(guid, group->GetGUID());
}
}
@@ -184,7 +184,7 @@ void LFGGroupScript::OnRemoveMember(Group* group, ObjectGuid guid, RemoveMethod
}
if (isLFG && state != LFG_STATE_FINISHED_DUNGEON) // Need more players to finish the dungeon
- if (Player* leader = ObjectAccessor::FindPlayer(sLFGMgr->GetLeader(gguid)))
+ if (Player* leader = ObjectAccessor::FindConnectedPlayer(sLFGMgr->GetLeader(gguid)))
leader->GetSession()->SendLfgOfferContinue(sLFGMgr->GetDungeon(gguid, false));
}
diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp
index 7a0ee24aeca..8f75cd34f28 100644
--- a/src/server/game/Entities/Creature/Creature.cpp
+++ b/src/server/game/Entities/Creature/Creature.cpp
@@ -875,7 +875,7 @@ Player* Creature::GetLootRecipient() const
{
if (!m_lootRecipient)
return NULL;
- return ObjectAccessor::FindPlayer(m_lootRecipient);
+ return ObjectAccessor::FindConnectedPlayer(m_lootRecipient);
}
Group* Creature::GetLootRecipientGroup() const
@@ -1887,6 +1887,9 @@ void Creature::CallForHelp(float radius)
bool Creature::CanAssistTo(const Unit* u, const Unit* enemy, bool checkfaction /*= true*/) const
{
+ if (IsInEvadeMode())
+ return false;
+
// is it true?
if (!HasReactState(REACT_AGGRESSIVE))
return false;
@@ -2416,16 +2419,6 @@ std::string const & Creature::GetNameForLocaleIdx(LocaleConstant loc_idx) const
return GetName();
}
-//Do not if this works or not, moving creature to another map is very dangerous
-void Creature::FarTeleportTo(Map* map, float X, float Y, float Z, float O)
-{
- CleanupBeforeRemoveFromMap(false);
- GetMap()->RemoveFromMap(this, false);
- Relocate(X, Y, Z, O);
- SetMap(map);
- GetMap()->AddToMap(this);
-}
-
uint32 Creature::GetPetAutoSpellOnPos(uint8 pos) const
{
if (pos >= MAX_SPELL_CHARM || m_charmInfo->GetCharmSpell(pos)->GetType() != ACT_ENABLED)
diff --git a/src/server/game/Entities/Creature/Creature.h b/src/server/game/Entities/Creature/Creature.h
index b7c86aebfdf..c147c3e3f27 100644
--- a/src/server/game/Entities/Creature/Creature.h
+++ b/src/server/game/Entities/Creature/Creature.h
@@ -669,8 +669,6 @@ class Creature : public Unit, public GridObject<Creature>, public MapObject
float m_SightDistance, m_CombatDistance;
- void FarTeleportTo(Map* map, float X, float Y, float Z, float O);
-
bool m_isTempWorldObject; //true when possessed
// Handling caster facing during spellcast
diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp
index 334cd5ce905..46c9c80851b 100644
--- a/src/server/game/Entities/GameObject/GameObject.cpp
+++ b/src/server/game/Entities/GameObject/GameObject.cpp
@@ -2185,7 +2185,7 @@ Player* GameObject::GetLootRecipient() const
{
if (!m_lootRecipient)
return NULL;
- return ObjectAccessor::FindPlayer(m_lootRecipient);
+ return ObjectAccessor::FindConnectedPlayer(m_lootRecipient);
}
Group* GameObject::GetLootRecipientGroup() const
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index 0b7f358a1d3..14ca3a645d7 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -151,7 +151,7 @@ uint32 const MasterySpells[MAX_CLASSES] =
87491, // Druid
};
-uint64 const MAX_MONEY_AMOUNT = static_cast<uint64>(std::numeric_limits<int64>::max());
+uint64 const MAX_MONEY_AMOUNT = 9999999999ULL;
// == PlayerTaxi ================================================
@@ -4834,11 +4834,8 @@ void Player::DeleteFromDB(ObjectGuid playerguid, uint32 accountId, bool updateRe
{
if (Player* pFriend = ObjectAccessor::FindPlayer(ObjectGuid(HIGHGUID_PLAYER, 0, (*resultFriends)[0].GetUInt32())))
{
- if (pFriend->IsInWorld())
- {
- pFriend->GetSocial()->RemoveFromSocialList(guid, false);
- sSocialMgr->SendFriendStatus(pFriend, FRIEND_REMOVED, guid, false);
- }
+ pFriend->GetSocial()->RemoveFromSocialList(guid, false);
+ sSocialMgr->SendFriendStatus(pFriend, FRIEND_REMOVED, guid, false);
}
} while (resultFriends->NextRow());
}
@@ -21403,7 +21400,7 @@ void Player::RemovePetitionsAndSigns(ObjectGuid guid, uint32 type)
ObjectGuid petitionguid = ObjectGuid(HIGHGUID_ITEM, fields[1].GetUInt32());
// send update if charter owner in game
- Player* owner = ObjectAccessor::FindPlayer(ownerguid);
+ Player* owner = ObjectAccessor::FindConnectedPlayer(ownerguid);
if (owner)
owner->GetSession()->SendPetitionQueryOpcode(petitionguid);
} while (result->NextRow());
diff --git a/src/server/game/Entities/Player/SocialMgr.cpp b/src/server/game/Entities/Player/SocialMgr.cpp
index af076b8a5fb..c4b0165d4bc 100644
--- a/src/server/game/Entities/Player/SocialMgr.cpp
+++ b/src/server/game/Entities/Player/SocialMgr.cpp
@@ -295,7 +295,7 @@ void SocialMgr::BroadcastToFriendListers(Player* player, WorldPacket* packet)
if (itr2 != itr->second.m_playerSocialMap.end() && (itr2->second.Flags & SOCIAL_FLAG_FRIEND))
{
Player* target = ObjectAccessor::FindPlayer(ObjectGuid(HIGHGUID_PLAYER, 0, itr->first));
- if (!target || !target->IsInWorld())
+ if (!target)
continue;
WorldSession* session = target->GetSession();
diff --git a/src/server/game/Entities/Transport/Transport.cpp b/src/server/game/Entities/Transport/Transport.cpp
index 983e2e7c4b3..f237c1aa71a 100644
--- a/src/server/game/Entities/Transport/Transport.cpp
+++ b/src/server/game/Entities/Transport/Transport.cpp
@@ -618,19 +618,6 @@ bool Transport::TeleportTransport(uint32 newMapid, float x, float y, float z, fl
switch (obj->GetTypeId())
{
- case TYPEID_UNIT:
- if (!obj->ToUnit()->GetOwnerGUID().IsPlayer()) // pets should be teleported with player
- obj->ToCreature()->FarTeleportTo(newMap, destX, destY, destZ, destO);
- break;
- case TYPEID_GAMEOBJECT:
- {
- GameObject* go = obj->ToGameObject();
- go->GetMap()->RemoveFromMap(go, false);
- go->Relocate(destX, destY, destZ, destO);
- go->SetMap(newMap);
- newMap->AddToMap(go);
- break;
- }
case TYPEID_PLAYER:
if (!obj->ToPlayer()->TeleportTo(newMapid, destX, destY, destZ, destO, TELE_TO_NOT_LEAVE_TRANSPORT))
RemovePassenger(obj);
@@ -639,6 +626,7 @@ bool Transport::TeleportTransport(uint32 newMapid, float x, float y, float z, fl
obj->AddObjectToRemoveList();
break;
default:
+ RemovePassenger(obj);
break;
}
}
diff --git a/src/server/game/Globals/ObjectAccessor.cpp b/src/server/game/Globals/ObjectAccessor.cpp
index 16dabe4fcad..65b7d19aee3 100644
--- a/src/server/game/Globals/ObjectAccessor.cpp
+++ b/src/server/game/Globals/ObjectAccessor.cpp
@@ -212,6 +212,11 @@ Player* ObjectAccessor::FindPlayer(ObjectGuid guid)
return GetObjectInWorld(guid, (Player*)NULL);
}
+Player* ObjectAccessor::FindConnectedPlayer(ObjectGuid guid)
+{
+ return HashMapHolder<Player>::Find(guid);
+}
+
Unit* ObjectAccessor::FindUnit(ObjectGuid guid)
{
return GetObjectInWorld(guid, (Unit*)NULL);
@@ -237,6 +242,24 @@ Player* ObjectAccessor::FindPlayerByName(std::string const& name)
return NULL;
}
+Player* ObjectAccessor::FindConnectedPlayerByName(std::string const& name)
+{
+ boost::shared_lock<boost::shared_mutex> lock(*HashMapHolder<Player>::GetLock());
+
+ std::string nameStr = name;
+ std::transform(nameStr.begin(), nameStr.end(), nameStr.begin(), ::tolower);
+ HashMapHolder<Player>::MapType const& m = GetPlayers();
+ for (HashMapHolder<Player>::MapType::const_iterator iter = m.begin(); iter != m.end(); ++iter)
+ {
+ std::string currentName = iter->second->GetName();
+ std::transform(currentName.begin(), currentName.end(), currentName.begin(), ::tolower);
+ if (nameStr.compare(currentName) == 0)
+ return iter->second;
+ }
+
+ return NULL;
+}
+
void ObjectAccessor::SaveAllPlayers()
{
boost::shared_lock<boost::shared_mutex> lock(*HashMapHolder<Player>::GetLock());
diff --git a/src/server/game/Globals/ObjectAccessor.h b/src/server/game/Globals/ObjectAccessor.h
index a23932fb702..0b7f7d11f8d 100644
--- a/src/server/game/Globals/ObjectAccessor.h
+++ b/src/server/game/Globals/ObjectAccessor.h
@@ -170,6 +170,10 @@ class ObjectAccessor
static Unit* FindUnit(ObjectGuid);
static Player* FindPlayerByName(std::string const& name);
+ // this returns Player even if he is not in world, for example teleporting
+ static Player* FindConnectedPlayer(ObjectGuid);
+ static Player* FindConnectedPlayerByName(std::string const& name);
+
// when using this, you must use the hashmapholder's lock
static HashMapHolder<Player>::MapType const& GetPlayers()
{
diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp
index b5cabd70d3c..6ceee339d70 100644
--- a/src/server/game/Globals/ObjectMgr.cpp
+++ b/src/server/game/Globals/ObjectMgr.cpp
@@ -1782,6 +1782,21 @@ void ObjectMgr::LoadCreatures()
data.phaseGroup = 0;
}
+ if (sWorld->getBoolConfig(CONFIG_CALCULATE_CREATURE_ZONE_AREA_DATA))
+ {
+ uint32 zoneId = 0;
+ uint32 areaId = 0;
+ sMapMgr->GetZoneAndAreaId(zoneId, areaId, data.mapid, data.posX, data.posY, data.posZ);
+
+ PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_UPD_CREATURE_ZONE_AREA_DATA);
+
+ stmt->setUInt32(0, zoneId);
+ stmt->setUInt32(1, areaId);
+ stmt->setUInt64(2, guid);
+
+ WorldDatabase.Execute(stmt);
+ }
+
// Add to grid if not managed by the game event or pool system
if (gameEvent == 0 && PoolId == 0)
AddCreatureToGrid(guid, &data);
@@ -2105,6 +2120,21 @@ void ObjectMgr::LoadGameobjects()
data.phaseMask = 1;
}
+ if (sWorld->getBoolConfig(CONFIG_CALCULATE_GAMEOBJECT_ZONE_AREA_DATA))
+ {
+ uint32 zoneId = 0;
+ uint32 areaId = 0;
+ sMapMgr->GetZoneAndAreaId(zoneId, areaId, data.mapid, data.posX, data.posY, data.posZ);
+
+ PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_UPD_GAMEOBJECT_ZONE_AREA_DATA);
+
+ stmt->setUInt32(0, zoneId);
+ stmt->setUInt32(1, areaId);
+ stmt->setUInt64(2, guid);
+
+ WorldDatabase.Execute(stmt);
+ }
+
if (gameEvent == 0 && PoolId == 0) // if not this is to be managed by GameEvent System or Pool system
AddGameobjectToGrid(guid, &data);
++count;
@@ -2165,7 +2195,7 @@ ObjectGuid ObjectMgr::GetPlayerGUIDByName(std::string const& name) const
bool ObjectMgr::GetPlayerNameByGUID(ObjectGuid guid, std::string& name) const
{
// prevent DB access for online player
- if (Player* player = ObjectAccessor::FindPlayer(guid))
+ if (Player* player = ObjectAccessor::FindConnectedPlayer(guid))
{
name = player->GetName();
return true;
@@ -2189,7 +2219,7 @@ bool ObjectMgr::GetPlayerNameByGUID(ObjectGuid guid, std::string& name) const
uint32 ObjectMgr::GetPlayerTeamByGUID(ObjectGuid guid) const
{
// prevent DB access for online player
- if (Player* player = ObjectAccessor::FindPlayer(guid))
+ if (Player* player = ObjectAccessor::FindConnectedPlayer(guid))
{
return Player::TeamForRace(player->getRace());
}
@@ -2212,7 +2242,7 @@ uint32 ObjectMgr::GetPlayerTeamByGUID(ObjectGuid guid) const
uint32 ObjectMgr::GetPlayerAccountIdByGUID(ObjectGuid guid) const
{
// prevent DB access for online player
- if (Player* player = ObjectAccessor::FindPlayer(guid))
+ if (Player* player = ObjectAccessor::FindConnectedPlayer(guid))
{
return player->GetSession()->GetAccountId();
}
@@ -5551,7 +5581,7 @@ void ObjectMgr::ReturnOrDeleteOldMails(bool serverUp)
Player* player = NULL;
if (serverUp)
- player = ObjectAccessor::FindPlayer(ObjectGuid(HIGHGUID_PLAYER, m->receiver));
+ player = ObjectAccessor::FindConnectedPlayer(ObjectGuid(HIGHGUID_PLAYER, m->receiver));
if (player && player->m_mailsLoaded)
{ // this code will run very improbably (the time is between 4 and 5 am, in game is online a player, who has old mail
diff --git a/src/server/game/Grids/Notifiers/GridNotifiers.cpp b/src/server/game/Grids/Notifiers/GridNotifiers.cpp
index d5b1022b351..111a5dba77f 100644
--- a/src/server/game/Grids/Notifiers/GridNotifiers.cpp
+++ b/src/server/game/Grids/Notifiers/GridNotifiers.cpp
@@ -73,7 +73,7 @@ void VisibleNotifier::SendToSelf()
if (it->IsPlayer())
{
Player* player = ObjectAccessor::FindPlayer(*it);
- if (player && player->IsInWorld() && !player->isNeedNotify(NOTIFY_VISIBILITY_CHANGED))
+ if (player && !player->isNeedNotify(NOTIFY_VISIBILITY_CHANGED))
player->UpdateVisibilityOf(&i_player);
}
}
diff --git a/src/server/game/Groups/Group.cpp b/src/server/game/Groups/Group.cpp
index 53c5139e20f..95d67f3cb8b 100644
--- a/src/server/game/Groups/Group.cpp
+++ b/src/server/game/Groups/Group.cpp
@@ -526,7 +526,7 @@ bool Group::RemoveMember(ObjectGuid guid, const RemoveMethod& method /*= GROUP_R
// remove member and change leader (if need) only if strong more 2 members _before_ member remove (BG/BF allow 1 member group)
if (GetMembersCount() > ((isBGGroup() || isLFGGroup() || isBFGroup()) ? 1u : 2u))
{
- Player* player = ObjectAccessor::FindPlayer(guid);
+ Player* player = ObjectAccessor::FindConnectedPlayer(guid);
if (player)
{
// Battleground group handling
@@ -610,7 +610,7 @@ bool Group::RemoveMember(ObjectGuid guid, const RemoveMethod& method /*= GROUP_R
{
for (member_witerator itr = m_memberSlots.begin(); itr != m_memberSlots.end(); ++itr)
{
- if (ObjectAccessor::FindPlayer(itr->guid))
+ if (ObjectAccessor::FindConnectedPlayer(itr->guid))
{
ChangeLeader(itr->guid);
break;
@@ -622,7 +622,7 @@ bool Group::RemoveMember(ObjectGuid guid, const RemoveMethod& method /*= GROUP_R
if (isLFGGroup() && GetMembersCount() == 1)
{
- Player* leader = ObjectAccessor::FindPlayer(GetLeaderGUID());
+ Player* leader = ObjectAccessor::FindConnectedPlayer(GetLeaderGUID());
uint32 mapId = sLFGMgr->GetDungeonMapId(GetGUID());
if (!mapId || !leader || (leader->IsAlive() && leader->GetMapId() != mapId))
{
@@ -651,7 +651,7 @@ void Group::ChangeLeader(ObjectGuid newLeaderGuid)
if (slot == m_memberSlots.end())
return;
- Player* newLeader = ObjectAccessor::FindPlayer(slot->guid);
+ Player* newLeader = ObjectAccessor::FindConnectedPlayer(slot->guid);
// Don't allow switching leader to offline players
if (!newLeader)
@@ -699,7 +699,7 @@ void Group::ChangeLeader(ObjectGuid newLeaderGuid)
CharacterDatabase.CommitTransaction(trans);
}
- if (Player* oldLeader = ObjectAccessor::FindPlayer(m_leaderGuid))
+ if (Player* oldLeader = ObjectAccessor::FindConnectedPlayer(m_leaderGuid))
oldLeader->RemoveFlag(PLAYER_FLAGS, PLAYER_FLAGS_GROUP_LEADER);
newLeader->SetFlag(PLAYER_FLAGS, PLAYER_FLAGS_GROUP_LEADER);
@@ -719,7 +719,7 @@ void Group::Disband(bool hideDestroy /* = false */)
Player* player;
for (member_citerator citr = m_memberSlots.begin(); citr != m_memberSlots.end(); ++citr)
{
- player = ObjectAccessor::FindPlayer(citr->guid);
+ player = ObjectAccessor::FindConnectedPlayer(citr->guid);
if (!player)
continue;
@@ -818,7 +818,7 @@ void Group::SendLootStartRoll(uint32 countDown, uint32 mapid, const Roll &r)
for (Roll::PlayerVote::const_iterator itr=r.playerVote.begin(); itr != r.playerVote.end(); ++itr)
{
- Player* p = ObjectAccessor::FindPlayer(itr->first);
+ Player* p = ObjectAccessor::FindConnectedPlayer(itr->first);
if (!p || !p->GetSession())
continue;
@@ -865,7 +865,7 @@ void Group::SendLootRoll(ObjectGuid sourceGuid, ObjectGuid targetGuid, uint8 rol
for (Roll::PlayerVote::const_iterator itr = roll.playerVote.begin(); itr != roll.playerVote.end(); ++itr)
{
- Player* p = ObjectAccessor::FindPlayer(itr->first);
+ Player* p = ObjectAccessor::FindConnectedPlayer(itr->first);
if (!p || !p->GetSession())
continue;
@@ -888,7 +888,7 @@ void Group::SendLootRollWon(ObjectGuid sourceGuid, ObjectGuid targetGuid, uint8
for (Roll::PlayerVote::const_iterator itr = roll.playerVote.begin(); itr != roll.playerVote.end(); ++itr)
{
- Player* p = ObjectAccessor::FindPlayer(itr->first);
+ Player* p = ObjectAccessor::FindConnectedPlayer(itr->first);
if (!p || !p->GetSession())
continue;
@@ -908,7 +908,7 @@ void Group::SendLootAllPassed(Roll const& roll)
for (Roll::PlayerVote::const_iterator itr = roll.playerVote.begin(); itr != roll.playerVote.end(); ++itr)
{
- Player* player = ObjectAccessor::FindPlayer(itr->first);
+ Player* player = ObjectAccessor::FindConnectedPlayer(itr->first);
if (!player || !player->GetSession())
continue;
@@ -1000,7 +1000,7 @@ void Group::GroupLoot(Loot* loot, WorldObject* pLootedObject)
{
for (Roll::PlayerVote::const_iterator itr=r->playerVote.begin(); itr != r->playerVote.end(); ++itr)
{
- Player* p = ObjectAccessor::FindPlayer(itr->first);
+ Player* p = ObjectAccessor::FindConnectedPlayer(itr->first);
if (!p || !p->GetSession())
continue;
@@ -1143,7 +1143,7 @@ void Group::NeedBeforeGreed(Loot* loot, WorldObject* lootedObject)
//Broadcast Pass and Send Rollstart
for (Roll::PlayerVote::const_iterator itr = r->playerVote.begin(); itr != r->playerVote.end(); ++itr)
{
- Player* p = ObjectAccessor::FindPlayer(itr->first);
+ Player* p = ObjectAccessor::FindConnectedPlayer(itr->first);
if (!p || !p->GetSession())
continue;
@@ -1206,7 +1206,7 @@ void Group::NeedBeforeGreed(Loot* loot, WorldObject* lootedObject)
//Broadcast Pass and Send Rollstart
for (Roll::PlayerVote::const_iterator itr = r->playerVote.begin(); itr != r->playerVote.end(); ++itr)
{
- Player* p = ObjectAccessor::FindPlayer(itr->first);
+ Player* p = ObjectAccessor::FindConnectedPlayer(itr->first);
if (!p || !p->GetSession())
continue;
@@ -1373,7 +1373,7 @@ void Group::CountTheRoll(Rolls::iterator rollI)
}
}
SendLootRollWon(ObjectGuid::Empty, maxguid, maxresul, ROLL_NEED, *roll);
- player = ObjectAccessor::FindPlayer(maxguid);
+ player = ObjectAccessor::FindConnectedPlayer(maxguid);
if (player && player->GetSession())
{
@@ -1422,7 +1422,7 @@ void Group::CountTheRoll(Rolls::iterator rollI)
}
}
SendLootRollWon(ObjectGuid::Empty, maxguid, maxresul, rollvote, *roll);
- player = ObjectAccessor::FindPlayer(maxguid);
+ player = ObjectAccessor::FindConnectedPlayer(maxguid);
if (player && player->GetSession())
{
@@ -1539,7 +1539,7 @@ void Group::SendUpdate()
void Group::SendUpdateToPlayer(ObjectGuid playerGUID, MemberSlot* slot)
{
- Player* player = ObjectAccessor::FindPlayer(playerGUID);
+ Player* player = ObjectAccessor::FindConnectedPlayer(playerGUID);
if (!player || !player->GetSession() || player->GetGroup() != this)
return;
@@ -1575,7 +1575,7 @@ void Group::SendUpdateToPlayer(ObjectGuid playerGUID, MemberSlot* slot)
if (slot->guid == citr->guid)
continue;
- Player* member = ObjectAccessor::FindPlayer(citr->guid);
+ Player* member = ObjectAccessor::FindConnectedPlayer(citr->guid);
uint8 onlineState = (member && !member->GetSession()->PlayerLogout()) ? MEMBER_STATUS_ONLINE : MEMBER_STATUS_OFFLINE;
onlineState = onlineState | ((isBGGroup() || isBFGroup()) ? MEMBER_STATUS_PVP : 0);
@@ -1667,7 +1667,7 @@ void Group::OfflineReadyCheck()
{
for (member_citerator citr = m_memberSlots.begin(); citr != m_memberSlots.end(); ++citr)
{
- Player* player = ObjectAccessor::FindPlayer(citr->guid);
+ Player* player = ObjectAccessor::FindConnectedPlayer(citr->guid);
if (!player || !player->GetSession())
{
WorldPacket data(MSG_RAID_READY_CHECK_CONFIRM, 9);
@@ -1750,7 +1750,7 @@ void Group::ChangeMembersGroup(ObjectGuid guid, uint8 group)
}
// In case the moved player is online, update the player object with the new sub group references
- if (Player* player = ObjectAccessor::FindPlayer(guid))
+ if (Player* player = ObjectAccessor::FindConnectedPlayer(guid))
{
if (player->GetGroup() == this)
player->GetGroupRef().setSubGroup(group);
@@ -2175,7 +2175,7 @@ void Group::BroadcastGroupUpdate(void)
for (member_citerator citr = m_memberSlots.begin(); citr != m_memberSlots.end(); ++citr)
{
Player* pp = ObjectAccessor::FindPlayer(citr->guid);
- if (pp && pp->IsInWorld())
+ if (pp)
{
pp->ForceValuesUpdateAtIndex(UNIT_FIELD_BYTES_2);
pp->ForceValuesUpdateAtIndex(UNIT_FIELD_FACTIONTEMPLATE);
diff --git a/src/server/game/Guilds/Guild.cpp b/src/server/game/Guilds/Guild.cpp
index 3f346a0b8c7..b7f3f2c2f79 100644
--- a/src/server/game/Guilds/Guild.cpp
+++ b/src/server/game/Guilds/Guild.cpp
@@ -1760,7 +1760,7 @@ void Guild::HandleBuyBankTab(WorldSession* session, uint8 tabId)
void Guild::HandleInviteMember(WorldSession* session, std::string const& name)
{
- Player* pInvitee = sObjectAccessor->FindPlayerByName(name);
+ Player* pInvitee = ObjectAccessor::FindPlayerByName(name);
if (!pInvitee)
{
SendCommandResult(session, GUILD_COMMAND_INVITE, ERR_GUILD_PLAYER_NOT_FOUND_S, name);
@@ -2616,7 +2616,7 @@ void Guild::BroadcastToGuild(WorldSession* session, bool officerOnly, std::strin
WorldPacket data;
ChatHandler::BuildChatPacket(data, officerOnly ? CHAT_MSG_OFFICER : CHAT_MSG_GUILD, Language(language), session->GetPlayer(), NULL, msg);
for (Members::const_iterator itr = m_members.begin(); itr != m_members.end(); ++itr)
- if (Player* player = itr->second->FindPlayer())
+ if (Player* player = itr->second->FindConnectedPlayer())
if (player->GetSession() && _HasRankRight(player, officerOnly ? GR_RIGHT_OFFCHATLISTEN : GR_RIGHT_GCHATLISTEN) &&
!player->GetSocial()->HasIgnore(session->GetPlayer()->GetGUIDLow()))
player->GetSession()->SendPacket(&data);
@@ -2642,7 +2642,7 @@ void Guild::BroadcastPacketToRank(WorldPacket* packet, uint8 rankId) const
{
for (Members::const_iterator itr = m_members.begin(); itr != m_members.end(); ++itr)
if (itr->second->IsRank(rankId))
- if (Player* player = itr->second->FindPlayer())
+ if (Player* player = itr->second->FindConnectedPlayer())
player->GetSession()->SendPacket(packet);
}
@@ -2697,7 +2697,7 @@ void Guild::MassInviteToEvent(WorldSession* session, uint32 minLevel, uint32 max
// Members handling
bool Guild::AddMember(ObjectGuid guid, uint8 rankId)
{
- Player* player = ObjectAccessor::FindPlayer(guid);
+ Player* player = ObjectAccessor::FindConnectedPlayer(guid);
// Player cannot be in guild
if (player)
{
@@ -2777,7 +2777,7 @@ bool Guild::AddMember(ObjectGuid guid, uint8 rankId)
void Guild::DeleteMember(ObjectGuid guid, bool isDisbanding, bool isKicked, bool canDeleteGuild)
{
uint32 lowguid = guid.GetCounter();
- Player* player = ObjectAccessor::FindPlayer(guid);
+ Player* player = ObjectAccessor::FindConnectedPlayer(guid);
// Guild master can be deleted when loading guild and guid doesn't exist in characters table
// or when he is removed from guild by gm command
diff --git a/src/server/game/Guilds/Guild.h b/src/server/game/Guilds/Guild.h
index 5448180e0ae..4160edf5250 100644
--- a/src/server/game/Guilds/Guild.h
+++ b/src/server/game/Guilds/Guild.h
@@ -413,6 +413,7 @@ private:
void ResetValues(bool weekly = false);
inline Player* FindPlayer() const { return ObjectAccessor::FindPlayer(m_guid); }
+ inline Player* FindConnectedPlayer() const { return ObjectAccessor::FindConnectedPlayer(m_guid); }
private:
uint32 m_guildId;
@@ -855,7 +856,7 @@ public:
void BroadcastWorker(Do& _do, Player* except = NULL)
{
for (Members::iterator itr = m_members.begin(); itr != m_members.end(); ++itr)
- if (Player* player = itr->second->FindPlayer())
+ if (Player* player = itr->second->FindConnectedPlayer())
if (player != except)
_do(player);
}
diff --git a/src/server/game/Handlers/ArenaTeamHandler.cpp b/src/server/game/Handlers/ArenaTeamHandler.cpp
index d9303d0295a..0f40650691f 100644
--- a/src/server/game/Handlers/ArenaTeamHandler.cpp
+++ b/src/server/game/Handlers/ArenaTeamHandler.cpp
@@ -147,7 +147,7 @@ void WorldSession::HandleArenaTeamInviteOpcode(WorldPacket& recvData)
if (!normalizePlayerName(invitedName))
return;
- player = sObjectAccessor->FindPlayerByName(invitedName);
+ player = ObjectAccessor::FindPlayerByName(invitedName);
}
if (!player)
diff --git a/src/server/game/Handlers/CalendarHandler.cpp b/src/server/game/Handlers/CalendarHandler.cpp
index 954b4483f62..4d3b7dd024e 100644
--- a/src/server/game/Handlers/CalendarHandler.cpp
+++ b/src/server/game/Handlers/CalendarHandler.cpp
@@ -436,7 +436,7 @@ void WorldSession::HandleCalendarEventInvite(WorldPacket& recvData)
recvData >> eventId >> inviteId >> name >> isPreInvite >> isGuildEvent;
- if (Player* player = sObjectAccessor->FindPlayerByName(name.c_str()))
+ if (Player* player = ObjectAccessor::FindConnectedPlayerByName(name))
{
// Invitee is online
inviteeGuid = player->GetGUID();
diff --git a/src/server/game/Handlers/CharacterHandler.cpp b/src/server/game/Handlers/CharacterHandler.cpp
index feefaec83ab..bef7aada6e9 100644
--- a/src/server/game/Handlers/CharacterHandler.cpp
+++ b/src/server/game/Handlers/CharacterHandler.cpp
@@ -47,6 +47,7 @@
#include "World.h"
#include "WorldPacket.h"
#include "WorldSession.h"
+#include "BattlenetServerManager.h"
class LoginQueryHolder : public SQLQueryHolder
{
@@ -689,13 +690,13 @@ void WorldSession::HandleCharCreateCallback(PreparedQueryResult result, Characte
PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_DEL_REALM_CHARACTERS_BY_REALM);
stmt->setUInt32(0, GetAccountId());
- stmt->setUInt32(1, realmID);
+ stmt->setUInt32(1, realmHandle.Index);
trans->Append(stmt);
stmt = LoginDatabase.GetPreparedStatement(LOGIN_INS_REALM_CHARACTERS);
stmt->setUInt32(0, createInfo->CharCount);
stmt->setUInt32(1, GetAccountId());
- stmt->setUInt32(2, realmID);
+ stmt->setUInt32(2, realmHandle.Index);
trans->Append(stmt);
LoginDatabase.CommitTransaction(trans);
@@ -784,7 +785,7 @@ void WorldSession::HandleCharDeleteOpcode(WorldPacket& recvData)
{
std::string dump;
if (PlayerDumpWriter().GetDump(guid.GetCounter(), dump))
- sLog->outCharDump(dump.c_str(), accountId, guid.GetCounter(), name.c_str());
+ sLog->outCharDump(dump.c_str(), accountId, guid.GetRawValue(), name.c_str());
}
sGuildFinderMgr->RemoveAllMembershipRequestsFromPlayer(guid);
@@ -1139,6 +1140,8 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder* holder)
sScriptMgr->OnPlayerLogin(pCurrChar, firstLogin);
+ sBattlenetServer.SendChangeToonOnlineState(GetBattlenetAccountId(), GetAccountId(), _player->GetGUID(), _player->GetName(), true);
+
delete holder;
}
diff --git a/src/server/game/Handlers/ChatHandler.cpp b/src/server/game/Handlers/ChatHandler.cpp
index a65c03b25a1..73600ba7c60 100644
--- a/src/server/game/Handlers/ChatHandler.cpp
+++ b/src/server/game/Handlers/ChatHandler.cpp
@@ -326,7 +326,7 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData)
break;
}
- Player* receiver = sObjectAccessor->FindPlayerByName(to);
+ Player* receiver = ObjectAccessor::FindConnectedPlayerByName(to);
if (!receiver || (lang != LANG_ADDON && !receiver->isAcceptWhispers() && receiver->GetSession()->HasPermission(rbac::RBAC_PERM_CAN_FILTER_WHISPERS) && !receiver->IsInWhisperWhiteList(sender->GetGUID())))
{
SendPlayerNotFoundNotice(to);
@@ -803,7 +803,7 @@ void WorldSession::HandleChatIgnoredOpcode(WorldPacket& recvData)
recvData.ReadByteSeq(guid[7]);
recvData.ReadByteSeq(guid[2]);
- Player* player = ObjectAccessor::FindPlayer(guid);
+ Player* player = ObjectAccessor::FindConnectedPlayer(guid);
if (!player || !player->GetSession())
return;
diff --git a/src/server/game/Handlers/GroupHandler.cpp b/src/server/game/Handlers/GroupHandler.cpp
index 149d309f995..10a16dc6b48 100644
--- a/src/server/game/Handlers/GroupHandler.cpp
+++ b/src/server/game/Handlers/GroupHandler.cpp
@@ -106,7 +106,7 @@ void WorldSession::HandleGroupInviteOpcode(WorldPacket& recvData)
return;
}
- Player* player = sObjectAccessor->FindPlayerByName(memberName);
+ Player* player = ObjectAccessor::FindPlayerByName(memberName);
// no player
if (!player)
@@ -384,7 +384,7 @@ void WorldSession::HandleGroupInviteResponseOpcode(WorldPacket& recvData)
else
{
// Remember leader if online (group pointer will be invalid if group gets disbanded)
- Player* leader = ObjectAccessor::FindPlayer(group->GetLeaderGUID());
+ Player* leader = ObjectAccessor::FindConnectedPlayer(group->GetLeaderGUID());
// uninvite, group can be deleted
GetPlayer()->UninviteFromGroup();
@@ -500,7 +500,7 @@ void WorldSession::HandleGroupSetLeaderOpcode(WorldPacket& recvData)
ObjectGuid guid;
recvData >> guid;
- Player* player = ObjectAccessor::FindPlayer(guid);
+ Player* player = ObjectAccessor::FindConnectedPlayer(guid);
Group* group = GetPlayer()->GetGroup();
if (!group || !player)
@@ -755,7 +755,7 @@ void WorldSession::HandleRaidTargetUpdateOpcode(WorldPacket& recvData)
if (guid.IsPlayer())
{
- Player* target = ObjectAccessor::FindPlayer(guid);
+ Player* target = ObjectAccessor::FindConnectedPlayer(guid);
if (!target || target->IsHostileTo(GetPlayer()))
return;
@@ -831,7 +831,7 @@ void WorldSession::HandleGroupChangeSubGroupOpcode(WorldPacket& recvData)
if (!group->HasFreeSlotSubGroup(groupNr))
return;
- Player* movedPlayer = sObjectAccessor->FindPlayerByName(name);
+ Player* movedPlayer = ObjectAccessor::FindConnectedPlayerByName(name);
ObjectGuid guid;
if (movedPlayer)
@@ -1200,7 +1200,7 @@ void WorldSession::HandleRequestPartyMemberStatsOpcode(WorldPacket& recvData)
ObjectGuid Guid;
recvData >> Guid;
- Player* player = HashMapHolder<Player>::Find(Guid);
+ Player* player = ObjectAccessor::FindConnectedPlayer(Guid);
if (!player)
{
WorldPacket data(SMSG_PARTY_MEMBER_STATS_FULL, 3+4+2);
diff --git a/src/server/game/Handlers/LFGHandler.cpp b/src/server/game/Handlers/LFGHandler.cpp
index ea8f86e2adf..654a92f5c4e 100644
--- a/src/server/game/Handlers/LFGHandler.cpp
+++ b/src/server/game/Handlers/LFGHandler.cpp
@@ -230,8 +230,8 @@ void WorldSession::HandleLfgSetRolesOpcode(WorldPacket& recvData)
return;
}
ObjectGuid gguid = group->GetGUID();
- TC_LOG_DEBUG("lfg", "CMSG_LFG_SET_ROLES: Group %u, Player %s, Roles: %u",
- gguid.GetCounter(), GetPlayerInfo().c_str(), roles);
+ TC_LOG_DEBUG("lfg", "CMSG_LFG_SET_ROLES: Group %s, Player %s, Roles: %u",
+ gguid.ToString().c_str(), GetPlayerInfo().c_str(), roles);
sLFGMgr->UpdateRoleCheck(gguid, guid, roles);
}
@@ -497,8 +497,8 @@ void WorldSession::SendLfgUpdateStatus(lfg::LfgUpdateData const& updateData, boo
void WorldSession::SendLfgRoleChosen(ObjectGuid guid, uint8 roles)
{
- TC_LOG_DEBUG("lfg", "SMSG_LFG_ROLE_CHOSEN %s guid: %u roles: %u",
- GetPlayerInfo().c_str(), guid.GetCounter(), roles);
+ TC_LOG_DEBUG("lfg", "SMSG_LFG_ROLE_CHOSEN %s guid: %s roles: %u",
+ GetPlayerInfo().c_str(), guid.ToString().c_str(), roles);
WorldPacket data(SMSG_LFG_ROLE_CHOSEN, 8 + 1 + 4);
data << uint64(guid); // Guid
@@ -531,7 +531,7 @@ void WorldSession::SendLfgRoleCheckUpdate(lfg::LfgRoleCheck const& roleCheck)
// Leader info MUST be sent 1st :S
ObjectGuid guid = roleCheck.leader;
uint8 roles = roleCheck.roles.find(guid)->second;
- Player* player = ObjectAccessor::FindPlayer(guid);
+ Player* player = ObjectAccessor::FindConnectedPlayer(guid);
data << uint64(guid); // Guid
data << uint8(roles > 0); // Ready
data << uint32(roles); // Roles
@@ -544,7 +544,7 @@ void WorldSession::SendLfgRoleCheckUpdate(lfg::LfgRoleCheck const& roleCheck)
guid = it->first;
roles = it->second;
- player = ObjectAccessor::FindPlayer(guid);
+ player = ObjectAccessor::FindConnectedPlayer(guid);
data << uint64(guid); // Guid
data << uint8(roles > 0); // Ready
data << uint32(roles); // Roles
@@ -709,10 +709,10 @@ void WorldSession::SendLfgBootProposalUpdate(lfg::LfgPlayerBoot const& boot)
}
}
TC_LOG_DEBUG("lfg", "SMSG_LFG_BOOT_PROPOSAL_UPDATE %s inProgress: %u - "
- "didVote: %u - agree: %u - victim: %u votes: %u - agrees: %u - left: %u - "
+ "didVote: %u - agree: %u - victim: %s votes: %u - agrees: %u - left: %u - "
"needed: %u - reason %s",
GetPlayerInfo().c_str(), uint8(boot.inProgress), uint8(playerVote != lfg::LFG_ANSWER_PENDING),
- uint8(playerVote == lfg::LFG_ANSWER_AGREE), boot.victim.GetCounter(), votesNum, agreeNum,
+ uint8(playerVote == lfg::LFG_ANSWER_AGREE), boot.victim.ToString().c_str(), votesNum, agreeNum,
secsleft, lfg::LFG_GROUP_KICK_VOTES_NEEDED, boot.reason.c_str());
WorldPacket data(SMSG_LFG_BOOT_PROPOSAL_UPDATE, 1 + 1 + 1 + 1 + 8 + 4 + 4 + 4 + 4 + boot.reason.length());
data << uint8(boot.inProgress); // Vote in progress
diff --git a/src/server/game/Handlers/MailHandler.cpp b/src/server/game/Handlers/MailHandler.cpp
index adf70223db9..e2f9f36163e 100644
--- a/src/server/game/Handlers/MailHandler.cpp
+++ b/src/server/game/Handlers/MailHandler.cpp
@@ -194,7 +194,7 @@ void WorldSession::HandleSendMail(WorldPacket& recvData)
return;
}
- Player* receiver = ObjectAccessor::FindPlayer(receiverGuid);
+ Player* receiver = ObjectAccessor::FindConnectedPlayer(receiverGuid);
uint32 receiverTeam = 0;
uint8 mailsCount = 0; //do not allow to send to one player more than 100 mails
@@ -554,7 +554,7 @@ void WorldSession::HandleMailTakeItem(WorldPacket& recvData)
if (m->COD > 0) //if there is COD, take COD money from player and send them to sender by mail
{
ObjectGuid sender_guid(HIGHGUID_PLAYER, m->sender);
- Player* receiver = ObjectAccessor::FindPlayer(sender_guid);
+ Player* receiver = ObjectAccessor::FindConnectedPlayer(sender_guid);
uint32 sender_accId = 0;
diff --git a/src/server/game/Handlers/MiscHandler.cpp b/src/server/game/Handlers/MiscHandler.cpp
index 279b06e2cef..a149d066a05 100644
--- a/src/server/game/Handlers/MiscHandler.cpp
+++ b/src/server/game/Handlers/MiscHandler.cpp
@@ -258,7 +258,7 @@ void WorldSession::HandleWhoOpcode(WorldPacket& recvData)
boost::shared_lock<boost::shared_mutex> lock(*HashMapHolder<Player>::GetLock());
- HashMapHolder<Player>::MapType const& m = sObjectAccessor->GetPlayers();
+ HashMapHolder<Player>::MapType const& m = ObjectAccessor::GetPlayers();
for (HashMapHolder<Player>::MapType::const_iterator itr = m.begin(); itr != m.end(); ++itr)
{
Player* target = itr->second;
@@ -415,7 +415,8 @@ void WorldSession::HandleLogoutRequestOpcode(WorldPacket& /*recvData*/)
// not set flags if player can't free move to prevent lost state at logout cancel
if (GetPlayer()->CanFreeMove())
{
- GetPlayer()->SetStandState(UNIT_STAND_STATE_SIT);
+ if (GetPlayer()->getStandState() == UNIT_STAND_STATE_STAND)
+ GetPlayer()->SetStandState(UNIT_STAND_STATE_SIT);
GetPlayer()->SetRooted(true);
GetPlayer()->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED);
}
@@ -608,7 +609,7 @@ void WorldSession::HandleAddFriendOpcodeCallBack(PreparedQueryResult result, std
team = Player::TeamForRace(fields[1].GetUInt8());
friendAccountId = fields[2].GetUInt32();
- if (HasPermission(rbac::RBAC_PERM_ALLOW_GM_FRIEND) || AccountMgr::IsPlayerAccount(AccountMgr::GetSecurity(friendAccountId, realmID)))
+ if (HasPermission(rbac::RBAC_PERM_ALLOW_GM_FRIEND) || AccountMgr::IsPlayerAccount(AccountMgr::GetSecurity(friendAccountId, realmHandle.Index)))
{
if (friendGuid)
{
@@ -621,7 +622,7 @@ void WorldSession::HandleAddFriendOpcodeCallBack(PreparedQueryResult result, std
else
{
Player* pFriend = ObjectAccessor::FindPlayer(friendGuid);
- if (pFriend && pFriend->IsInWorld() && pFriend->IsVisibleGloballyFor(GetPlayer()))
+ if (pFriend && pFriend->IsVisibleGloballyFor(GetPlayer()))
friendResult = FRIEND_ADDED_ONLINE;
else
friendResult = FRIEND_ADDED_OFFLINE;
@@ -1374,7 +1375,7 @@ void WorldSession::HandleWhoisOpcode(WorldPacket& recvData)
return;
}
- Player* player = sObjectAccessor->FindPlayerByName(charname);
+ Player* player = ObjectAccessor::FindConnectedPlayerByName(charname);
if (!player)
{
diff --git a/src/server/game/Handlers/PetitionsHandler.cpp b/src/server/game/Handlers/PetitionsHandler.cpp
index d3d32745c5e..a8df52344a0 100644
--- a/src/server/game/Handlers/PetitionsHandler.cpp
+++ b/src/server/game/Handlers/PetitionsHandler.cpp
@@ -263,7 +263,7 @@ void WorldSession::HandlePetitionShowSignOpcode(WorldPacket& recvData)
if (!result)
{
- TC_LOG_DEBUG("entities.player.items", "Petition %u is not found for player %u %s", petitionguid.GetCounter(), GetPlayer()->GetGUIDLow(), GetPlayer()->GetName().c_str());
+ TC_LOG_DEBUG("entities.player.items", "Petition %s is not found for player %u %s", petitionguid.ToString().c_str(), GetPlayer()->GetGUIDLow(), GetPlayer()->GetName().c_str());
return;
}
Field* fields = result->Fetch();
@@ -581,7 +581,7 @@ void WorldSession::HandlePetitionSignOpcode(WorldPacket& recvData)
// item->SetUInt32Value(ITEM_FIELD_ENCHANTMENT_1_1+1, signs);
// update for owner if online
- if (Player* owner = ObjectAccessor::FindPlayer(ownerGuid))
+ if (Player* owner = ObjectAccessor::FindConnectedPlayer(ownerGuid))
owner->GetSession()->SendPacket(&data);
}
@@ -605,7 +605,7 @@ void WorldSession::HandlePetitionDeclineOpcode(WorldPacket& recvData)
Field* fields = result->Fetch();
ObjectGuid ownerguid(HIGHGUID_PLAYER, 0, fields[0].GetUInt32());
- Player* owner = ObjectAccessor::FindPlayer(ownerguid);
+ Player* owner = ObjectAccessor::FindConnectedPlayer(ownerguid);
if (owner) // petition owner online
{
WorldPacket data(MSG_PETITION_DECLINE, 8);
@@ -626,7 +626,7 @@ void WorldSession::HandleOfferPetitionOpcode(WorldPacket& recvData)
recvData >> petitionguid; // petition guid
recvData >> plguid; // player guid
- player = ObjectAccessor::FindPlayer(plguid);
+ player = ObjectAccessor::FindConnectedPlayer(plguid);
if (!player)
return;
diff --git a/src/server/game/Handlers/QueryHandler.cpp b/src/server/game/Handlers/QueryHandler.cpp
index 1418cd8a2d8..84f117a0000 100644
--- a/src/server/game/Handlers/QueryHandler.cpp
+++ b/src/server/game/Handlers/QueryHandler.cpp
@@ -33,7 +33,7 @@
void WorldSession::SendNameQueryOpcode(ObjectGuid guid)
{
- Player* player = ObjectAccessor::FindPlayer(guid);
+ Player* player = ObjectAccessor::FindConnectedPlayer(guid);
CharacterNameData const* nameData = sWorld->GetCharacterNameData(guid);
WorldPacket data(SMSG_NAME_QUERY_RESPONSE, (8+1+1+1+1+1+10));
diff --git a/src/server/game/Instances/InstanceSaveMgr.cpp b/src/server/game/Instances/InstanceSaveMgr.cpp
index 9f565c8d58d..f739c0f35dd 100644
--- a/src/server/game/Instances/InstanceSaveMgr.cpp
+++ b/src/server/game/Instances/InstanceSaveMgr.cpp
@@ -385,7 +385,7 @@ void InstanceSaveManager::LoadResetTimes()
if (oldresettime != newresettime)
CharacterDatabase.DirectPExecute("UPDATE instance_reset SET resettime = '%u' WHERE mapid = '%u' AND difficulty = '%u'", uint32(newresettime), mapid, difficulty);
- SetResetTimeFor(mapid, difficulty, newresettime);
+ InitializeResetTimeFor(mapid, difficulty, newresettime);
} while (result->NextRow());
}
@@ -422,7 +422,7 @@ void InstanceSaveManager::LoadResetTimes()
CharacterDatabase.DirectPExecute("UPDATE instance_reset SET resettime = '" UI64FMTD "' WHERE mapid = '%u' AND difficulty= '%u'", (uint64)t, mapid, difficulty);
}
- SetResetTimeFor(mapid, difficulty, t);
+ InitializeResetTimeFor(mapid, difficulty, t);
// schedule the global reset/warning
uint8 type;
diff --git a/src/server/game/Instances/InstanceSaveMgr.h b/src/server/game/Instances/InstanceSaveMgr.h
index 72d180c2373..b2c86d5152b 100644
--- a/src/server/game/Instances/InstanceSaveMgr.h
+++ b/src/server/game/Instances/InstanceSaveMgr.h
@@ -191,11 +191,20 @@ class InstanceSaveManager
return itr != m_resetTimeByMapDifficulty.end() ? itr->second : 0;
}
- void SetResetTimeFor(uint32 mapid, Difficulty d, time_t t)
+ // Use this on startup when initializing reset times
+ void InitializeResetTimeFor(uint32 mapid, Difficulty d, time_t t)
{
m_resetTimeByMapDifficulty[MAKE_PAIR32(mapid, d)] = t;
}
+ // Use this only when updating existing reset times
+ void SetResetTimeFor(uint32 mapid, Difficulty d, time_t t)
+ {
+ ResetTimeByMapDifficultyMap::iterator itr = m_resetTimeByMapDifficulty.find(MAKE_PAIR32(mapid, d));
+ ASSERT(itr != m_resetTimeByMapDifficulty.end());
+ itr->second = t;
+ }
+
ResetTimeByMapDifficultyMap const& GetResetTimeMap() const
{
return m_resetTimeByMapDifficulty;
diff --git a/src/server/game/Loot/LootMgr.cpp b/src/server/game/Loot/LootMgr.cpp
index 4a30b4f4b97..35b62bd24c3 100644
--- a/src/server/game/Loot/LootMgr.cpp
+++ b/src/server/game/Loot/LootMgr.cpp
@@ -272,9 +272,14 @@ void LootStore::ReportUnusedIds(LootIdSet const& lootIdSet) const
TC_LOG_ERROR("sql.sql", "Table '%s' Entry %d isn't %s and not referenced from loot, and thus useless.", GetName(), *itr, GetEntryName());
}
-void LootStore::ReportNonExistingId(uint32 id) const
+void LootStore::ReportNonExistingId(uint32 lootId) const
{
- TC_LOG_ERROR("sql.sql", "Table '%s' Entry %d (%s) does not exist but is used as loot id in DB.", GetName(), id, GetEntryName());
+ TC_LOG_ERROR("sql.sql", "Table '%s' Entry %d does not exist", GetName(), lootId);
+}
+
+void LootStore::ReportNonExistingId(uint32 lootId, const char* ownerType, uint32 ownerId) const
+{
+ TC_LOG_ERROR("sql.sql", "Table '%s' Entry %d does not exist but it is used by %s %d", GetName(), lootId, ownerType, ownerId);
}
//
@@ -1223,7 +1228,7 @@ void LootTemplate::LootGroup::CheckLootRefs(LootTemplateMap const& /*store*/, Lo
if (item->reference > 0)
{
if (!LootTemplates_Reference.GetLootFor(item->reference))
- LootTemplates_Reference.ReportNonExistingId(item->reference);
+ LootTemplates_Reference.ReportNonExistingId(item->reference, "Reference", item->itemid);
else if (ref_set)
ref_set->erase(item->reference);
}
@@ -1235,7 +1240,7 @@ void LootTemplate::LootGroup::CheckLootRefs(LootTemplateMap const& /*store*/, Lo
if (item->reference > 0)
{
if (!LootTemplates_Reference.GetLootFor(item->reference))
- LootTemplates_Reference.ReportNonExistingId(item->reference);
+ LootTemplates_Reference.ReportNonExistingId(item->reference, "Reference", item->itemid);
else if (ref_set)
ref_set->erase(item->reference);
}
@@ -1436,7 +1441,7 @@ void LootTemplate::CheckLootRefs(LootTemplateMap const& store, LootIdSet* ref_se
if (item->reference > 0)
{
if (!LootTemplates_Reference.GetLootFor(item->reference))
- LootTemplates_Reference.ReportNonExistingId(item->reference);
+ LootTemplates_Reference.ReportNonExistingId(item->reference, "Reference", item->itemid);
else if (ref_set)
ref_set->erase(item->reference);
}
@@ -1530,7 +1535,7 @@ void LoadLootTemplates_Creature()
if (uint32 lootid = itr->second.lootid)
{
if (lootIdSet.find(lootid) == lootIdSet.end())
- LootTemplates_Creature.ReportNonExistingId(lootid);
+ LootTemplates_Creature.ReportNonExistingId(lootid, "Creature", itr->second.Entry);
else
lootIdSetUsed.insert(lootid);
}
@@ -1622,7 +1627,7 @@ void LoadLootTemplates_Gameobject()
if (uint32 lootid = itr->second.GetLootId())
{
if (lootIdSet.find(lootid) == lootIdSet.end())
- LootTemplates_Gameobject.ReportNonExistingId(lootid);
+ LootTemplates_Gameobject.ReportNonExistingId(lootid, "Gameobject", itr->second.entry);
else
lootIdSetUsed.insert(lootid);
}
@@ -1709,7 +1714,7 @@ void LoadLootTemplates_Pickpocketing()
if (uint32 lootid = itr->second.pickpocketLootId)
{
if (lootIdSet.find(lootid) == lootIdSet.end())
- LootTemplates_Pickpocketing.ReportNonExistingId(lootid);
+ LootTemplates_Pickpocketing.ReportNonExistingId(lootid, "Creature", itr->second.Entry);
else
lootIdSetUsed.insert(lootid);
}
@@ -1796,7 +1801,7 @@ void LoadLootTemplates_Skinning()
if (uint32 lootid = itr->second.SkinLootId)
{
if (lootIdSet.find(lootid) == lootIdSet.end())
- LootTemplates_Skinning.ReportNonExistingId(lootid);
+ LootTemplates_Skinning.ReportNonExistingId(lootid, "Creature", itr->second.Entry);
else
lootIdSetUsed.insert(lootid);
}
@@ -1840,7 +1845,7 @@ void LoadLootTemplates_Spell()
// ignore 61756 (Northrend Inscription Research (FAST QA VERSION) for example
if (!(spellInfo->Attributes & SPELL_ATTR0_NOT_SHAPESHIFT) || (spellInfo->Attributes & SPELL_ATTR0_TRADESPELL))
{
- LootTemplates_Spell.ReportNonExistingId(spell_id);
+ LootTemplates_Spell.ReportNonExistingId(spell_id, "Spell", spellInfo->Id);
}
}
else
diff --git a/src/server/game/Loot/LootMgr.h b/src/server/game/Loot/LootMgr.h
index 1685996fd03..52632393ca1 100644
--- a/src/server/game/Loot/LootMgr.h
+++ b/src/server/game/Loot/LootMgr.h
@@ -216,7 +216,8 @@ class LootStore
uint32 LoadAndCollectLootIds(LootIdSet& ids_set);
void CheckLootRefs(LootIdSet* ref_set = NULL) const; // check existence reference and remove it from ref_set
void ReportUnusedIds(LootIdSet const& ids_set) const;
- void ReportNonExistingId(uint32 id) const;
+ void ReportNonExistingId(uint32 lootId) const;
+ void ReportNonExistingId(uint32 lootId, const char* ownerType, uint32 ownerId) const;
bool HaveLootFor(uint32 loot_id) const { return m_LootTemplates.find(loot_id) != m_LootTemplates.end(); }
bool HaveQuestLootFor(uint32 loot_id) const;
diff --git a/src/server/game/Mails/Mail.cpp b/src/server/game/Mails/Mail.cpp
index 2459e468c25..820a54b9760 100644
--- a/src/server/game/Mails/Mail.cpp
+++ b/src/server/game/Mails/Mail.cpp
@@ -131,7 +131,7 @@ void MailDraft::deleteIncludedItems(SQLTransaction& trans, bool inDB /*= false*/
void MailDraft::SendReturnToSender(uint32 sender_acc, uint32 sender_guid, uint32 receiver_guid, SQLTransaction& trans)
{
ObjectGuid receiverGuid(HIGHGUID_PLAYER, receiver_guid);
- Player* receiver = ObjectAccessor::FindPlayer(receiverGuid);
+ Player* receiver = ObjectAccessor::FindConnectedPlayer(receiverGuid);
uint32 rc_account = 0;
if (!receiver)
diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp
index ab50d16d8f5..f5f9546b7b2 100644
--- a/src/server/game/Maps/Map.cpp
+++ b/src/server/game/Maps/Map.cpp
@@ -20,6 +20,7 @@
#include "Battleground.h"
#include "MMapFactory.h"
#include "CellImpl.h"
+#include "DisableMgr.h"
#include "DynamicTree.h"
#include "GridNotifiers.h"
#include "GridNotifiersImpl.h"
@@ -119,7 +120,7 @@ bool Map::ExistVMap(uint32 mapid, int gx, int gy)
void Map::LoadMMap(int gx, int gy)
{
- if (!MMAP::MMapFactory::IsPathfindingEnabled(GetId()))
+ if (!DisableMgr::IsPathfindingEnabled(GetId()))
return;
bool mmapLoadResult = MMAP::MMapFactory::createOrGetMMapManager()->loadMap((sWorld->GetDataPath() + "mmaps").c_str(), GetId(), gx, gy);
@@ -1585,7 +1586,7 @@ GridMap::~GridMap()
unloadData();
}
-bool GridMap::loadData(char* filename)
+bool GridMap::loadData(const char* filename)
{
// Unload old data if exist
unloadData();
@@ -2967,7 +2968,7 @@ bool InstanceMap::AddPlayerToMap(Player* player)
InstanceGroupBind* groupBind = group->GetBoundInstance(this);
if (playerBind && playerBind->save != mapSave)
{
- TC_LOG_ERROR("maps", "InstanceMap::Add: player %s(%d) is being put into instance %s %d, %d, %d, %d, %d, %d but he is in group %d and is bound to instance %d, %d, %d, %d, %d, %d!", player->GetName().c_str(), player->GetGUIDLow(), GetMapName(), mapSave->GetMapId(), mapSave->GetInstanceId(), mapSave->GetDifficulty(), mapSave->GetPlayerCount(), mapSave->GetGroupCount(), mapSave->CanReset(), group->GetLeaderGUID().GetCounter(), playerBind->save->GetMapId(), playerBind->save->GetInstanceId(), playerBind->save->GetDifficulty(), playerBind->save->GetPlayerCount(), playerBind->save->GetGroupCount(), playerBind->save->CanReset());
+ TC_LOG_ERROR("maps", "InstanceMap::Add: player %s(%d) is being put into instance %s %d, %d, %d, %d, %d, %d but he is in group %s and is bound to instance %d, %d, %d, %d, %d, %d!", player->GetName().c_str(), player->GetGUIDLow(), GetMapName(), mapSave->GetMapId(), mapSave->GetInstanceId(), mapSave->GetDifficulty(), mapSave->GetPlayerCount(), mapSave->GetGroupCount(), mapSave->CanReset(), group->GetLeaderGUID().ToString().c_str(), playerBind->save->GetMapId(), playerBind->save->GetInstanceId(), playerBind->save->GetDifficulty(), playerBind->save->GetPlayerCount(), playerBind->save->GetGroupCount(), playerBind->save->CanReset());
if (groupBind)
TC_LOG_ERROR("maps", "InstanceMap::Add: the group is bound to the instance %s %d, %d, %d, %d, %d, %d", GetMapName(), groupBind->save->GetMapId(), groupBind->save->GetInstanceId(), groupBind->save->GetDifficulty(), groupBind->save->GetPlayerCount(), groupBind->save->GetGroupCount(), groupBind->save->CanReset());
//ASSERT(false);
@@ -2981,7 +2982,7 @@ bool InstanceMap::AddPlayerToMap(Player* player)
// cannot jump to a different instance without resetting it
if (groupBind->save != mapSave)
{
- TC_LOG_ERROR("maps", "InstanceMap::Add: player %s(%d) is being put into instance %d, %d, %d but he is in group %d which is bound to instance %d, %d, %d!", player->GetName().c_str(), player->GetGUIDLow(), mapSave->GetMapId(), mapSave->GetInstanceId(), mapSave->GetDifficulty(), group->GetLeaderGUID().GetCounter(), groupBind->save->GetMapId(), groupBind->save->GetInstanceId(), groupBind->save->GetDifficulty());
+ TC_LOG_ERROR("maps", "InstanceMap::Add: player %s(%d) is being put into instance %d, %d, %d but he is in group %s which is bound to instance %d, %d, %d!", player->GetName().c_str(), player->GetGUIDLow(), mapSave->GetMapId(), mapSave->GetInstanceId(), mapSave->GetDifficulty(), group->GetLeaderGUID().ToString().c_str(), groupBind->save->GetMapId(), groupBind->save->GetInstanceId(), groupBind->save->GetDifficulty());
TC_LOG_ERROR("maps", "MapSave players: %d, group count: %d", mapSave->GetPlayerCount(), mapSave->GetGroupCount());
if (groupBind->save)
TC_LOG_ERROR("maps", "GroupBind save players: %d, group count: %d", groupBind->save->GetPlayerCount(), groupBind->save->GetGroupCount());
diff --git a/src/server/game/Maps/Map.h b/src/server/game/Maps/Map.h
index c0b50b078d8..cf10f48f82e 100644
--- a/src/server/game/Maps/Map.h
+++ b/src/server/game/Maps/Map.h
@@ -200,7 +200,7 @@ class GridMap
public:
GridMap();
~GridMap();
- bool loadData(char* filaname);
+ bool loadData(const char* filename);
void unloadData();
uint16 getArea(float x, float y) const;
diff --git a/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.cpp
index dbe8c8b0329..2e859a7a56f 100644
--- a/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.cpp
+++ b/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.cpp
@@ -99,7 +99,12 @@ void RandomMovementGenerator<Creature>::_setRandomLocation(Creature* creature)
if (is_air_ok)
i_nextMoveTime.Reset(0);
else
- i_nextMoveTime.Reset(urand(500, 10000));
+ {
+ if (roll_chance_i(50))
+ i_nextMoveTime.Reset(urand(5000, 10000));
+ else
+ i_nextMoveTime.Reset(urand(50, 400));
+ }
creature->AddUnitState(UNIT_STATE_ROAMING_MOVE);
diff --git a/src/server/game/Movement/PathGenerator.cpp b/src/server/game/Movement/PathGenerator.cpp
index 2ef465f6775..523cfb7ea2f 100644
--- a/src/server/game/Movement/PathGenerator.cpp
+++ b/src/server/game/Movement/PathGenerator.cpp
@@ -23,7 +23,7 @@
#include "MMapFactory.h"
#include "MMapManager.h"
#include "Log.h"
-
+#include "DisableMgr.h"
#include "DetourCommon.h"
#include "DetourNavMeshQuery.h"
@@ -39,7 +39,7 @@ PathGenerator::PathGenerator(const Unit* owner) :
TC_LOG_DEBUG("maps", "++ PathGenerator::PathGenerator for %u \n", _sourceUnit->GetGUIDLow());
uint32 mapId = _sourceUnit->GetMapId();
- if (MMAP::MMapFactory::IsPathfindingEnabled(mapId))
+ if (DisableMgr::IsPathfindingEnabled(mapId))
{
MMAP::MMapManager* mmap = MMAP::MMapFactory::createOrGetMMapManager();
_navMesh = mmap->GetNavMesh(mapId);
diff --git a/src/server/game/Server/BattlenetServerManager.cpp b/src/server/game/Server/BattlenetServerManager.cpp
new file mode 100644
index 00000000000..b267926c6ff
--- /dev/null
+++ b/src/server/game/Server/BattlenetServerManager.cpp
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2008-2014 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 "Config.h"
+#include "World.h"
+#include "ZmqContext.h"
+#include "BattlenetServerManager.h"
+
+void Battlenet::ServerManager::InitializeConnection()
+{
+ std::string bnetserverAddress = sConfigMgr->GetStringDefault("BnetServer.Address", "127.0.0.1");
+ int32 bnetserverPort = sConfigMgr->GetIntDefault("BnetServer.Port", 1118);
+ _socket = new ZmqMux("inproc://bnetmgr", "tcp://" + bnetserverAddress + ":" + std::to_string(bnetserverPort));
+ _socket->Start();
+}
+
+void Battlenet::ServerManager::CloseConnection()
+{
+ _socket->End();
+ delete _socket;
+ _socket = nullptr;
+}
+
+Battlenet::Header Battlenet::ServerManager::CreateHeader(BnetCommands command)
+{
+ Header header;
+ header.Ipc.Channel = IPC_CHANNEL_BNET;
+ header.Ipc.Command = command;
+ header.Realm = realmHandle;
+ return header;
+}
+
+void Battlenet::ServerManager::SendChangeToonOnlineState(uint32 battlenetAccountId, uint32 gameAccountId, ObjectGuid guid, std::string const& name, bool online)
+{
+ // Do nothing for Grunt login
+ if (!battlenetAccountId)
+ return;
+
+ Header header = CreateHeader(BNET_CHANGE_TOON_ONLINE_STATE);
+ ToonHandle toon;
+ toon.AccountId = battlenetAccountId;
+ toon.GameAccountId = gameAccountId;
+ toon.Guid = guid;
+ toon.Name = name;
+
+ zmqpp::message msg;
+ msg << header;
+ msg << toon;
+ msg << online;
+
+ _socket->Send(&msg);
+}
diff --git a/src/server/game/Server/BattlenetServerManager.h b/src/server/game/Server/BattlenetServerManager.h
new file mode 100644
index 00000000000..fe103a1c981
--- /dev/null
+++ b/src/server/game/Server/BattlenetServerManager.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2008-2014 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 BattlenetMgr_h__
+#define BattlenetMgr_h__
+
+#include "ZmqMux.h"
+#include "Commands.h"
+
+namespace zmqpp
+{
+ class socket;
+}
+
+namespace Battlenet
+{
+ class ServerManager
+ {
+ ServerManager() : _socket(nullptr) { }
+
+ public:
+ void InitializeConnection();
+ void CloseConnection();
+
+ static ServerManager& Instance()
+ {
+ static ServerManager instance;
+ return instance;
+ }
+
+ void SendChangeToonOnlineState(uint32 battlenetAccountId, uint32 gameAccountId, ObjectGuid guid, std::string const& name, bool online);
+
+ private:
+ static Header CreateHeader(BnetCommands command);
+ ZmqMux* _socket;
+ };
+}
+
+#define sBattlenetServer Battlenet::ServerManager::Instance()
+
+#endif // BattlenetMgr_h__
diff --git a/src/server/game/Server/WorldSession.cpp b/src/server/game/Server/WorldSession.cpp
index 428e0582867..0fd46f0d20b 100644
--- a/src/server/game/Server/WorldSession.cpp
+++ b/src/server/game/Server/WorldSession.cpp
@@ -47,6 +47,7 @@
#include "Transport.h"
#include "WardenWin.h"
#include "WardenMac.h"
+#include "BattlenetServerManager.h"
namespace {
@@ -56,8 +57,7 @@ std::string const DefaultPlayerName = "<none>";
bool MapSessionFilter::Process(WorldPacket* packet)
{
- Opcodes opcode = DropHighBytes(packet->GetOpcode());
- OpcodeHandler const* opHandle = opcodeTable[opcode];
+ OpcodeHandler const* opHandle = opcodeTable[packet->GetOpcode()];
//let's check if our opcode can be really processed in Map::Update()
if (opHandle->ProcessingPlace == PROCESS_INPLACE)
@@ -79,8 +79,7 @@ bool MapSessionFilter::Process(WorldPacket* packet)
//OR packet handler is not thread-safe!
bool WorldSessionFilter::Process(WorldPacket* packet)
{
- Opcodes opcode = DropHighBytes(packet->GetOpcode());
- OpcodeHandler const* opHandle = opcodeTable[opcode];
+ OpcodeHandler const* opHandle = opcodeTable[packet->GetOpcode()];
//check if packet handler is supposed to be safe
if (opHandle->ProcessingPlace == PROCESS_INPLACE)
return true;
@@ -584,6 +583,9 @@ void WorldSession::LogoutPlayer(bool save)
_player->CleanupsBeforeDelete();
TC_LOG_INFO("entities.player.character", "Account: %d (IP: %s) Logout Character:[%s] (GUID: %u) Level: %d",
GetAccountId(), GetRemoteAddress().c_str(), _player->GetName().c_str(), _player->GetGUIDLow(), _player->getLevel());
+
+ sBattlenetServer.SendChangeToonOnlineState(GetBattlenetAccountId(), GetAccountId(), _player->GetGUID(), _player->GetName(), false);
+
if (Map* _map = _player->FindMap())
_map->RemovePlayerFromMap(_player, true);
@@ -1145,11 +1147,11 @@ void WorldSession::LoadPermissions()
AccountMgr::GetName(id, name);
uint8 secLevel = GetSecurity();
- _RBACData = new rbac::RBACData(id, name, realmID, secLevel);
+ _RBACData = new rbac::RBACData(id, name, realmHandle.Index, secLevel);
_RBACData->LoadFromDB();
TC_LOG_DEBUG("rbac", "WorldSession::LoadPermissions [AccountId: %u, Name: %s, realmId: %d, secLevel: %u]",
- id, name.c_str(), realmID, secLevel);
+ id, name.c_str(), realmHandle.Index, secLevel);
}
rbac::RBACData* WorldSession::GetRBACData()
@@ -1164,7 +1166,7 @@ bool WorldSession::HasPermission(uint32 permission)
bool hasPermission = _RBACData->HasPermission(permission);
TC_LOG_DEBUG("rbac", "WorldSession::HasPermission [AccountId: %u, Name: %s, realmId: %d]",
- _RBACData->GetId(), _RBACData->GetName().c_str(), realmID);
+ _RBACData->GetId(), _RBACData->GetName().c_str(), realmHandle.Index);
return hasPermission;
}
@@ -1172,7 +1174,7 @@ bool WorldSession::HasPermission(uint32 permission)
void WorldSession::InvalidateRBACData()
{
TC_LOG_DEBUG("rbac", "WorldSession::Invalidaterbac::RBACData [AccountId: %u, Name: %s, realmId: %d]",
- _RBACData->GetId(), _RBACData->GetName().c_str(), realmID);
+ _RBACData->GetId(), _RBACData->GetName().c_str(), realmHandle.Index);
delete _RBACData;
_RBACData = NULL;
}
diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h
index 4ec407f5254..02a185b0b63 100644
--- a/src/server/game/Server/WorldSession.h
+++ b/src/server/game/Server/WorldSession.h
@@ -144,7 +144,6 @@ public:
virtual bool Process(WorldPacket* /*packet*/) { return true; }
virtual bool ProcessLogout() const { return true; }
- static Opcodes DropHighBytes(Opcodes opcode) { return Opcodes(opcode & 0xFFFF); }
protected:
WorldSession* const m_pSession;
diff --git a/src/server/game/Server/WorldSocket.cpp b/src/server/game/Server/WorldSocket.cpp
index f37354f7e65..7933ddfeb4d 100644
--- a/src/server/game/Server/WorldSocket.cpp
+++ b/src/server/game/Server/WorldSocket.cpp
@@ -162,7 +162,7 @@ bool WorldSocket::ReadDataHandler()
{
ClientPktHeader* header = reinterpret_cast<ClientPktHeader*>(_headerBuffer.GetReadPointer());
- Opcodes opcode = PacketFilter::DropHighBytes(Opcodes(header->cmd));
+ Opcodes opcode = Opcodes(header->cmd);
std::string opcodeName = GetOpcodeNameForLogging(opcode);
@@ -213,6 +213,20 @@ bool WorldSocket::ReadDataHandler()
return false;
}
+ // prevent invalid memory access/crash with custom opcodes
+ if (opcode >= NUM_OPCODE_HANDLERS)
+ {
+ CloseSocket();
+ return false;
+ }
+
+ OpcodeHandler const* handler = opcodeTable[opcode];
+ if (!handler)
+ {
+ TC_LOG_ERROR("network.opcode", "No defined handler for opcode %s sent by %s", GetOpcodeNameForLogging(packet.GetOpcode()).c_str(), _worldSession->GetPlayerInfo().c_str());
+ return true;
+ }
+
// Our Idle timer will reset on any non PING opcodes.
// Catches people idling on the login screen and any lingering ingame connections.
_worldSession->ResetTimeOutTime();
@@ -392,7 +406,7 @@ void WorldSocket::HandleAuthSession(WorldPacket& recvPacket)
return;
}
- if (realmIndex != realmID)
+ if (realmIndex != realmHandle.Index)
{
SendAuthResponseError(REALM_LIST_REALM_NOT_FOUND);
TC_LOG_ERROR("network", "WorldSocket::HandleAuthSession: Sent Auth Response (bad realm).");
@@ -471,7 +485,7 @@ void WorldSocket::HandleAuthSession(WorldPacket& recvPacket)
stmt = LoginDatabase.GetPreparedStatement(LOGIN_GET_GMLEVEL_BY_REALMID);
stmt->setUInt32(0, id);
- stmt->setInt32(1, int32(realmID));
+ stmt->setInt32(1, int32(realmHandle.Index));
result = LoginDatabase.Query(stmt);
diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp
index 108f23bcc6a..3d0955f5d97 100644
--- a/src/server/game/Spells/Spell.cpp
+++ b/src/server/game/Spells/Spell.cpp
@@ -4383,7 +4383,10 @@ void Spell::TakeAmmo()
if (!pItem || pItem->IsBroken() || pItem->GetTemplate()->SubClass == ITEM_SUBCLASS_WEAPON_WAND)
return;
- if (pItem->GetTemplate()->InventoryType == INVTYPE_THROWN)
+ if ((pItem->GetTemplate()->InventoryType == INVTYPE_THROWN ||
+ pItem->GetTemplate()->InventoryType == INVTYPE_RANGED ||
+ pItem->GetTemplate()->InventoryType == INVTYPE_RANGEDRIGHT)
+ && roll_chance_f(sWorld->getRate(RATE_DURABILITY_LOSS_DAMAGE)))
{
if (pItem->GetMaxStackCount() == 1)
{
diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp
index d5ddf62b441..46fac6340a8 100644
--- a/src/server/game/Spells/SpellMgr.cpp
+++ b/src/server/game/Spells/SpellMgr.cpp
@@ -2385,6 +2385,14 @@ void SpellMgr::LoadSpellLinked()
TC_LOG_ERROR("sql.sql", "Spell %u listed in `spell_linked_spell` does not exist", abs(trigger));
continue;
}
+
+ if (effect >= 0)
+ for (uint8 j = 0; j < MAX_SPELL_EFFECTS; ++j)
+ {
+ if (spellInfo->Effects[j].CalcValue() == abs(effect))
+ TC_LOG_ERROR("sql.sql", "Spell %u Effect: %u listed in `spell_linked_spell` has same bp%u like effect (possible hack)", abs(trigger), abs(effect), j);
+ }
+
spellInfo = GetSpellInfo(abs(effect));
if (!spellInfo)
{
@@ -3330,7 +3338,7 @@ void SpellMgr::LoadSpellInfoCorrections()
break;
case 51798: // Brewfest - Relay Race - Intro - Quest Complete
case 47134: // Quest Complete
- //! HACK: This spell break quest complete for alliance and on retail not used °_O
+ //! HACK: This spell break quest complete for alliance and on retail not used °_O
spellInfo->Effects[EFFECT_0].Effect = 0;
break;
// ULDUAR SPELLS
diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp
index 3a183ec50bc..d3d06d0ee8a 100644
--- a/src/server/game/World/World.cpp
+++ b/src/server/game/World/World.cpp
@@ -1303,6 +1303,9 @@ void World::LoadConfigSettings(bool reload)
// AHBot
m_int_configs[CONFIG_AHBOT_UPDATE_INTERVAL] = sConfigMgr->GetIntDefault("AuctionHouseBot.Update.Interval", 20);
+ m_bool_configs[CONFIG_CALCULATE_CREATURE_ZONE_AREA_DATA] = sConfigMgr->GetBoolDefault("Calculate.Creature.Zone.Area.Data", false);
+ m_bool_configs[CONFIG_CALCULATE_GAMEOBJECT_ZONE_AREA_DATA] = sConfigMgr->GetBoolDefault("Calculate.Gameoject.Zone.Area.Data", false);
+
// call ScriptMgr if we're reloading the configuration
if (reload)
sScriptMgr->OnConfigLoad(reload);
@@ -1322,6 +1325,13 @@ void World::SetInitialWorldSettings()
///- Initialize detour memory management
dtAllocSetCustom(dtCustomAlloc, dtCustomFree);
+ ///- Initialize VMapManager function pointers (to untangle game/collision circular deps)
+ if (VMAP::VMapManager2* vmmgr2 = dynamic_cast<VMAP::VMapManager2*>(VMAP::VMapFactory::createOrGetVMapManager()))
+ {
+ vmmgr2->GetLiquidFlagsPtr = &GetLiquidFlags;
+ vmmgr2->IsVMAPDisabledForPtr = &DisableMgr::IsVMAPDisabledFor;
+ }
+
///- Initialize config settings
LoadConfigSettings();
@@ -1365,7 +1375,7 @@ void World::SetInitialWorldSettings()
uint32 server_type = IsFFAPvPRealm() ? uint32(REALM_TYPE_PVP) : getIntConfig(CONFIG_GAME_TYPE);
uint32 realm_zone = getIntConfig(CONFIG_REALM_ZONE);
- LoginDatabase.PExecute("UPDATE realmlist SET icon = %u, timezone = %u WHERE id = '%d'", server_type, realm_zone, realmID); // One-time query
+ LoginDatabase.PExecute("UPDATE realmlist SET icon = %u, timezone = %u WHERE id = '%d'", server_type, realm_zone, realmHandle.Index); // One-time query
///- Remove the bones (they should not exist in DB though) and old corpses after a restart
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_OLD_CORPSES);
@@ -1787,7 +1797,7 @@ void World::SetInitialWorldSettings()
m_startTime = m_gameTime;
LoginDatabase.PExecute("INSERT INTO uptime (realmid, starttime, uptime, revision) VALUES(%u, %u, 0, '%s')",
- realmID, uint32(m_startTime), _FULLVERSION); // One-time query
+ realmHandle.Index, uint32(m_startTime), _FULLVERSION); // One-time query
m_timers[WUPDATE_WEATHERS].SetInterval(1*IN_MILLISECONDS);
m_timers[WUPDATE_AUCTIONS].SetInterval(MINUTE*IN_MILLISECONDS);
@@ -2069,7 +2079,7 @@ void World::Update(uint32 diff)
stmt->setUInt32(0, tmpDiff);
stmt->setUInt16(1, uint16(maxOnlinePlayers));
- stmt->setUInt32(2, realmID);
+ stmt->setUInt32(2, realmHandle.Index);
stmt->setUInt32(3, uint32(m_startTime));
LoginDatabase.Execute(stmt);
@@ -2489,7 +2499,7 @@ bool World::RemoveBanAccount(BanMode mode, std::string const& nameOrIP)
/// Ban an account or ban an IP address, duration will be parsed using TimeStringToSecs if it is positive, otherwise permban
BanReturn World::BanCharacter(std::string const& name, std::string const& duration, std::string const& reason, std::string const& author)
{
- Player* pBanned = sObjectAccessor->FindPlayerByName(name);
+ Player* pBanned = ObjectAccessor::FindConnectedPlayerByName(name);
uint32 guid = 0;
uint32 duration_secs = TimeStringToSecs(duration);
@@ -2530,7 +2540,7 @@ BanReturn World::BanCharacter(std::string const& name, std::string const& durati
/// Remove a ban from a character
bool World::RemoveBanCharacter(std::string const& name)
{
- Player* pBanned = sObjectAccessor->FindPlayerByName(name);
+ Player* pBanned = ObjectAccessor::FindConnectedPlayerByName(name);
uint32 guid = 0;
/// Pick a player to ban if not online
@@ -2799,13 +2809,13 @@ void World::_UpdateRealmCharCount(PreparedQueryResult resultCharCount)
PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_DEL_REALM_CHARACTERS_BY_REALM);
stmt->setUInt32(0, accountId);
- stmt->setUInt32(1, realmID);
+ stmt->setUInt32(1, realmHandle.Index);
LoginDatabase.Execute(stmt);
stmt = LoginDatabase.GetPreparedStatement(LOGIN_INS_REALM_CHARACTERS);
stmt->setUInt8(0, charCount);
stmt->setUInt32(1, accountId);
- stmt->setUInt32(2, realmID);
+ stmt->setUInt32(2, realmHandle.Index);
LoginDatabase.Execute(stmt);
}
}
@@ -2974,7 +2984,7 @@ void World::ResetCurrencyWeekCap()
void World::LoadDBAllowedSecurityLevel()
{
PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_REALMLIST_SECURITY_LEVEL);
- stmt->setInt32(0, int32(realmID));
+ stmt->setInt32(0, int32(realmHandle.Index));
PreparedQueryResult result = LoginDatabase.Query(stmt);
if (result)
diff --git a/src/server/game/World/World.h b/src/server/game/World/World.h
index 3bbc4e48eea..2c74e3929fe 100644
--- a/src/server/game/World/World.h
+++ b/src/server/game/World/World.h
@@ -24,6 +24,7 @@
#define __WORLD_H
#include "Common.h"
+#include "Commands.h"
#include "ObjectGuid.h"
#include "Timer.h"
#include "SharedDefines.h"
@@ -166,6 +167,8 @@ enum WorldBoolConfigs
CONFIG_INSTANCES_RESET_ANNOUNCE,
CONFIG_IP_BASED_ACTION_LOGGING,
CONFIG_ALLOW_TRACK_BOTH_RESOURCES,
+ CONFIG_CALCULATE_CREATURE_ZONE_AREA_DATA,
+ CONFIG_CALCULATE_GAMEOBJECT_ZONE_AREA_DATA,
BOOL_CONFIG_VALUE_COUNT
};
@@ -877,7 +880,7 @@ class World
std::deque<std::future<PreparedQueryResult>> m_realmCharCallbacks;
};
-extern uint32 realmID;
+extern Battlenet::RealmHandle realmHandle;
#define sWorld World::instance()
#endif
diff --git a/src/server/ipc/CMakeLists.txt b/src/server/ipc/CMakeLists.txt
new file mode 100644
index 00000000000..93a5d630dfe
--- /dev/null
+++ b/src/server/ipc/CMakeLists.txt
@@ -0,0 +1,24 @@
+# Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
+#
+# This file is free software; as a special exception the author gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+file(GLOB_RECURSE sources_ipc *.cpp *.h)
+
+set(ipc_SRCS
+ ${sources_ipc}
+)
+
+include_directories(
+ ${CMAKE_BINARY_DIR}
+ ${CMAKE_SOURCE_DIR}/dep/zmqpp
+ ${CMAKE_SOURCE_DIR}/src/server/shared/
+ ${ZMQ_INCLUDE_DIR}
+)
+
+add_library(ipc STATIC ${ipc_SRCS})
diff --git a/src/server/ipc/Commands.cpp b/src/server/ipc/Commands.cpp
new file mode 100644
index 00000000000..8e494fc34b9
--- /dev/null
+++ b/src/server/ipc/Commands.cpp
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2008-2014 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 "Commands.h"
+#include <zmqpp/message.hpp>
+
+zmqpp::message& operator>>(zmqpp::message& msg, IPCHeader& header)
+{
+ msg >> header.Channel;
+ msg >> header.Command;
+ return msg;
+}
+
+zmqpp::message& operator>>(zmqpp::message& msg, Battlenet::RealmHandle& realm)
+{
+ msg >> realm.Region;
+ msg >> realm.Battlegroup;
+ msg >> realm.Index;
+ return msg;
+}
+
+zmqpp::message& operator>>(zmqpp::message& msg, Battlenet::Header& header)
+{
+ msg >> header.Ipc;
+ msg >> header.Realm;
+ return msg;
+}
+
+zmqpp::message& operator>>(zmqpp::message& msg, Battlenet::ToonHandle& toonHandle)
+{
+ msg >> toonHandle.AccountId;
+ msg >> toonHandle.GameAccountId;
+ msg >> toonHandle.Guid;
+ msg >> toonHandle.Name;
+ return msg;
+}
+
+zmqpp::message& operator<<(zmqpp::message& msg, IPCHeader& header)
+{
+ msg << header.Channel;
+ msg << header.Command;
+ return msg;
+}
+
+zmqpp::message& operator<<(zmqpp::message& msg, Battlenet::RealmHandle& realm)
+{
+ msg << realm.Region;
+ msg << realm.Battlegroup;
+ msg << realm.Index;
+ return msg;
+}
+
+zmqpp::message& operator<<(zmqpp::message& msg, Battlenet::Header& header)
+{
+ msg << header.Ipc;
+ msg << header.Realm;
+ return msg;
+}
+
+zmqpp::message& operator<<(zmqpp::message& msg, Battlenet::ToonHandle& toonHandle)
+{
+ msg << toonHandle.AccountId;
+ msg << toonHandle.GameAccountId;
+ msg << toonHandle.Guid;
+ msg << toonHandle.Name;
+ return msg;
+}
diff --git a/src/server/ipc/Commands.h b/src/server/ipc/Commands.h
new file mode 100644
index 00000000000..05309a45022
--- /dev/null
+++ b/src/server/ipc/Commands.h
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2008-2014 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 _COMMANDS_H
+#define _COMMANDS_H
+
+#include "Define.h"
+#include <string>
+
+enum Channels
+{
+ IPC_CHANNEL_BNET,
+
+ MAX_IPC_CHANNELS,
+};
+
+enum BnetCommands
+{
+ BNET_CHANGE_TOON_ONLINE_STATE,
+
+ IPC_BNET_MAX_COMMAND
+};
+
+struct IPCHeader
+{
+ uint8 Channel;
+ uint8 Command;
+};
+
+namespace Battlenet
+{
+ struct RealmHandle
+ {
+ uint8 Region;
+ uint8 Battlegroup;
+ uint32 Index;
+ };
+
+ struct Header
+ {
+ IPCHeader Ipc;
+ RealmHandle Realm;
+ };
+
+ struct ToonHandle
+ {
+ uint32 AccountId;
+ uint32 GameAccountId;
+ uint64 Guid;
+ std::string Name;
+ };
+}
+
+namespace zmqpp
+{
+ class message;
+}
+
+zmqpp::message& operator>>(zmqpp::message& msg, IPCHeader& header);
+zmqpp::message& operator>>(zmqpp::message& msg, Battlenet::RealmHandle& realm);
+zmqpp::message& operator>>(zmqpp::message& msg, Battlenet::Header& header);
+zmqpp::message& operator>>(zmqpp::message& msg, Battlenet::ToonHandle& toonHandle);
+
+zmqpp::message& operator<<(zmqpp::message& msg, IPCHeader& header);
+zmqpp::message& operator<<(zmqpp::message& msg, Battlenet::RealmHandle& realm);
+zmqpp::message& operator<<(zmqpp::message& msg, Battlenet::Header& header);
+zmqpp::message& operator<<(zmqpp::message& msg, Battlenet::ToonHandle& toonHandle);
+
+#endif // _COMMANDS_H
diff --git a/src/server/ipc/ZMQTask.cpp b/src/server/ipc/ZMQTask.cpp
new file mode 100644
index 00000000000..0d25dc2babf
--- /dev/null
+++ b/src/server/ipc/ZMQTask.cpp
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2008-2014 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 "ZMQTask.h"
+#include "ZmqContext.h"
+#include <zmqpp/message.hpp>
+
+ZMQTask::ZMQTask()
+{
+ _poller = new zmqpp::poller();
+}
+
+ZMQTask::~ZMQTask()
+{
+ delete _poller;
+ _poller = NULL;
+ delete _inproc;
+ delete _thread;
+}
+
+void ZMQTask::Start()
+{
+ _inproc = sIpcContext->CreateInprocSubscriber();
+ _poller->add(*_inproc);
+
+ HandleOpen();
+ _thread = new std::thread(&ZMQTask::Run, this);
+}
+
+void ZMQTask::End()
+{
+ _thread->join();
+ _inproc->close();
+ HandleClose();
+}
+
+bool ZMQTask::ProcessExit()
+{
+ if (_poller->events(*_inproc) == zmqpp::poller::poll_in)
+ {
+ int op1;
+ do
+ {
+ zmqpp::message msg;
+ if (!_inproc->receive(msg, true))
+ return false; //No more messages to read from sock. This shouldn't happen.
+
+ // strip 'internalmq.' from message
+ std::string cmd = msg.get(0).substr(11);
+ if (cmd == "kill")
+ return true;
+
+ _inproc->get(zmqpp::socket_option::events, op1);
+ } while (op1 & zmqpp::poller::poll_in);
+ }
+
+ return false;
+}
+
+void ZMQTask::Pipeline(zmqpp::socket* from, zmqpp::socket* to)
+{
+ /*
+ Push messages from socket to socket.
+ */
+ if (_poller->events(*from) == zmqpp::poller::poll_in)
+ {
+ int32 op1, op2;
+ do
+ {
+ zmqpp::message msg;
+ if (!from->receive(msg, true))
+ return; //No more messages to read from socket. This shouldn't happen.
+
+ to->send(msg);
+ from->get(zmqpp::socket_option::events, op1);
+ to->get(zmqpp::socket_option::events, op2);
+ } while(op1 & zmqpp::poller::poll_in && op2 & zmqpp::poller::poll_out);
+ }
+}
diff --git a/src/server/ipc/ZMQTask.h b/src/server/ipc/ZMQTask.h
new file mode 100644
index 00000000000..24251893aaa
--- /dev/null
+++ b/src/server/ipc/ZMQTask.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2008-2014 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 __ZMQTASK_H
+#define __ZMQTASK_H
+
+#include "Define.h"
+#include <thread>
+#include <zmqpp/poller.hpp>
+#include <zmqpp/socket.hpp>
+
+/*
+ This class serves as a base for all long running tasks
+ It is set up to terminate its running task upon receiving "kill" command
+*/
+class ZMQTask
+{
+public:
+ ZMQTask();
+ virtual ~ZMQTask();
+
+ void Start();
+ void End();
+ virtual void Run() = 0;
+
+protected:
+ virtual void HandleOpen() { }
+ virtual void HandleClose() { }
+ void Pipeline(zmqpp::socket* from, zmqpp::socket* to);
+ bool ProcessExit();
+
+ zmqpp::poller* _poller;
+
+ zmqpp::socket* _inproc;
+ std::thread* _thread;
+};
+
+#endif // __ZMQTASK_H
diff --git a/src/server/ipc/ZmqContext.cpp b/src/server/ipc/ZmqContext.cpp
new file mode 100644
index 00000000000..305e6b1d843
--- /dev/null
+++ b/src/server/ipc/ZmqContext.cpp
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2008-2014 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 "ZmqContext.h"
+
+ZmqContext::ZmqContext() : _inproc(nullptr)
+{
+}
+
+ZmqContext::~ZmqContext()
+{
+ delete _inproc;
+}
+
+zmqpp::socket* ZmqContext::CreateNewSocket(zmqpp::socket_type type)
+{
+ std::unique_lock<std::mutex> lock(_mutex);
+ return new zmqpp::socket(_context, type);
+}
+
+void ZmqContext::Initialize()
+{
+ _inproc = new zmqpp::socket(_context, zmqpp::socket_type::pub);
+ _inproc->bind("inproc://workers");
+}
+
+zmqpp::socket* ZmqContext::CreateInprocSubscriber()
+{
+ zmqpp::socket* sub = CreateNewSocket(zmqpp::socket_type::sub);
+ sub->connect("inproc://workers");
+ sub->subscribe("internalmq.");
+ return sub;
+}
+
+void ZmqContext::Close()
+{
+ _inproc->send("internalmq.kill");
+}
diff --git a/src/server/ipc/ZmqContext.h b/src/server/ipc/ZmqContext.h
new file mode 100644
index 00000000000..a6ad12b1b70
--- /dev/null
+++ b/src/server/ipc/ZmqContext.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2008-2014 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 __ZMQCONTEX_H
+#define __ZMQCONTEX_H
+
+#include <zmqpp/zmqpp.hpp>
+#include <mutex>
+
+/*
+ * We need to serialize access to zmq context otherwise stuff blows up.
+ */
+class ZmqContext
+{
+public:
+ ~ZmqContext();
+
+ static ZmqContext* Instance()
+ {
+ static ZmqContext instance;
+ return &instance;
+ }
+
+ zmqpp::socket* CreateNewSocket(zmqpp::socket_type);
+ void Initialize();
+ zmqpp::socket* CreateInprocSubscriber();
+ void Close();
+
+private:
+ ZmqContext();
+ ZmqContext(ZmqContext const&) = delete;
+ ZmqContext& operator=(ZmqContext const&) = delete;
+
+ zmqpp::context _context;
+ std::mutex _mutex;
+ zmqpp::socket* _inproc;
+};
+
+#define sIpcContext ZmqContext::Instance()
+
+#endif
diff --git a/src/server/ipc/ZmqListener.cpp b/src/server/ipc/ZmqListener.cpp
new file mode 100644
index 00000000000..98333305e58
--- /dev/null
+++ b/src/server/ipc/ZmqListener.cpp
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2008-2014 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 "ZmqListener.h"
+#include "ZmqContext.h"
+
+ZmqListener::ZmqListener(std::string const& from, std::string const& to)
+{
+ _from = sIpcContext->CreateNewSocket(zmqpp::socket_type::sub);
+ _to = sIpcContext->CreateNewSocket(zmqpp::socket_type::push);
+ _from->connect(from);
+ _to->bind(to);
+}
+
+ZmqListener::~ZmqListener()
+{
+ delete _from;
+ delete _to;
+}
+
+void ZmqListener::HandleOpen()
+{
+}
+
+void ZmqListener::HandleClose()
+{
+ _from->close();
+ _to->close();
+}
+
+void ZmqListener::Run()
+{
+ while (!ProcessExit())
+ {
+ _poller->poll();
+
+ while (_poller->events(*_from) & zmqpp::poller::poll_in &&
+ _poller->events(*_to) & zmqpp::poller::poll_out)
+ {
+ zmqpp::message msg;
+ _from->receive(msg);
+ _to->send(msg);
+ }
+ }
+}
+
+void ZmqListener::Subscribe(std::string const& keyword)
+{
+ _from->subscribe(keyword);
+}
+
+void ZmqListener::Unsubscribe(std::string const& keyword)
+{
+ _from->unsubscribe(keyword);
+}
diff --git a/src/server/authserver/Server/BattlenetSessionManager.cpp b/src/server/ipc/ZmqListener.h
index 91ba2b65094..8b79ba67f6d 100644
--- a/src/server/authserver/Server/BattlenetSessionManager.cpp
+++ b/src/server/ipc/ZmqListener.h
@@ -15,23 +15,37 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "BattlenetSessionManager.h"
+#ifndef __ZMQLISTENER_H
+#define __ZMQLISTENER_H
-bool Battlenet::SessionManager::StartNetwork(boost::asio::io_service& service, std::string const& bindIp, uint16 port)
+#include "ZMQTask.h"
+#include <zmqpp/zmqpp.hpp>
+
+class ZmqListener : public ZMQTask
{
- if (!BaseSocketMgr::StartNetwork(service, bindIp, port))
- return false;
+/*
+ * Read broadcasts from remote PUB socket, and forward them to
+ * another socket.
+ *
+ * from - client SUB socket
+ * to - listen PUSH socket
+ *
+ */
+public:
+ ZmqListener(std::string const& from, std::string const& to);
+ ~ZmqListener();
+ void Run() override;
- _acceptor->AsyncAcceptManaged(&OnSocketAccept);
- return true;
-}
+ void Subscribe(std::string const& keyword);
+ void Unsubscribe(std::string const& keyword);
-NetworkThread<Battlenet::Session>* Battlenet::SessionManager::CreateThreads() const
-{
- return new NetworkThread<Session>[GetNetworkThreadCount()];
-}
+protected:
+ void HandleOpen() override;
+ void HandleClose() override;
-void Battlenet::SessionManager::OnSocketAccept(tcp::socket&& sock)
-{
- sBattlenetSessionMgr.OnSocketOpen(std::forward<tcp::socket>(sock));
-}
+private:
+ zmqpp::socket* _from;
+ zmqpp::socket* _to;
+};
+
+#endif
diff --git a/src/server/ipc/ZmqMux.cpp b/src/server/ipc/ZmqMux.cpp
new file mode 100644
index 00000000000..4b5a4f48b05
--- /dev/null
+++ b/src/server/ipc/ZmqMux.cpp
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2008-2014 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 "ZmqMux.h"
+#include "ZmqContext.h"
+
+ZmqMux::ZmqMux(std::string from_uri, std::string to_uri):
+ _fromAddress(from_uri)
+{
+ printf("Opening muxer thread from %s to %s\n", from_uri.c_str(), to_uri.c_str());
+ _from = sIpcContext->CreateNewSocket(zmqpp::socket_type::pull);
+ _to = sIpcContext->CreateNewSocket(zmqpp::socket_type::push);
+
+ _from->bind(from_uri);
+ _to->connect(to_uri);
+}
+
+ZmqMux::~ZmqMux()
+{
+ delete _from;
+ delete _to;
+}
+
+void ZmqMux::HandleOpen()
+{
+ _poller->add(*_from);
+ _poller->add(*_to, zmqpp::poller::poll_out);
+}
+
+bool ZmqMux::Send(zmqpp::message* m, bool dont_block)
+{
+ if (_socket.get() == nullptr)
+ {
+ _socket.reset(sIpcContext->CreateNewSocket(zmqpp::socket_type::push));
+ _socket->connect(_fromAddress);
+ }
+
+ return _socket->send(*m, dont_block);
+}
+
+void ZmqMux::Run()
+{
+ for (;;)
+ {
+ if (!_poller->poll())
+ break;
+
+ if (ProcessExit())
+ break;
+
+ Pipeline(_from, _to);
+ }
+}
diff --git a/src/server/ipc/ZmqMux.h b/src/server/ipc/ZmqMux.h
new file mode 100644
index 00000000000..4b81f11daaf
--- /dev/null
+++ b/src/server/ipc/ZmqMux.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2008-2014 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 __ZMQMUX_H
+#define __ZMQMUX_H
+
+#include "ZMQTask.h"
+#include <string>
+#include <boost/thread/tss.hpp>
+
+/*
+ * Multiplexes zmq messages from many threads,
+ * and then passes them to another socket.
+ */
+class ZmqMux : public ZMQTask
+{
+public:
+ ZmqMux(std::string from, std::string to);
+ ~ZmqMux();
+ bool Send(zmqpp::message*, bool dont_block = false);
+ void Run() override;
+
+protected:
+ void HandleOpen() override;
+
+private:
+ boost::thread_specific_ptr<zmqpp::socket> _socket;
+ zmqpp::socket* _from;
+ zmqpp::socket* _to;
+ std::string const _fromAddress;
+};
+
+#endif
diff --git a/src/server/ipc/ZmqWorker.cpp b/src/server/ipc/ZmqWorker.cpp
new file mode 100644
index 00000000000..f205ea831b5
--- /dev/null
+++ b/src/server/ipc/ZmqWorker.cpp
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2008-2014 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 "ZmqWorker.h"
+#include "ZmqContext.h"
+
+ZmqWorker::ZmqWorker(std::string task_uri, std::string res_uri) :
+ _taskUri(task_uri), _resultsUri(res_uri)
+{
+}
+
+ZmqWorker::~ZmqWorker()
+{
+ delete _taskQueue;
+ delete _results;
+ delete _inproc;
+}
+
+void ZmqWorker::HandleOpen()
+{
+ _taskQueue = sIpcContext->CreateNewSocket(zmqpp::socket_type::pull);
+ _results = sIpcContext->CreateNewSocket(zmqpp::socket_type::push);
+
+ _taskQueue->connect(_taskUri);
+ _results->connect(_resultsUri);
+
+ _poller->add(*_taskQueue);
+}
+
+void ZmqWorker::HandleClose()
+{
+ _taskQueue->close();
+ _results->close();
+}
+
+void ZmqWorker::Run()
+{
+ while (!ProcessExit())
+ {
+ _poller->poll();
+ if (_poller->events(*_taskQueue) & zmqpp::poller::poll_in)
+ PerformWork();
+ }
+}
+
+void ZmqWorker::PerformWork()
+{
+ int32 op1;
+ do
+ {
+ zmqpp::message msg;
+ _taskQueue->receive(msg);
+ Dispatch(msg);
+ _taskQueue->get(zmqpp::socket_option::events, op1);
+ } while (op1 & zmqpp::poller::poll_in);
+}
diff --git a/src/server/ipc/ZmqWorker.h b/src/server/ipc/ZmqWorker.h
new file mode 100644
index 00000000000..b3e221e9129
--- /dev/null
+++ b/src/server/ipc/ZmqWorker.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2008-2014 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 __ZMQWORKER_H
+#define __ZMQWORKER_H
+
+#include "ZMQTask.h"
+#include <zmqpp/zmqpp.hpp>
+
+class ZmqWorker : public ZMQTask
+{
+public:
+ ZmqWorker(std::string task_uri, std::string res_uri);
+ ~ZmqWorker();
+ void Run() override;
+
+protected:
+ void HandleOpen() override;
+ void HandleClose() override;
+ zmqpp::socket* _results;
+
+private:
+ void PerformWork();
+ virtual void Dispatch(zmqpp::message const&) = 0;
+ zmqpp::socket* _taskQueue;
+ std::string _taskUri;
+ std::string _resultsUri;
+};
+
+#endif
diff --git a/src/server/scripts/CMakeLists.txt b/src/server/scripts/CMakeLists.txt
index e92c883eeff..eab6a36d02e 100644
--- a/src/server/scripts/CMakeLists.txt
+++ b/src/server/scripts/CMakeLists.txt
@@ -64,6 +64,7 @@ include_directories(
${CMAKE_SOURCE_DIR}/src/server/shared/Packets
${CMAKE_SOURCE_DIR}/src/server/shared/Threading
${CMAKE_SOURCE_DIR}/src/server/shared/Utilities
+ ${CMAKE_SOURCE_DIR}/src/server/ipc
${CMAKE_SOURCE_DIR}/src/server/collision
${CMAKE_SOURCE_DIR}/src/server/collision/Management
${CMAKE_SOURCE_DIR}/src/server/collision/Models
diff --git a/src/server/scripts/Commands/cs_ban.cpp b/src/server/scripts/Commands/cs_ban.cpp
index e11ee0008d2..370d03162d1 100644
--- a/src/server/scripts/Commands/cs_ban.cpp
+++ b/src/server/scripts/Commands/cs_ban.cpp
@@ -299,7 +299,7 @@ public:
if (!*args)
return false;
- Player* target = sObjectAccessor->FindPlayerByName(args);
+ Player* target = ObjectAccessor::FindPlayerByName(args);
uint32 targetGuid = 0;
std::string name(args);
diff --git a/src/server/scripts/Commands/cs_character.cpp b/src/server/scripts/Commands/cs_character.cpp
index 8254d08558a..c8961d4fad8 100644
--- a/src/server/scripts/Commands/cs_character.cpp
+++ b/src/server/scripts/Commands/cs_character.cpp
@@ -776,7 +776,7 @@ public:
ObjectGuid characterGuid;
uint32 accountId;
- Player* player = sObjectAccessor->FindPlayerByName(characterName);
+ Player* player = ObjectAccessor::FindPlayerByName(characterName);
if (player)
{
characterGuid = player->GetGUID();
diff --git a/src/server/scripts/Commands/cs_debug.cpp b/src/server/scripts/Commands/cs_debug.cpp
index 4b555fcf625..862b683597a 100644
--- a/src/server/scripts/Commands/cs_debug.cpp
+++ b/src/server/scripts/Commands/cs_debug.cpp
@@ -559,10 +559,10 @@ public:
for (uint8 j = 0; j < bag->GetBagSize(); ++j)
if (Item* item2 = bag->GetItemByPos(j))
if (item2->GetState() == state)
- handler->PSendSysMessage("bag: 255 slot: %d guid: %d owner: %d", item2->GetSlot(), item2->GetGUIDLow(), item2->GetOwnerGUID().GetCounter());
+ handler->PSendSysMessage("bag: 255 slot: %d %s owner: %s", item2->GetSlot(), item2->GetGUID().ToString().c_str(), item2->GetOwnerGUID().ToString().c_str());
}
else if (item->GetState() == state)
- handler->PSendSysMessage("bag: 255 slot: %d guid: %d owner: %d", item->GetSlot(), item->GetGUIDLow(), item->GetOwnerGUID().GetCounter());
+ handler->PSendSysMessage("bag: 255 slot: %d %s owner: %s", item->GetSlot(), item->GetGUID().ToString().c_str(), item->GetOwnerGUID().ToString().c_str());
}
}
}
@@ -624,14 +624,14 @@ public:
if (item->GetOwnerGUID() != player->GetGUID())
{
- handler->PSendSysMessage("The item with slot %d and itemguid %d does have non-matching owner guid (%d) and player guid (%d) !", item->GetSlot(), item->GetGUIDLow(), item->GetOwnerGUID().GetCounter(), player->GetGUIDLow());
+ handler->PSendSysMessage("The item with slot %d %s does have non-matching owner guid %s and %s!", item->GetSlot(), item->GetGUID().ToString().c_str(), item->GetOwnerGUID().ToString().c_str(), player->GetGUID().ToString().c_str());
error = true;
continue;
}
if (Bag* container = item->GetContainer())
{
- handler->PSendSysMessage("The item with slot %d and guid %d has a container (slot: %d, guid: %d) but shouldn't!", item->GetSlot(), item->GetGUIDLow(), container->GetSlot(), container->GetGUIDLow());
+ handler->PSendSysMessage("The item with slot %d %s has a container (slot: %d, %s) but shouldn't!", item->GetSlot(), item->GetGUID().ToString().c_str(), container->GetSlot(), container->GetGUID().ToString().c_str());
error = true;
continue;
}
@@ -684,7 +684,7 @@ public:
if (item2->GetOwnerGUID() != player->GetGUID())
{
- handler->PSendSysMessage("The item in bag %d at slot %d and with itemguid %d, the owner's guid (%d) and the player's guid (%d) don't match!", bag->GetSlot(), item2->GetSlot(), item2->GetGUIDLow(), item2->GetOwnerGUID().GetCounter(), player->GetGUIDLow());
+ handler->PSendSysMessage("The item in bag %d at slot %d and %s, the owner (%s) and the player (%s) don't match!", bag->GetSlot(), item2->GetSlot(), item2->GetGUID().ToString().c_str(), item2->GetOwnerGUID().ToString().c_str(), player->GetGUID().ToString().c_str());
error = true;
continue;
}
@@ -692,14 +692,14 @@ public:
Bag* container = item2->GetContainer();
if (!container)
{
- handler->PSendSysMessage("The item in bag %d at slot %d with guid %d has no container!", bag->GetSlot(), item2->GetSlot(), item2->GetGUIDLow());
+ handler->PSendSysMessage("The item in bag %d at slot %d %s has no container!", bag->GetSlot(), item2->GetSlot(), item2->GetGUID().ToString().c_str());
error = true;
continue;
}
if (container != bag)
{
- handler->PSendSysMessage("The item in bag %d at slot %d with guid %d has a different container(slot %d guid %d)!", bag->GetSlot(), item2->GetSlot(), item2->GetGUIDLow(), container->GetSlot(), container->GetGUIDLow());
+ handler->PSendSysMessage("The item in bag %d at slot %d %s has a different container(slot %d %s)!", bag->GetSlot(), item2->GetSlot(), item2->GetGUID().ToString().c_str(), container->GetSlot(), container->GetGUID().ToString().c_str());
error = true;
continue;
}
@@ -746,14 +746,14 @@ public:
if (item->GetOwnerGUID() != player->GetGUID())
{
- handler->PSendSysMessage("queue(%zu): For the item with guid %d, the owner's guid (%d) and the player's guid (%d) don't match!", i, item->GetGUIDLow(), item->GetOwnerGUID().GetCounter(), player->GetGUIDLow());
+ handler->PSendSysMessage("queue(%zu): For the item %s, the owner (%s) and the player (%s) don't match!", i, item->GetGUID().ToString().c_str(), item->GetOwnerGUID().ToString().c_str(), player->GetGUID().ToString().c_str());
error = true;
continue;
}
if (item->GetQueuePos() != i)
{
- handler->PSendSysMessage("queue(%zu): For the item with guid %d, the queuepos doesn't match it's position in the queue!", i, item->GetGUIDLow());
+ handler->PSendSysMessage("queue(%zu): For the item %s, the queuepos doesn't match it's position in the queue!", i, item->GetGUID().ToString().c_str());
error = true;
continue;
}
@@ -765,14 +765,14 @@ public:
if (test == NULL)
{
- handler->PSendSysMessage("queue(%zu): The bag(%d) and slot(%d) values for the item with guid %d are incorrect, the player doesn't have any item at that position!", i, item->GetBagSlot(), item->GetSlot(), item->GetGUIDLow());
+ handler->PSendSysMessage("queue(%zu): The bag(%d) and slot(%d) values for %s are incorrect, the player doesn't have any item at that position!", i, item->GetBagSlot(), item->GetSlot(), item->GetGUID().ToString().c_str());
error = true;
continue;
}
if (test != item)
{
- handler->PSendSysMessage("queue(%zu): The bag(%d) and slot(%d) values for the item with guid %d are incorrect, an item which guid is %d is there instead!", i, item->GetBagSlot(), item->GetSlot(), item->GetGUIDLow(), test->GetGUIDLow());
+ handler->PSendSysMessage("queue(%zu): The bag(%d) and slot(%d) values for the %s are incorrect, %s is there instead!", i, item->GetBagSlot(), item->GetSlot(), item->GetGUID().ToString().c_str(), test->GetGUID().ToString().c_str());
error = true;
continue;
}
diff --git a/src/server/scripts/Commands/cs_gm.cpp b/src/server/scripts/Commands/cs_gm.cpp
index 27ec4835ce6..24da9e37327 100644
--- a/src/server/scripts/Commands/cs_gm.cpp
+++ b/src/server/scripts/Commands/cs_gm.cpp
@@ -121,7 +121,7 @@ public:
bool footer = false;
boost::shared_lock<boost::shared_mutex> lock(*HashMapHolder<Player>::GetLock());
- HashMapHolder<Player>::MapType const& m = sObjectAccessor->GetPlayers();
+ HashMapHolder<Player>::MapType const& m = ObjectAccessor::GetPlayers();
for (HashMapHolder<Player>::MapType::const_iterator itr = m.begin(); itr != m.end(); ++itr)
{
AccountTypes itrSec = itr->second->GetSession()->GetSecurity();
@@ -163,7 +163,7 @@ public:
///- Get the accounts with GM Level >0
PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_GM_ACCOUNTS);
stmt->setUInt8(0, uint8(SEC_MODERATOR));
- stmt->setInt32(1, int32(realmID));
+ stmt->setInt32(1, int32(realmHandle.Index));
PreparedQueryResult result = LoginDatabase.Query(stmt);
if (result)
diff --git a/src/server/scripts/Commands/cs_group.cpp b/src/server/scripts/Commands/cs_group.cpp
index e39aca6f6a7..a558d977b85 100644
--- a/src/server/scripts/Commands/cs_group.cpp
+++ b/src/server/scripts/Commands/cs_group.cpp
@@ -343,7 +343,7 @@ public:
// Check if iterator is online. If is...
Player* p = ObjectAccessor::FindPlayer((*itr).guid);
- if (p && p->IsInWorld())
+ if (p)
{
// ... than, it prints information like "is online", where he is, etc...
onlineState = "online";
diff --git a/src/server/scripts/Commands/cs_message.cpp b/src/server/scripts/Commands/cs_message.cpp
index f2067e6c70b..715487eff99 100644
--- a/src/server/scripts/Commands/cs_message.cpp
+++ b/src/server/scripts/Commands/cs_message.cpp
@@ -211,7 +211,7 @@ public:
std::string name = strtok(NULL, " ");
if (normalizePlayerName(name))
{
- if (Player* player = sObjectAccessor->FindPlayerByName(name))
+ if (Player* player = ObjectAccessor::FindPlayerByName(name))
{
handler->GetSession()->GetPlayer()->RemoveFromWhisperWhiteList(player->GetGUID());
handler->PSendSysMessage(LANG_COMMAND_WHISPEROFFPLAYER, name.c_str());
diff --git a/src/server/scripts/Commands/cs_misc.cpp b/src/server/scripts/Commands/cs_misc.cpp
index 9277956262f..75dbf975857 100644
--- a/src/server/scripts/Commands/cs_misc.cpp
+++ b/src/server/scripts/Commands/cs_misc.cpp
@@ -35,6 +35,7 @@
#include "LFG.h"
#include "GroupMgr.h"
#include "MMapFactory.h"
+#include "DisableMgr.h"
class misc_commandscript : public CommandScript
{
@@ -185,7 +186,7 @@ public:
uint32 haveMap = Map::ExistMap(mapId, gridX, gridY) ? 1 : 0;
uint32 haveVMap = Map::ExistVMap(mapId, gridX, gridY) ? 1 : 0;
- uint32 haveMMap = (MMAP::MMapFactory::IsPathfindingEnabled(mapId) && MMAP::MMapFactory::createOrGetMMapManager()->GetNavMesh(handler->GetSession()->GetPlayer()->GetMapId())) ? 1 : 0;
+ uint32 haveMMap = (DisableMgr::IsPathfindingEnabled(mapId) && MMAP::MMapFactory::createOrGetMMapManager()->GetNavMesh(handler->GetSession()->GetPlayer()->GetMapId())) ? 1 : 0;
if (haveVMap)
{
@@ -1541,7 +1542,7 @@ public:
// Query the prepared statement for login data
stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_PINFO);
- stmt->setInt32(0, int32(realmID));
+ stmt->setInt32(0, int32(realmHandle.Index));
stmt->setUInt32(1, accId);
PreparedQueryResult result = LoginDatabase.Query(stmt);
@@ -2193,7 +2194,7 @@ public:
if (args && args[0] != '\0')
{
- target = sObjectAccessor->FindPlayerByName(args);
+ target = ObjectAccessor::FindPlayerByName(args);
if (!target)
{
handler->SendSysMessage(LANG_PLAYER_NOT_FOUND);
@@ -2281,7 +2282,7 @@ public:
// find the player
std::string name = arg1;
normalizePlayerName(name);
- player = sObjectAccessor->FindPlayerByName(name);
+ player = ObjectAccessor::FindPlayerByName(name);
// Check if we have duration set
if (arg2 && isNumeric(arg2))
{
@@ -2345,7 +2346,7 @@ public:
{
name = targetName;
normalizePlayerName(name);
- player = sObjectAccessor->FindPlayerByName(name);
+ player = ObjectAccessor::FindPlayerByName(name);
}
else // If no name was entered - use target
{
@@ -2421,7 +2422,7 @@ public:
int32 remaintime = fields[1].GetInt32();
// Save the frozen player to update remaining time in case of future .listfreeze uses
// before the frozen state expires
- if (Player* frozen = sObjectAccessor->FindPlayerByName(player))
+ if (Player* frozen = ObjectAccessor::FindPlayerByName(player))
frozen->SaveToDB();
// Notify the freeze duration
if (remaintime == -1) // Permanent duration
diff --git a/src/server/scripts/Commands/cs_mmaps.cpp b/src/server/scripts/Commands/cs_mmaps.cpp
index 969027139fc..a6a7fac3cb5 100644
--- a/src/server/scripts/Commands/cs_mmaps.cpp
+++ b/src/server/scripts/Commands/cs_mmaps.cpp
@@ -25,6 +25,7 @@
#include "ScriptMgr.h"
#include "Chat.h"
+#include "DisableMgr.h"
#include "ObjectMgr.h"
#include "Player.h"
#include "PointMovementGenerator.h"
@@ -209,7 +210,7 @@ public:
{
uint32 mapId = handler->GetSession()->GetPlayer()->GetMapId();
handler->PSendSysMessage("mmap stats:");
- handler->PSendSysMessage(" global mmap pathfinding is %sabled", MMAP::MMapFactory::IsPathfindingEnabled(mapId) ? "en" : "dis");
+ handler->PSendSysMessage(" global mmap pathfinding is %sabled", DisableMgr::IsPathfindingEnabled(mapId) ? "en" : "dis");
MMAP::MMapManager* manager = MMAP::MMapFactory::createOrGetMMapManager();
handler->PSendSysMessage(" %u maps loaded with %u tiles overall", manager->getLoadedMapsCount(), manager->getLoadedTilesCount());
diff --git a/src/server/scripts/Commands/cs_rbac.cpp b/src/server/scripts/Commands/cs_rbac.cpp
index 95ef5ab6984..ab960026d69 100644
--- a/src/server/scripts/Commands/cs_rbac.cpp
+++ b/src/server/scripts/Commands/cs_rbac.cpp
@@ -160,7 +160,7 @@ public:
if (!rdata)
{
- data->rbac = new rbac::RBACData(accountId, accountName, realmID, AccountMgr::GetSecurity(accountId, realmID));
+ data->rbac = new rbac::RBACData(accountId, accountName, realmHandle.Index, AccountMgr::GetSecurity(accountId, realmHandle.Index));
data->rbac->LoadFromDB();
data->needDelete = true;
}
diff --git a/src/server/scripts/Commands/cs_reset.cpp b/src/server/scripts/Commands/cs_reset.cpp
index faf87adc7b6..2823c2c8c5d 100644
--- a/src/server/scripts/Commands/cs_reset.cpp
+++ b/src/server/scripts/Commands/cs_reset.cpp
@@ -295,7 +295,7 @@ public:
CharacterDatabase.Execute(stmt);
boost::shared_lock<boost::shared_mutex> lock(*HashMapHolder<Player>::GetLock());
- HashMapHolder<Player>::MapType const& plist = sObjectAccessor->GetPlayers();
+ HashMapHolder<Player>::MapType const& plist = ObjectAccessor::GetPlayers();
for (HashMapHolder<Player>::MapType::const_iterator itr = plist.begin(); itr != plist.end(); ++itr)
itr->second->SetAtLoginFlag(atLogin);
diff --git a/src/server/scripts/Commands/cs_ticket.cpp b/src/server/scripts/Commands/cs_ticket.cpp
index 674658f41ff..a06bd95f6b6 100644
--- a/src/server/scripts/Commands/cs_ticket.cpp
+++ b/src/server/scripts/Commands/cs_ticket.cpp
@@ -98,7 +98,7 @@ public:
ObjectGuid targetGuid = sObjectMgr->GetPlayerGUIDByName(target);
uint32 accountId = sObjectMgr->GetPlayerAccountIdByGUID(targetGuid);
// Target must exist and have administrative rights
- if (!AccountMgr::HasPermission(accountId, rbac::RBAC_PERM_COMMANDS_BE_ASSIGNED_TICKET, realmID))
+ if (!AccountMgr::HasPermission(accountId, rbac::RBAC_PERM_COMMANDS_BE_ASSIGNED_TICKET, realmHandle.Index))
{
handler->SendSysMessage(LANG_COMMAND_TICKETASSIGNERROR_A);
return true;
@@ -122,7 +122,7 @@ public:
// Assign ticket
SQLTransaction trans = SQLTransaction(NULL);
- ticket->SetAssignedTo(targetGuid, AccountMgr::IsAdminAccount(AccountMgr::GetSecurity(accountId, realmID)));
+ ticket->SetAssignedTo(targetGuid, AccountMgr::IsAdminAccount(AccountMgr::GetSecurity(accountId, realmHandle.Index)));
ticket->SaveToDB(trans);
sTicketMgr->UpdateLastChange();
@@ -162,12 +162,9 @@ public:
// Inform player, who submitted this ticket, that it is closed
if (Player* submitter = ticket->GetPlayer())
{
- if (submitter->IsInWorld())
- {
- WorldPacket data(SMSG_GMTICKET_DELETETICKET, 4);
- data << uint32(GMTICKET_RESPONSE_TICKET_DELETED);
- submitter->GetSession()->SendPacket(&data);
- }
+ WorldPacket data(SMSG_GMTICKET_DELETETICKET, 4);
+ data << uint32(GMTICKET_RESPONSE_TICKET_DELETED);
+ submitter->GetSession()->SendPacket(&data);
}
return true;
}
@@ -232,8 +229,7 @@ public:
}
if (Player* player = ticket->GetPlayer())
- if (player->IsInWorld())
- ticket->SendResponse(player->GetSession());
+ ticket->SendResponse(player->GetSession());
SQLTransaction trans = SQLTransaction(NULL);
ticket->SetCompleted();
@@ -273,13 +269,10 @@ public:
if (Player* player = ticket->GetPlayer())
{
- if (player->IsInWorld())
- {
- // Force abandon ticket
- WorldPacket data(SMSG_GMTICKET_DELETETICKET, 4);
- data << uint32(GMTICKET_RESPONSE_TICKET_DELETED);
- player->GetSession()->SendPacket(&data);
- }
+ // Force abandon ticket
+ WorldPacket data(SMSG_GMTICKET_DELETETICKET, 4);
+ data << uint32(GMTICKET_RESPONSE_TICKET_DELETED);
+ player->GetSession()->SendPacket(&data);
}
return true;
@@ -301,8 +294,7 @@ public:
ticket->SetEscalatedStatus(TICKET_IN_ESCALATION_QUEUE);
if (Player* player = ticket->GetPlayer())
- if (player->IsInWorld())
- sTicketMgr->SendTicket(player->GetSession(), ticket);
+ sTicketMgr->SendTicket(player->GetSession(), ticket);
sTicketMgr->UpdateLastChange();
return true;
@@ -372,13 +364,13 @@ public:
// Get security level of player, whom this ticket is assigned to
uint32 security = SEC_PLAYER;
Player* assignedPlayer = ticket->GetAssignedPlayer();
- if (assignedPlayer && assignedPlayer->IsInWorld())
+ if (assignedPlayer)
security = assignedPlayer->GetSession()->GetSecurity();
else
{
ObjectGuid guid = ticket->GetAssignedToGUID();
uint32 accountId = sObjectMgr->GetPlayerAccountIdByGUID(guid);
- security = AccountMgr::GetSecurity(accountId, realmID);
+ security = AccountMgr::GetSecurity(accountId, realmHandle.Index);
}
// Check security
@@ -435,7 +427,7 @@ public:
// Detect target's GUID
ObjectGuid guid;
- if (Player* player = sObjectAccessor->FindPlayerByName(name))
+ if (Player* player = ObjectAccessor::FindPlayerByName(name))
guid = player->GetGUID();
else
guid = sObjectMgr->GetPlayerGUIDByName(name);
diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/instance_culling_of_stratholme.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/instance_culling_of_stratholme.cpp
index c25a061d622..cb3fa49216b 100644
--- a/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/instance_culling_of_stratholme.cpp
+++ b/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/instance_culling_of_stratholme.cpp
@@ -204,7 +204,7 @@ class instance_culling_of_stratholme : public InstanceMapScript
if (state == DONE)
{
if (GameObject* go = instance->GetGameObject(_malGanisChestGUID))
- go->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_INTERACT_COND);
+ go->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
instance->SummonCreature(NPC_CHROMIE_3, ChromieSummonPos[1]);
}
break;
diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_anubarak_trial.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_anubarak_trial.cpp
index d5bd2bcae7e..072dbd81fd8 100644
--- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_anubarak_trial.cpp
+++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_anubarak_trial.cpp
@@ -212,7 +212,6 @@ class boss_anubarak_trial : public CreatureScript
}
void MoveInLineOfSight(Unit* /*who*/) override
-
{
if (!_intro)
{
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 79fb154d6e3..e3ad891fdc7 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
@@ -68,15 +68,10 @@ class instance_trial_of_the_crusader : public InstanceMapScript
else
player->SendUpdateWorldState(UPDATE_STATE_UI_SHOW, 0);
- // make sure Anub'arak isnt missing and floor is destroyed after a crash
+ // make sure Anub'arak isnt missing
if (GetBossState(BOSS_LICH_KING) == DONE && TrialCounter && GetBossState(BOSS_ANUBARAK) != DONE)
- {
- if (Creature* anubArak = ObjectAccessor::GetCreature(*player, GetGuidData(NPC_ANUBARAK)))
- anubArak = player->SummonCreature(NPC_ANUBARAK, AnubarakLoc[0].GetPositionX(), AnubarakLoc[0].GetPositionY(), AnubarakLoc[0].GetPositionZ(), 3, TEMPSUMMON_CORPSE_TIMED_DESPAWN, DESPAWN_TIME);
-
- if (GameObject* floor = ObjectAccessor::GetGameObject(*player, GetGuidData(GO_ARGENT_COLISEUM_FLOOR)))
- floor->SetDestructibleState(GO_DESTRUCTIBLE_DAMAGED);
- }
+ if (!ObjectAccessor::GetCreature(*player, GetGuidData(NPC_ANUBARAK)))
+ player->SummonCreature(NPC_ANUBARAK, AnubarakLoc[0], TEMPSUMMON_CORPSE_TIMED_DESPAWN, DESPAWN_TIME);
}
void OpenDoor(ObjectGuid guid)
@@ -160,23 +155,15 @@ class instance_trial_of_the_crusader : public InstanceMapScript
switch (go->GetEntry())
{
case GO_CRUSADERS_CACHE_10:
- if (instance->GetSpawnMode() == RAID_DIFFICULTY_10MAN_NORMAL)
- CrusadersCacheGUID = go->GetGUID();
- break;
case GO_CRUSADERS_CACHE_25:
- if (instance->GetSpawnMode() == RAID_DIFFICULTY_25MAN_NORMAL)
- CrusadersCacheGUID = go->GetGUID();
- break;
case GO_CRUSADERS_CACHE_10_H:
- if (instance->GetSpawnMode() == RAID_DIFFICULTY_10MAN_HEROIC)
- CrusadersCacheGUID = go->GetGUID();
- break;
case GO_CRUSADERS_CACHE_25_H:
- if (instance->GetSpawnMode() == RAID_DIFFICULTY_25MAN_HEROIC)
- CrusadersCacheGUID = go->GetGUID();
+ CrusadersCacheGUID = go->GetGUID();
break;
case GO_ARGENT_COLISEUM_FLOOR:
FloorGUID = go->GetGUID();
+ if (GetBossState(BOSS_LICH_KING) == DONE)
+ go->SetDestructibleState(GO_DESTRUCTIBLE_DAMAGED);
break;
case GO_MAIN_GATE_DOOR:
MainGateDoorGUID = go->GetGUID();
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 d8ec322c57c..885017c24dd 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
@@ -207,11 +207,8 @@ class npc_announcer_toc10 : public CreatureScript
creature->CastSpell(creature, SPELL_CORPSE_TELEPORT, false);
creature->CastSpell(creature, SPELL_DESTROY_FLOOR_KNOCKUP, false);
- Creature* anubArak = ObjectAccessor::GetCreature(*creature, instance->GetGuidData(NPC_ANUBARAK));
- if (!anubArak || !anubArak->IsAlive())
- anubArak = creature->SummonCreature(NPC_ANUBARAK, AnubarakLoc[0].GetPositionX(), AnubarakLoc[0].GetPositionY(), AnubarakLoc[0].GetPositionZ(), 3, TEMPSUMMON_CORPSE_TIMED_DESPAWN, DESPAWN_TIME);
-
- instance->SetBossState(BOSS_ANUBARAK, NOT_STARTED);
+ 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);
@@ -319,19 +316,15 @@ class boss_lich_king_toc : public CreatureScript
case 5080:
{
if (GameObject* go = ObjectAccessor::GetGameObject(*me, _instance->GetGuidData(GO_ARGENT_COLISEUM_FLOOR)))
- {
- go->SetDisplayId(DISPLAYID_DESTROYED_FLOOR);
- go->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_DAMAGED | GO_FLAG_NODESPAWN);
- go->SetGoState(GO_STATE_ACTIVE);
- }
+ go->SetDestructibleState(GO_DESTRUCTIBLE_DAMAGED);
me->CastSpell(me, SPELL_CORPSE_TELEPORT, false);
me->CastSpell(me, SPELL_DESTROY_FLOOR_KNOCKUP, false);
_instance->SetBossState(BOSS_LICH_KING, DONE);
- Creature* temp = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(NPC_ANUBARAK));
- if (!temp || !temp->IsAlive())
- temp = me->SummonCreature(NPC_ANUBARAK, AnubarakLoc[0].GetPositionX(), AnubarakLoc[0].GetPositionY(), AnubarakLoc[0].GetPositionZ(), 3, TEMPSUMMON_CORPSE_TIMED_DESPAWN, DESPAWN_TIME);
+
+ if (!ObjectAccessor::GetCreature(*me, _instance->GetGuidData(NPC_ANUBARAK)))
+ me->SummonCreature(NPC_ANUBARAK, AnubarakLoc[0], TEMPSUMMON_CORPSE_TIMED_DESPAWN, DESPAWN_TIME);
_instance->SetData(TYPE_EVENT, 0);
diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/trial_of_the_crusader.h b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/trial_of_the_crusader.h
index cf08fb75228..e37148aa508 100644
--- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/trial_of_the_crusader.h
+++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/trial_of_the_crusader.h
@@ -42,9 +42,7 @@ enum SpellIds
enum MiscData
{
- DESPAWN_TIME = 1200000,
-
- DISPLAYID_DESTROYED_FLOOR = 9060
+ DESPAWN_TIME = 1200000
};
const Position ToCSpawnLoc[]=
@@ -133,7 +131,7 @@ const Position LichKingLoc[]=
const Position AnubarakLoc[]=
{
- {787.932556f, 133.289780f, 142.612152f, 0}, // 0 - Anub'arak start location
+ {783.9305f, 132.9722f, 142.6711f, 3.141593f}, // 0 - Anub'arak Spawn Location (sniffed)
{695.240051f, 137.834824f, 142.200000f, 0}, // 1 - Anub'arak move point location
{694.886353f, 102.484665f, 142.119614f, 0}, // 3 - Nerub Spawn
{694.500671f, 185.363968f, 142.117905f, 0}, // 5 - Nerub Spawn
@@ -232,13 +230,13 @@ enum CreatureIds
NPC_HORDE_WARLOCK = 34450,
NPC_HORDE_WARRIOR = 34453,
- NPC_LIGHTBANE = 34497,
- NPC_DARKBANE = 34496,
+ NPC_LIGHTBANE = 34497,
+ NPC_DARKBANE = 34496,
- NPC_DARK_ESSENCE = 34567,
- NPC_LIGHT_ESSENCE = 34568,
+ NPC_DARK_ESSENCE = 34567,
+ NPC_LIGHT_ESSENCE = 34568,
- NPC_ANUBARAK = 34564
+ NPC_ANUBARAK = 34564
};
enum GameObjectIds
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_rotface.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_rotface.cpp
index 5e55256ae59..d5c07fb6942 100644
--- a/src/server/scripts/Northrend/IcecrownCitadel/boss_rotface.cpp
+++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_rotface.cpp
@@ -178,6 +178,8 @@ class boss_rotface : public CreatureScript
if (summon->GetEntry() == NPC_VILE_GAS_STALKER)
if (Creature* professor = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_PROFESSOR_PUTRICIDE)))
professor->CastSpell(summon, SPELL_VILE_GAS_H, true);
+
+ summons.Summon(summon);
}
void UpdateAI(uint32 diff) override
diff --git a/src/server/scripts/Northrend/Ulduar/HallsOfStone/instance_halls_of_stone.cpp b/src/server/scripts/Northrend/Ulduar/HallsOfStone/instance_halls_of_stone.cpp
index d6c7b18eabd..880d032265a 100644
--- a/src/server/scripts/Northrend/Ulduar/HallsOfStone/instance_halls_of_stone.cpp
+++ b/src/server/scripts/Northrend/Ulduar/HallsOfStone/instance_halls_of_stone.cpp
@@ -91,7 +91,7 @@ class instance_halls_of_stone : public InstanceMapScript
case GO_TRIBUNAL_CHEST_HERO:
TribunalChestGUID = go->GetGUID();
if (GetBossState(DATA_BRANN_EVENT) == DONE)
- go->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_INTERACT_COND);
+ go->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
break;
case GO_TRIBUNAL_SKY_FLOOR:
TribunalSkyFloorGUID = go->GetGUID();
@@ -160,7 +160,7 @@ class instance_halls_of_stone : public InstanceMapScript
if (state == DONE)
{
if (GameObject* go = instance->GetGameObject(TribunalChestGUID))
- go->RemoveFlag(GAMEOBJECT_FLAGS,GO_FLAG_INTERACT_COND);
+ go->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
}
break;
default:
diff --git a/src/server/scripts/Outland/Auchindoun/SethekkHalls/boss_darkweaver_syth.cpp b/src/server/scripts/Outland/Auchindoun/SethekkHalls/boss_darkweaver_syth.cpp
index e6ffa3f8979..6ec69ee11af 100644
--- a/src/server/scripts/Outland/Auchindoun/SethekkHalls/boss_darkweaver_syth.cpp
+++ b/src/server/scripts/Outland/Auchindoun/SethekkHalls/boss_darkweaver_syth.cpp
@@ -72,7 +72,7 @@ public:
struct boss_darkweaver_sythAI : public BossAI
{
boss_darkweaver_sythAI(Creature* creature) : BossAI(creature, DATA_DARKWEAVER_SYTH)
- {
+ {
Initialize();
}
diff --git a/src/server/scripts/Outland/BlackTemple/boss_reliquary_of_souls.cpp b/src/server/scripts/Outland/BlackTemple/boss_reliquary_of_souls.cpp
index dd0e271a02d..23abf48233e 100644
--- a/src/server/scripts/Outland/BlackTemple/boss_reliquary_of_souls.cpp
+++ b/src/server/scripts/Outland/BlackTemple/boss_reliquary_of_souls.cpp
@@ -117,7 +117,7 @@ public:
void Reset() override
{
- ReliquaryGUID.Clear();
+ ReliquaryGUID.Clear();
}
void EnterCombat(Unit* /*who*/) override
diff --git a/src/server/scripts/World/go_scripts.cpp b/src/server/scripts/World/go_scripts.cpp
index 65cb2c2abce..752ea2feb1c 100644
--- a/src/server/scripts/World/go_scripts.cpp
+++ b/src/server/scripts/World/go_scripts.cpp
@@ -24,7 +24,6 @@ go_ethereum_stasis
go_sacred_fire_of_life
go_shrine_of_the_birds
go_southfury_moonstone
-go_field_repair_bot_74A
go_orb_of_command
go_resonite_cask
go_tablet_of_madness
@@ -94,24 +93,6 @@ public:
};
/*######
-## go_field_repair_bot_74A
-######*/
-
-class go_field_repair_bot_74A : public GameObjectScript
-{
-public:
- go_field_repair_bot_74A() : GameObjectScript("go_field_repair_bot_74A") { }
-
- bool OnGossipHello(Player* player, GameObject* /*go*/) override
- {
- if (player->HasSkill(SKILL_ENGINEERING) && player->GetBaseSkillValue(SKILL_ENGINEERING) >= 300 && !player->HasSpell(22704))
- player->CastSpell(player, 22864, false);
-
- return true;
- }
-};
-
-/*######
## go_gilded_brazier (Paladin First Trail quest (9678))
######*/
@@ -1213,7 +1194,6 @@ void AddSC_go_scripts()
{
new go_cat_figurine();
new go_barov_journal();
- new go_field_repair_bot_74A();
new go_gilded_brazier();
new go_orb_of_command();
new go_shrine_of_the_birds();
diff --git a/src/server/shared/Database/Implementation/WorldDatabase.cpp b/src/server/shared/Database/Implementation/WorldDatabase.cpp
index ecbd0e9244c..531d092d039 100644
--- a/src/server/shared/Database/Implementation/WorldDatabase.cpp
+++ b/src/server/shared/Database/Implementation/WorldDatabase.cpp
@@ -89,4 +89,6 @@ void WorldDatabaseConnection::DoPrepareStatements()
PrepareStatement(WORLD_INS_DISABLES, "INSERT INTO disables (entry, sourceType, flags, comment) VALUES (?, ?, ?, ?)", CONNECTION_ASYNC);
PrepareStatement(WORLD_SEL_DISABLES, "SELECT entry FROM disables WHERE entry = ? AND sourceType = ?", CONNECTION_SYNCH);
PrepareStatement(WORLD_DEL_DISABLES, "DELETE FROM disables WHERE entry = ? AND sourceType = ?", CONNECTION_ASYNC);
+ PrepareStatement(WORLD_UPD_CREATURE_ZONE_AREA_DATA, "UPDATE creature SET zoneId = ?, areaId = ? WHERE guid = ?", CONNECTION_ASYNC);
+ PrepareStatement(WORLD_UPD_GAMEOBJECT_ZONE_AREA_DATA, "UPDATE gameobject SET zoneId = ?, areaId = ? WHERE guid = ?", CONNECTION_ASYNC);
}
diff --git a/src/server/shared/Database/Implementation/WorldDatabase.h b/src/server/shared/Database/Implementation/WorldDatabase.h
index 8a5bd206021..a398b412c50 100644
--- a/src/server/shared/Database/Implementation/WorldDatabase.h
+++ b/src/server/shared/Database/Implementation/WorldDatabase.h
@@ -110,6 +110,8 @@ enum WorldDatabaseStatements
WORLD_SEL_DISABLES,
WORLD_INS_DISABLES,
WORLD_DEL_DISABLES,
+ WORLD_UPD_CREATURE_ZONE_AREA_DATA,
+ WORLD_UPD_GAMEOBJECT_ZONE_AREA_DATA,
MAX_WORLDDATABASE_STATEMENTS
};
diff --git a/src/server/shared/Logging/Log.cpp b/src/server/shared/Logging/Log.cpp
index a7b6b418cc4..3305b364f0f 100644
--- a/src/server/shared/Logging/Log.cpp
+++ b/src/server/shared/Logging/Log.cpp
@@ -334,7 +334,7 @@ bool Log::SetLogLevel(std::string const& name, const char* newLevelc, bool isLog
return true;
}
-void Log::outCharDump(char const* str, uint32 accountId, uint32 guid, char const* name)
+void Log::outCharDump(char const* str, uint32 accountId, uint64 guid, char const* name)
{
if (!str || !ShouldLog("entities.player.dump", LOG_LEVEL_INFO))
return;
diff --git a/src/server/shared/Logging/Log.h b/src/server/shared/Logging/Log.h
index 78e7e012bbe..e2d4baa5f0e 100644
--- a/src/server/shared/Logging/Log.h
+++ b/src/server/shared/Logging/Log.h
@@ -62,7 +62,7 @@ class Log
void outMessage(std::string const& f, LogLevel level, char const* str, ...) ATTR_PRINTF(4, 5);
void outCommand(uint32 account, const char * str, ...) ATTR_PRINTF(3, 4);
- void outCharDump(char const* str, uint32 account_id, uint32 guid, char const* name);
+ void outCharDump(char const* str, uint32 account_id, uint64 guid, char const* name);
void SetRealmId(uint32 id);
diff --git a/src/server/worldserver/CMakeLists.txt b/src/server/worldserver/CMakeLists.txt
index 0cdf5f13f79..65972e680ef 100644
--- a/src/server/worldserver/CMakeLists.txt
+++ b/src/server/worldserver/CMakeLists.txt
@@ -47,6 +47,7 @@ include_directories(
${CMAKE_SOURCE_DIR}/dep/gsoap
${CMAKE_SOURCE_DIR}/dep/sockets/include
${CMAKE_SOURCE_DIR}/dep/SFMT
+ ${CMAKE_SOURCE_DIR}/dep/zmqpp
${CMAKE_SOURCE_DIR}/src/server/collision
${CMAKE_SOURCE_DIR}/src/server/collision/Management
${CMAKE_SOURCE_DIR}/src/server/collision/Models
@@ -64,6 +65,7 @@ include_directories(
${CMAKE_SOURCE_DIR}/src/server/shared/Packets
${CMAKE_SOURCE_DIR}/src/server/shared/Threading
${CMAKE_SOURCE_DIR}/src/server/shared/Utilities
+ ${CMAKE_SOURCE_DIR}/src/server/ipc
${CMAKE_SOURCE_DIR}/src/server/game
${CMAKE_SOURCE_DIR}/src/server/game/Accounts
${CMAKE_SOURCE_DIR}/src/server/game/Achievements
@@ -141,6 +143,7 @@ include_directories(
${MYSQL_INCLUDE_DIR}
${OPENSSL_INCLUDE_DIR}
${VALGRIND_INCLUDE_DIR}
+ ${ZMQ_INCLUDE_DIR}
)
add_executable(worldserver
@@ -164,18 +167,21 @@ set_target_properties(worldserver PROPERTIES LINK_FLAGS "${worldserver_LINK_FLAG
target_link_libraries(worldserver
game
+ ipc
shared
scripts
collision
g3dlib
gsoap
Detour
+ zmqpp
${JEMALLOC_LIBRARY}
${READLINE_LIBRARY}
${TERMCAP_LIBRARY}
${MYSQL_LIBRARY}
${OPENSSL_LIBRARIES}
${ZLIB_LIBRARIES}
+ ${ZMQ_LIBRARY}
${CMAKE_THREAD_LIBS_INIT}
${Boost_LIBRARIES}
)
diff --git a/src/server/worldserver/Main.cpp b/src/server/worldserver/Main.cpp
index 6c93343b8de..c5127b8f3e2 100644
--- a/src/server/worldserver/Main.cpp
+++ b/src/server/worldserver/Main.cpp
@@ -20,13 +20,9 @@
/// @{
/// \file
-#include <openssl/opensslv.h>
-#include <openssl/crypto.h>
-#include <boost/asio/io_service.hpp>
-#include <boost/asio/deadline_timer.hpp>
-#include <boost/program_options.hpp>
-
#include "Common.h"
+#include "Commands.h"
+#include "ZmqContext.h"
#include "DatabaseEnv.h"
#include "AsyncAcceptor.h"
#include "RASession.h"
@@ -47,6 +43,12 @@
#include "SystemConfig.h"
#include "WorldSocket.h"
#include "WorldSocketMgr.h"
+#include "BattlenetServerManager.h"
+#include <openssl/opensslv.h>
+#include <openssl/crypto.h>
+#include <boost/asio/io_service.hpp>
+#include <boost/asio/deadline_timer.hpp>
+#include <boost/program_options.hpp>
using namespace boost::program_options;
@@ -79,7 +81,7 @@ uint32 _maxCoreStuckTimeInMs(0);
WorldDatabaseWorkerPool WorldDatabase; ///< Accessor to the world database
CharacterDatabaseWorkerPool CharacterDatabase; ///< Accessor to the character database
LoginDatabaseWorkerPool LoginDatabase; ///< Accessor to the realm/login database
-uint32 realmID; ///< Id of the realm
+Battlenet::RealmHandle realmHandle; ///< Id of the realm
void SignalHandler(const boost::system::error_code& error, int signalNumber);
void FreezeDetectorHandler(const boost::system::error_code& error);
@@ -188,7 +190,7 @@ extern int main(int argc, char** argv)
}
// Set server offline (not connectable)
- LoginDatabase.DirectPExecute("UPDATE realmlist SET flag = (flag & ~%u) | %u WHERE id = '%d'", REALM_FLAG_OFFLINE, REALM_FLAG_INVALID, realmID);
+ LoginDatabase.DirectPExecute("UPDATE realmlist SET flag = (flag & ~%u) | %u WHERE id = '%d'", REALM_FLAG_OFFLINE, REALM_FLAG_INVALID, realmHandle.Index);
// Initialize the World
sWorld->SetInitialWorldSettings();
@@ -223,7 +225,7 @@ extern int main(int argc, char** argv)
sWorldSocketMgr.StartNetwork(_ioService, worldListener, worldPort);
// Set server online (allow connecting now)
- LoginDatabase.DirectPExecute("UPDATE realmlist SET flag = flag & ~%u, population = 0 WHERE id = '%u'", REALM_FLAG_INVALID, realmID);
+ LoginDatabase.DirectPExecute("UPDATE realmlist SET flag = flag & ~%u, population = 0 WHERE id = '%u'", REALM_FLAG_INVALID, realmHandle.Index);
// Start the freeze check callback cycle in 5 seconds (cycle itself is 1 sec)
if (int coreStuckTime = sConfigMgr->GetIntDefault("MaxCoreStuckTime", 0))
@@ -234,6 +236,10 @@ extern int main(int argc, char** argv)
TC_LOG_INFO("server.worldserver", "Starting up anti-freeze thread (%u seconds max stuck time)...", coreStuckTime);
}
+ sIpcContext->Initialize();
+
+ sBattlenetServer.InitializeConnection();
+
TC_LOG_INFO("server.worldserver", "%s (worldserver-daemon) ready...", _FULLVERSION);
sScriptMgr->OnStartup();
@@ -245,6 +251,10 @@ extern int main(int argc, char** argv)
sScriptMgr->OnShutdown();
+ sIpcContext->Close();
+
+ sBattlenetServer.CloseConnection();
+
sWorld->KickAll(); // save and kick all players
sWorld->UpdateSessions(1); // real players unload required UpdateSessions call
@@ -260,7 +270,7 @@ extern int main(int argc, char** argv)
sOutdoorPvPMgr->Die();
// set server offline
- LoginDatabase.DirectPExecute("UPDATE realmlist SET flag = flag | %u WHERE id = '%d'", REALM_FLAG_OFFLINE, realmID);
+ LoginDatabase.DirectPExecute("UPDATE realmlist SET flag = flag | %u WHERE id = '%d'", REALM_FLAG_OFFLINE, realmHandle.Index);
// Clean up threads if any
if (soapThread != nullptr)
@@ -523,13 +533,24 @@ bool StartDB()
}
///- Get the realm Id from the configuration file
- realmID = sConfigMgr->GetIntDefault("RealmID", 0);
- if (!realmID)
+ realmHandle.Index = sConfigMgr->GetIntDefault("RealmID", 0);
+ if (!realmHandle.Index)
{
TC_LOG_ERROR("server.worldserver", "Realm ID not defined in configuration file");
return false;
}
- TC_LOG_INFO("server.worldserver", "Realm running as realm ID %d", realmID);
+
+ QueryResult realmIdQuery = LoginDatabase.PQuery("SELECT `Region`,`Battlegroup` FROM `realmlist` WHERE `id`=%u", realmHandle.Index);
+ if (!realmIdQuery)
+ {
+ TC_LOG_ERROR("server.worldserver", "Realm id %u not defined in realmlist table", realmHandle.Index);
+ return false;
+ }
+
+ realmHandle.Region = (*realmIdQuery)[0].GetUInt8();
+ realmHandle.Battlegroup = (*realmIdQuery)[1].GetUInt8();
+
+ TC_LOG_INFO("server.worldserver", "Realm running as realm ID %u region %u battlegroup %u", realmHandle.Index, uint32(realmHandle.Region), uint32(realmHandle.Battlegroup));
///- Clean the database before starting
ClearOnlineAccounts();
@@ -556,7 +577,7 @@ void StopDB()
void ClearOnlineAccounts()
{
// Reset online status for all accounts with characters on the current realm
- LoginDatabase.DirectPExecute("UPDATE account SET online = 0 WHERE online > 0 AND id IN (SELECT acctid FROM realmcharacters WHERE realmid = %d)", realmID);
+ LoginDatabase.DirectPExecute("UPDATE account SET online = 0 WHERE online > 0 AND id IN (SELECT acctid FROM realmcharacters WHERE realmid = %d)", realmHandle.Index);
// Reset online status for all characters
CharacterDatabase.DirectExecute("UPDATE characters SET online = 0 WHERE online <> 0");
diff --git a/src/server/worldserver/worldserver.conf.dist b/src/server/worldserver/worldserver.conf.dist
index d1a4c244ba2..57d97756d70 100644
--- a/src/server/worldserver/worldserver.conf.dist
+++ b/src/server/worldserver/worldserver.conf.dist
@@ -267,9 +267,9 @@ ChangeWeatherInterval = 600000
#
# PlayerSaveInterval
# Description: Time (in milliseconds) for player save interval.
-# Default: 900000 - (15 min)
+# Default: 90000 - (90 seconds)
-PlayerSaveInterval = 900000
+PlayerSaveInterval = 90000
#
# PlayerSave.Stats.MinLevel
@@ -289,7 +289,7 @@ PlayerSave.Stats.SaveOnlyOnLogout = 1
#
# mmap.enablePathFinding
-# Description: Enable/Disable pathfinding using mmaps - experimental.
+# Description: Enable/Disable pathfinding using mmaps - recommended.
# Default: 0 - (Disabled)
# 1 - (Enabled)
@@ -2004,9 +2004,9 @@ AutoBroadcast.Center = 0
#
# AutoBroadcast.Timer
# Description: Timer (in milliseconds) for auto broadcasts.
-# Default: 60000 - (60 seconds)
+# Default: 60000 - (10 minutes)
-AutoBroadcast.Timer = 60000
+AutoBroadcast.Timer = 600000
#
###################################################################################################
@@ -2620,6 +2620,20 @@ PlayerDump.DisallowOverwrite = 1
UI.ShowQuestLevelsInDialogs = 0
#
+# Calculate.Creature.Zone.Area.Data
+# Description: Calculate at loading creature zoneId / areaId and save in creature table (WARNING: SLOW WORLD SERVER STARTUP)
+# Default: 0 - (Do not show)
+
+Calculate.Creature.Zone.Area.Data = 0
+
+#
+# Calculate.Gameoject.Zone.Area.Data
+# Description: Calculate at loading gameobject zoneId / areaId and save in gameobject table (WARNING: SLOW WORLD SERVER STARTUP)
+# Default: 0 - (Do not show)
+
+Calculate.Gameoject.Zone.Area.Data = 0
+
+#
###################################################################################################
###################################################################################################
@@ -3275,6 +3289,8 @@ Currency.ConquestPointsArenaReward = 180
#
###################################################################################################
+
+###################################################################################################
# PACKET SPOOF PROTECTION SETTINGS
#
# These settings determine which action to take when harmful packet spoofing is detected.
@@ -3308,3 +3324,24 @@ PacketSpoof.BanDuration = 86400
#
###################################################################################################
+
+###################################################################################################
+# IPC SETTINGS
+#
+# BnetServer.Address
+# Description: Determines IP address of battle.net server to connect to.
+# Default: 127.0.0.1
+#
+
+BnetServer.Address = 127.0.0.1
+
+#
+# BnetServer.Port
+# Description: Determines port to use when connecting to battle.net server.
+# Default: 1118
+#
+
+BnetServer.Port = 1118
+
+#
+###################################################################################################
diff --git a/src/tools/mmaps_generator/MapBuilder.cpp b/src/tools/mmaps_generator/MapBuilder.cpp
index 885dd24d760..2f8b35fd52d 100644
--- a/src/tools/mmaps_generator/MapBuilder.cpp
+++ b/src/tools/mmaps_generator/MapBuilder.cpp
@@ -27,14 +27,6 @@
#include "DetourNavMesh.h"
#include "DetourCommon.h"
-#include "DisableMgr.h"
-
-uint32 GetLiquidFlags(uint32 /*liquidType*/) { return 0; }
-namespace DisableMgr
-{
- bool IsDisabledFor(DisableType /*type*/, uint32 /*entry*/, Unit const* /*unit*/, uint8 /*flags*/ /*= 0*/) { return false; }
-}
-
#define MMAP_MAGIC 0x4d4d4150 // 'MMAP'
#define MMAP_VERSION 5
diff --git a/src/tools/mmaps_generator/PathCommon.h b/src/tools/mmaps_generator/PathCommon.h
index 8285fef74f2..694e40dacde 100644
--- a/src/tools/mmaps_generator/PathCommon.h
+++ b/src/tools/mmaps_generator/PathCommon.h
@@ -62,7 +62,7 @@ namespace MMAP
if (*++filter == '\0') // wildcard at end of filter means all remaing chars match
return true;
- while (true)
+ for (;;)
{
if (*filter == *str)
break;