aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/server/bnetserver/CMakeLists.txt1
-rw-r--r--src/server/bnetserver/Packets/PacketManager.cpp2
-rw-r--r--src/server/bnetserver/Realms/RealmList.cpp43
-rw-r--r--src/server/bnetserver/Realms/RealmList.h62
-rw-r--r--src/server/bnetserver/Realms/WorldListener.cpp4
-rw-r--r--src/server/game/Battlefield/Battlefield.cpp26
-rw-r--r--src/server/game/Battlefield/Battlefield.h8
-rw-r--r--src/server/game/Battlegrounds/Battleground.cpp22
-rw-r--r--src/server/game/Battlegrounds/Battleground.h7
-rw-r--r--src/server/game/Battlegrounds/BattlegroundMgr.cpp7
-rw-r--r--src/server/game/Battlegrounds/BattlegroundMgr.h1
-rw-r--r--src/server/game/Battlegrounds/Zones/BattlegroundEY.cpp10
-rw-r--r--src/server/game/CMakeLists.txt1
-rw-r--r--src/server/game/Entities/Object/Updates/UpdateData.cpp4
-rw-r--r--src/server/game/Entities/Player/Player.cpp45
-rw-r--r--src/server/game/Entities/Player/Player.h4
-rw-r--r--src/server/game/Events/GameEventMgr.cpp10
-rw-r--r--src/server/game/Globals/ObjectMgr.cpp10
-rw-r--r--src/server/game/Handlers/AuctionHouseHandler.cpp4
-rw-r--r--src/server/game/Handlers/CharacterHandler.cpp49
-rw-r--r--src/server/game/Handlers/LFGHandler.cpp4
-rw-r--r--src/server/game/Scripting/ScriptLoader.cpp12
-rw-r--r--src/server/game/Server/Packet.cpp158
-rw-r--r--src/server/game/Server/Packet.h8
-rw-r--r--src/server/game/Server/Packets/AuctionHousePackets.cpp6
-rw-r--r--src/server/game/Server/Packets/AuctionHousePackets.h7
-rw-r--r--src/server/game/Server/Packets/AuthenticationPackets.cpp7
-rw-r--r--src/server/game/Server/Packets/AuthenticationPackets.h23
-rw-r--r--src/server/game/Server/Packets/BattlegroundPackets.cpp26
-rw-r--r--src/server/game/Server/Packets/BattlegroundPackets.h40
-rw-r--r--src/server/game/Server/Packets/GuildPackets.cpp1
-rw-r--r--src/server/game/Server/Packets/GuildPackets.h3
-rw-r--r--src/server/game/Server/Packets/WorldStatePackets.cpp52
-rw-r--r--src/server/game/Server/Packets/WorldStatePackets.h64
-rw-r--r--src/server/game/Server/Protocol/Opcodes.cpp34
-rw-r--r--src/server/game/Server/Protocol/Opcodes.h92
-rw-r--r--src/server/game/Server/WorldPacket.h18
-rw-r--r--src/server/game/Server/WorldSession.cpp92
-rw-r--r--src/server/game/Server/WorldSession.h13
-rw-r--r--src/server/game/Server/WorldSocket.cpp192
-rw-r--r--src/server/game/Server/WorldSocket.h22
-rw-r--r--src/server/game/Server/WorldSocketMgr.cpp7
-rw-r--r--src/server/game/Server/WorldSocketMgr.h3
-rw-r--r--src/server/game/Spells/Spell.cpp4
-rw-r--r--src/server/game/World/World.cpp17
-rw-r--r--src/server/game/World/World.h9
-rw-r--r--src/server/scripts/Maelstrom/CMakeLists.txt7
-rw-r--r--src/server/scripts/Maelstrom/Stonecore/boss_corborus.cpp319
-rw-r--r--src/server/scripts/Maelstrom/Stonecore/boss_high_priestess_azil.cpp808
-rw-r--r--src/server/scripts/Maelstrom/Stonecore/boss_ozruk.cpp287
-rw-r--r--src/server/scripts/Maelstrom/Stonecore/boss_slabhide.cpp599
-rw-r--r--src/server/scripts/Maelstrom/Stonecore/instance_stonecore.cpp262
-rw-r--r--src/server/scripts/Maelstrom/Stonecore/stonecore.cpp442
-rw-r--r--src/server/scripts/Maelstrom/Stonecore/stonecore.h72
-rw-r--r--src/server/scripts/Northrend/Ulduar/Ulduar/instance_ulduar.cpp58
-rw-r--r--src/server/scripts/Northrend/Ulduar/Ulduar/ulduar.h49
-rw-r--r--src/server/shared/CMakeLists.txt3
-rw-r--r--src/server/shared/Cryptography/Authentication/WorldPacketCrypt.cpp15
-rw-r--r--src/server/shared/Cryptography/Authentication/WorldPacketCrypt.h1
-rw-r--r--src/server/shared/Database/Field.cpp12
-rw-r--r--src/server/shared/Database/Field.h6
-rw-r--r--src/server/shared/Database/PreparedStatement.cpp6
-rw-r--r--src/server/shared/Database/QueryResult.cpp2
-rw-r--r--src/server/shared/Networking/SocketMgr.h1
-rw-r--r--src/server/shared/Realm/Realm.cpp53
-rw-r--r--src/server/shared/Realm/Realm.h86
-rw-r--r--src/server/worldserver/Main.cpp64
-rw-r--r--src/server/worldserver/worldserver.conf.dist11
68 files changed, 3981 insertions, 416 deletions
diff --git a/src/server/bnetserver/CMakeLists.txt b/src/server/bnetserver/CMakeLists.txt
index 5b854018d47..5d1edef5b81 100644
--- a/src/server/bnetserver/CMakeLists.txt
+++ b/src/server/bnetserver/CMakeLists.txt
@@ -55,6 +55,7 @@ include_directories(
${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/Realm
${CMAKE_SOURCE_DIR}/src/server/shared/Threading
${CMAKE_SOURCE_DIR}/src/server/shared/Utilities
${CMAKE_SOURCE_DIR}/src/server/ipc
diff --git a/src/server/bnetserver/Packets/PacketManager.cpp b/src/server/bnetserver/Packets/PacketManager.cpp
index cbfd0c8b2b6..faf38e8a5bc 100644
--- a/src/server/bnetserver/Packets/PacketManager.cpp
+++ b/src/server/bnetserver/Packets/PacketManager.cpp
@@ -79,7 +79,7 @@ Battlenet::PacketManager::PacketManager()
void Battlenet::PacketManager::RegisterAuthenticationPackets()
{
- REGISTER_CLIENT_PACKET_NAME(PacketHeader(Authentication::CMSG_LOGON_REQUEST, AUTHENTICATION), "Authentication::LogonRequest3");
+ REGISTER_CLIENT_PACKET_NAME(PacketHeader(Authentication::CMSG_LOGON_REQUEST, AUTHENTICATION), "Authentication::LogonRequest");
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);
diff --git a/src/server/bnetserver/Realms/RealmList.cpp b/src/server/bnetserver/Realms/RealmList.cpp
index cc7e1d492a8..a876aa93a07 100644
--- a/src/server/bnetserver/Realms/RealmList.cpp
+++ b/src/server/bnetserver/Realms/RealmList.cpp
@@ -24,49 +24,6 @@
#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)
{
}
diff --git a/src/server/bnetserver/Realms/RealmList.h b/src/server/bnetserver/Realms/RealmList.h
index dc78a00dfdd..718e26d2564 100644
--- a/src/server/bnetserver/Realms/RealmList.h
+++ b/src/server/bnetserver/Realms/RealmList.h
@@ -20,6 +20,7 @@
#define _REALMLIST_H
#include "Common.h"
+#include "Realm.h"
#include "WorldListener.h"
#include <boost/asio/ip/address.hpp>
#include <boost/asio/ip/tcp.hpp>
@@ -28,67 +29,6 @@
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
{
diff --git a/src/server/bnetserver/Realms/WorldListener.cpp b/src/server/bnetserver/Realms/WorldListener.cpp
index 30886a67310..9c9f1029e87 100644
--- a/src/server/bnetserver/Realms/WorldListener.cpp
+++ b/src/server/bnetserver/Realms/WorldListener.cpp
@@ -98,7 +98,9 @@ void WorldListener::HandleToonOnlineStatusChange(Battlenet::RealmHandle const& r
if (online)
{
Battlenet::WoWRealm::ToonReady* toonReady = new Battlenet::WoWRealm::ToonReady();
- toonReady->Realm = realm;
+ toonReady->Realm.Battlegroup = realm.Battlegroup;
+ toonReady->Realm.Index = realm.Index;
+ toonReady->Realm.Region = realm.Region;
toonReady->Guid = toonHandle.Guid;
toonReady->Name = toonHandle.Name;
session->AsyncWrite(toonReady);
diff --git a/src/server/game/Battlefield/Battlefield.cpp b/src/server/game/Battlefield/Battlefield.cpp
index c06ade69f01..401844b6151 100644
--- a/src/server/game/Battlefield/Battlefield.cpp
+++ b/src/server/game/Battlefield/Battlefield.cpp
@@ -29,6 +29,7 @@
#include "ObjectAccessor.h"
#include "ObjectMgr.h"
#include "WorldPacket.h"
+#include "WorldStatePackets.h"
Battlefield::Battlefield()
{
@@ -351,7 +352,7 @@ void Battlefield::DoPlaySoundToAll(uint32 SoundID)
data << uint32(SoundID);
data << uint64(0);
- BroadcastPacketToWar(data);
+ BroadcastPacketToWar(&data);
}
bool Battlefield::HasPlayer(Player* player) const
@@ -410,28 +411,28 @@ void Battlefield::TeamCastSpell(TeamId team, int32 spellId)
}
}
-void Battlefield::BroadcastPacketToZone(WorldPacket& data) const
+void Battlefield::BroadcastPacketToZone(WorldPacket const* data) const
{
for (uint8 team = 0; team < BG_TEAMS_COUNT; ++team)
for (GuidSet::const_iterator itr = m_players[team].begin(); itr != m_players[team].end(); ++itr)
if (Player* player = ObjectAccessor::FindPlayer(*itr))
- player->SendDirectMessage(&data);
+ player->SendDirectMessage(data);
}
-void Battlefield::BroadcastPacketToQueue(WorldPacket& data) const
+void Battlefield::BroadcastPacketToQueue(WorldPacket const* 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::FindConnectedPlayer(*itr))
- player->SendDirectMessage(&data);
+ player->SendDirectMessage(data);
}
-void Battlefield::BroadcastPacketToWar(WorldPacket& data) const
+void Battlefield::BroadcastPacketToWar(WorldPacket const* data) const
{
for (uint8 team = 0; team < BG_TEAMS_COUNT; ++team)
for (GuidSet::const_iterator itr = m_PlayersInWar[team].begin(); itr != m_PlayersInWar[team].end(); ++itr)
if (Player* player = ObjectAccessor::FindPlayer(*itr))
- player->SendDirectMessage(&data);
+ player->SendDirectMessage(data);
}
void Battlefield::SendWarning(uint8 id, WorldObject const* target /*= nullptr*/)
@@ -440,12 +441,13 @@ void Battlefield::SendWarning(uint8 id, WorldObject const* target /*= nullptr*/)
sCreatureTextMgr->SendChat(stalker, id, target);
}
-void Battlefield::SendUpdateWorldState(uint32 field, uint32 value)
+void Battlefield::SendUpdateWorldState(uint32 variable, uint32 value, bool hidden /*= false*/)
{
- for (uint8 i = 0; i < BG_TEAMS_COUNT; ++i)
- for (GuidSet::iterator itr = m_players[i].begin(); itr != m_players[i].end(); ++itr)
- if (Player* player = ObjectAccessor::FindPlayer(*itr))
- player->SendUpdateWorldState(field, value);
+ WorldPackets::WorldState::UpdateWorldState worldstate;
+ worldstate.VariableID = variable;
+ worldstate.Value = value;
+ worldstate.Hidden = hidden;
+ BroadcastPacketToZone(worldstate.Write());
}
void Battlefield::RegisterZone(uint32 zoneId)
diff --git a/src/server/game/Battlefield/Battlefield.h b/src/server/game/Battlefield/Battlefield.h
index 29b8f4a5126..03557779ab1 100644
--- a/src/server/game/Battlefield/Battlefield.h
+++ b/src/server/game/Battlefield/Battlefield.h
@@ -200,7 +200,7 @@ class Battlefield : public ZoneScript
virtual bool SetupBattlefield() { return true; }
/// Update data of a worldstate to all players present in zone
- void SendUpdateWorldState(uint32 field, uint32 value);
+ void SendUpdateWorldState(uint32 variable, uint32 value, bool hidden = false);
/**
* \brief Called every time for update bf data and time
@@ -397,9 +397,9 @@ class Battlefield : public ZoneScript
virtual void SendRemoveWorldStates(Player* /*player*/) { }
// use for send a packet for all player list
- void BroadcastPacketToZone(WorldPacket& data) const;
- void BroadcastPacketToQueue(WorldPacket& data) const;
- void BroadcastPacketToWar(WorldPacket& data) const;
+ void BroadcastPacketToZone(WorldPacket const* data) const;
+ void BroadcastPacketToQueue(WorldPacket const* data) const;
+ void BroadcastPacketToWar(WorldPacket const* data) const;
// CapturePoint system
void AddCapturePoint(BfCapturePoint* cp) { m_capturePoints[cp->GetCapturePointEntry()] = cp; }
diff --git a/src/server/game/Battlegrounds/Battleground.cpp b/src/server/game/Battlegrounds/Battleground.cpp
index 396b549c0bc..be043aa289a 100644
--- a/src/server/game/Battlegrounds/Battleground.cpp
+++ b/src/server/game/Battlegrounds/Battleground.cpp
@@ -37,6 +37,7 @@
#include "SpellAuras.h"
#include "Util.h"
#include "WorldPacket.h"
+#include "WorldStatePackets.h"
#include "Transport.h"
namespace Trinity
@@ -634,14 +635,14 @@ Position const* Battleground::GetTeamStartPosition(TeamId teamId) const
return &StartPosition[teamId];
}
-void Battleground::SendPacketToAll(WorldPacket* packet)
+void Battleground::SendPacketToAll(WorldPacket const* packet) const
{
for (BattlegroundPlayerMap::const_iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr)
if (Player* player = _GetPlayer(itr, "SendPacketToAll"))
player->SendDirectMessage(packet);
}
-void Battleground::SendPacketToTeam(uint32 TeamID, WorldPacket* packet, Player* sender, bool self)
+void Battleground::SendPacketToTeam(uint32 TeamID, WorldPacket const* packet, Player* sender, bool self) const
{
for (BattlegroundPlayerMap::const_iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr)
{
@@ -716,18 +717,13 @@ void Battleground::RewardReputationToTeam(uint32 faction_id, uint32 Reputation,
}
}
-void Battleground::UpdateWorldState(uint32 Field, uint32 Value)
+void Battleground::UpdateWorldState(uint32 variable, uint32 value, bool hidden /*= false*/)
{
- WorldPacket data;
- sBattlegroundMgr->BuildUpdateWorldStatePacket(&data, Field, Value);
- SendPacketToAll(&data);
-}
-
-void Battleground::UpdateWorldStateForPlayer(uint32 field, uint32 value, Player* player)
-{
- WorldPacket data;
- sBattlegroundMgr->BuildUpdateWorldStatePacket(&data, field, value);
- player->SendDirectMessage(&data);
+ WorldPackets::WorldState::UpdateWorldState worldstate;
+ worldstate.VariableID = variable;
+ worldstate.Value = value;
+ worldstate.Hidden = hidden;
+ SendPacketToAll(worldstate.Write());
}
void Battleground::EndBattleground(uint32 winner)
diff --git a/src/server/game/Battlegrounds/Battleground.h b/src/server/game/Battlegrounds/Battleground.h
index fc52178c52d..aa0bb6fbb4c 100644
--- a/src/server/game/Battlegrounds/Battleground.h
+++ b/src/server/game/Battlegrounds/Battleground.h
@@ -347,8 +347,8 @@ class Battleground
// Packet Transfer
// method that should fill worldpacket with actual world states (not yet implemented for all battlegrounds!)
virtual void FillInitialWorldStates(WorldPacket& /*data*/) { }
- void SendPacketToTeam(uint32 TeamID, WorldPacket* packet, Player* sender = NULL, bool self = true);
- void SendPacketToAll(WorldPacket* packet);
+ void SendPacketToTeam(uint32 TeamID, WorldPacket const* packet, Player* sender = NULL, bool self = true) const;
+ void SendPacketToAll(WorldPacket const* packet) const;
void SendChatMessage(Creature* source, uint8 textId, WorldObject* target = NULL);
@@ -361,8 +361,7 @@ class Battleground
void RemoveAuraOnTeam(uint32 SpellID, uint32 TeamID);
void RewardHonorToTeam(uint32 Honor, uint32 TeamID);
void RewardReputationToTeam(uint32 faction_id, uint32 Reputation, uint32 TeamID);
- void UpdateWorldState(uint32 Field, uint32 Value);
- void UpdateWorldStateForPlayer(uint32 Field, uint32 Value, Player* player);
+ void UpdateWorldState(uint32 variable, uint32 value, bool hidden = false);
virtual void EndBattleground(uint32 winner);
void BlockMovement(Player* player);
diff --git a/src/server/game/Battlegrounds/BattlegroundMgr.cpp b/src/server/game/Battlegrounds/BattlegroundMgr.cpp
index eae6a831290..e1a3a9b065c 100644
--- a/src/server/game/Battlegrounds/BattlegroundMgr.cpp
+++ b/src/server/game/Battlegrounds/BattlegroundMgr.cpp
@@ -426,13 +426,6 @@ void BattlegroundMgr::BuildStatusFailedPacket(WorldPacket* data, Battleground* b
data->WriteByteSeq(unkGuid3[5]);
}
-void BattlegroundMgr::BuildUpdateWorldStatePacket(WorldPacket* data, uint32 field, uint32 value)
-{
- data->Initialize(SMSG_UPDATE_WORLD_STATE, 4+4);
- *data << uint32(field);
- *data << uint32(value);
-}
-
void BattlegroundMgr::BuildPlaySoundPacket(WorldPacket* data, uint32 soundid)
{
data->Initialize(SMSG_PLAY_SOUND, 4 + 8);
diff --git a/src/server/game/Battlegrounds/BattlegroundMgr.h b/src/server/game/Battlegrounds/BattlegroundMgr.h
index 23689c03fba..9e330373685 100644
--- a/src/server/game/Battlegrounds/BattlegroundMgr.h
+++ b/src/server/game/Battlegrounds/BattlegroundMgr.h
@@ -74,7 +74,6 @@ class BattlegroundMgr
void BuildPlayerLeftBattlegroundPacket(WorldPacket* data, ObjectGuid guid);
void BuildBattlegroundListPacket(WorldPacket* data, ObjectGuid guid, Player* player, BattlegroundTypeId bgTypeId);
void BuildStatusFailedPacket(WorldPacket* data, Battleground* bg, Player* pPlayer, uint8 QueueSlot, GroupJoinBattlegroundResult result);
- void BuildUpdateWorldStatePacket(WorldPacket* data, uint32 field, uint32 value);
void BuildBattlegroundStatusPacket(WorldPacket* data, Battleground* bg, Player* player, uint8 queueSlot, uint8 statusId, uint32 time1, uint32 time2, uint8 arenaType);
void BuildPlaySoundPacket(WorldPacket* data, uint32 soundId);
void SendAreaSpiritHealerQueryOpcode(Player* player, Battleground* bg, ObjectGuid guid);
diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundEY.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundEY.cpp
index 034f7c91999..1663f4da049 100644
--- a/src/server/game/Battlegrounds/Zones/BattlegroundEY.cpp
+++ b/src/server/game/Battlegrounds/Zones/BattlegroundEY.cpp
@@ -179,9 +179,9 @@ void BattlegroundEY::CheckSomeoneJoinedPoint()
{
//player joined point!
//show progress bar
- UpdateWorldStateForPlayer(PROGRESS_BAR_PERCENT_GREY, BG_EY_PROGRESS_BAR_PERCENT_GREY, player);
- UpdateWorldStateForPlayer(PROGRESS_BAR_STATUS, m_PointBarStatus[i], player);
- UpdateWorldStateForPlayer(PROGRESS_BAR_SHOW, BG_EY_PROGRESS_BAR_SHOW, player);
+ player->SendUpdateWorldState(PROGRESS_BAR_PERCENT_GREY, BG_EY_PROGRESS_BAR_PERCENT_GREY);
+ player->SendUpdateWorldState(PROGRESS_BAR_STATUS, m_PointBarStatus[i]);
+ player->SendUpdateWorldState(PROGRESS_BAR_SHOW, BG_EY_PROGRESS_BAR_SHOW);
//add player to point
m_PlayersNearPoint[i].push_back(m_PlayersNearPoint[EY_POINTS_MAX][j]);
//remove player from "free space"
@@ -222,7 +222,7 @@ void BattlegroundEY::CheckSomeoneLeftPoint()
{
m_PlayersNearPoint[EY_POINTS_MAX].push_back(m_PlayersNearPoint[i][j]);
m_PlayersNearPoint[i].erase(m_PlayersNearPoint[i].begin() + j);
- this->UpdateWorldStateForPlayer(PROGRESS_BAR_SHOW, BG_EY_PROGRESS_BAR_DONT_SHOW, player);
+ player->SendUpdateWorldState(PROGRESS_BAR_SHOW, BG_EY_PROGRESS_BAR_DONT_SHOW);
}
else
{
@@ -265,7 +265,7 @@ void BattlegroundEY::UpdatePointStatuses()
Player* player = ObjectAccessor::FindPlayer(m_PlayersNearPoint[point][i]);
if (player)
{
- this->UpdateWorldStateForPlayer(PROGRESS_BAR_STATUS, m_PointBarStatus[point], player);
+ player->SendUpdateWorldState(PROGRESS_BAR_STATUS, m_PointBarStatus[point]);
//if point owner changed we must evoke event!
if (pointOwnerTeamId != m_PointOwnedByTeam[point])
{
diff --git a/src/server/game/CMakeLists.txt b/src/server/game/CMakeLists.txt
index bcf1a33a626..d18fce9b829 100644
--- a/src/server/game/CMakeLists.txt
+++ b/src/server/game/CMakeLists.txt
@@ -128,6 +128,7 @@ include_directories(
${CMAKE_SOURCE_DIR}/src/server/shared/Logging
${CMAKE_SOURCE_DIR}/src/server/shared/Networking
${CMAKE_SOURCE_DIR}/src/server/shared/Packets
+ ${CMAKE_SOURCE_DIR}/src/server/shared/Realm
${CMAKE_SOURCE_DIR}/src/server/shared/Threading
${CMAKE_SOURCE_DIR}/src/server/shared/Utilities
${CMAKE_SOURCE_DIR}/src/server/ipc
diff --git a/src/server/game/Entities/Object/Updates/UpdateData.cpp b/src/server/game/Entities/Object/Updates/UpdateData.cpp
index df7f6fdcc77..74f6b62e398 100644
--- a/src/server/game/Entities/Object/Updates/UpdateData.cpp
+++ b/src/server/game/Entities/Object/Updates/UpdateData.cpp
@@ -45,11 +45,11 @@ void UpdateData::AddUpdateBlock(const ByteBuffer &block)
bool UpdateData::BuildPacket(WorldPacket* packet)
{
ASSERT(packet->empty()); // shouldn't happen
- packet->Initialize(SMSG_UPDATE_OBJECT, 2 + 4 + (m_outOfRangeGUIDs.empty() ? 0 : 1 + 4 + 9 * m_outOfRangeGUIDs.size()) + m_data.wpos());
+ packet->Initialize(SMSG_UPDATE_OBJECT, 2 + 4 + (m_outOfRangeGUIDs.empty() ? 0 : 1 + 4 + 9 * m_outOfRangeGUIDs.size()) + m_data.wpos(), CONNECTION_TYPE_INSTANCE);
*packet << uint32(m_blockCount);
*packet << uint16(m_map);
-
+
if (packet->WriteBit(!m_outOfRangeGUIDs.empty()))
{
*packet << uint16(0);
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index 99561741931..1ad85c237ac 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -41,6 +41,7 @@
#include "DisableMgr.h"
#include "Formulas.h"
#include "GameEventMgr.h"
+#include "GameObjectAI.h"
#include "GossipDef.h"
#include "GridNotifiers.h"
#include "GridNotifiersImpl.h"
@@ -55,6 +56,7 @@
#include "Log.h"
#include "MapInstanced.h"
#include "MapManager.h"
+#include "MovementStructures.h"
#include "ObjectAccessor.h"
#include "ObjectMgr.h"
#include "Opcodes.h"
@@ -81,8 +83,7 @@
#include "World.h"
#include "WorldPacket.h"
#include "WorldSession.h"
-#include "MovementStructures.h"
-#include "GameObjectAI.h"
+#include "WorldStatePackets.h"
#define ZONE_UPDATE_INTERVAL (1*IN_MILLISECONDS)
@@ -6516,7 +6517,7 @@ void Player::SendMessageToSet(WorldPacket* data, Player const* skipped_rcvr)
VisitNearbyWorldObject(GetVisibilityRange(), notifier);
}
-void Player::SendDirectMessage(WorldPacket* data)
+void Player::SendDirectMessage(WorldPacket const* data)
{
m_session->SendPacket(data);
}
@@ -9084,13 +9085,13 @@ void Player::SendNotifyLootItemRemoved(uint8 lootSlot)
GetSession()->SendPacket(&data);
}
-void Player::SendUpdateWorldState(uint32 Field, uint32 Value)
+void Player::SendUpdateWorldState(uint32 variable, uint32 value, bool hidden /*= false*/)
{
- WorldPacket data(SMSG_UPDATE_WORLD_STATE, 4+4+1);
- data << Field;
- data << Value;
- data << uint8(0);
- GetSession()->SendPacket(&data);
+ WorldPackets::WorldState::UpdateWorldState worldstate;
+ worldstate.VariableID = variable;
+ worldstate.Value = value;
+ worldstate.Hidden = hidden;
+ SendDirectMessage(worldstate.Write());
}
void Player::SendInitWorldStates(uint32 zoneid, uint32 areaid)
@@ -9110,22 +9111,22 @@ void Player::SendInitWorldStates(uint32 zoneid, uint32 areaid)
data << uint32(areaid); // area id, new 2.1.0
size_t countPos = data.wpos();
data << uint16(0); // count of uint64 blocks
- data << uint32(0x8d8) << uint32(0x0); // 1
- data << uint32(0x8d7) << uint32(0x0); // 2
- data << uint32(0x8d6) << uint32(0x0); // 3
- data << uint32(0x8d5) << uint32(0x0); // 4
- data << uint32(0x8d4) << uint32(0x0); // 5
- data << uint32(0x8d3) << uint32(0x0); // 6
- // 7 1 - Arena season in progress, 0 - end of season
- data << uint32(0xC77) << uint32(sWorld->getBoolConfig(CONFIG_ARENA_SEASON_IN_PROGRESS));
- // 8 Arena season id
- data << uint32(0xF3D) << uint32(sWorld->getIntConfig(CONFIG_ARENA_SEASON_ID));
+ data << uint32(2264) << uint32(0); // 1
+ data << uint32(2263) << uint32(0); // 2
+ data << uint32(2262) << uint32(0); // 3
+ data << uint32(2261) << uint32(0); // 4
+ data << uint32(2260) << uint32(0); // 5
+ data << uint32(2259) << uint32(0); // 6
+
+ data << uint32(3191) << uint32(sWorld->getBoolConfig(CONFIG_ARENA_SEASON_IN_PROGRESS) ? sWorld->getIntConfig(CONFIG_ARENA_SEASON_ID) : 0); // 7 Current Season - Arena season in progress
+ // 0 - End of season
+ data << uint32(3901) << uint32(sWorld->getIntConfig(CONFIG_ARENA_SEASON_ID) - sWorld->getBoolConfig(CONFIG_ARENA_SEASON_IN_PROGRESS)); // 8 PreviousSeason
if (mapid == 530) // Outland
{
- data << uint32(0x9bf) << uint32(0x0); // 7
- data << uint32(0x9bd) << uint32(0xF); // 8
- data << uint32(0x9bb) << uint32(0xF); // 9
+ data << uint32(2495) << uint32(0x0); // 7
+ data << uint32(2493) << uint32(0xF); // 8
+ data << uint32(2491) << uint32(0xF); // 9
}
// insert <field> <value>
diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h
index e0655a39daa..0f5418e24e7 100644
--- a/src/server/game/Entities/Player/Player.h
+++ b/src/server/game/Entities/Player/Player.h
@@ -2248,8 +2248,8 @@ class Player : public Unit, public GridObject<Player>
void DeleteEquipmentSet(uint64 setGuid);
void SendInitWorldStates(uint32 zone, uint32 area);
- void SendUpdateWorldState(uint32 Field, uint32 Value);
- void SendDirectMessage(WorldPacket* data);
+ void SendUpdateWorldState(uint32 variable, uint32 value, bool hidden = false);
+ void SendDirectMessage(WorldPacket const* data);
void SendBGWeekendWorldStates();
void SendBattlefieldWorldStates();
diff --git a/src/server/game/Events/GameEventMgr.cpp b/src/server/game/Events/GameEventMgr.cpp
index 780360dc945..cf46272080e 100644
--- a/src/server/game/Events/GameEventMgr.cpp
+++ b/src/server/game/Events/GameEventMgr.cpp
@@ -19,7 +19,6 @@
#include "GameEventMgr.h"
#include "World.h"
#include "ObjectMgr.h"
-#include "WorldPacket.h"
#include "PoolMgr.h"
#include "Language.h"
#include "Log.h"
@@ -29,6 +28,7 @@
#include "BattlegroundMgr.h"
#include "UnitAI.h"
#include "GameObjectAI.h"
+#include "WorldStatePackets.h"
bool GameEventMgr::CheckOneGameEvent(uint16 entry) const
{
@@ -1486,9 +1486,11 @@ void GameEventMgr::UpdateWorldStates(uint16 event_id, bool Activate)
BattlemasterListEntry const* bl = sBattlemasterListStore.LookupEntry(bgTypeId);
if (bl && bl->HolidayWorldStateId)
{
- WorldPacket data;
- sBattlegroundMgr->BuildUpdateWorldStatePacket(&data, bl->HolidayWorldStateId, Activate ? 1 : 0);
- sWorld->SendGlobalMessage(&data);
+ WorldPackets::WorldState::UpdateWorldState worldstate;
+ worldstate.VariableID = bl->HolidayWorldStateId;
+ worldstate.Value = Activate;
+ //worldstate.Hidden = false;
+ sWorld->SendGlobalMessage(worldstate.Write());
}
}
}
diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp
index 13e390bc362..576ebf4f547 100644
--- a/src/server/game/Globals/ObjectMgr.cpp
+++ b/src/server/game/Globals/ObjectMgr.cpp
@@ -2678,7 +2678,7 @@ void ObjectMgr::LoadItemTemplates()
itemTemplate.ItemId = itemId;
itemTemplate.Class = uint32(fields[1].GetUInt8());
itemTemplate.SubClass = uint32(fields[2].GetUInt8());
- itemTemplate.SoundOverrideSubclass = fields[3].GetInt32();
+ itemTemplate.SoundOverrideSubclass = fields[3].GetInt8();
itemTemplate.Name1 = fields[4].GetString();
itemTemplate.DisplayInfoID = fields[5].GetUInt32();
itemTemplate.Quality = uint32(fields[6].GetUInt8());
@@ -6365,11 +6365,11 @@ void ObjectMgr::SetHighestGuids()
result = WorldDatabase.Query("SELECT MAX(guid) FROM gameobject");
if (result)
- _gameObjectGuidGenerator.Set((*result)[0].GetUInt32() + 1);
+ _gameObjectGuidGenerator.Set((*result)[0].GetUInt64() + 1);
result = WorldDatabase.Query("SELECT MAX(guid) FROM transports");
if (result)
- _moTransportGuidGenerator.Set((*result)[0].GetUInt32() + 1);
+ _moTransportGuidGenerator.Set((*result)[0].GetUInt64() + 1);
result = CharacterDatabase.Query("SELECT MAX(id) FROM auctionhouse");
if (result)
@@ -8832,8 +8832,8 @@ void ObjectMgr::LoadCreatureClassLevelStats()
}
}
- stats.BaseMana = fields[8].GetUInt16();
- stats.BaseArmor = fields[9].GetUInt16();
+ stats.BaseMana = fields[8].GetUInt32();
+ stats.BaseArmor = fields[9].GetUInt32();
stats.AttackPower = fields[10].GetUInt16();
stats.RangedAttackPower = fields[11].GetUInt16();
diff --git a/src/server/game/Handlers/AuctionHouseHandler.cpp b/src/server/game/Handlers/AuctionHouseHandler.cpp
index e35baca3efc..bad38c91e79 100644
--- a/src/server/game/Handlers/AuctionHouseHandler.cpp
+++ b/src/server/game/Handlers/AuctionHouseHandler.cpp
@@ -65,7 +65,7 @@ void WorldSession::SendAuctionHello(ObjectGuid guid, Creature* unit)
if (!ahEntry)
return;
- WorldPacket data(MSG_AUCTION_HELLO, 12);
+ WorldPacket data(SMSG_AUCTION_HELLO, 12);
data << guid;
data << uint32(ahEntry->houseId);
data << uint8(1); // 3.3.3: 1 - AH enabled, 0 - AH disabled
@@ -74,7 +74,7 @@ void WorldSession::SendAuctionHello(ObjectGuid guid, Creature* unit)
void WorldSession::SendAuctionCommandResult(AuctionEntry* auction, uint32 action, uint32 errorCode, uint32 /*bidError = 0*/)
{
- WorldPackets::AuctionHousePackets::AuctionCommandResult auctionCommandResult;
+ WorldPackets::AuctionHouse::AuctionCommandResult auctionCommandResult;
auctionCommandResult.InitializeAuction(auction);
auctionCommandResult.Action = action;
auctionCommandResult.ErrorCode = errorCode;
diff --git a/src/server/game/Handlers/CharacterHandler.cpp b/src/server/game/Handlers/CharacterHandler.cpp
index 6845ebb383b..dd6090a0d62 100644
--- a/src/server/game/Handlers/CharacterHandler.cpp
+++ b/src/server/game/Handlers/CharacterHandler.cpp
@@ -19,7 +19,10 @@
#include "AccountMgr.h"
#include "ArenaTeam.h"
#include "ArenaTeamMgr.h"
+#include "AuthenticationPackets.h"
#include "Battleground.h"
+#include "BattlegroundPackets.h"
+#include "BattlenetServerManager.h"
#include "CalendarMgr.h"
#include "CharacterPackets.h"
#include "Chat.h"
@@ -50,7 +53,6 @@
#include "World.h"
#include "WorldPacket.h"
#include "WorldSession.h"
-#include "BattlenetServerManager.h"
class LoginQueryHolder : public SQLQueryHolder
{
@@ -761,7 +763,7 @@ void WorldSession::HandlePlayerLoginOpcode(WorldPackets::Character::PlayerLogin&
TC_LOG_DEBUG("network", "WORLD: Recvd Player Logon Message");
- m_playerLoading = true;
+ m_playerLoading = playerLogin.Guid;
TC_LOG_DEBUG("network", "Character %s logging in", playerLogin.Guid.ToString().c_str());
@@ -772,11 +774,32 @@ void WorldSession::HandlePlayerLoginOpcode(WorldPackets::Character::PlayerLogin&
return;
}
- LoginQueryHolder* holder = new LoginQueryHolder(GetAccountId(), playerLogin.Guid);
+ boost::system::error_code ignored_error;
+ boost::asio::ip::tcp::endpoint instanceAddress = realm.GetAddressForClient(boost::asio::ip::address::from_string(GetRemoteAddress(), ignored_error));
+ instanceAddress.port(sWorld->getIntConfig(CONFIG_PORT_INSTANCE));
+
+ WorldPackets::Auth::ConnectTo connectTo;
+ connectTo.Key = MAKE_PAIR64(GetAccountId(), CONNECTION_TYPE_INSTANCE);
+ connectTo.Serial = 1;
+ connectTo.Payload.Where = instanceAddress;
+ connectTo.Con = CONNECTION_TYPE_INSTANCE;
+
+ SendPacket(connectTo.Write());
+}
+
+void WorldSession::HandleContinuePlayerLogin()
+{
+ if (!PlayerLoading() || GetPlayer())
+ {
+ KickPlayer();
+ return;
+ }
+
+ LoginQueryHolder* holder = new LoginQueryHolder(GetAccountId(), m_playerLoading);
if (!holder->Initialize())
{
delete holder; // delete all unprocessed queries
- m_playerLoading = false;
+ m_playerLoading.Clear();
return;
}
@@ -809,7 +832,7 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder* holder)
KickPlayer(); // disconnect client, player no set to session and it will not deleted or saved at kick
delete pCurrChar; // delete it manually
delete holder; // delete all unprocessed queries
- m_playerLoading = false;
+ m_playerLoading.Clear();
return;
}
@@ -870,6 +893,20 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder* holder)
TC_LOG_DEBUG("network", "WORLD: Sent motd (SMSG_MOTD)");
}
+ SendSetTimeZoneInformation();
+
+ // Send PVPSeason
+ {
+ WorldPackets::Battleground::PVPSeason season;
+ season.PreviousSeason = sWorld->getIntConfig(CONFIG_ARENA_SEASON_ID) - sWorld->getBoolConfig(CONFIG_ARENA_SEASON_IN_PROGRESS);
+
+ if (sWorld->getBoolConfig(CONFIG_ARENA_SEASON_IN_PROGRESS))
+ season.CurrentSeason = sWorld->getIntConfig(CONFIG_ARENA_SEASON_ID);
+
+ SendPacket(season.Write());
+ TC_LOG_DEBUG("network", "WORLD: Sent PVPSeason");
+ }
+
// send server info
{
if (sWorld->getIntConfig(CONFIG_ENABLE_SINFO_LOGIN) == 1)
@@ -1049,7 +1086,7 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder* holder)
if (!pCurrChar->IsStandState() && !pCurrChar->HasUnitState(UNIT_STATE_STUNNED))
pCurrChar->SetStandState(UNIT_STAND_STATE_STAND);
- m_playerLoading = false;
+ m_playerLoading.Clear();
// Handle Login-Achievements (should be handled after loading)
_player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_ON_LOGIN, 1);
diff --git a/src/server/game/Handlers/LFGHandler.cpp b/src/server/game/Handlers/LFGHandler.cpp
index 014e9f7b9d6..39e3edb30ed 100644
--- a/src/server/game/Handlers/LFGHandler.cpp
+++ b/src/server/game/Handlers/LFGHandler.cpp
@@ -115,7 +115,9 @@ void WorldSession::HandleLfgJoinOpcode(WorldPacket& recvData)
{
uint32 dungeon;
recvData >> dungeon;
- newDungeons.insert((dungeon & 0x00FFFFFF)); // remove the type from the dungeon entry
+ dungeon &= 0x00FFFFFF; // remove the type from the dungeon entry
+ if (dungeon)
+ newDungeons.insert(dungeon);
}
TC_LOG_DEBUG("lfg", "CMSG_LFG_JOIN %s roles: %u, Dungeons: %u, Comment: %s",
diff --git a/src/server/game/Scripting/ScriptLoader.cpp b/src/server/game/Scripting/ScriptLoader.cpp
index 0e43a63c98e..ad727fc17d2 100644
--- a/src/server/game/Scripting/ScriptLoader.cpp
+++ b/src/server/game/Scripting/ScriptLoader.cpp
@@ -677,6 +677,12 @@ void AddSC_zangarmarsh();
// Maelstrom
void AddSC_kezan();
+void AddSC_instance_stonecore(); // Stonecore
+void AddSC_stonecore();
+void AddSC_boss_corborus();
+void AddSC_boss_slabhide();
+void AddSC_boss_ozruk();
+void AddSC_boss_high_priestess_azil();
// Events
void AddSC_event_childrens_week();
@@ -1411,6 +1417,12 @@ void AddMaelstromScripts()
{
#ifdef SCRIPTS
AddSC_kezan();
+ AddSC_instance_stonecore(); // Stonecore
+ AddSC_stonecore();
+ AddSC_boss_corborus();
+ AddSC_boss_slabhide();
+ AddSC_boss_ozruk();
+ AddSC_boss_high_priestess_azil();
#endif
}
diff --git a/src/server/game/Server/Packet.cpp b/src/server/game/Server/Packet.cpp
index 10b472bee67..ee805c18610 100644
--- a/src/server/game/Server/Packet.cpp
+++ b/src/server/game/Server/Packet.cpp
@@ -17,6 +17,164 @@
#include "Packet.h"
+inline bool IsInstanceOnlyOpcode(uint32 opcode)
+{
+ // TODO: Use names when known
+ switch (opcode)
+ {
+ case 0x000F: // Client
+ case 0x0111: // Client
+ case 0x03E4: // Client
+ case 0x0549: // Client
+ case 0x054C: // Client
+ case 0x055A: // Client
+ case 0x056C: // Client
+ case 0x057A: // Client
+ case 0x057B: // Client
+ case 0x05CC: // Client
+ case 0x05EA: // Client
+ case 0x05EC: // Client
+ case 0x05F9: // Client
+ case 0x05FB: // Client
+ case 0x074C: // Client
+ case 0x075B: // Client
+ case 0x076C: // Client
+ case 0x077B: // Client
+ case 0x077C: // Client
+ case 0x07CC: // Client
+ case 0x07DB: // Client
+ case 0x07EC: // Client
+ case 0x07FB: // Client
+ case 0x07FC: // Client
+ case 0x0827: // Client
+ case 0x0935: // Client
+ case 0x0F0C: // ClientSpell
+ case 0x0F10: // ClientSpell
+ case 0x0F1B: // ClientSpell
+ case 0x0F1C: // ClientSpell
+ case 0x0F20: // ClientSpell
+ case 0x0F2C: // ClientSpell
+ case 0x0F2F: // ClientSpell
+ case 0x0F3B: // ClientSpell
+ case 0x0F8B: // ClientSpell
+ case 0x0F8C: // ClientSpell
+ case 0x0F90: // ClientSpell
+ case 0x0F9F: // ClientSpell
+ case 0x0FA0: // ClientSpell
+ case SMSG_ATTACKSTOP: // Client
+ case 0x14C9: // Client
+ case 0x154A: // Client
+ case 0x155A: // Client
+ case 0x155C: // Client
+ case SMSG_QUESTGIVER_STATUS: // ClientQuest
+ case 0x156A: // Client
+ case 0x156B: // Client
+ case 0x157A: // Client
+ case 0x157B: // Client
+ case 0x15DC: // Client
+ case 0x15EB: // Client
+ case 0x15FB: // Client
+ case 0x170C: // ClientSpell
+ case 0x171C: // ClientSpell
+ case 0x171F: // ClientSpell
+ case 0x172C: // ClientSpell
+ case 0x172F: // ClientSpell
+ case 0x173C: // ClientSpell
+ case 0x173F: // ClientSpell
+ case 0x1740: // ClientSpell
+ case 0x1790: // ClientSpell
+ case 0x179B: // ClientSpell
+ case 0x179F: // ClientSpell
+ case SMSG_ATTACKSTART: // Client
+ case 0x1D82: // ClientQuest
+ case 0x1D83: // ClientQuest
+ case 0x1D85: // ClientQuest
+ case 0x1D87: // ClientQuest
+ case 0x1D93: // ClientQuest
+ case 0x1D96: // ClientQuest
+ case 0x1D97: // ClientQuest
+ case 0x1DA1: // ClientQuest
+ case 0x1DA2: // ClientQuest
+ case 0x1DA3: // ClientQuest
+ case 0x1DA4: // ClientQuest
+ case 0x1DA5: // ClientQuest
+ case 0x1DA7: // ClientQuest
+ case SMSG_QUERY_TIME_RESPONSE: // Client
+ case 0x1DC2: // ClientQuest
+ case 0x1DC6: // ClientQuest
+ case 0x1DC7: // ClientQuest
+ case 0x1DD2: // ClientQuest
+ case 0x1DD3: // ClientQuest
+ case 0x1DD6: // ClientQuest
+ case 0x1DD7: // ClientQuest
+ case 0x1DD8: // ClientQuest
+ case 0x1DE4: // ClientQuest
+ case 0x1DE5: // ClientQuest
+ case 0x1DE7: // ClientQuest
+ case 0x1F02: // ClientQuest
+ case 0x1F06: // ClientQuest
+ case 0x1F07: // ClientQuest
+ case 0x1F0C: // ClientSpell
+ case 0x1F12: // ClientQuest
+ case 0x1F13: // ClientQuest
+ case 0x1F16: // ClientQuest
+ case 0x1F17: // ClientQuest
+ case 0x1F18: // ClientQuest
+ case 0x1F1C: // ClientSpell
+ case 0x1F1F: // ClientSpell
+ case 0x1F24: // ClientQuest
+ case 0x1F25: // ClientQuest
+ case 0x1F27: // ClientQuest
+ case 0x1F2C: // ClientSpell
+ case 0x1F2F: // ClientSpell
+ case 0x1F3C: // ClientSpell
+ case 0x1F3F: // ClientSpell
+ case 0x1F40: // ClientSpell
+ case 0x1F44: // ClientQuest
+ case 0x1F48: // ClientQuest
+ case 0x1F51: // ClientQuest
+ case 0x1F55: // ClientQuest
+ case 0x1F57: // ClientQuest
+ case 0x1F61: // ClientQuest
+ case 0x1F63: // ClientQuest
+ case 0x1F64: // ClientQuest
+ case 0x1F65: // ClientQuest
+ case 0x1F67: // ClientQuest
+ case 0x1F85: // ClientQuest
+ case 0x1F86: // ClientQuest
+ case 0x1F87: // ClientQuest
+ case 0x1F90: // ClientSpell
+ case 0x1F92: // ClientQuest
+ case 0x1F94: // ClientQuest
+ case 0x1F96: // ClientQuest
+ case 0x1F97: // ClientQuest
+ case 0x1F9B: // ClientSpell
+ case 0x1F9F: // ClientSpell
+ case 0x1FA1: // ClientQuest
+ case 0x1FA2: // ClientQuest
+ case 0x1FA3: // ClientQuest
+ case 0x1FA4: // ClientQuest
+ case 0x1FA5: // ClientQuest
+ case 0x1FA7: // ClientQuest
+ case 0x1FC2: // ClientQuest
+ case 0x1FC6: // ClientQuest
+ case 0x1FC7: // ClientQuest
+ case 0x1FD2: // ClientQuest
+ case 0x1FD3: // ClientQuest
+ case 0x1FD6: // ClientQuest
+ case 0x1FD7: // ClientQuest
+ case 0x1FD8: // ClientQuest
+ case 0x1FE4: // ClientQuest
+ case 0x1FE5: // ClientQuest
+ case 0x1FE7: // ClientQuest
+ return true;
+ default:
+ return false;
+ }
+}
+
WorldPackets::ServerPacket::ServerPacket(OpcodeServer opcode, size_t initialSize /*= 200*/) : Packet(WorldPacket(opcode, initialSize))
{
+ if (IsInstanceOnlyOpcode(opcode))
+ _connectionIndex = CONNECTION_TYPE_INSTANCE;
}
diff --git a/src/server/game/Server/Packet.h b/src/server/game/Server/Packet.h
index 66061166ede..1a2ba87f90a 100644
--- a/src/server/game/Server/Packet.h
+++ b/src/server/game/Server/Packet.h
@@ -25,7 +25,11 @@ namespace WorldPackets
class Packet
{
public:
- Packet(WorldPacket&& worldPacket) : _worldPacket(std::move(worldPacket)) { }
+ Packet(WorldPacket&& worldPacket) : _worldPacket(std::move(worldPacket))
+ {
+ _connectionIndex = _worldPacket.GetConnection();
+ }
+
virtual ~Packet() = default;
Packet(Packet const& right) = delete;
@@ -35,9 +39,11 @@ namespace WorldPackets
virtual void Read() = 0;
size_t GetSize() const { return _worldPacket.size(); }
+ ConnectionType GetConnection() const { return _connectionIndex; }
protected:
WorldPacket _worldPacket;
+ ConnectionType _connectionIndex;
};
class ServerPacket : public Packet
diff --git a/src/server/game/Server/Packets/AuctionHousePackets.cpp b/src/server/game/Server/Packets/AuctionHousePackets.cpp
index 56fa0ed396b..bb1a10be254 100644
--- a/src/server/game/Server/Packets/AuctionHousePackets.cpp
+++ b/src/server/game/Server/Packets/AuctionHousePackets.cpp
@@ -19,10 +19,10 @@
#include "AuctionHouseMgr.h"
#include "ObjectGuid.h"
-WorldPackets::AuctionHousePackets::AuctionCommandResult::AuctionCommandResult()
+WorldPackets::AuctionHouse::AuctionCommandResult::AuctionCommandResult()
: ServerPacket(SMSG_AUCTION_COMMAND_RESULT, 4 + 4 + 4 + 8 + 4 + 8 + 8 + 8) { }
-void WorldPackets::AuctionHousePackets::AuctionCommandResult::InitializeAuction(AuctionEntry* auction)
+void WorldPackets::AuctionHouse::AuctionCommandResult::InitializeAuction(AuctionEntry* auction)
{
if (auction)
{
@@ -33,7 +33,7 @@ void WorldPackets::AuctionHousePackets::AuctionCommandResult::InitializeAuction(
}
}
-WorldPacket const* WorldPackets::AuctionHousePackets::AuctionCommandResult::Write()
+WorldPacket const* WorldPackets::AuctionHouse::AuctionCommandResult::Write()
{
_worldPacket << uint32(AuctionId);
_worldPacket << uint32(Action);
diff --git a/src/server/game/Server/Packets/AuctionHousePackets.h b/src/server/game/Server/Packets/AuctionHousePackets.h
index bf392246a20..4204c5c6afc 100644
--- a/src/server/game/Server/Packets/AuctionHousePackets.h
+++ b/src/server/game/Server/Packets/AuctionHousePackets.h
@@ -20,13 +20,11 @@
#include "Packet.h"
#include "ObjectGuid.h"
-class ObjectGuid;
-
struct AuctionEntry;
namespace WorldPackets
{
- namespace AuctionHousePackets
+ namespace AuctionHouse
{
class AuctionCommandResult final : public ServerPacket
{
@@ -54,4 +52,5 @@ namespace WorldPackets
};
}
}
-#endif
+
+#endif // AuctionHousePackets_h__
diff --git a/src/server/game/Server/Packets/AuthenticationPackets.cpp b/src/server/game/Server/Packets/AuthenticationPackets.cpp
index a57f5f60244..95f2379e82f 100644
--- a/src/server/game/Server/Packets/AuthenticationPackets.cpp
+++ b/src/server/game/Server/Packets/AuthenticationPackets.cpp
@@ -585,3 +585,10 @@ WorldPacket const* WorldPackets::Auth::ConnectTo::Write()
_worldPacket << uint8(Con);
return &_worldPacket;
}
+
+void WorldPackets::Auth::AuthContinuedSession::Read()
+{
+ _worldPacket >> DosResponse;
+ _worldPacket >> Key;
+ _worldPacket.read(Digest, SHA_DIGEST_LENGTH);
+}
diff --git a/src/server/game/Server/Packets/AuthenticationPackets.h b/src/server/game/Server/Packets/AuthenticationPackets.h
index 1d194b0b2a9..70aa38cac8e 100644
--- a/src/server/game/Server/Packets/AuthenticationPackets.h
+++ b/src/server/game/Server/Packets/AuthenticationPackets.h
@@ -168,6 +168,29 @@ namespace WorldPackets
BigNumber dmq1;
BigNumber iqmp;
};
+
+ class AuthContinuedSession final : public ClientPacket
+ {
+ public:
+ AuthContinuedSession(WorldPacket&& packet) : ClientPacket(std::move(packet))
+ {
+ memset(Digest, 0, SHA_DIGEST_LENGTH);
+ }
+
+ void Read() override;
+
+ uint64 DosResponse = 0;
+ uint64 Key = 0;
+ uint8 Digest[SHA_DIGEST_LENGTH];
+ };
+
+ class ResumeComms final : public ServerPacket
+ {
+ public:
+ ResumeComms() : ServerPacket(SMSG_RESUME_COMMS, 0) { }
+
+ WorldPacket const* Write() override { return &_worldPacket; }
+ };
}
}
diff --git a/src/server/game/Server/Packets/BattlegroundPackets.cpp b/src/server/game/Server/Packets/BattlegroundPackets.cpp
new file mode 100644
index 00000000000..8a1bec1173b
--- /dev/null
+++ b/src/server/game/Server/Packets/BattlegroundPackets.cpp
@@ -0,0 +1,26 @@
+/*
+ * 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 "BattlegroundPackets.h"
+
+WorldPacket const* WorldPackets::Battleground::PVPSeason::Write()
+{
+ _worldPacket << uint32(CurrentSeason);
+ _worldPacket << uint32(PreviousSeason);
+
+ return &_worldPacket;
+}
diff --git a/src/server/game/Server/Packets/BattlegroundPackets.h b/src/server/game/Server/Packets/BattlegroundPackets.h
new file mode 100644
index 00000000000..77dc8238438
--- /dev/null
+++ b/src/server/game/Server/Packets/BattlegroundPackets.h
@@ -0,0 +1,40 @@
+/*
+ * 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 BattlegroundPackets_h__
+#define BattlegroundPackets_h__
+
+#include "Packet.h"
+
+namespace WorldPackets
+{
+ namespace Battleground
+ {
+ class PVPSeason final : public ServerPacket
+ {
+ public:
+ PVPSeason() : ServerPacket(SMSG_PVP_SEASON, 8) { }
+
+ WorldPacket const* Write() override;
+
+ uint32 PreviousSeason = 0;
+ uint32 CurrentSeason = 0;
+ };
+ }
+}
+
+#endif // BattlegroundPackets_h__
diff --git a/src/server/game/Server/Packets/GuildPackets.cpp b/src/server/game/Server/Packets/GuildPackets.cpp
index ee864b256bb..b94fb7839bf 100644
--- a/src/server/game/Server/Packets/GuildPackets.cpp
+++ b/src/server/game/Server/Packets/GuildPackets.cpp
@@ -16,7 +16,6 @@
*/
#include "GuildPackets.h"
-#include "ObjectGuid.h"
WorldPackets::Guild::QueryGuildInfo::QueryGuildInfo(WorldPacket&& packet)
: ClientPacket(std::move(packet))
diff --git a/src/server/game/Server/Packets/GuildPackets.h b/src/server/game/Server/Packets/GuildPackets.h
index 17159a017e0..479ceba6280 100644
--- a/src/server/game/Server/Packets/GuildPackets.h
+++ b/src/server/game/Server/Packets/GuildPackets.h
@@ -19,8 +19,7 @@
#define GuildPackets_h__
#include "Packet.h"
-
-class ObjectGuid;
+#include "ObjectGuid.h"
namespace WorldPackets
{
diff --git a/src/server/game/Server/Packets/WorldStatePackets.cpp b/src/server/game/Server/Packets/WorldStatePackets.cpp
new file mode 100644
index 00000000000..7d062841003
--- /dev/null
+++ b/src/server/game/Server/Packets/WorldStatePackets.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 "WorldStatePackets.h"
+
+WorldPackets::WorldState::InitWorldStates::InitWorldStates()
+ : ServerPacket(SMSG_INIT_WORLD_STATES, 16) { }
+
+WorldPacket const* WorldPackets::WorldState::InitWorldStates::Write()
+{
+ _worldPacket.reserve(16 + Worldstates.size() * 8);
+
+ _worldPacket << uint32(AreaID);
+ _worldPacket << uint32(SubareaID);
+ _worldPacket << uint32(MapID);
+
+ _worldPacket << uint32(Worldstates.size());
+ for (WorldStateInfo const& wsi : Worldstates)
+ {
+ _worldPacket << uint32(wsi.VariableID);
+ _worldPacket << uint32(wsi.Value);
+ }
+
+ return &_worldPacket;
+}
+
+WorldPackets::WorldState::UpdateWorldState::UpdateWorldState()
+ : ServerPacket(SMSG_UPDATE_WORLD_STATE, 9) { }
+
+WorldPacket const* WorldPackets::WorldState::UpdateWorldState::Write()
+{
+ _worldPacket << uint32(VariableID);
+ _worldPacket << int32(Value);
+ _worldPacket.WriteBit(Hidden);
+ _worldPacket.FlushBits();
+
+ return &_worldPacket;
+}
diff --git a/src/server/game/Server/Packets/WorldStatePackets.h b/src/server/game/Server/Packets/WorldStatePackets.h
new file mode 100644
index 00000000000..7f9cdfe80de
--- /dev/null
+++ b/src/server/game/Server/Packets/WorldStatePackets.h
@@ -0,0 +1,64 @@
+/*
+ * 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 WorldStatePackets_h__
+#define WorldStatePackets_h__
+
+#include "Packet.h"
+
+namespace WorldPackets
+{
+ namespace WorldState
+ {
+ class InitWorldStates final : public ServerPacket
+ {
+ public:
+ struct WorldStateInfo
+ {
+ WorldStateInfo(uint32 variableID, int32 value)
+ : VariableID(variableID), Value(value) { }
+
+ uint32 VariableID;
+ int32 Value;
+ };
+
+ InitWorldStates();
+
+ WorldPacket const* Write() override;
+
+ uint32 AreaID = 0; ///< ZoneId
+ uint32 SubareaID = 0; ///< AreaId
+ uint32 MapID = 0; ///< MapId
+
+ std::list<WorldStateInfo> Worldstates;
+ };
+
+ class UpdateWorldState final : public ServerPacket
+ {
+ public:
+ UpdateWorldState();
+
+ WorldPacket const* Write() override;
+
+ int32 Value = 0;
+ bool Hidden = false; ///< @todo: research
+ uint32 VariableID = 0;
+ };
+ }
+}
+
+#endif // WorldStatePackets_h__
diff --git a/src/server/game/Server/Protocol/Opcodes.cpp b/src/server/game/Server/Protocol/Opcodes.cpp
index b22dc575c0c..97fc18a1c2f 100644
--- a/src/server/game/Server/Protocol/Opcodes.cpp
+++ b/src/server/game/Server/Protocol/Opcodes.cpp
@@ -130,6 +130,7 @@ void OpcodeTable::Initialize()
DEFINE_OPCODE_HANDLER_OLD(CMSG_ARENA_TEAM_ROSTER, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleArenaTeamRosterOpcode );
DEFINE_OPCODE_HANDLER_OLD(CMSG_ATTACKSTOP, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::HandleAttackStopOpcode );
DEFINE_OPCODE_HANDLER_OLD(CMSG_ATTACKSWING, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::HandleAttackSwingOpcode );
+ DEFINE_OPCODE_HANDLER_OLD(CMSG_AUCTION_HELLO, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleAuctionHelloOpcode );
DEFINE_OPCODE_HANDLER_OLD(CMSG_AUCTION_LIST_BIDDER_ITEMS, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleAuctionListBidderItems );
DEFINE_OPCODE_HANDLER_OLD(CMSG_AUCTION_LIST_ITEMS, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleAuctionListItems );
DEFINE_OPCODE_HANDLER_OLD(CMSG_AUCTION_LIST_OWNER_ITEMS, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleAuctionListOwnerItems );
@@ -137,6 +138,7 @@ void OpcodeTable::Initialize()
DEFINE_OPCODE_HANDLER_OLD(CMSG_AUCTION_PLACE_BID, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleAuctionPlaceBid );
DEFINE_OPCODE_HANDLER_OLD(CMSG_AUCTION_REMOVE_ITEM, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleAuctionRemoveItem );
DEFINE_OPCODE_HANDLER_OLD(CMSG_AUCTION_SELL_ITEM, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleAuctionSellItem );
+ DEFINE_OPCODE_HANDLER_OLD(CMSG_AUTH_CONTINUED_SESSION, STATUS_NEVER, PROCESS_THREADUNSAFE, &WorldSession::Handle_EarlyProccess );
DEFINE_OPCODE_HANDLER_OLD(CMSG_AUTH_SESSION, STATUS_NEVER, PROCESS_THREADUNSAFE, &WorldSession::Handle_EarlyProccess );
DEFINE_OPCODE_HANDLER_OLD(CMSG_AUTOBANK_ITEM, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleAutoBankItemOpcode );
DEFINE_OPCODE_HANDLER_OLD(CMSG_AUTOEQUIP_ITEM, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleAutoEquipItemOpcode );
@@ -160,6 +162,8 @@ void OpcodeTable::Initialize()
DEFINE_OPCODE_HANDLER_OLD(CMSG_BATTLEMASTER_JOIN_ARENA, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleBattlemasterJoinArena );
DEFINE_OPCODE_HANDLER_OLD(CMSG_BATTLEMASTER_JOIN_RATED, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
DEFINE_OPCODE_HANDLER_OLD(CMSG_BATTLE_PAY_GET_PRODUCT_LIST_QUERY, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ DEFINE_OPCODE_HANDLER_OLD(CMSG_BATTLE_PAY_GET_PURCHASE_LIST_QUERY, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ DEFINE_OPCODE_HANDLER_OLD(CMSG_BATTLE_PET_NAME_QUERY, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
DEFINE_OPCODE_HANDLER_OLD(CMSG_BEGIN_TRADE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleBeginTradeOpcode );
DEFINE_OPCODE_HANDLER_OLD(CMSG_BINDER_ACTIVATE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleBinderActivateOpcode );
DEFINE_OPCODE_HANDLER_OLD(CMSG_BUG, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleBugOpcode );
@@ -497,13 +501,13 @@ void OpcodeTable::Initialize()
DEFINE_OPCODE_HANDLER_OLD(CMSG_QUEST_NPC_QUERY, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestNPCQuery );
DEFINE_OPCODE_HANDLER_OLD(CMSG_QUEST_POI_QUERY, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestPOIQuery );
DEFINE_OPCODE_HANDLER_OLD(CMSG_QUEST_QUERY, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestQueryOpcode );
+ DEFINE_OPCODE_HANDLER_OLD(CMSG_QUEUED_MESSAGES_END, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
DEFINE_HANDLER(CMSG_RANDOMIZE_CHAR_NAME, STATUS_AUTHED, PROCESS_THREADUNSAFE, WorldPackets::Character::GenerateRandomCharacterName, &WorldSession::HandleRandomizeCharNameOpcode);
DEFINE_OPCODE_HANDLER_OLD(CMSG_READ_ITEM, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleReadItem );
DEFINE_OPCODE_HANDLER_OLD(CMSG_REALM_SPLIT, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleRealmSplitOpcode );
DEFINE_OPCODE_HANDLER_OLD(CMSG_RECLAIM_CORPSE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleReclaimCorpseOpcode );
- DEFINE_OPCODE_HANDLER_OLD(CMSG_REDIRECTION_AUTH_PROOF, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
DEFINE_OPCODE_HANDLER_OLD(CMSG_REFORGE_ITEM, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::HandleReforgeItemOpcode );
- DEFINE_HANDLER(CMSG_REORDER_CHARACTERS, STATUS_AUTHED, PROCESS_INPLACE, WorldPackets::Character::ReorderCharacters, &WorldSession::HandleReorderCharacters);
+ DEFINE_HANDLER(CMSG_REORDER_CHARACTERS, STATUS_AUTHED, PROCESS_THREADUNSAFE, WorldPackets::Character::ReorderCharacters, &WorldSession::HandleReorderCharacters);
DEFINE_OPCODE_HANDLER_OLD(CMSG_REPAIR_ITEM, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleRepairItemOpcode );
DEFINE_OPCODE_HANDLER_OLD(CMSG_REPOP_REQUEST, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleRepopRequestOpcode );
DEFINE_OPCODE_HANDLER_OLD(CMSG_REPORT_PVP_AFK, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleReportPvPAFK );
@@ -549,6 +553,7 @@ void OpcodeTable::Initialize()
DEFINE_OPCODE_HANDLER_OLD(CMSG_SET_FACTION_ATWAR, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleSetFactionAtWar );
DEFINE_OPCODE_HANDLER_OLD(CMSG_SET_FACTION_INACTIVE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleSetFactionInactiveOpcode );
DEFINE_OPCODE_HANDLER_OLD(CMSG_SET_GUILD_BANK_TEXT, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleSetGuildBankTabText );
+ DEFINE_OPCODE_HANDLER_OLD(CMSG_SET_LOOT_SPECIALIZATION, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
DEFINE_OPCODE_HANDLER_OLD(CMSG_SET_PET_SLOT, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
DEFINE_OPCODE_HANDLER_OLD(CMSG_SET_PLAYER_DECLINED_NAMES, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleSetPlayerDeclinedNames );
DEFINE_OPCODE_HANDLER_OLD(CMSG_SET_PREFERED_CEMETERY, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
@@ -576,7 +581,8 @@ void OpcodeTable::Initialize()
DEFINE_OPCODE_HANDLER_OLD(CMSG_SUBMIT_COMPLAIN, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
DEFINE_OPCODE_HANDLER_OLD(CMSG_SUGGESTION_SUBMIT, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
DEFINE_OPCODE_HANDLER_OLD(CMSG_SUMMON_RESPONSE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleSummonResponseOpcode );
- DEFINE_OPCODE_HANDLER_OLD(CMSG_SUSPEND_TOKEN, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ DEFINE_OPCODE_HANDLER_OLD(CMSG_SUSPEND_COMMS_ACK, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ DEFINE_OPCODE_HANDLER_OLD(CMSG_SUSPEND_TOKEN_RESPONSE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
DEFINE_OPCODE_HANDLER_OLD(CMSG_SWAP_INV_ITEM, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleSwapInvItemOpcode );
DEFINE_OPCODE_HANDLER_OLD(CMSG_SWAP_ITEM, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleSwapItem );
DEFINE_OPCODE_HANDLER_OLD(CMSG_SYNC_DANCE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
@@ -622,9 +628,6 @@ void OpcodeTable::Initialize()
DEFINE_OPCODE_HANDLER_OLD(CMSG_WORLD_TELEPORT, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleWorldTeleportOpcode );
DEFINE_OPCODE_HANDLER_OLD(CMSG_WRAP_ITEM, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleWrapItemOpcode );
DEFINE_OPCODE_HANDLER_OLD(CMSG_ZONEUPDATE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleZoneUpdateOpcode );
- DEFINE_OPCODE_HANDLER_OLD(MSG_AUCTION_HELLO, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleAuctionHelloOpcode );
- DEFINE_OPCODE_HANDLER_OLD(MSG_CHANNEL_START, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
- DEFINE_OPCODE_HANDLER_OLD(MSG_CHANNEL_UPDATE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
DEFINE_OPCODE_HANDLER_OLD(MSG_CORPSE_QUERY, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleCorpseQueryOpcode );
DEFINE_OPCODE_HANDLER_OLD(MSG_INSPECT_ARENA_TEAMS, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleInspectArenaTeamsOpcode );
DEFINE_OPCODE_HANDLER_OLD(MSG_LIST_STABLED_PETS, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleListStabledPetsOpcode );
@@ -679,6 +682,7 @@ void OpcodeTable::Initialize()
DEFINE_SERVER_OPCODE_HANDLER(SMSG_ACCOUNT_DATA_TIMES, STATUS_NEVER);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_ACCOUNT_INFO_RESPONSE, STATUS_UNHANDLED);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_ACCOUNT_MOUNT_UPDATE, STATUS_UNHANDLED);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_ACCOUNT_RESTRICTED_WARNING, STATUS_UNHANDLED);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_ACHIEVEMENT_DELETED, STATUS_UNHANDLED);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_ACHIEVEMENT_EARNED, STATUS_UNHANDLED);
@@ -692,7 +696,6 @@ void OpcodeTable::Initialize()
DEFINE_SERVER_OPCODE_HANDLER(SMSG_AREA_TRIGGER_MESSAGE, STATUS_UNHANDLED);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_AREA_TRIGGER_MOVEMENT_UPDATE, STATUS_UNHANDLED);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_ARENA_ERROR, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_ARENA_SEASON_WORLD_STATE, STATUS_UNHANDLED);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_ARENA_UNIT_DESTROYED, STATUS_UNHANDLED);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_ARENA_TEAM_CHANGE_FAILED_QUEUED, STATUS_UNHANDLED);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_ARENA_TEAM_COMMAND_RESULT, STATUS_UNHANDLED);
@@ -711,6 +714,7 @@ void OpcodeTable::Initialize()
DEFINE_SERVER_OPCODE_HANDLER(SMSG_AUCTION_BIDDER_LIST_RESULT, STATUS_UNHANDLED);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_AUCTION_BIDDER_NOTIFICATION, STATUS_UNHANDLED);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_AUCTION_COMMAND_RESULT, STATUS_UNHANDLED);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_AUCTION_HELLO, STATUS_UNHANDLED);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_AUCTION_LIST_PENDING_SALES, STATUS_UNHANDLED);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_AUCTION_LIST_RESULT, STATUS_UNHANDLED);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_AUCTION_OWNER_LIST_RESULT, STATUS_UNHANDLED);
@@ -745,8 +749,12 @@ void OpcodeTable::Initialize()
DEFINE_SERVER_OPCODE_HANDLER(SMSG_BATTLEGROUND_INFO_THROTTLED, STATUS_UNHANDLED);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_BATTLEGROUND_PLAYER_JOINED, STATUS_UNHANDLED);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_BATTLEGROUND_PLAYER_LEFT, STATUS_UNHANDLED);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_BATTLE_PAY_GET_DISTRIBUTION_LIST_RESPONSE, STATUS_UNHANDLED);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_BATTLE_PAY_GET_PRODUCT_LIST_RESPONSE, STATUS_UNHANDLED);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_BATTLE_PAY_GET_PURCHASE_LIST_RESPONSE, STATUS_UNHANDLED);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_BATTLE_PET_JOURNAL, STATUS_UNHANDLED);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_BATTLE_PET_JOURNAL_LOCK_ACQUIRED, STATUS_UNHANDLED);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_BATTLE_PET_NAME_QUERY_RESPONSE, STATUS_UNHANDLED);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_BINDER_CONFIRM, STATUS_UNHANDLED);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_BINDPOINTUPDATE, STATUS_UNHANDLED);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_BINDZONEREPLY, STATUS_UNHANDLED);
@@ -782,6 +790,8 @@ void OpcodeTable::Initialize()
DEFINE_SERVER_OPCODE_HANDLER(SMSG_CHANNEL_LIST, STATUS_UNHANDLED);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_CHANNEL_MEMBER_COUNT, STATUS_UNHANDLED);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_CHANNEL_NOTIFY, STATUS_UNHANDLED);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_CHANNEL_START, STATUS_UNHANDLED);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_CHANNEL_UPDATE, STATUS_UNHANDLED);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_CHARACTER_LOGIN_FAILED, STATUS_UNHANDLED);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_CHAR_CREATE, STATUS_NEVER);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_CHAR_CUSTOMIZE, STATUS_UNHANDLED);
@@ -834,6 +844,7 @@ void OpcodeTable::Initialize()
DEFINE_SERVER_OPCODE_HANDLER(SMSG_CUSTOM_LOAD_SCREEN, STATUS_UNHANDLED);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_DAMAGE_CALC_LOG, STATUS_UNHANDLED);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_DANCE_QUERY_RESPONSE, STATUS_UNHANDLED);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_DANCE_STUDIO_CREATE_RESULT, STATUS_UNHANDLED);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_DB_REPLY, STATUS_UNHANDLED);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_DEATH_RELEASE_LOC, STATUS_UNHANDLED);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_DEBUG_RUNE_REGEN, STATUS_UNHANDLED);
@@ -877,7 +888,6 @@ void OpcodeTable::Initialize()
DEFINE_SERVER_OPCODE_HANDLER(SMSG_FORCEACTIONSHOW, STATUS_UNHANDLED);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_FORCED_DEATH_UPDATE, STATUS_UNHANDLED);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_FORCE_ANIM, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_FORCE_SEND_QUEUED_PACKETS, STATUS_UNHANDLED);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_FORCE_SET_VEHICLE_REC_ID, STATUS_UNHANDLED);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_FORGE_MASTER_SET, STATUS_UNHANDLED);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_FRIEND_STATUS, STATUS_UNHANDLED);
@@ -1166,6 +1176,7 @@ void OpcodeTable::Initialize()
DEFINE_SERVER_OPCODE_HANDLER(SMSG_PVP_CREDIT, STATUS_UNHANDLED);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_PVP_LOG_DATA, STATUS_UNHANDLED);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_PVP_OPTIONS_ENABLED, STATUS_UNHANDLED);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_PVP_SEASON, STATUS_NEVER);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUERY_QUESTS_COMPLETED_RESPONSE, STATUS_UNHANDLED);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUERY_TIME_RESPONSE, STATUS_UNHANDLED);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUESTGIVER_OFFER_REWARD, STATUS_UNHANDLED);
@@ -1202,7 +1213,7 @@ void OpcodeTable::Initialize()
DEFINE_SERVER_OPCODE_HANDLER(SMSG_REALM_SPLIT, STATUS_UNHANDLED);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_REAL_GROUP_UPDATE, STATUS_UNHANDLED);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_RECEIVED_MAIL, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_REDIRECT_CLIENT, STATUS_UNHANDLED);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_REDIRECT_CLIENT, STATUS_NEVER);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_REFER_A_FRIEND_EXPIRED, STATUS_UNHANDLED);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_REFER_A_FRIEND_FAILURE, STATUS_UNHANDLED);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_REFORGE_RESULT, STATUS_UNHANDLED);
@@ -1215,6 +1226,7 @@ void OpcodeTable::Initialize()
DEFINE_SERVER_OPCODE_HANDLER(SMSG_RESET_COMPRESSION_CONTEXT, STATUS_UNHANDLED);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_RESET_FAILED_NOTIFY, STATUS_UNHANDLED);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_RESPOND_INSPECT_ACHIEVEMENTS, STATUS_UNHANDLED);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_RESUME_COMMS, STATUS_NEVER);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_RESURRECT_FAILED, STATUS_UNHANDLED);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_RESURRECT_REQUEST, STATUS_UNHANDLED);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_RESYNC_RUNES, STATUS_UNHANDLED);
@@ -1312,7 +1324,7 @@ void OpcodeTable::Initialize()
DEFINE_SERVER_OPCODE_HANDLER(SMSG_SUPERCEDED_SPELL, STATUS_UNHANDLED);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_SUPPRESS_NPC_GREETINGS, STATUS_UNHANDLED);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_SUSPEND_COMMS, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_SUSPEND_TOKEN_RESPONSE, STATUS_UNHANDLED);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_SUSPEND_TOKEN, STATUS_UNHANDLED);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_TALENTS_ERROR, STATUS_UNHANDLED);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_TALENTS_INFO, STATUS_UNHANDLED);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_TALENTS_INVOLUNTARILY_RESET, STATUS_UNHANDLED);
@@ -1353,7 +1365,7 @@ void OpcodeTable::Initialize()
DEFINE_SERVER_OPCODE_HANDLER(SMSG_UPDATE_LAST_INSTANCE, STATUS_UNHANDLED);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_UPDATE_OBJECT, STATUS_NEVER);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_UPDATE_SERVER_PLAYER_POSITION, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_UPDATE_WORLD_STATE, STATUS_UNHANDLED);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_UPDATE_WORLD_STATE, STATUS_NEVER);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_USERLIST_ADD, STATUS_UNHANDLED);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_USERLIST_REMOVE, STATUS_UNHANDLED);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_USERLIST_UPDATE, STATUS_UNHANDLED);
diff --git a/src/server/game/Server/Protocol/Opcodes.h b/src/server/game/Server/Protocol/Opcodes.h
index d8ac4b68d9e..879554e8bd6 100644
--- a/src/server/game/Server/Protocol/Opcodes.h
+++ b/src/server/game/Server/Protocol/Opcodes.h
@@ -26,6 +26,12 @@
#include "Common.h"
#include <iomanip>
+enum ConnectionType
+{
+ CONNECTION_TYPE_REALM = 0,
+ CONNECTION_TYPE_INSTANCE = 1
+};
+
enum OpcodeMisc : uint32
{
MAX_OPCODE = 0x1FFF,
@@ -70,6 +76,7 @@ enum OpcodeClient : uint32
CMSG_AUCTION_PLACE_BID = 0xBADD,
CMSG_AUCTION_REMOVE_ITEM = 0xBADD,
CMSG_AUCTION_SELL_ITEM = 0xBADD,
+ CMSG_AUTH_CONTINUED_SESSION = 0x0485,
CMSG_AUTH_SESSION = 0x0487,
CMSG_AUTOBANK_ITEM = 0xBADD,
CMSG_AUTOEQUIP_GROUND_ITEM = 0xBADD,
@@ -98,6 +105,8 @@ enum OpcodeClient : uint32
CMSG_BATTLEMASTER_JOIN_RATED = 0xBADD,
CMSG_BATTLEMASTER_HELLO = 0xBADD,
CMSG_BATTLE_PAY_GET_PRODUCT_LIST_QUERY = 0x1389,
+ CMSG_BATTLE_PAY_GET_PURCHASE_LIST_QUERY = 0x120C,
+ CMSG_BATTLE_PET_NAME_QUERY = 0x041C,
CMSG_BEGIN_TRADE = 0xBADD,
CMSG_BINDER_ACTIVATE = 0xBADD,
CMSG_BOT_DETECTED2 = 0xBADD,
@@ -123,7 +132,7 @@ enum OpcodeClient : uint32
CMSG_CALENDAR_GUILD_FILTER = 0xBADD,
CMSG_CALENDAR_REMOVE_EVENT = 0xBADD,
CMSG_CALENDAR_UPDATE_EVENT = 0xBADD,
- CMSG_CANCEL_AURA = 0xBADD,
+ CMSG_CANCEL_AURA = 0x08AE,
CMSG_CANCEL_AUTO_REPEAT_SPELL = 0xBADD,
CMSG_CANCEL_CAST = 0xBADD,
CMSG_CANCEL_CHANNELLING = 0xBADD,
@@ -207,7 +216,7 @@ enum OpcodeClient : uint32
CMSG_EQUIPMENT_SET_USE = 0xBADD,
CMSG_FACTION_BONUS_INFO = 0x0928,
CMSG_FAR_SIGHT = 0xBADD,
- CMSG_FORCE_MOVE_ROOT_ACK = 0xBADD,
+ CMSG_FORCE_MOVE_ROOT_ACK = 0x0B73,
CMSG_FORCE_MOVE_UNROOT_ACK = 0xBADD,
CMSG_GAMEOBJECT_QUERY = 0x03AE,
CMSG_GAMEOBJ_REPORT_USE = 0x082E,
@@ -378,7 +387,7 @@ enum OpcodeClient : uint32
CMSG_MOVE_FORCE_SWIM_SPEED_CHANGE_ACK = 0xBADD,
CMSG_MOVE_FORCE_TURN_RATE_CHANGE_ACK = 0xBADD,
CMSG_MOVE_FORCE_WALK_SPEED_CHANGE_ACK = 0xBADD,
- CMSG_MOVE_GRAVITY_DISABLE_ACK = 0xBADD,
+ CMSG_MOVE_GRAVITY_DISABLE_ACK = 0x0553,
CMSG_MOVE_GRAVITY_ENABLE_ACK = 0xBADD,
CMSG_MOVE_HEARTBEAT = 0x19C1,
CMSG_MOVE_HOVER_ACK = 0xBADD,
@@ -389,7 +398,7 @@ enum OpcodeClient : uint32
CMSG_MOVE_SET_CAN_FLY = 0xBADD,
CMSG_MOVE_SET_CAN_FLY_ACK = 0xBADD,
CMSG_MOVE_SET_CAN_TRANSITION_BETWEEN_SWIM_AND_FLY_ACK = 0xBADD,
- CMSG_MOVE_SET_COLLISION_HEIGHT_ACK = 0xBADD,
+ CMSG_MOVE_SET_COLLISION_HEIGHT_ACK = 0x0141,
CMSG_MOVE_SET_RELATIVE_POSITION = 0xBADD,
CMSG_MOVE_SET_VEHICLE_REC_ID_ACK = 0xBADD,
CMSG_MOVE_SPLINE_DONE = 0xBADD,
@@ -462,11 +471,11 @@ enum OpcodeClient : uint32
CMSG_QUEST_NPC_QUERY = 0x0B81,
CMSG_QUEST_POI_QUERY = 0x0BD9,
CMSG_QUEST_QUERY = 0x09A6,
+ CMSG_QUEUED_MESSAGES_END = 0x04DF,
CMSG_RANDOMIZE_CHAR_NAME = 0x1981,
CMSG_READ_ITEM = 0xBADD,
CMSG_REALM_SPLIT = 0xBADD,
CMSG_RECLAIM_CORPSE = 0xBADD,
- CMSG_REDIRECTION_AUTH_PROOF = 0x0485,
CMSG_REFORGE_ITEM = 0xBADD,
CMSG_REORDER_CHARACTERS = 0x0DAA,
CMSG_REPAIR_ITEM = 0xBADD,
@@ -490,7 +499,7 @@ enum OpcodeClient : uint32
CMSG_REQUEST_VEHICLE_NEXT_SEAT = 0xBADD,
CMSG_REQUEST_VEHICLE_PREV_SEAT = 0xBADD,
CMSG_REQUEST_VEHICLE_SWITCH_SEAT = 0xBADD,
- CMSG_RESET_FACTION_CHEAT = 0x0C56,
+ CMSG_RESET_FACTION_CHEAT = 0xBADD,
CMSG_RESET_INSTANCES = 0xBADD,
CMSG_RESURRECT_RESPONSE = 0xBADD,
CMSG_RETURN_TO_GRAVEYARD = 0xBADD,
@@ -522,10 +531,11 @@ enum OpcodeClient : uint32
CMSG_SET_FACTION_INACTIVE = 0xBADD,
CMSG_SET_GUILD_BANK_TEXT = 0xBADD,
CMSG_SET_LFG_COMMENT = 0xBADD,
+ CMSG_SET_LOOT_SPECIALIZATION = 0x0226,
CMSG_SET_PET_SLOT = 0xBADD,
CMSG_SET_PLAYER_DECLINED_NAMES = 0xBADD,
CMSG_SET_PREFERED_CEMETERY = 0xBADD,
- CMSG_SET_RAID_DIFFICULTY = 0x04DF,
+ CMSG_SET_RAID_DIFFICULTY = 0xBADD,
CMSG_SET_RELATIVE_POSITION = 0xBADD,
CMSG_SET_SAVED_INSTANCE_EXTEND = 0xBADD,
CMSG_SET_SELECTION = 0x05BD,
@@ -541,7 +551,7 @@ enum OpcodeClient : uint32
CMSG_SHOWING_CLOAK = 0x0132,
CMSG_SHOWING_HELM = 0x11E1,
CMSG_SOCKET_GEMS = 0xBADD,
- CMSG_SPELLCLICK = 0xBADD,
+ CMSG_SPELLCLICK = 0x0BC2,
CMSG_SPIRIT_HEALER_ACTIVATE = 0xBADD,
CMSG_SPLIT_ITEM = 0xBADD,
CMSG_STANDSTATECHANGE = 0xBADD,
@@ -552,7 +562,8 @@ enum OpcodeClient : uint32
CMSG_SUBMIT_COMPLAIN = 0xBADD,
CMSG_SUGGESTION_SUBMIT = 0xBADD,
CMSG_SUMMON_RESPONSE = 0xBADD,
- CMSG_SUSPEND_TOKEN = 0x0142,
+ CMSG_SUSPEND_COMMS_ACK = 0x0C56,
+ CMSG_SUSPEND_TOKEN_RESPONSE = 0x0142,
CMSG_SWAP_INV_ITEM = 0xBADD,
CMSG_SWAP_ITEM = 0xBADD,
CMSG_SYNC_DANCE = 0xBADD,
@@ -570,7 +581,7 @@ enum OpcodeClient : uint32
CMSG_TOTEM_DESTROYED = 0xBADD,
CMSG_TRAINER_BUY_SPELL = 0xBADD,
CMSG_TRAINER_LIST = 0xBADD,
- CMSG_TRANSMOGRIFY_ITEMS = 0xBADD,
+ CMSG_TRANSMOGRIFY_ITEMS = 0x0A85,
CMSG_TRIGGER_CINEMATIC_CHEAT = 0xBADD,
CMSG_TURN_IN_PETITION = 0xBADD,
CMSG_TUTORIAL_CLEAR = 0xBADD,
@@ -590,9 +601,9 @@ enum OpcodeClient : uint32
CMSG_VIOLENCE_LEVEL = 0x098D,
CMSG_VOICE_SESSION_ENABLE = 0xBADD,
CMSG_VOID_STORAGE_QUERY = 0x019E,
- CMSG_VOID_STORAGE_TRANSFER = 0xBADD,
+ CMSG_VOID_STORAGE_TRANSFER = 0x0463,
CMSG_VOID_STORAGE_UNLOCK = 0xBADD,
- CMSG_VOID_SWAP_ITEM = 0xBADD,
+ CMSG_VOID_SWAP_ITEM = 0x0619,
CMSG_WARDEN_DATA = 0x0BA1,
CMSG_WARGAME_ACCEPT = 0xBADD,
CMSG_WARGAME_START = 0xBADD,
@@ -602,9 +613,6 @@ enum OpcodeClient : uint32
CMSG_WORLD_TELEPORT = 0xBADD,
CMSG_WRAP_ITEM = 0xBADD,
CMSG_ZONEUPDATE = 0xBADD,
- MSG_AUCTION_HELLO = 0xBADD,
- MSG_CHANNEL_START = 0xBADD, // SMSG only?
- MSG_CHANNEL_UPDATE = 0xBADD, // SMSG only?
MSG_CORPSE_QUERY = 0xBADD,
MSG_GM_BIND_OTHER = 0xBADD,
MSG_GM_SHOWLABEL = 0xBADD,
@@ -674,6 +682,7 @@ enum OpcodeServer : uint32
{
SMSG_ACCOUNT_DATA_TIMES = 0x0120,
SMSG_ACCOUNT_INFO_RESPONSE = 0xBADD,
+ SMSG_ACCOUNT_MOUNT_UPDATE = 0x0140,
SMSG_ACCOUNT_RESTRICTED_WARNING = 0xBADD,
SMSG_ACHIEVEMENT_DELETED = 0xBADD,
SMSG_ACHIEVEMENT_EARNED = 0xBADD,
@@ -681,7 +690,7 @@ enum OpcodeServer : uint32
SMSG_ACTIVATETAXIREPLY = 0xBADD,
SMSG_ADDON_INFO = 0x1D9F,
SMSG_ADD_RUNE_POWER = 0xBADD,
- SMSG_AI_REACTION = 0xBADD,
+ SMSG_AI_REACTION = 0x0BA1,
SMSG_ALL_ACHIEVEMENT_DATA = 0xBADD,
SMSG_ALL_ACHIEVEMENT_DATA_ACCOUNT = 0x0123,
SMSG_ALL_ACHIEVEMENT_DATA_PLAYER = 0x0030,
@@ -689,7 +698,6 @@ enum OpcodeServer : uint32
SMSG_AREA_TRIGGER_MESSAGE = 0xBADD,
SMSG_AREA_TRIGGER_MOVEMENT_UPDATE = 0xBADD,
SMSG_ARENA_ERROR = 0xBADD,
- SMSG_ARENA_SEASON_WORLD_STATE = 0x09E3,
SMSG_ARENA_UNIT_DESTROYED = 0xBADD,
SMSG_ARENA_TEAM_CHANGE_FAILED_QUEUED = 0xBADD,
SMSG_ARENA_TEAM_COMMAND_RESULT = 0xBADD,
@@ -734,7 +742,7 @@ enum OpcodeServer : uint32
SMSG_BATTLEFIELD_MGR_STATE_CHANGE = 0xBADD,
SMSG_BATTLEFIELD_PLAYER_POSITIONS = 0xBADD,
SMSG_BATTLEFIELD_PORT_DENIED = 0xBADD,
- SMSG_BATTLEFIELD_RATED_INFO = 0xBADD,
+ SMSG_BATTLEFIELD_RATED_INFO = 0x1F0A,
SMSG_BATTLEFIELD_STATUS = 0xBADD,
SMSG_BATTLEFIELD_STATUS_QUEUED = 0xBADD,
SMSG_BATTLEFIELD_STATUS_ACTIVE = 0xBADD,
@@ -744,8 +752,12 @@ enum OpcodeServer : uint32
SMSG_BATTLEGROUND_INFO_THROTTLED = 0xBADD,
SMSG_BATTLEGROUND_PLAYER_JOINED = 0xBADD,
SMSG_BATTLEGROUND_PLAYER_LEFT = 0xBADD,
+ SMSG_BATTLE_PAY_GET_DISTRIBUTION_LIST_RESPONSE = 0x0F2A,
SMSG_BATTLE_PAY_GET_PRODUCT_LIST_RESPONSE = 0x12A4,
+ SMSG_BATTLE_PAY_GET_PURCHASE_LIST_RESPONSE = 0x168A,
SMSG_BATTLE_PET_JOURNAL = 0x19A2,
+ SMSG_BATTLE_PET_JOURNAL_LOCK_ACQUIRED = 0x01A3,
+ SMSG_BATTLE_PET_NAME_QUERY_RESPONSE = 0x09EC,
SMSG_BINDER_CONFIRM = 0xBADD,
SMSG_BINDPOINTUPDATE = 0x0A30,
SMSG_BINDZONEREPLY = 0xBADD,
@@ -784,6 +796,8 @@ enum OpcodeServer : uint32
SMSG_CHANNEL_MEMBER_COUNT = 0xBADD,
SMSG_CHANNEL_NOTIFY = 0x0643,
SMSG_CHANNEL_NOTIFY_JOINED = 0x1602,
+ SMSG_CHANNEL_START = 0x016C,
+ SMSG_CHANNEL_UPDATE = 0x19DB,
SMSG_CHARACTER_LOGIN_FAILED = 0xBADD,
SMSG_CHAR_CREATE = 0x0107,
SMSG_CHAR_CUSTOMIZE = 0xBADD,
@@ -842,6 +856,7 @@ enum OpcodeServer : uint32
SMSG_DAMAGE_CALC_LOG = 0xBADD,
SMSG_DAMAGE_DONE_OBSOLETE = 0xBADD,
SMSG_DANCE_QUERY_RESPONSE = 0xBADD,
+ SMSG_DANCE_STUDIO_CREATE_RESULT = 0x178D,
SMSG_DB_REPLY = 0x1939,
SMSG_DEATH_RELEASE_LOC = 0xBADD,
SMSG_DEBUG_RUNE_REGEN = 0xBADD,
@@ -887,7 +902,6 @@ enum OpcodeServer : uint32
SMSG_FORCED_DEATH_UPDATE = 0xBADD,
SMSG_FORCE_ANIM = 0xBADD,
SMSG_FORCE_DISPLAY_UPDATE = 0xBADD,
- SMSG_FORCE_SEND_QUEUED_PACKETS = 0xBADD,
SMSG_FORCE_SET_VEHICLE_REC_ID = 0xBADD,
SMSG_FORGE_MASTER_SET = 0xBADD,
SMSG_FRIEND_STATUS = 0xBADD,
@@ -931,7 +945,7 @@ enum OpcodeServer : uint32
SMSG_GUILD_ACHIEVEMENT_MEMBERS = 0xBADD,
SMSG_GUILD_BANK_LIST = 0xBADD,
SMSG_GUILD_BANK_LOG_QUERY_RESULT = 0xBADD,
- SMSG_GUILD_BANK_MONEY_WITHDRAWN = 0xBADD,
+ SMSG_GUILD_BANK_MONEY_WITHDRAWN = 0x1047,
SMSG_GUILD_BANK_QUERY_TEXT_RESULT = 0xBADD,
SMSG_GUILD_CANCEL = 0xBADD,
SMSG_GUILD_CHALLENGE_COMPLETED = 0xBADD,
@@ -960,7 +974,7 @@ enum OpcodeServer : uint32
SMSG_GUILD_NEWS_DELETED = 0xBADD,
SMSG_GUILD_NEWS_UPDATE = 0xBADD,
SMSG_GUILD_PARTY_STATE_RESPONSE = 0x1225,
- SMSG_GUILD_PERMISSIONS_QUERY_RESULTS = 0xBADD,
+ SMSG_GUILD_PERMISSIONS_QUERY_RESULTS = 0x1827,
SMSG_GUILD_QUERY_RESPONSE = 0x1046,
SMSG_GUILD_RANK = 0x1218,
SMSG_GUILD_RANKS_UPDATE = 0xBADD,
@@ -1086,16 +1100,16 @@ enum OpcodeServer : uint32
SMSG_MOVE_COLLISION_DISABLE = 0xBADD,
SMSG_MOVE_COLLISION_ENABLE = 0xBADD,
SMSG_MOVE_FEATHER_FALL = 0xBADD,
- SMSG_MOVE_GRAVITY_DISABLE = 0xBADD,
+ SMSG_MOVE_GRAVITY_DISABLE = 0x02C6,
SMSG_MOVE_GRAVITY_ENABLE = 0xBADD,
SMSG_MOVE_KNOCK_BACK = 0xBADD,
SMSG_MOVE_LAND_WALK = 0xBADD,
SMSG_MOVE_NORMAL_FALL = 0xBADD,
- SMSG_MOVE_ROOT = 0xBADD,
+ SMSG_MOVE_ROOT = 0x1B5A,
SMSG_MOVE_SET_ACTIVE_MOVER = 0xBADD,
SMSG_MOVE_SET_CAN_FLY = 0xBADD,
SMSG_MOVE_SET_CAN_TRANSITION_BETWEEN_SWIM_AND_FLY = 0xBADD,
- SMSG_MOVE_SET_COLLISION_HEIGHT = 0xBADD,
+ SMSG_MOVE_SET_COLLISION_HEIGHT = 0x008D,
SMSG_MOVE_SET_COMPOUND_STATE = 0xBADD,
SMSG_MOVE_SET_FLIGHT_BACK_SPEED = 0xBADD,
SMSG_MOVE_SET_FLIGHT_SPEED = 0xBADD,
@@ -1123,7 +1137,7 @@ enum OpcodeServer : uint32
SMSG_MOVE_UPDATE_RUN_SPEED = 0xBADD,
SMSG_MOVE_UPDATE_SWIM_BACK_SPEED = 0xBADD,
SMSG_MOVE_UPDATE_SWIM_SPEED = 0xBADD,
- SMSG_MOVE_UPDATE_TELEPORT = 0xBADD,
+ SMSG_MOVE_UPDATE_TELEPORT = 0x03D5,
SMSG_MOVE_UPDATE_TURN_RATE = 0xBADD,
SMSG_MOVE_UPDATE_WALK_SPEED = 0xBADD,
SMSG_MOVE_WATER_WALK = 0xBADD,
@@ -1139,7 +1153,7 @@ enum OpcodeServer : uint32
SMSG_NPC_TEXT_UPDATE = 0x1122,
SMSG_NPC_WONT_TALK = 0xBADD,
SMSG_OFFER_PETITION_ERROR = 0xBADD,
- SMSG_ON_CANCEL_EXPECTED_RIDE_VEHICLE_AURA = 0xBADD,
+ SMSG_ON_CANCEL_EXPECTED_RIDE_VEHICLE_AURA = 0x053F,
SMSG_OPEN_CONTAINER = 0xBADD,
SMSG_OPEN_LFG_DUNGEON_FINDER = 0xBADD,
SMSG_OVERRIDE_LIGHT = 0xBADD,
@@ -1184,7 +1198,7 @@ enum OpcodeServer : uint32
SMSG_PLAY_MUSIC = 0xBADD,
SMSG_PLAY_OBJECT_SOUND = 0xBADD,
SMSG_PLAY_ONE_SHOT_ANIM_KIT = 0xBADD,
- SMSG_PLAY_SOUND = 0xBADD,
+ SMSG_PLAY_SOUND = 0x02D2,
SMSG_PLAY_SPELL_VISUAL = 0xBADD,
SMSG_PLAY_SPELL_VISUAL_KIT = 0xBADD,
SMSG_PLAY_TIME_WARNING = 0xBADD,
@@ -1197,8 +1211,9 @@ enum OpcodeServer : uint32
SMSG_PVP_CREDIT = 0xBADD,
SMSG_PVP_LOG_DATA = 0xBADD,
SMSG_PVP_OPTIONS_ENABLED = 0xBADD,
+ SMSG_PVP_SEASON = 0x09E3,
SMSG_QUERY_QUESTS_COMPLETED_RESPONSE = 0xBADD,
- SMSG_QUERY_TIME_RESPONSE = 0xBADD,
+ SMSG_QUERY_TIME_RESPONSE = 0x1DB0,
SMSG_QUESTGIVER_OFFER_REWARD = 0xBADD,
SMSG_QUESTGIVER_QUEST_COMPLETE = 0xBADD,
SMSG_QUESTGIVER_QUEST_DETAILS = 0x15B3,
@@ -1248,6 +1263,7 @@ enum OpcodeServer : uint32
SMSG_RESET_FAILED_NOTIFY = 0xBADD,
SMSG_RESISTLOG = 0xBADD,
SMSG_RESPOND_INSPECT_ACHIEVEMENTS = 0xBADD,
+ SMSG_RESUME_COMMS = 0x07C9,
SMSG_RESURRECT_FAILED = 0xBADD,
SMSG_RESURRECT_REQUEST = 0xBADD,
SMSG_RESYNC_RUNES = 0xBADD,
@@ -1268,13 +1284,13 @@ enum OpcodeServer : uint32
SMSG_SET_FACTION_STANDING = 0xBADD,
SMSG_SET_FACTION_VISIBLE = 0xBADD,
SMSG_SET_FLAT_SPELL_MODIFIER = 0x1884,
- SMSG_SET_FORCED_REACTIONS = 0xBADD,
+ SMSG_SET_FORCED_REACTIONS = 0x09A9,
SMSG_SET_MELEE_ANIM_KIT = 0xBADD,
SMSG_SET_MOVEMENT_ANIM_KIT = 0xBADD,
SMSG_SET_PCT_SPELL_MODIFIER = 0x113C,
SMSG_SET_PHASE_SHIFT = 0x00D1,
SMSG_SET_PLAYER_DECLINED_NAMES_RESULT = 0xBADD,
- SMSG_SET_PLAY_HOVER_ANIM = 0xBADD,
+ SMSG_SET_PLAY_HOVER_ANIM = 0x02D4,
SMSG_SET_PROFICIENCY = 0x00D3,
SMSG_SET_PROJECTILE_POSITION = 0xBADD,
SMSG_SET_TIME_ZONE_INFORMATION = 0x153E,
@@ -1304,11 +1320,11 @@ enum OpcodeServer : uint32
SMSG_SPELL_FAILURE = 0xBADD,
SMSG_SPELL_GO = 0x1161,
SMSG_SPELL_START = 0x0803,
- SMSG_SPELL_UPDATE_CHAIN_TARGETS = 0xBADD,
+ SMSG_SPELL_UPDATE_CHAIN_TARGETS = 0x0374,
SMSG_SPIRIT_HEALER_CONFIRM = 0xBADD,
SMSG_SPLINE_MOVE_COLLISION_DISABLE = 0xBADD,
SMSG_SPLINE_MOVE_COLLISION_ENABLE = 0xBADD,
- SMSG_SPLINE_MOVE_GRAVITY_DISABLE = 0xBADD,
+ SMSG_SPLINE_MOVE_GRAVITY_DISABLE = 0x03B2,
SMSG_SPLINE_MOVE_GRAVITY_ENABLE = 0xBADD,
SMSG_SPLINE_MOVE_ROOT = 0xBADD,
SMSG_SPLINE_MOVE_SET_ANIM = 0xBADD,
@@ -1333,10 +1349,10 @@ enum OpcodeServer : uint32
SMSG_SPLINE_MOVE_STOP_SWIM = 0xBADD,
SMSG_SPLINE_MOVE_UNROOT = 0xBADD,
SMSG_SPLINE_MOVE_UNSET_FLYING = 0xBADD,
- SMSG_SPLINE_MOVE_UNSET_HOVER = 0xBADD,
+ SMSG_SPLINE_MOVE_UNSET_HOVER = 0x1959,
SMSG_SPLINE_MOVE_WATER_WALK = 0xBADD,
SMSG_STABLE_RESULT = 0xBADD,
- SMSG_STANDSTATE_UPDATE = 0xBADD,
+ SMSG_STANDSTATE_UPDATE = 0x1311,
SMSG_START_MIRROR_TIMER = 0xBADD,
SMSG_START_TIMER = 0xBADD,
SMSG_STOP_DANCE = 0xBADD,
@@ -1347,7 +1363,7 @@ enum OpcodeServer : uint32
SMSG_SUPERCEDED_SPELL = 0xBADD,
SMSG_SUPPRESS_NPC_GREETINGS = 0xBADD,
SMSG_SUSPEND_COMMS = 0x076A,
- SMSG_SUSPEND_TOKEN_RESPONSE = 0x12A2,
+ SMSG_SUSPEND_TOKEN = 0x12A2,
SMSG_TALENTS_ERROR = 0xBADD,
SMSG_TALENTS_INFO = 0x012D,
SMSG_TALENTS_INVOLUNTARILY_RESET = 0xBADD,
@@ -1398,11 +1414,11 @@ enum OpcodeServer : uint32
SMSG_VOICE_SESSION_LEAVE = 0xBADD,
SMSG_VOICE_SESSION_ROSTER_UPDATE = 0xBADD,
SMSG_VOICE_SET_TALKER_MUTED = 0xBADD,
- SMSG_VOID_ITEM_SWAP_RESPONSE = 0xBADD,
+ SMSG_VOID_ITEM_SWAP_RESPONSE = 0x1131,
SMSG_VOID_STORAGE_CONTENTS = 0x0108,
SMSG_VOID_STORAGE_FAILED = 0xBADD,
- SMSG_VOID_STORAGE_TRANSFER_CHANGES = 0xBADD,
- SMSG_VOID_TRANSFER_RESULT = 0xBADD,
+ SMSG_VOID_STORAGE_TRANSFER_CHANGES = 0x0321,
+ SMSG_VOID_TRANSFER_RESULT = 0x0539,
SMSG_WAIT_QUEUE_FINISH = 0xBADD,
SMSG_WAIT_QUEUE_UPDATE = 0xBADD,
SMSG_WARDEN_DATA = 0x0BEC,
diff --git a/src/server/game/Server/WorldPacket.h b/src/server/game/Server/WorldPacket.h
index e7d6d4fb5b1..65b2f6fcae1 100644
--- a/src/server/game/Server/WorldPacket.h
+++ b/src/server/game/Server/WorldPacket.h
@@ -27,17 +27,18 @@ class WorldPacket : public ByteBuffer
{
public:
// just container for later use
- WorldPacket() : ByteBuffer(0), m_opcode(UNKNOWN_OPCODE)
+ WorldPacket() : ByteBuffer(0), m_opcode(UNKNOWN_OPCODE), _connection(CONNECTION_TYPE_REALM)
{
}
- explicit WorldPacket(uint32 opcode, size_t res = 200) : ByteBuffer(res), m_opcode(opcode) { }
+ WorldPacket(uint32 opcode, size_t res = 200, ConnectionType connection = CONNECTION_TYPE_REALM) : ByteBuffer(res),
+ m_opcode(opcode), _connection(connection) { }
- WorldPacket(WorldPacket&& packet) : ByteBuffer(std::move(packet)), m_opcode(packet.m_opcode)
+ WorldPacket(WorldPacket&& packet) : ByteBuffer(std::move(packet)), m_opcode(packet.m_opcode), _connection(packet._connection)
{
}
- WorldPacket(WorldPacket const& right) : ByteBuffer(right), m_opcode(right.m_opcode)
+ WorldPacket(WorldPacket const& right) : ByteBuffer(right), m_opcode(right.m_opcode), _connection(right._connection)
{
}
@@ -46,26 +47,31 @@ class WorldPacket : public ByteBuffer
if (this != &right)
{
m_opcode = right.m_opcode;
+ _connection = right._connection;
ByteBuffer::operator =(right);
}
return *this;
}
- WorldPacket(uint32 opcode, MessageBuffer&& buffer) : ByteBuffer(std::move(buffer)), m_opcode(opcode) { }
+ WorldPacket(uint32 opcode, MessageBuffer&& buffer, ConnectionType connection) : ByteBuffer(std::move(buffer)), m_opcode(opcode), _connection(connection) { }
- void Initialize(uint32 opcode, size_t newres = 200)
+ void Initialize(uint32 opcode, size_t newres = 200, ConnectionType connection = CONNECTION_TYPE_REALM)
{
clear();
_storage.reserve(newres);
m_opcode = opcode;
+ _connection = connection;
}
uint32 GetOpcode() const { return m_opcode; }
void SetOpcode(uint32 opcode) { m_opcode = opcode; }
+ ConnectionType GetConnection() const { return _connection; }
+
protected:
uint32 m_opcode;
+ ConnectionType _connection;
};
#endif
diff --git a/src/server/game/Server/WorldSession.cpp b/src/server/game/Server/WorldSession.cpp
index 0164ad9a575..f427b91787a 100644
--- a/src/server/game/Server/WorldSession.cpp
+++ b/src/server/game/Server/WorldSession.cpp
@@ -106,7 +106,6 @@ WorldSession::WorldSession(uint32 id, uint32 battlenetAccountId, std::shared_ptr
AntiDOS(this),
m_GUIDLow(UI64LIT(0)),
_player(NULL),
- m_Socket(sock),
_security(sec),
_accountId(id),
_battlenetAccountId(battlenetAccountId),
@@ -114,7 +113,6 @@ WorldSession::WorldSession(uint32 id, uint32 battlenetAccountId, std::shared_ptr
_warden(NULL),
_logoutTime(0),
m_inQueue(false),
- m_playerLoading(false),
m_playerLogout(false),
m_playerRecentlyLogout(false),
m_playerSave(false),
@@ -140,17 +138,9 @@ WorldSession::WorldSession(uint32 id, uint32 battlenetAccountId, std::shared_ptr
LoginDatabase.PExecute("UPDATE account SET online = 1 WHERE id = %u;", GetAccountId()); // One-time query
}
- InitializeQueryCallbackParameters();
+ m_Socket[0] = sock;
- _compressionStream = new z_stream();
- _compressionStream->zalloc = (alloc_func)NULL;
- _compressionStream->zfree = (free_func)NULL;
- _compressionStream->opaque = (voidpf)NULL;
- _compressionStream->avail_in = 0;
- _compressionStream->next_in = NULL;
- int32 z_res = deflateInit2(_compressionStream, sWorld->getIntConfig(CONFIG_COMPRESSION), Z_DEFLATED, -15, 8, Z_DEFAULT_STRATEGY);
- if (z_res != Z_OK)
- TC_LOG_ERROR("network", "Can't initialize packet compression (zlib: deflateInit) Error code: %i (%s)", z_res, zError(z_res));
+ InitializeQueryCallbackParameters();
}
/// WorldSession destructor
@@ -161,10 +151,13 @@ WorldSession::~WorldSession()
LogoutPlayer (true);
/// - If have unclosed socket, close it
- if (m_Socket)
+ for (uint8 i = 0; i < 2; ++i)
{
- m_Socket->CloseSocket();
- m_Socket = nullptr;
+ if (m_Socket[i])
+ {
+ m_Socket[i]->CloseSocket();
+ m_Socket[i].reset();
+ }
}
delete _warden;
@@ -176,12 +169,6 @@ WorldSession::~WorldSession()
delete packet;
LoginDatabase.PExecute("UPDATE account SET online = 0 WHERE id = %u;", GetAccountId()); // One-time query
-
- int32 z_res = deflateEnd(_compressionStream);
- if (z_res != Z_OK && z_res != Z_DATA_ERROR) // Z_DATA_ERROR signals that internal state was BUSY
- TC_LOG_ERROR("network", "Can't close packet compression stream (zlib: deflateEnd) Error code: %i (%s)", z_res, zError(z_res));
-
- delete _compressionStream;
}
std::string const & WorldSession::GetPlayerName() const
@@ -205,7 +192,7 @@ std::string WorldSession::GetPlayerInfo() const
/// Send a packet to the client
void WorldSession::SendPacket(WorldPacket const* packet, bool forced /*= false*/)
{
- if (!m_Socket)
+ if (!m_Socket[packet->GetConnection()])
return;
if (packet->GetOpcode() == NULL_OPCODE)
@@ -265,38 +252,7 @@ void WorldSession::SendPacket(WorldPacket const* packet, bool forced /*= false*/
sScriptMgr->OnPacketSend(this, *packet);
- m_Socket->SendPacket(*packet);
-}
-
-uint32 WorldSession::CompressPacket(uint8* buffer, WorldPacket const& packet)
-{
- uint32 opcode = packet.GetOpcode();
- uint32 bufferSize = deflateBound(_compressionStream, packet.size() + sizeof(opcode));
-
- _compressionStream->next_out = buffer;
- _compressionStream->avail_out = bufferSize;
- _compressionStream->next_in = (Bytef*)&opcode;
- _compressionStream->avail_in = sizeof(uint32);
-
- int32 z_res = deflate(_compressionStream, Z_BLOCK);
- if (z_res != Z_OK)
- {
- TC_LOG_ERROR("network", "Can't compress packet opcode (zlib: deflate) Error code: %i (%s, msg: %s)", z_res, zError(z_res), _compressionStream->msg);
- return 0;
- }
-
- _compressionStream->next_in = (Bytef*)packet.contents();
- _compressionStream->avail_in = packet.size();
-
- z_res = deflate(_compressionStream, Z_SYNC_FLUSH);
- if (z_res != Z_OK)
- {
- TC_LOG_ERROR("network", "Can't compress packet data (zlib: deflate) Error code: %i (%s, msg: %s)", z_res, zError(z_res), _compressionStream->msg);
- return 0;
- }
-
-
- return bufferSize - _compressionStream->avail_out;
+ m_Socket[packet->GetConnection()]->SendPacket(*packet);
}
/// Add an incoming packet to the queue
@@ -332,7 +288,7 @@ bool WorldSession::Update(uint32 diff, PacketFilter& updater)
///- Before we process anything:
/// If necessary, kick the player from the character select screen
if (IsConnectionIdle())
- m_Socket->CloseSocket();
+ m_Socket[0]->CloseSocket();
///- Retrieve packets from the receive queue and call the appropriate handlers
/// not process packets if socket already closed
@@ -349,7 +305,7 @@ bool WorldSession::Update(uint32 diff, PacketFilter& updater)
uint32 processedPackets = 0;
time_t currentTime = time(NULL);
- while (m_Socket && !_recvQueue.empty() && _recvQueue.peek(true) != firstDelayedPacket && _recvQueue.next(packet, updater))
+ while (m_Socket[0] && !_recvQueue.empty() && _recvQueue.peek(true) != firstDelayedPacket && _recvQueue.next(packet, updater))
{
if (!AntiDOS.EvaluateOpcode(*packet, currentTime))
KickPlayer();
@@ -458,7 +414,7 @@ bool WorldSession::Update(uint32 diff, PacketFilter& updater)
break;
}
- if (m_Socket && m_Socket->IsOpen() && _warden)
+ if (m_Socket[0] && m_Socket[0]->IsOpen() && _warden)
_warden->Update();
ProcessQueryCallbacks();
@@ -469,23 +425,24 @@ bool WorldSession::Update(uint32 diff, PacketFilter& updater)
{
time_t currTime = time(NULL);
///- If necessary, log the player out
- if (ShouldLogOut(currTime) && !m_playerLoading)
+ if (ShouldLogOut(currTime) && m_playerLoading.IsEmpty())
LogoutPlayer(true);
- if (m_Socket && GetPlayer() && _warden)
+ if (m_Socket[0] && GetPlayer() && _warden)
_warden->Update();
///- Cleanup socket pointer if need
- if (m_Socket && !m_Socket->IsOpen())
+ if ((m_Socket[0] && !m_Socket[0]->IsOpen()) || (m_Socket[1] && !m_Socket[1]->IsOpen()))
{
expireTime -= expireTime > diff ? diff : expireTime;
if (expireTime < diff || forceExit || !GetPlayer())
{
- m_Socket = nullptr;
+ m_Socket[0].reset();
+ m_Socket[1].reset();
}
}
- if (!m_Socket)
+ if (!m_Socket[0])
return false; //Will remove this session from the world session map
}
@@ -587,7 +544,7 @@ void WorldSession::LogoutPlayer(bool save)
// remove player from the group if he is:
// a) in group; b) not in raid group; c) logging out normally (not being kicked or disconnected)
- if (_player->GetGroup() && !_player->GetGroup()->isRaidGroup() && m_Socket)
+ if (_player->GetGroup() && !_player->GetGroup()->isRaidGroup() && m_Socket[0])
_player->RemoveFromGroup();
//! Send update to group and reset stored max enchanting level
@@ -640,10 +597,13 @@ void WorldSession::LogoutPlayer(bool save)
/// Kick a player out of the World
void WorldSession::KickPlayer()
{
- if (m_Socket)
+ for (uint8 i = 0; i < 2; ++i)
{
- m_Socket->CloseSocket();
- forceExit = true;
+ if (m_Socket[i])
+ {
+ m_Socket[i]->CloseSocket();
+ forceExit = true;
+ }
}
}
diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h
index c77ad210ebc..83a746c8f44 100644
--- a/src/server/game/Server/WorldSession.h
+++ b/src/server/game/Server/WorldSession.h
@@ -54,7 +54,6 @@ struct DeclinedName;
struct ItemTemplate;
struct MovementInfo;
struct TradeStatusInfo;
-struct z_stream_s;
namespace lfg
{
@@ -228,7 +227,7 @@ class WorldSession
WorldSession(uint32 id, uint32 battlenetAccountId, std::shared_ptr<WorldSocket> sock, AccountTypes sec, uint8 expansion, time_t mute_time, LocaleConstant locale, uint32 recruiter, bool isARecruiter);
~WorldSession();
- bool PlayerLoading() const { return m_playerLoading; }
+ bool PlayerLoading() const { return !m_playerLoading.IsEmpty(); }
bool PlayerLogout() const { return m_playerLogout; }
bool PlayerLogoutWithSave() const { return m_playerLogout && m_playerSave; }
bool PlayerRecentlyLoggedOut() const { return m_playerRecentlyLogout; }
@@ -238,7 +237,7 @@ class WorldSession
bool IsAddonRegistered(const std::string& prefix) const;
void SendPacket(WorldPacket const* packet, bool forced = false);
- uint32 CompressPacket(uint8* buffer, WorldPacket const& packet);
+ void AddInstanceConnection(std::shared_ptr<WorldSocket> sock) { m_Socket[1] = sock; }
void SendNotification(const char *format, ...) ATTR_PRINTF(2, 3);
void SendNotification(uint32 string_id, ...);
@@ -424,8 +423,6 @@ class WorldSession
uint32 GetRecruiterId() const { return recruiterId; }
bool IsARecruiter() const { return isRecruiter; }
- z_stream_s* GetCompressionStream() { return _compressionStream; }
-
public: // opcodes handlers
void Handle_NULL(WorldPacket& recvPacket); // not used
@@ -441,6 +438,7 @@ class WorldSession
void HandleCharCreateOpcode(WorldPackets::Character::CharacterCreate& charCreate);
void HandleCharCreateCallback(PreparedQueryResult result, WorldPackets::Character::CharacterCreateInfo* createInfo);
void HandlePlayerLoginOpcode(WorldPackets::Character::PlayerLogin& playerLogin);
+ void HandleContinuePlayerLogin();
void HandleLoadScreenOpcode(WorldPacket& recvPacket);
void HandlePlayerLogin(LoginQueryHolder * holder);
void HandleCharRenameOpcode(WorldPacket& recvData);
@@ -1091,7 +1089,7 @@ class WorldSession
ObjectGuid::LowType m_GUIDLow; // set logined or recently logout player (while m_playerRecentlyLogout set)
Player* _player;
- std::shared_ptr<WorldSocket> m_Socket;
+ std::shared_ptr<WorldSocket> m_Socket[2];
std::string m_Address; // Current Remote Address
// std::string m_LAddress; // Last Attempted Remote Adress - we can not set attempted ip for a non-existing session!
@@ -1107,7 +1105,7 @@ class WorldSession
time_t _logoutTime;
bool m_inQueue; // session wait in auth.queue
- bool m_playerLoading; // code processed in LoginPlayer
+ ObjectGuid m_playerLoading; // code processed in LoginPlayer
bool m_playerLogout; // code processed in LogoutPlayer
bool m_playerRecentlyLogout;
bool m_playerSave;
@@ -1124,7 +1122,6 @@ class WorldSession
uint32 recruiterId;
bool isRecruiter;
LockedQueue<WorldPacket*> _recvQueue;
- z_stream_s* _compressionStream;
rbac::RBACData* _RBACData;
uint32 expireTime;
bool forceExit;
diff --git a/src/server/game/Server/WorldSocket.cpp b/src/server/game/Server/WorldSocket.cpp
index 23bd9a65f88..9cdb05ac79b 100644
--- a/src/server/game/Server/WorldSocket.cpp
+++ b/src/server/game/Server/WorldSocket.cpp
@@ -25,6 +25,7 @@
#include "SHA1.h"
#include "PacketLog.h"
#include "BattlenetAccountMgr.h"
+#include "World.h"
#include <zlib.h>
#include <memory>
@@ -53,12 +54,22 @@ uint32 const SizeOfClientHeader[2][2] =
uint32 const SizeOfServerHeader[2] = { sizeof(uint16) + sizeof(uint32), sizeof(uint32) };
-WorldSocket::WorldSocket(tcp::socket&& socket)
- : Socket(std::move(socket)), _authSeed(rand32()), _OverSpeedPings(0), _worldSession(nullptr), _initialized(false)
+WorldSocket::WorldSocket(tcp::socket&& socket) : Socket(std::move(socket)),
+ _authSeed(rand32()), _OverSpeedPings(0), _worldSession(nullptr),
+ _initialized(false), _type(CONNECTION_TYPE_REALM)
{
_headerBuffer.Resize(SizeOfClientHeader[0][0]);
}
+WorldSocket::~WorldSocket()
+{
+ if (_compressionStream)
+ {
+ deflateEnd(_compressionStream);
+ delete _compressionStream;
+ }
+}
+
void WorldSocket::Start()
{
AsyncRead();
@@ -75,15 +86,13 @@ void WorldSocket::Start()
void WorldSocket::HandleSendAuthSession()
{
- BigNumber seed1;
- BigNumber seed2;
- seed1.SetRand(16 * 8);
- seed2.SetRand(16 * 8);
+ _encryptSeed.SetRand(16 * 8);
+ _decryptSeed.SetRand(16 * 8);
WorldPackets::Auth::AuthChallenge challenge;
challenge.Challenge = _authSeed;
- memcpy(&challenge.DosChallenge[0], seed1.AsByteArray(16).get(), 16);
- memcpy(&challenge.DosChallenge[4], seed2.AsByteArray(16).get(), 16);
+ memcpy(&challenge.DosChallenge[0], _encryptSeed.AsByteArray(16).get(), 16);
+ memcpy(&challenge.DosChallenge[4], _decryptSeed.AsByteArray(16).get(), 16);
challenge.DosZeroBits = 1;
SendPacket(*challenge.Write());
@@ -204,7 +213,7 @@ bool WorldSocket::ReadDataHandler()
std::string opcodeName = GetOpcodeNameForLogging(opcode);
- WorldPacket packet(opcode, std::move(_packetBuffer));
+ WorldPacket packet(opcode, std::move(_packetBuffer), GetConnectionType());
if (sPacketLog->CanLogPacket())
sPacketLog->LogPacket(packet, CLIENT_TO_SERVER, GetRemoteIpAddress(), GetRemotePort());
@@ -217,15 +226,32 @@ bool WorldSocket::ReadDataHandler()
HandlePing(packet);
break;
case CMSG_AUTH_SESSION:
+ {
if (_worldSession)
{
TC_LOG_ERROR("network", "WorldSocket::ProcessIncoming: received duplicate CMSG_AUTH_SESSION from %s", _worldSession->GetPlayerInfo().c_str());
break;
}
- HandleAuthSession(packet);
+ WorldPackets::Auth::AuthSession authSession(std::move(packet));
+ authSession.Read();
+ HandleAuthSession(authSession);
+ break;
+ }
+ case CMSG_AUTH_CONTINUED_SESSION:
+ {
+ if (_worldSession)
+ {
+ TC_LOG_ERROR("network", "WorldSocket::ProcessIncoming: received duplicate CMSG_AUTH_CONTINUED_SESSION from %s", _worldSession->GetPlayerInfo().c_str());
+ break;
+ }
+
+ WorldPackets::Auth::AuthContinuedSession authSession(std::move(packet));
+ authSession.Read();
+ HandleAuthContinuedSession(authSession);
break;
- /*
+ }
+ /*
case CMSG_KEEP_ALIVE:
TC_LOG_DEBUG("network", "%s", opcodeName.c_str());
sScriptMgr->OnPacketReceive(_worldSession, packet);
@@ -286,6 +312,20 @@ bool WorldSocket::ReadDataHandler()
return false;
}
+ _compressionStream = new z_stream();
+ _compressionStream->zalloc = (alloc_func)NULL;
+ _compressionStream->zfree = (free_func)NULL;
+ _compressionStream->opaque = (voidpf)NULL;
+ _compressionStream->avail_in = 0;
+ _compressionStream->next_in = NULL;
+ int32 z_res = deflateInit2(_compressionStream, sWorld->getIntConfig(CONFIG_COMPRESSION), Z_DEFLATED, -15, 8, Z_DEFAULT_STRATEGY);
+ if (z_res != Z_OK)
+ {
+ TC_LOG_ERROR("network", "Can't initialize packet compression (zlib: deflateInit) Error code: %i (%s)", z_res, zError(z_res));
+ CloseSocket();
+ return false;
+ }
+
_initialized = true;
_headerBuffer.Resize(SizeOfClientHeader[1][0]);
_packetBuffer.Reset();
@@ -295,6 +335,35 @@ bool WorldSocket::ReadDataHandler()
return true;
}
+void WorldSocket::SendPacket(WorldPacket const& packet)
+{
+ if (!IsOpen())
+ return;
+
+ if (sPacketLog->CanLogPacket())
+ sPacketLog->LogPacket(packet, SERVER_TO_CLIENT, GetRemoteIpAddress(), GetRemotePort());
+
+ TC_LOG_TRACE("network.opcode", "S->C: %s %s", (_worldSession ? _worldSession->GetPlayerInfo() : GetRemoteIpAddress().to_string()).c_str(), GetOpcodeNameForLogging(static_cast<OpcodeServer>(packet.GetOpcode())).c_str());
+
+ uint32 packetSize = packet.size();
+ uint32 sizeOfHeader = SizeOfServerHeader[_authCrypt.IsInitialized()];
+ if (packetSize > 0x400)
+ packetSize = compressBound(packetSize) + sizeof(CompressedWorldPacket);
+
+ std::unique_lock<std::mutex> guard(_writeLock);
+
+#ifndef TC_SOCKET_USE_IOCP
+ if (_writeQueue.empty() && _writeBuffer.GetRemainingSpace() >= sizeOfHeader + packetSize)
+ WritePacketToBuffer(packet, _writeBuffer);
+ else
+#endif
+ {
+ MessageBuffer buffer(sizeOfHeader + packetSize);
+ WritePacketToBuffer(packet, buffer);
+ QueuePacket(std::move(buffer), guard);
+ }
+}
+
void WorldSocket::WritePacketToBuffer(WorldPacket const& packet, MessageBuffer& buffer)
{
ServerPktHeader header;
@@ -306,7 +375,7 @@ void WorldSocket::WritePacketToBuffer(WorldPacket const& packet, MessageBuffer&
uint8* headerPos = buffer.GetWritePointer();
buffer.WriteCompleted(sizeOfHeader);
- if (packetSize > 0x400 && _worldSession)
+ if (packetSize > 0x400)
{
CompressedWorldPacket cmp;
cmp.UncompressedSize = packetSize + 4;
@@ -316,7 +385,7 @@ void WorldSocket::WritePacketToBuffer(WorldPacket const& packet, MessageBuffer&
uint8* compressionInfo = buffer.GetWritePointer();
buffer.WriteCompleted(sizeof(CompressedWorldPacket));
- uint32 compressedSize = _worldSession->CompressPacket(buffer.GetWritePointer(), packet);
+ uint32 compressedSize = CompressPacket(buffer.GetWritePointer(), packet);
cmp.CompressedAdler = adler32(0x9827D8F1, buffer.GetWritePointer(), compressedSize);
@@ -344,40 +413,39 @@ void WorldSocket::WritePacketToBuffer(WorldPacket const& packet, MessageBuffer&
memcpy(headerPos, &header, sizeOfHeader);
}
-void WorldSocket::SendPacket(WorldPacket const& packet)
+uint32 WorldSocket::CompressPacket(uint8* buffer, WorldPacket const& packet)
{
- if (!IsOpen())
- return;
-
- if (sPacketLog->CanLogPacket())
- sPacketLog->LogPacket(packet, SERVER_TO_CLIENT, GetRemoteIpAddress(), GetRemotePort());
+ uint32 opcode = packet.GetOpcode();
+ uint32 bufferSize = deflateBound(_compressionStream, packet.size() + sizeof(opcode));
- TC_LOG_TRACE("network.opcode", "S->C: %s %s", (_worldSession ? _worldSession->GetPlayerInfo() : GetRemoteIpAddress().to_string()).c_str(), GetOpcodeNameForLogging(static_cast<OpcodeServer>(packet.GetOpcode())).c_str());
+ _compressionStream->next_out = buffer;
+ _compressionStream->avail_out = bufferSize;
+ _compressionStream->next_in = (Bytef*)&opcode;
+ _compressionStream->avail_in = sizeof(uint32);
- uint32 packetSize = packet.size();
- uint32 sizeOfHeader = SizeOfServerHeader[_authCrypt.IsInitialized()];
- if (packetSize > 0x400 && _worldSession)
- packetSize = compressBound(packetSize) + sizeof(CompressedWorldPacket);
+ int32 z_res = deflate(_compressionStream, Z_BLOCK);
+ if (z_res != Z_OK)
+ {
+ TC_LOG_ERROR("network", "Can't compress packet opcode (zlib: deflate) Error code: %i (%s, msg: %s)", z_res, zError(z_res), _compressionStream->msg);
+ return 0;
+ }
- std::unique_lock<std::mutex> guard(_writeLock);
+ _compressionStream->next_in = (Bytef*)packet.contents();
+ _compressionStream->avail_in = packet.size();
-#ifndef TC_SOCKET_USE_IOCP
- if (_writeQueue.empty() && _writeBuffer.GetRemainingSpace() >= sizeOfHeader + packetSize)
- WritePacketToBuffer(packet, _writeBuffer);
- else
-#endif
+ z_res = deflate(_compressionStream, Z_SYNC_FLUSH);
+ if (z_res != Z_OK)
{
- MessageBuffer buffer(sizeOfHeader + packetSize);
- WritePacketToBuffer(packet, buffer);
- QueuePacket(std::move(buffer), guard);
+ TC_LOG_ERROR("network", "Can't compress packet data (zlib: deflate) Error code: %i (%s, msg: %s)", z_res, zError(z_res), _compressionStream->msg);
+ return 0;
}
+
+
+ return bufferSize - _compressionStream->avail_out;
}
-void WorldSocket::HandleAuthSession(WorldPacket& recvPacket)
+void WorldSocket::HandleAuthSession(WorldPackets::Auth::AuthSession& authSession)
{
- WorldPackets::Auth::AuthSession authSession(std::move(recvPacket));
- authSession.Read();
-
uint8 security;
uint32 id;
LocaleConstant locale;
@@ -598,6 +666,56 @@ void WorldSocket::HandleAuthSession(WorldPacket& recvPacket)
sWorld->AddSession(_worldSession);
}
+void WorldSocket::HandleAuthContinuedSession(WorldPackets::Auth::AuthContinuedSession& authSession)
+{
+ uint32 accountId = PAIR64_LOPART(authSession.Key);
+ _type = ConnectionType(PAIR64_HIPART(authSession.Key));
+ QueryResult result = LoginDatabase.PQuery("SELECT username, sessionkey FROM account WHERE id = %u", accountId);
+ if (!result)
+ {
+ SendAuthResponseError(AUTH_UNKNOWN_ACCOUNT);
+ DelayedCloseSocket();
+ return;
+ }
+
+ Field* fields = result->Fetch();
+ std::string login = fields[0].GetString();
+ BigNumber k;
+ k.SetHexStr(fields[1].GetCString());
+
+ _authCrypt.Init(&k, _encryptSeed.AsByteArray().get(), _decryptSeed.AsByteArray().get());
+ _headerBuffer.Resize(SizeOfClientHeader[1][1]);
+
+ SHA1Hash sha;
+ sha.UpdateData(login);
+ sha.UpdateBigNumbers(&k, NULL);
+ sha.UpdateData((uint8*)&_authSeed, 4);
+ sha.Finalize();
+
+ if (memcmp(sha.GetDigest(), authSession.Digest, sha.GetLength()))
+ {
+ SendAuthResponseError(AUTH_UNKNOWN_ACCOUNT);
+ TC_LOG_ERROR("network", "WorldSocket::HandleAuthContinuedSession: Authentication failed for account: %u ('%s') address: %s", accountId, login.c_str(), GetRemoteIpAddress().to_string().c_str());
+ DelayedCloseSocket();
+ return;
+ }
+
+ _worldSession = sWorld->FindSession(accountId);
+ if (!_worldSession)
+ {
+ SendAuthResponseError(AUTH_SESSION_EXPIRED);
+ TC_LOG_ERROR("network", "WorldSocket::HandleAuthContinuedSession: No active session found for account: %u ('%s') address: %s", accountId, login.c_str(), GetRemoteIpAddress().to_string().c_str());
+ DelayedCloseSocket();
+ return;
+ }
+
+ WorldPackets::Auth::ResumeComms resumeComms;
+ SendPacket(*resumeComms.Write());
+
+ _worldSession->AddInstanceConnection(shared_from_this());
+ _worldSession->HandleContinuePlayerLogin();
+}
+
void WorldSocket::SendAuthResponseError(uint8 code)
{
WorldPackets::Auth::AuthResponse response;
diff --git a/src/server/game/Server/WorldSocket.h b/src/server/game/Server/WorldSocket.h
index e0dad0a43a1..16769c68c33 100644
--- a/src/server/game/Server/WorldSocket.h
+++ b/src/server/game/Server/WorldSocket.h
@@ -31,10 +31,16 @@
#include <boost/asio/buffer.hpp>
using boost::asio::ip::tcp;
+struct z_stream_s;
namespace WorldPackets
{
class ServerPacket;
+ namespace Auth
+ {
+ class AuthSession;
+ class AuthContinuedSession;
+ }
}
#pragma pack(push, 1)
@@ -67,6 +73,7 @@ class WorldSocket : public Socket<WorldSocket>
public:
WorldSocket(tcp::socket&& socket);
+ ~WorldSocket();
WorldSocket(WorldSocket const& right) = delete;
WorldSocket& operator=(WorldSocket const& right) = delete;
@@ -74,7 +81,8 @@ public:
void Start() override;
void SendPacket(WorldPacket const& packet);
- void WritePacketToBuffer(WorldPacket const& packet, MessageBuffer& buffer);
+
+ ConnectionType GetConnectionType() const { return _type; }
protected:
void ReadHandler() override;
@@ -82,16 +90,24 @@ protected:
bool ReadDataHandler();
private:
+ void WritePacketToBuffer(WorldPacket const& packet, MessageBuffer& buffer);
+ uint32 CompressPacket(uint8* buffer, WorldPacket const& packet);
+
void HandleSendAuthSession();
- void HandleAuthSession(WorldPacket& recvPacket);
+ void HandleAuthSession(WorldPackets::Auth::AuthSession& authSession);
+ void HandleAuthContinuedSession(WorldPackets::Auth::AuthContinuedSession& authSession);
void SendAuthResponseError(uint8 code);
void HandlePing(WorldPacket& recvPacket);
void ExtractOpcodeAndSize(ClientPktHeader const* header, uint32& opcode, uint32& size) const;
+ ConnectionType _type;
+
uint32 _authSeed;
WorldPacketCrypt _authCrypt;
+ BigNumber _encryptSeed;
+ BigNumber _decryptSeed;
std::chrono::steady_clock::time_point _LastPingTime;
uint32 _OverSpeedPings;
@@ -101,6 +117,8 @@ private:
MessageBuffer _headerBuffer;
MessageBuffer _packetBuffer;
+ z_stream_s* _compressionStream;
+
bool _initialized;
};
diff --git a/src/server/game/Server/WorldSocketMgr.cpp b/src/server/game/Server/WorldSocketMgr.cpp
index 21f62fa265c..5fcd308f376 100644
--- a/src/server/game/Server/WorldSocketMgr.cpp
+++ b/src/server/game/Server/WorldSocketMgr.cpp
@@ -46,6 +46,11 @@ WorldSocketMgr::WorldSocketMgr() : BaseSocketMgr(), _socketSendBufferSize(-1), m
{
}
+WorldSocketMgr::~WorldSocketMgr()
+{
+ delete _instanceAcceptor;
+}
+
bool WorldSocketMgr::StartNetwork(boost::asio::io_service& service, std::string const& bindIp, uint16 port)
{
_tcpNoDelay = sConfigMgr->GetBoolDefault("Network.TcpNodelay", true);
@@ -64,8 +69,10 @@ bool WorldSocketMgr::StartNetwork(boost::asio::io_service& service, std::string
}
BaseSocketMgr::StartNetwork(service, bindIp, port);
+ _instanceAcceptor = new AsyncAcceptor(service, bindIp, uint16(sWorld->getIntConfig(CONFIG_PORT_INSTANCE)));
_acceptor->AsyncAcceptManaged(&OnSocketAccept);
+ _instanceAcceptor->AsyncAcceptManaged(&OnSocketAccept);
sScriptMgr->OnNetworkStart();
return true;
diff --git a/src/server/game/Server/WorldSocketMgr.h b/src/server/game/Server/WorldSocketMgr.h
index 92a28d0c135..389818b2f9b 100644
--- a/src/server/game/Server/WorldSocketMgr.h
+++ b/src/server/game/Server/WorldSocketMgr.h
@@ -35,6 +35,8 @@ class WorldSocketMgr : public SocketMgr<WorldSocket>
typedef SocketMgr<WorldSocket> BaseSocketMgr;
public:
+ ~WorldSocketMgr();
+
static WorldSocketMgr& Instance()
{
static WorldSocketMgr instance;
@@ -55,6 +57,7 @@ protected:
NetworkThread<WorldSocket>* CreateThreads() const override;
private:
+ AsyncAcceptor* _instanceAcceptor;
int32 _socketSendBufferSize;
int32 m_SockOutUBuff;
bool _tcpNoDelay;
diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp
index 659e7ad46ef..2dc6aa3f7a7 100644
--- a/src/server/game/Spells/Spell.cpp
+++ b/src/server/game/Spells/Spell.cpp
@@ -4207,7 +4207,7 @@ void Spell::SendChannelUpdate(uint32 time)
m_caster->SetUInt32Value(UNIT_CHANNEL_SPELL, 0);
}
- WorldPacket data(MSG_CHANNEL_UPDATE, 8+4);
+ WorldPacket data(SMSG_CHANNEL_UPDATE, 8+4);
data << m_caster->GetPackGUID();
data << uint32(time);
@@ -4221,7 +4221,7 @@ void Spell::SendChannelStart(uint32 duration)
if (m_UniqueTargetInfo.size() + m_UniqueGOTargetInfo.size() == 1) // this is for TARGET_SELECT_CATEGORY_NEARBY
channelTarget = !m_UniqueTargetInfo.empty() ? m_UniqueTargetInfo.front().targetGUID : m_UniqueGOTargetInfo.front().targetGUID;
- WorldPacket data(MSG_CHANNEL_START, (8+4+4));
+ WorldPacket data(SMSG_CHANNEL_START, (8+4+4));
data << m_caster->GetPackGUID();
data << uint32(m_spellInfo->Id);
data << uint32(duration);
diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp
index 4900b655766..8bc360abf4d 100644
--- a/src/server/game/World/World.cpp
+++ b/src/server/game/World/World.cpp
@@ -650,9 +650,16 @@ void World::LoadConfigSettings(bool reload)
uint32 val = sConfigMgr->GetIntDefault("WorldServerPort", 8085);
if (val != m_int_configs[CONFIG_PORT_WORLD])
TC_LOG_ERROR("server.loading", "WorldServerPort option can't be changed at worldserver.conf reload, using current value (%u).", m_int_configs[CONFIG_PORT_WORLD]);
+
+ val = sConfigMgr->GetIntDefault("InstanceServerPort", 8086);
+ if (val != m_int_configs[CONFIG_PORT_INSTANCE])
+ TC_LOG_ERROR("server.loading", "InstanceServerPort option can't be changed at worldserver.conf reload, using current value (%u).", m_int_configs[CONFIG_PORT_INSTANCE]);
}
else
+ {
m_int_configs[CONFIG_PORT_WORLD] = sConfigMgr->GetIntDefault("WorldServerPort", 8085);
+ m_int_configs[CONFIG_PORT_INSTANCE] = sConfigMgr->GetIntDefault("InstanceServerPort", 8086);
+ }
m_int_configs[CONFIG_SOCKET_TIMEOUTTIME] = sConfigMgr->GetIntDefault("SocketTimeOutTime", 900000);
m_int_configs[CONFIG_SESSION_ADD_DELAY] = sConfigMgr->GetIntDefault("SessionAddDelay", 10000);
@@ -1079,11 +1086,11 @@ void World::LoadConfigSettings(bool reload)
m_int_configs[CONFIG_ARENA_RATED_UPDATE_TIMER] = sConfigMgr->GetIntDefault ("Arena.RatedUpdateTimer", 5 * IN_MILLISECONDS);
m_bool_configs[CONFIG_ARENA_QUEUE_ANNOUNCER_ENABLE] = sConfigMgr->GetBoolDefault("Arena.QueueAnnouncer.Enable", false);
m_bool_configs[CONFIG_ARENA_QUEUE_ANNOUNCER_PLAYERONLY] = sConfigMgr->GetBoolDefault("Arena.QueueAnnouncer.PlayerOnly", false);
- m_int_configs[CONFIG_ARENA_SEASON_ID] = sConfigMgr->GetIntDefault ("Arena.ArenaSeason.ID", 1);
+ m_int_configs[CONFIG_ARENA_SEASON_ID] = sConfigMgr->GetIntDefault ("Arena.ArenaSeason.ID", 15);
m_int_configs[CONFIG_ARENA_START_RATING] = sConfigMgr->GetIntDefault ("Arena.ArenaStartRating", 0);
m_int_configs[CONFIG_ARENA_START_PERSONAL_RATING] = sConfigMgr->GetIntDefault ("Arena.ArenaStartPersonalRating", 1000);
m_int_configs[CONFIG_ARENA_START_MATCHMAKER_RATING] = sConfigMgr->GetIntDefault ("Arena.ArenaStartMatchmakerRating", 1500);
- m_bool_configs[CONFIG_ARENA_SEASON_IN_PROGRESS] = sConfigMgr->GetBoolDefault("Arena.ArenaSeason.InProgress", true);
+ m_bool_configs[CONFIG_ARENA_SEASON_IN_PROGRESS] = sConfigMgr->GetBoolDefault("Arena.ArenaSeason.InProgress", false);
m_bool_configs[CONFIG_ARENA_LOG_EXTENDED_INFO] = sConfigMgr->GetBoolDefault("ArenaLog.ExtendedInfo", false);
m_bool_configs[CONFIG_OFFHAND_CHECK_AT_SPELL_UNLEARN] = sConfigMgr->GetBoolDefault("OffhandCheckAtSpellUnlearn", true);
@@ -2209,7 +2216,7 @@ void World::ForceGameEventUpdate()
}
/// Send a packet to all players (except self if mentioned)
-void World::SendGlobalMessage(WorldPacket* packet, WorldSession* self, uint32 team)
+void World::SendGlobalMessage(WorldPacket const* packet, WorldSession* self, uint32 team)
{
SessionMap::const_iterator itr;
for (itr = m_sessions.begin(); itr != m_sessions.end(); ++itr)
@@ -2226,7 +2233,7 @@ void World::SendGlobalMessage(WorldPacket* packet, WorldSession* self, uint32 te
}
/// Send a packet to all GMs (except self if mentioned)
-void World::SendGlobalGMMessage(WorldPacket* packet, WorldSession* self, uint32 team)
+void World::SendGlobalGMMessage(WorldPacket const* packet, WorldSession* self, uint32 team)
{
for (SessionMap::const_iterator itr = m_sessions.begin(); itr != m_sessions.end(); ++itr)
{
@@ -2354,7 +2361,7 @@ void World::SendGlobalText(const char* text, WorldSession* self)
}
/// Send a packet to all players (or players selected team) in the zone (except self if mentioned)
-bool World::SendZoneMessage(uint32 zone, WorldPacket* packet, WorldSession* self, uint32 team)
+bool World::SendZoneMessage(uint32 zone, WorldPacket const* packet, WorldSession* self, uint32 team)
{
bool foundPlayerToSend = false;
SessionMap::const_iterator itr;
diff --git a/src/server/game/World/World.h b/src/server/game/World/World.h
index 3c3e40cc76b..7bf8f5b70e7 100644
--- a/src/server/game/World/World.h
+++ b/src/server/game/World/World.h
@@ -30,6 +30,7 @@
#include "SharedDefines.h"
#include "QueryResult.h"
#include "Callback.h"
+#include "Realm/Realm.h"
#include <atomic>
#include <map>
@@ -204,6 +205,7 @@ enum WorldIntConfigs
CONFIG_INTERVAL_CHANGEWEATHER,
CONFIG_INTERVAL_DISCONNECT_TOLERANCE,
CONFIG_PORT_WORLD,
+ CONFIG_PORT_INSTANCE,
CONFIG_SOCKET_TIMEOUTTIME,
CONFIG_SESSION_ADD_DELAY,
CONFIG_GAME_TYPE,
@@ -660,9 +662,9 @@ class World
void SendGlobalText(const char* text, WorldSession* self);
void SendGMText(uint32 string_id, ...);
void SendServerMessage(ServerMessageType type, const char *text = "", Player* player = NULL);
- void SendGlobalMessage(WorldPacket* packet, WorldSession* self = nullptr, uint32 team = 0);
- void SendGlobalGMMessage(WorldPacket* packet, WorldSession* self = nullptr, uint32 team = 0);
- bool SendZoneMessage(uint32 zone, WorldPacket* packet, WorldSession* self = nullptr, uint32 team = 0);
+ void SendGlobalMessage(WorldPacket const* packet, WorldSession* self = nullptr, uint32 team = 0);
+ void SendGlobalGMMessage(WorldPacket const* packet, WorldSession* self = nullptr, uint32 team = 0);
+ bool SendZoneMessage(uint32 zone, WorldPacket const* packet, WorldSession* self = nullptr, uint32 team = 0);
void SendZoneText(uint32 zone, const char *text, WorldSession* self = nullptr, uint32 team = 0);
/// Are we in the middle of a shutdown?
@@ -887,6 +889,7 @@ class World
};
extern Battlenet::RealmHandle realmHandle;
+extern Realm realm;
uint32 GetVirtualRealmAddress();
#define sWorld World::instance()
diff --git a/src/server/scripts/Maelstrom/CMakeLists.txt b/src/server/scripts/Maelstrom/CMakeLists.txt
index 79f0789fd3f..8d3f1ee1c69 100644
--- a/src/server/scripts/Maelstrom/CMakeLists.txt
+++ b/src/server/scripts/Maelstrom/CMakeLists.txt
@@ -9,6 +9,13 @@
set(scripts_STAT_SRCS
${scripts_STAT_SRCS}
Maelstrom/kezan.cpp
+ Maelstrom/Stonecore/instance_stonecore.cpp
+ Maelstrom/Stonecore/stonecore.cpp
+ Maelstrom/Stonecore/stonecore.h
+ Maelstrom/Stonecore/boss_corborus.cpp
+ Maelstrom/Stonecore/boss_slabhide.cpp
+ Maelstrom/Stonecore/boss_ozruk.cpp
+ Maelstrom/Stonecore/boss_high_priestess_azil.cpp
)
message(" -> Prepared: The Maelstrom")
diff --git a/src/server/scripts/Maelstrom/Stonecore/boss_corborus.cpp b/src/server/scripts/Maelstrom/Stonecore/boss_corborus.cpp
new file mode 100644
index 00000000000..2d522928fce
--- /dev/null
+++ b/src/server/scripts/Maelstrom/Stonecore/boss_corborus.cpp
@@ -0,0 +1,319 @@
+/*
+ * 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 "ScriptMgr.h"
+#include "ScriptedCreature.h"
+#include "CreatureGroups.h"
+#include "stonecore.h"
+
+// TO-DO:
+// Find heroic sniffs and script spawning Crystal Shards on heroic mode.
+
+enum Spells
+{
+ // Corborus intro
+ SPELL_TWILIGHT_DOCUMENTS = 93167,
+ SPELL_RING_WYRM_CHARGE = 81237,
+ SPELL_DOOR_BREAK = 81232, // cast by World Trigger 22515
+
+ // Corborus boss
+ SPELL_DAMPENING_WAVE = 82415,
+ SPELL_CRYSTAL_BARRAGE = 86881, // 81638 triggers 81637
+// SPELL_CRYSTAL_BARRAGE_SHARD = 92012, // heroic only, summons Crystal Shard (TO-DO!)
+ SPELL_CLEAR_ALL_DEBUFFS = 34098,
+ SPELL_SUBMERGE = 81629,
+ SPELL_TRASHING_CHARGE_TELEPORT = 81839, // triggers 81864
+// SPELL_TRASHING_CHARGE_TELEPORT_2= 81838, // dummy, targets all players, threat update packet follows
+ SPELL_SUMMON_TRASHING_CHARGE = 81816,
+ SPELL_TRASHING_CHARGE_VISUAL = 81801, // cast time 3.5 sec
+ SPELL_TRASHING_CHARGE_EFFECT = 81828, // 40 yard radius
+ SPELL_EMERGE = 81948,
+
+ // Rock Borer npc (43917)
+ SPELL_ROCK_BORER_EMERGE = 82185,
+ SPELL_ROCK_BORE = 80028,
+};
+
+enum NPCs
+{
+ NPC_TRASHING_CHARGE = 43743,
+// NPC_CRYSTAL_SHARD = 49267, // 49473
+};
+
+enum Events
+{
+ EVENT_NONE,
+
+ // Corborus intro
+ EVENT_CORBORUS_CHARGE,
+ EVENT_CORBORUS_KNOCKBACK,
+ EVENT_CORBORUS_FACEPLAYERS,
+
+ // Corborus boss
+ EVENT_DAMPENING_WAVE,
+ EVENT_CRYSTAL_BARRAGE,
+ EVENT_SUBMERGE,
+ EVENT_TELEPORT,
+ EVENT_TRASHING_CHARGE,
+ EVENT_SUMMON_BEETLE,
+ EVENT_EMERGE,
+ EVENT_ATTACK,
+
+ // Rock Borer
+ EVENT_EMERGED,
+ EVENT_ROCK_BORE,
+};
+
+class boss_corborus : public CreatureScript
+{
+ public:
+ boss_corborus() : CreatureScript("boss_corborus") { }
+
+ struct boss_corborusAI : public BossAI
+ {
+ boss_corborusAI(Creature* creature) : BossAI(creature, DATA_CORBORUS)
+ {
+ stateIntro = NOT_STARTED;
+ }
+
+ void Reset() override
+ {
+ _Reset();
+ countTrashingCharge = 0;
+ events.ScheduleEvent(EVENT_DAMPENING_WAVE, 10000);
+ events.ScheduleEvent(EVENT_CRYSTAL_BARRAGE, 15000);
+ events.ScheduleEvent(EVENT_SUBMERGE, 36000);
+ }
+
+ void DoAction(int32 action) override
+ {
+ switch (action)
+ {
+ case ACTION_CORBORUS_INTRO: // Executes Corborus intro event
+ {
+ if (stateIntro != NOT_STARTED)
+ return;
+
+ stateIntro = IN_PROGRESS;
+
+ if (Creature* Millhouse = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_MILLHOUSE_MANASTORM)))
+ {
+ Millhouse->InterruptNonMeleeSpells(true);
+ Millhouse->RemoveAllAuras();
+ Millhouse->HandleEmoteCommand(EMOTE_ONESHOT_KNOCKDOWN);
+ }
+
+ events.ScheduleEvent(EVENT_CORBORUS_CHARGE, 1000);
+ break;
+ }
+ default:
+ break;
+ }
+ }
+
+ void UpdateAI(uint32 diff) override
+ {
+ if (!UpdateVictim() && stateIntro != IN_PROGRESS)
+ return;
+
+ events.Update(diff);
+
+ if (me->HasUnitState(UNIT_STATE_CASTING))
+ return;
+
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case EVENT_CORBORUS_CHARGE:
+ // Face Millhouse and other mobs
+ instance->SetData(DATA_MILLHOUSE_EVENT_FACE, 0);
+
+ // Open rock gate and cast visual from nearby worldtrigger
+ instance->HandleGameObject(instance->GetGuidData(GAMEOBJECT_CORBORUS_ROCKDOOR), true);
+ if (Creature* worldtrigger = me->FindNearestCreature(NPC_WORLDTRIGGER, 60.0f))
+ worldtrigger->CastSpell(worldtrigger, SPELL_DOOR_BREAK, true);
+
+ // Make Corborus charge
+ me->CastSpell(me, SPELL_RING_WYRM_CHARGE, true);
+
+ events.ScheduleEvent(EVENT_CORBORUS_KNOCKBACK, 1000);
+ break;
+ case EVENT_CORBORUS_KNOCKBACK:
+ // Spawn Twilight Documents (quest gameobject)
+ if (Creature* Millhouse = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_MILLHOUSE_MANASTORM)))
+ Millhouse->CastSpell(Millhouse, SPELL_TWILIGHT_DOCUMENTS, true);
+
+ // Knockback Millhouse and other mobs
+ instance->SetData(DATA_MILLHOUSE_EVENT_KNOCKBACK, 0);
+
+ events.ScheduleEvent(EVENT_CORBORUS_FACEPLAYERS, 2000);
+ break;
+ case EVENT_CORBORUS_FACEPLAYERS:
+ // Face Corborus to players and set new home position
+ me->SetFacingTo(3.176499f);
+ me->SetHomePosition(1154.55f, 878.843f, 284.963f, 3.176499f);
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC);
+
+ // Despawn Millhouse and all trash
+ instance->SetData(DATA_MILLHOUSE_EVENT_DESPAWN, 0);
+
+ stateIntro = DONE;
+ break;
+ case EVENT_DAMPENING_WAVE:
+ DoCastVictim(SPELL_DAMPENING_WAVE);
+ events.ScheduleEvent(EVENT_DAMPENING_WAVE, 15000);
+ break;
+ case EVENT_CRYSTAL_BARRAGE:
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100.0f, true))
+ DoCast(target, SPELL_CRYSTAL_BARRAGE);
+ events.ScheduleEvent(EVENT_CRYSTAL_BARRAGE, 10000);
+ break;
+ case EVENT_SUBMERGE:
+ events.RescheduleEvent(EVENT_DAMPENING_WAVE, 35000);
+ events.RescheduleEvent(EVENT_CRYSTAL_BARRAGE, 30000);
+ events.RescheduleEvent(EVENT_SUBMERGE, 100000);
+
+ me->SetReactState(REACT_PASSIVE);
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ DoCast(me, SPELL_CLEAR_ALL_DEBUFFS);
+ me->AttackStop();
+
+ DoCast(me, SPELL_SUBMERGE);
+
+ countTrashingCharge = 0;
+ events.ScheduleEvent(EVENT_TELEPORT, 500);
+ break;
+ case EVENT_TELEPORT:
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100.0f, true))
+ DoCast(target, SPELL_TRASHING_CHARGE_TELEPORT);
+ countTrashingCharge += 1;
+ if (countTrashingCharge <= 4)
+ events.ScheduleEvent(EVENT_TRASHING_CHARGE, 1000);
+ else
+ events.ScheduleEvent(EVENT_EMERGE, 2500);
+ break;
+ case EVENT_TRASHING_CHARGE:
+ DoCast(me, SPELL_SUMMON_TRASHING_CHARGE);
+ DoCast(me, SPELL_TRASHING_CHARGE_VISUAL);
+ events.ScheduleEvent(EVENT_TELEPORT, 5000);
+ break;
+ case EVENT_EMERGE:
+ me->RemoveAllAuras();
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ DoCast(me, SPELL_EMERGE);
+ events.ScheduleEvent(EVENT_ATTACK, 2500);
+ break;
+ case EVENT_ATTACK:
+ me->SetReactState(REACT_AGGRESSIVE);
+ break;
+ default:
+ break;
+ }
+ }
+
+ DoMeleeAttackIfReady();
+ }
+
+ void JustSummoned(Creature* summon) override
+ {
+ if (summon->GetEntry() != NPC_TRASHING_CHARGE)
+ return;
+
+ summon->SetReactState(REACT_PASSIVE);
+ summon->CastSpell(summon, SPELL_TRASHING_CHARGE_EFFECT);
+ summon->DespawnOrUnsummon(6000);
+ }
+
+ private:
+ EncounterState stateIntro;
+ uint32 countTrashingCharge;
+ };
+
+ CreatureAI* GetAI(Creature* creature) const override
+ {
+ return GetInstanceAI<boss_corborusAI>(creature);
+ }
+};
+
+// 43391 - Rock Borer
+class npc_rock_borer : public CreatureScript
+{
+ public:
+ npc_rock_borer() : CreatureScript("npc_rock_borer") { }
+
+ struct npc_rock_borerAI : public ScriptedAI
+ {
+ npc_rock_borerAI(Creature* creature) : ScriptedAI(creature)
+ {
+ me->SetDisableGravity(true);
+ me->SetReactState(REACT_PASSIVE);
+ events.ScheduleEvent(EVENT_EMERGED, 1200);
+ events.ScheduleEvent(EVENT_ROCK_BORE, urand(15000, 20000)); // Need sniffs for this timer
+ }
+
+ void IsSummonedBy(Unit* summoner) override
+ {
+ me->SetInCombatState(false, summoner);
+ DoCast(SPELL_ROCK_BORER_EMERGE);
+ }
+
+ void UpdateAI(uint32 diff) override
+ {
+ if (!UpdateVictim() && me->GetReactState() != REACT_PASSIVE)
+ return;
+
+ events.Update(diff);
+
+ if (me->HasUnitState(UNIT_STATE_CASTING))
+ return;
+
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case EVENT_EMERGED:
+ me->RemoveAurasDueToSpell(SPELL_ROCK_BORER_EMERGE);
+ me->SetReactState(REACT_AGGRESSIVE);
+ break;
+ case EVENT_ROCK_BORE:
+ DoCast(SPELL_ROCK_BORE);
+ events.ScheduleEvent(EVENT_ROCK_BORE, urand(15000, 20000)); // Need sniffs for this timer
+ break;
+ default:
+ break;
+ }
+ }
+
+ DoMeleeAttackIfReady();
+ }
+
+ private:
+ EventMap events;
+ };
+
+ CreatureAI* GetAI(Creature* creature) const override
+ {
+ return GetInstanceAI<npc_rock_borerAI>(creature);
+ }
+};
+
+void AddSC_boss_corborus()
+{
+ new boss_corborus();
+ new npc_rock_borer();
+}
diff --git a/src/server/scripts/Maelstrom/Stonecore/boss_high_priestess_azil.cpp b/src/server/scripts/Maelstrom/Stonecore/boss_high_priestess_azil.cpp
new file mode 100644
index 00000000000..477d3baf206
--- /dev/null
+++ b/src/server/scripts/Maelstrom/Stonecore/boss_high_priestess_azil.cpp
@@ -0,0 +1,808 @@
+/*
+ * 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 "ScriptMgr.h"
+#include "ScriptedCreature.h"
+#include "SpellScript.h"
+#include "Player.h"
+#include "Vehicle.h"
+#include "stonecore.h"
+
+enum Spells
+{
+ SPELL_ENERGY_SHIELD = 82858,
+
+ SPELL_CURSE_OF_BLOOD = 79345,
+ SPELL_FORCE_GRIP = 79351,
+ SPELL_SUMMON_GRAVITY_WELL = 79340,
+ SPELL_EARTH_FURY_ENERGY_SHIELD = 79050,
+
+ // Gravity Well
+ SPELL_GRAVITY_WELL_VISUAL = 79245,
+ SPELL_GRAVITY_WELL_AURA_DAMAGE = 79244,
+ SPELL_GRAVITY_WELL_AURA_PULL = 79333,
+
+ SPELL_GRAVITY_WELL_DAMAGE = 79249,
+ SPELL_GRAVITY_WELL_PULL = 79332,
+
+ // Fury of Earth phase
+ SPELL_EARTH_FURY_CASTING_VISUAL = 79002,
+ SPELL_SEISMIC_SHARD_SUMMON_1 = 86860,
+ SPELL_SEISMIC_SHARD_SUMMON_2 = 86858,
+ SPELL_SEISMIC_SHARD_SUMMON_3 = 86856,
+ SPELL_SEISMIC_SHARD_VISUAL = 79009,
+ SPELL_SEISMIC_SHARD_PREPARE = 86862,
+ SPELL_SEISMIC_SHARD_TARGETING = 80511,
+ SPELL_SEISMIC_SHARD_LAUNCH = 79015,
+ SPELL_SEISMIC_SHARD_MISSLE = 79014,
+ SPELL_EJECT_ALL_PASSENGERS = 68576,
+
+ // Add wave spells
+ SPELL_SUMMON_WAVE_SOUTH = 79200,
+ SPELL_SUMMON_WAVE_WEST = 79196,
+ SPELL_SUMMON_ADD_SOUTH = 79193,
+ SPELL_SUMMON_ADD_WEST = 79199,
+};
+
+enum NPCs
+{
+ NPC_DEVOUT_FOLLOWER = 42428,
+ NPC_SEISMIC_SHARD = 42355,
+};
+
+enum Texts
+{
+ SAY_AGGRO = 0,
+ SAY_PHASE_TWO = 1,
+ SAY_DEATH = 2,
+};
+
+enum Events
+{
+ EVENT_NONE,
+
+ EVENT_INTRO_MOVE,
+
+ EVENT_CURSE_OF_BLOOD,
+ EVENT_FORCE_GRIP,
+ EVENT_SUMMON_GRAVITY_WELL,
+ EVENT_ENERGY_SHIELD,
+ EVENT_EARTH_FURY,
+
+ EVENT_SUMMON_WAVE_SOUTH,
+ EVENT_SUMMON_WAVE_WEST,
+
+ EVENT_GRAVITY_WELL_AURA_DAMAGE,
+ EVENT_GRAVITY_WELL_AURA_PULL,
+
+ // Phase 2: Fury of Earth
+ EVENT_EARTH_FURY_FLY_UP,
+ EVENT_EARTH_FURY_FLY_ABOVE_PLATFORM,
+ EVENT_EARTH_FURY_CHECK_SEAT0,
+ EVENT_EARTH_FURY_LAUNCH_SHARD,
+ EVENT_EARTH_FURY_FLY_DOWN,
+ EVENT_START_ATTACK,
+
+ EVENT_LAUNCH,
+ EVENT_SEISMIC_SHARD_MOUNT
+};
+
+enum EventGroups
+{
+ EVENT_GROUP_PHASE_ONE,
+ EVENT_GROUP_ADDS,
+};
+
+enum Points
+{
+ POINT_NONE,
+
+ POINT_INTRO_MOVE,
+ POINT_FLY_UP,
+ POINT_ABOVE_PLATFORM,
+ POINT_PLATFORM,
+ POINT_GROUND,
+};
+
+Position const GroundPos = { 1331.82f, 980.314f, 207.542f };
+Position const AbovePlatformPos = { 1336.21f, 960.813f, 215.0f };
+
+// TO-DO:
+// - Find out why NPCs summoned by boss are usually two times bigger than their normal size.
+// - Find more sniffs and script Force Grip spell (79351)
+
+class boss_high_priestess_azil : public CreatureScript
+{
+ public:
+ boss_high_priestess_azil() : CreatureScript("boss_high_priestess_azil") { }
+
+ struct boss_high_priestess_azilAI : public BossAI
+ {
+ boss_high_priestess_azilAI(Creature* creature) : BossAI(creature, DATA_HIGH_PRIESTESS_AZIL), vehicle(creature->GetVehicleKit())
+ {
+ ASSERT(vehicle);
+ }
+
+ Vehicle* vehicle;
+
+ void Reset() override
+ {
+ _Reset();
+
+ me->SetCanFly(false);
+ me->SetDisableGravity(false);
+ me->SetReactState(REACT_PASSIVE);
+
+ events.ScheduleEvent(EVENT_INTRO_MOVE, 2000);
+ events.ScheduleEvent(EVENT_CURSE_OF_BLOOD, 6000, EVENT_GROUP_PHASE_ONE);
+ events.ScheduleEvent(EVENT_FORCE_GRIP, urand(8000,10000), EVENT_GROUP_PHASE_ONE);
+ events.ScheduleEvent(EVENT_SUMMON_GRAVITY_WELL, 16000, EVENT_GROUP_PHASE_ONE);
+ events.ScheduleEvent(EVENT_ENERGY_SHIELD, urand(35000,36000));
+ events.ScheduleEvent(EVENT_SUMMON_WAVE_SOUTH, 0);
+ events.ScheduleEvent(EVENT_SUMMON_WAVE_WEST, 40000);
+ }
+
+ void EnterCombat(Unit* /*victim*/) override
+ {
+ _EnterCombat();
+
+ DoCast(SPELL_ENERGY_SHIELD);
+ Talk(SAY_AGGRO);
+ }
+
+ void JustDied(Unit* killer) override
+ {
+ me->Say(SAY_DEATH);
+ }
+
+ /*
+ void PassengerBoarded(Unit* who, int8 seatId, bool apply) override
+ {
+ if (!apply || who->GetEntry() != NPC_SEISMIC_SHARD)
+ return;
+
+ Movement::MoveSplineInit init(who);
+ init.DisableTransportPathTransformations();
+ if (seatId == 0)
+ init.MoveTo(12.13748f, 0.0f, 2.442475f);
+ else if (seatId == 1)
+ init.MoveTo(12.13748f, 17.5f, 11.19248f);
+ else
+ init.MoveTo(12.13748f, -17.5f, 11.19248f);
+ init.Launch();
+ }
+ */
+
+ void MovementInform(uint32 type, uint32 id) override
+ {
+ if (type != POINT_MOTION_TYPE && id != POINT_INTRO_MOVE)
+ return;
+
+ switch (id)
+ {
+ case POINT_INTRO_MOVE:
+ me->RemoveAurasDueToSpell(SPELL_ENERGY_SHIELD);
+ me->SetReactState(REACT_AGGRESSIVE);
+ break;
+ case POINT_FLY_UP:
+ me->SetCanFly(true);
+ me->SetDisableGravity(true);
+ events.ScheduleEvent(EVENT_EARTH_FURY_FLY_ABOVE_PLATFORM, 1000);
+ break;
+ case POINT_ABOVE_PLATFORM:
+ me->SetFacingTo(5.218534f);
+ DoCast(SPELL_EARTH_FURY_CASTING_VISUAL);
+ DoCast(SPELL_SEISMIC_SHARD_SUMMON_1);
+ DoCast(SPELL_SEISMIC_SHARD_SUMMON_2);
+ DoCast(SPELL_SEISMIC_SHARD_SUMMON_3);
+ events.ScheduleEvent(EVENT_EARTH_FURY_CHECK_SEAT0, 6700);
+ break;
+ case POINT_GROUND:
+ DoCast(SPELL_EJECT_ALL_PASSENGERS);
+ me->SetCanFly(false);
+ me->SetDisableGravity(false);
+ me->SetReactState(REACT_AGGRESSIVE);
+ // Find more sniffs to correct these timers, this was copied from Reset() void.
+ events.ScheduleEvent(EVENT_CURSE_OF_BLOOD, 6000, EVENT_GROUP_PHASE_ONE);
+ events.ScheduleEvent(EVENT_FORCE_GRIP, urand(8000, 10000), EVENT_GROUP_PHASE_ONE);
+ events.ScheduleEvent(EVENT_SUMMON_GRAVITY_WELL, 16000, EVENT_GROUP_PHASE_ONE);
+ break;
+ default:
+ break;
+ }
+ }
+
+ void UpdateAI(uint32 diff) override
+ {
+ if (!UpdateVictim())
+ return;
+
+ events.Update(diff);
+
+ if (me->HasUnitState(UNIT_STATE_CASTING))
+ return;
+
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case EVENT_INTRO_MOVE:
+ me->GetMotionMaster()->MoveJump(GroundPos, me->GetSpeed(MOVE_FLIGHT), 1.918408f, POINT_INTRO_MOVE);
+ break;
+ case EVENT_CURSE_OF_BLOOD:
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100.0f, true))
+ DoCast(target, SPELL_CURSE_OF_BLOOD);
+ events.ScheduleEvent(EVENT_CURSE_OF_BLOOD, urand(13000, 15000), EVENT_GROUP_PHASE_ONE);
+ break;
+ case EVENT_FORCE_GRIP:
+ DoCastVictim(SPELL_FORCE_GRIP);
+ events.ScheduleEvent(EVENT_CURSE_OF_BLOOD, urand(13000, 15000), EVENT_GROUP_PHASE_ONE);
+ break;
+ case EVENT_SUMMON_GRAVITY_WELL:
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100.0f, true))
+ DoCast(target, SPELL_SUMMON_GRAVITY_WELL);
+ events.ScheduleEvent(EVENT_SUMMON_GRAVITY_WELL, urand(13000, 15000), EVENT_GROUP_PHASE_ONE);
+ break;
+ case EVENT_ENERGY_SHIELD:
+ events.CancelEventGroup(EVENT_GROUP_PHASE_ONE);
+ DoCast(SPELL_EARTH_FURY_ENERGY_SHIELD);
+ events.ScheduleEvent(EVENT_EARTH_FURY, 0);
+ break;
+ case EVENT_EARTH_FURY:
+ countSeismicShard = 3;
+ me->SetReactState(REACT_PASSIVE);
+ me->SetFacingTo(5.862942f);
+ events.ScheduleEvent(EVENT_EARTH_FURY_FLY_UP, 1600);
+ break;
+ case EVENT_EARTH_FURY_FLY_UP:
+ Talk(SAY_PHASE_TWO);
+ me->GetMotionMaster()->MovePoint(POINT_FLY_UP, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ() + 5);
+ break;
+ case EVENT_EARTH_FURY_FLY_ABOVE_PLATFORM:
+ me->GetMotionMaster()->MovePoint(POINT_ABOVE_PLATFORM, AbovePlatformPos);
+ break;
+ case EVENT_EARTH_FURY_CHECK_SEAT0:
+ if (!vehicle->GetPassenger(0))
+ DoCast(SPELL_SEISMIC_SHARD_PREPARE);
+ events.ScheduleEvent(EVENT_EARTH_FURY_LAUNCH_SHARD, 1800);
+ break;
+ case EVENT_EARTH_FURY_LAUNCH_SHARD:
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100.0f, true))
+ {
+ me->SetFacingToObject(target);
+ DoCast(target, SPELL_SEISMIC_SHARD_TARGETING);
+ DoCast(SPELL_SEISMIC_SHARD_LAUNCH);
+ countSeismicShard -= 1;
+ }
+ events.ScheduleEvent(countSeismicShard > 0 ? EVENT_EARTH_FURY_CHECK_SEAT0 : EVENT_EARTH_FURY_FLY_DOWN, 4800);
+ break;
+ case EVENT_EARTH_FURY_FLY_DOWN:
+ {
+ me->RemoveAurasDueToSpell(SPELL_EARTH_FURY_CASTING_VISUAL);
+ me->RemoveAurasDueToSpell(SPELL_EARTH_FURY_ENERGY_SHIELD);
+ Position pos = me->GetPosition();
+ pos.m_positionZ = me->GetMap()->GetHeight(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ());
+ me->GetMotionMaster()->MovePoint(POINT_GROUND, pos);
+ break;
+ }
+ case EVENT_SUMMON_WAVE_SOUTH:
+ if (Creature* worldtrigger = me->FindNearestCreature(NPC_WORLDTRIGGER, 150.0f))
+ worldtrigger->CastSpell(worldtrigger, SPELL_SUMMON_WAVE_SOUTH);
+ events.ScheduleEvent(EVENT_SUMMON_WAVE_SOUTH, 12000);
+ break;
+ case EVENT_SUMMON_WAVE_WEST:
+ if (Creature* worldtrigger = me->FindNearestCreature(NPC_WORLDTRIGGER, 150.0f))
+ worldtrigger->CastSpell(worldtrigger, SPELL_SUMMON_WAVE_WEST);
+ events.ScheduleEvent(EVENT_SUMMON_WAVE_WEST, 20000);
+ break;
+ default:
+ break;
+ }
+ }
+
+ DoMeleeAttackIfReady();
+ }
+
+ private:
+ uint8 countSeismicShard;
+ };
+
+ CreatureAI* GetAI(Creature* creature) const override
+ {
+ return GetInstanceAI<boss_high_priestess_azilAI>(creature);
+ }
+};
+
+// 42428 - Devout Follower
+class npc_devout_follower : public CreatureScript
+{
+public:
+ npc_devout_follower() : CreatureScript("npc_devout_follower") { }
+
+ struct npc_devout_followerAI : public ScriptedAI
+ {
+ npc_devout_followerAI(Creature* creature) : ScriptedAI(creature) { }
+
+ void IsSummonedBy(Unit* summoner) override
+ {
+ if (summoner->GetEntry() != NPC_WORLDTRIGGER)
+ return;
+
+ if (Unit* target = me->SelectNearestPlayer(200.0f))
+ {
+ me->AddThreat(target, 0.0f);
+ me->SetInCombatWith(target);
+ target->SetInCombatWith(me);
+ DoStartMovement(target);
+ me->Attack(target, true);
+ }
+ else
+ me->GetMotionMaster()->MovePoint(POINT_NONE, summoner->GetPosition());
+ }
+ };
+
+ CreatureAI* GetAI(Creature* creature) const override
+ {
+ return GetInstanceAI<npc_devout_followerAI>(creature);
+ }
+};
+
+// 42499 - Gravity Well
+class npc_gravity_well : public CreatureScript
+{
+public:
+ npc_gravity_well() : CreatureScript("npc_gravity_well") { }
+
+ struct npc_gravity_wellAI : public ScriptedAI
+ {
+ npc_gravity_wellAI(Creature* creature) : ScriptedAI(creature)
+ {
+ me->SetReactState(REACT_PASSIVE);
+ DoCast(SPELL_GRAVITY_WELL_VISUAL);
+ events.ScheduleEvent(EVENT_GRAVITY_WELL_AURA_DAMAGE, 3200);
+ events.ScheduleEvent(EVENT_GRAVITY_WELL_AURA_PULL, 4500);
+ if (!me->GetMap()->IsHeroic())
+ me->DespawnOrUnsummon(23200);
+ }
+
+ void KilledUnit(Unit* victim) override
+ {
+ if (victim->GetEntry() != NPC_DEVOUT_FOLLOWER)
+ return;
+
+ me->SetObjectScale(me->GetObjectScale() - 0.25f);
+ if (me->GetObjectScale() <= 0.0f)
+ me->DespawnOrUnsummon(1000);
+ }
+
+ void UpdateAI(uint32 diff) override
+ {
+ events.Update(diff);
+
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case EVENT_GRAVITY_WELL_AURA_DAMAGE:
+ me->RemoveAurasDueToSpell(SPELL_GRAVITY_WELL_VISUAL);
+ DoCast(SPELL_GRAVITY_WELL_AURA_DAMAGE);
+ break;
+ case EVENT_GRAVITY_WELL_AURA_PULL:
+ DoCast(SPELL_GRAVITY_WELL_AURA_PULL);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ private:
+ EventMap events;
+ };
+
+ CreatureAI* GetAI(Creature* creature) const override
+ {
+ return GetInstanceAI<npc_gravity_wellAI>(creature);
+ }
+};
+
+// 42355 - Seismic Shard
+class npc_seismic_shard : public CreatureScript
+{
+public:
+ npc_seismic_shard() : CreatureScript("npc_seismic_shard") { }
+
+ struct npc_seismic_shardAI : public ScriptedAI
+ {
+ npc_seismic_shardAI(Creature* creature) : ScriptedAI(creature)
+ {
+ instance = creature->GetInstanceScript();
+ me->SetDisableGravity(true);
+ me->SetReactState(REACT_PASSIVE);
+ DoCast(SPELL_SEISMIC_SHARD_VISUAL);
+
+ Movement::MoveSplineInit init(me);
+ FillPath(me->GetPosition(), init.Path());
+ init.SetFly();
+ init.Launch();
+
+ events.ScheduleEvent(EVENT_SEISMIC_SHARD_MOUNT, 2400);
+ }
+
+ void UpdateAI(uint32 diff) override
+ {
+ events.Update(diff);
+
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case EVENT_SEISMIC_SHARD_MOUNT:
+ if (Creature* highPriestAzil = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_HIGH_PRIESTESS_AZIL)))
+ if (Vehicle* vehicle = highPriestAzil->GetVehicleKit())
+ me->EnterVehicle(highPriestAzil, vehicle->GetNextEmptySeat(0, false)->first);
+ break;
+ default:
+ break;
+ }
+ }
+
+ }
+
+ private:
+ void FillPath(Position const& pos, Movement::PointsArray& path)
+ {
+ G3D::Vector3 point;
+
+ point.x = pos.GetPositionX();
+ point.y = pos.GetPositionY();
+ point.z = pos.GetPositionZ();
+
+ point.x -= 1.0f;
+ path.push_back(point);
+
+ point.x += 1.0f;
+ path.push_back(point);
+
+ point.z += 25.0f;
+ path.push_back(point);
+
+ path.push_back(point);
+ }
+
+ InstanceScript* instance;
+ EventMap events;
+ };
+
+ CreatureAI* GetAI(Creature* creature) const override
+ {
+ return GetInstanceAI<npc_seismic_shardAI>(creature);
+ }
+};
+
+// 79200 - Summon Follower
+class spell_summon_wave_south : public SpellScriptLoader
+{
+public:
+ spell_summon_wave_south() : SpellScriptLoader("spell_summon_wave_south") { }
+
+ class spell_summon_wave_south_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_summon_wave_south_SpellScript);
+
+ bool Validate(SpellInfo const* /*spellInfo*/) override
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_SUMMON_ADD_SOUTH))
+ return false;
+ return true;
+ }
+
+ void HandleScript(SpellEffIndex /*effIndex*/)
+ {
+ Unit* caster = GetCaster();
+ for (uint8 i = 0; i < 3; i++)
+ GetCaster()->CastSpell(GetCaster(), SPELL_SUMMON_ADD_SOUTH, true);
+ }
+
+ void Register() override
+ {
+ OnEffectHitTarget += SpellEffectFn(spell_summon_wave_south_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
+ }
+ };
+
+ SpellScript* GetSpellScript() const override
+ {
+ return new spell_summon_wave_south_SpellScript();
+ }
+};
+
+// 79196 - Summon Follower
+class spell_summon_wave_west : public SpellScriptLoader
+{
+public:
+ spell_summon_wave_west() : SpellScriptLoader("spell_summon_wave_west") { }
+
+ class spell_summon_wave_west_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_summon_wave_west_SpellScript);
+
+ bool Validate(SpellInfo const* /*spellInfo*/) override
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_SUMMON_ADD_WEST))
+ return false;
+ return true;
+ }
+
+ void HandleScript(SpellEffIndex /*effIndex*/)
+ {
+ Unit* caster = GetCaster();
+ for (uint8 i = 0; i < 10; i++)
+ GetCaster()->CastSpell(GetCaster(), SPELL_SUMMON_ADD_WEST, true);
+ }
+
+ void Register() override
+ {
+ OnEffectHitTarget += SpellEffectFn(spell_summon_wave_west_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
+ }
+ };
+
+ SpellScript* GetSpellScript() const override
+ {
+ return new spell_summon_wave_west_SpellScript();
+ }
+};
+
+// 79251 - Gravity Well (casts damage spell on units within 10 yards)
+class PlayerPetOrDevoutFollowerCheck
+{
+public:
+ bool operator()(WorldObject* object) const
+ {
+ // Valid targets are players, pets and Devout Followers
+ if (Creature* creature = object->ToCreature())
+ return (!creature->ToPet() && object->GetEntry() != NPC_DEVOUT_FOLLOWER);
+ return (!object->ToPlayer());
+ }
+};
+
+class spell_gravity_well_damage_nearby : public SpellScriptLoader
+{
+public:
+ spell_gravity_well_damage_nearby() : SpellScriptLoader("spell_gravity_well_damage_nearby") { }
+
+ class spell_gravity_well_damage_nearby_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_gravity_well_damage_nearby_SpellScript);
+
+ void SetRadiusMod()
+ {
+ GetSpell()->SetSpellValue(SPELLVALUE_RADIUS_MOD, int32(GetCaster()->GetObjectScale() * 10000 * 2 / 3));
+ }
+
+ void FilterTargets(std::list<WorldObject*>& unitList)
+ {
+ unitList.remove_if(PlayerPetOrDevoutFollowerCheck());
+ }
+
+ void HandleScript(SpellEffIndex /*effIndex*/)
+ {
+ GetCaster()->CastSpell(GetHitUnit(), SPELL_GRAVITY_WELL_DAMAGE, true);
+ }
+
+ void Register() override
+ {
+ BeforeCast += SpellCastFn(spell_gravity_well_damage_nearby_SpellScript::SetRadiusMod);
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_gravity_well_damage_nearby_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
+ OnEffectHitTarget += SpellEffectFn(spell_gravity_well_damage_nearby_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
+ }
+ };
+
+ SpellScript* GetSpellScript() const override
+ {
+ return new spell_gravity_well_damage_nearby_SpellScript();
+ }
+};
+
+// 79249 - Gravity Well (damage)
+class spell_gravity_well_damage : public SpellScriptLoader
+{
+public:
+ spell_gravity_well_damage() : SpellScriptLoader("spell_gravity_well_damage") { }
+
+ class spell_gravity_well_damage_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_gravity_well_damage_SpellScript);
+
+ void CalculateDamage(SpellEffIndex /*effIndex*/)
+ {
+ Unit* target = GetHitUnit();
+ if (!target)
+ return;
+
+ float distance = GetCaster()->GetDistance2d(target);
+
+ if (target->GetEntry() == NPC_DEVOUT_FOLLOWER)
+ SetHitDamage(int32(200000 - (1000 * distance))); //need more research on this formula, damage values from sniffs: 189264, 190318, 190478, 196134, 197672, 199735
+ else
+ SetHitDamage(int32(4000 - (200 * distance)));
+ }
+
+ void Register() override
+ {
+ OnEffectHitTarget += SpellEffectFn(spell_gravity_well_damage_SpellScript::CalculateDamage, EFFECT_0, SPELL_EFFECT_SCHOOL_DAMAGE);
+ }
+ };
+
+ SpellScript* GetSpellScript() const override
+ {
+ return new spell_gravity_well_damage_SpellScript();
+ }
+};
+
+// 79332 - Gravity Well (pull units within 10 yards)
+class PulledRecentlyCheck
+{
+public:
+ bool operator()(WorldObject* object) const
+ {
+ return (object->ToUnit() && object->ToUnit()->HasAura(SPELL_GRAVITY_WELL_PULL));
+ }
+};
+
+class spell_gravity_well_pull : public SpellScriptLoader
+{
+public:
+ spell_gravity_well_pull() : SpellScriptLoader("spell_gravity_well_pull") { }
+
+ class spell_gravity_well_pull_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_gravity_well_pull_SpellScript);
+
+ void SetRadiusMod()
+ {
+ GetSpell()->SetSpellValue(SPELLVALUE_RADIUS_MOD, int32(GetCaster()->GetObjectScale() * 10000 * 2 / 3));
+ }
+
+ void FilterTargets(std::list<WorldObject*>& unitList)
+ {
+ unitList.remove_if(PulledRecentlyCheck());
+ }
+
+ void Register() override
+ {
+ BeforeCast += SpellCastFn(spell_gravity_well_pull_SpellScript::SetRadiusMod);
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_gravity_well_pull_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
+ }
+ };
+
+ SpellScript* GetSpellScript() const override
+ {
+ return new spell_gravity_well_pull_SpellScript();
+ }
+};
+
+// 86862 - Seismic Shard (forces target to cast 86863)
+class spell_seismic_shard_prepare : public SpellScriptLoader
+{
+public:
+ spell_seismic_shard_prepare() : SpellScriptLoader("spell_seismic_shard_prepare") { }
+
+ class spell_seismic_shard_prepare_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_seismic_shard_prepare_SpellScript);
+
+ void SetTarget(WorldObject*& target)
+ {
+ target = GetCaster()->FindNearestCreature(NPC_SEISMIC_SHARD, 50.0f);
+ }
+
+ void Register() override
+ {
+ OnObjectTargetSelect += SpellObjectTargetSelectFn(spell_seismic_shard_prepare_SpellScript::SetTarget, EFFECT_0, TARGET_UNIT_NEARBY_ENTRY);
+ }
+ };
+
+ SpellScript* GetSpellScript() const override
+ {
+ return new spell_seismic_shard_prepare_SpellScript();
+ }
+};
+
+// 86863 - Seismic Shard (moves shard to seat 0)
+class spell_seismic_shard_change_seat : public SpellScriptLoader
+{
+public:
+ spell_seismic_shard_change_seat() : SpellScriptLoader("spell_seismic_shard_change_seat") { }
+
+ class spell_seismic_shard_change_seat_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_seismic_shard_change_seat_SpellScript);
+
+ void SetTarget(WorldObject*& target)
+ {
+ if (InstanceScript* instance = GetCaster()->GetInstanceScript())
+ target = ObjectAccessor::GetCreature(*GetCaster(), instance->GetGuidData(DATA_HIGH_PRIESTESS_AZIL));
+ }
+
+ void ChangeSeat(SpellEffIndex /*effIndex*/)
+ {
+ GetCaster()->ExitVehicle();
+ if (GetHitUnit()->IsVehicle())
+ GetCaster()->EnterVehicle(GetHitUnit(), 0);
+ }
+
+ void Register() override
+ {
+ OnObjectTargetSelect += SpellObjectTargetSelectFn(spell_seismic_shard_change_seat_SpellScript::SetTarget, EFFECT_0, TARGET_UNIT_NEARBY_ENTRY);
+ OnEffectHitTarget += SpellEffectFn(spell_seismic_shard_change_seat_SpellScript::ChangeSeat, EFFECT_0, SPELL_EFFECT_APPLY_AURA);
+ }
+ };
+
+ SpellScript* GetSpellScript() const override
+ {
+ return new spell_seismic_shard_change_seat_SpellScript();
+ }
+};
+
+// 79015 - Seismic Shard (launches shard)
+class spell_seismic_shard : public SpellScriptLoader
+{
+public:
+ spell_seismic_shard() : SpellScriptLoader("spell_seismic_shard") { }
+
+ class spell_seismic_shard_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_seismic_shard_SpellScript);
+
+ void HandleScript(SpellEffIndex /*effIndex*/)
+ {
+ Creature* target = GetHitUnit()->ToCreature();
+ if (!target)
+ return;
+
+ target->ExitVehicle();
+ DynamicObject* dynamicObject = GetCaster()->GetDynObject(SPELL_SEISMIC_SHARD_TARGETING);
+ target->CastSpell(dynamicObject->GetPositionX(), dynamicObject->GetPositionY(), dynamicObject->GetPositionZ(), SPELL_SEISMIC_SHARD_MISSLE, true);
+ }
+
+ void Register() override
+ {
+ OnEffectHitTarget += SpellEffectFn(spell_seismic_shard_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
+ }
+ };
+
+ SpellScript* GetSpellScript() const override
+ {
+ return new spell_seismic_shard_SpellScript();
+ }
+};
+
+void AddSC_boss_high_priestess_azil()
+{
+ new boss_high_priestess_azil();
+ new npc_devout_follower();
+ new npc_gravity_well();
+ new npc_seismic_shard();
+ new spell_summon_wave_south();
+ new spell_summon_wave_west();
+ new spell_gravity_well_damage_nearby();
+ new spell_gravity_well_damage();
+ new spell_gravity_well_pull();
+ new spell_seismic_shard_prepare();
+ new spell_seismic_shard_change_seat();
+ new spell_seismic_shard();
+}
diff --git a/src/server/scripts/Maelstrom/Stonecore/boss_ozruk.cpp b/src/server/scripts/Maelstrom/Stonecore/boss_ozruk.cpp
new file mode 100644
index 00000000000..92c9bba4bc1
--- /dev/null
+++ b/src/server/scripts/Maelstrom/Stonecore/boss_ozruk.cpp
@@ -0,0 +1,287 @@
+/*
+ * 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 "ScriptMgr.h"
+#include "ScriptedCreature.h"
+#include "SpellScript.h"
+#include "SpellAuraEffects.h"
+#include "Vehicle.h"
+#include "stonecore.h"
+
+enum Spells
+{
+ SPELL_ELEMENTIUM_BULWARK = 78939,
+ SPELL_GROUND_SLAM = 78903,
+ SPELL_ELEMENTIUM_SPIKE_SHIELD = 78835,
+ SPELL_SHATTER = 78807,
+ SPELL_ENRAGE = 80467,
+
+ // Rupture Controller and Rupture
+ SPELL_RUPTURE = 92393,
+// SPELL_RUPTURE_SUMMON_CENTER? = 95669, // summons rupture 8 yards front
+// SPELL_RUPTURE_SUMMON_LEFT? = 95348, // summons rupture 3 yards left?
+// SPELL_RUPTURE_SUMMON_RIGHT? = 92383, // summons rupture 3 yards right?
+ SPELL_RUPTURE_DAMAGE = 92381,
+};
+
+enum NPCs
+{
+ NPC_BOUNCER_SPIKE = 42189,
+ NPC_RUPTURE_CONTROLLER = 49597,
+ NPC_RUPTURE = 49576,
+};
+
+enum Texts
+{
+ SAY_AGGRO = 0,
+ SAY_ELEMENTIUM_BULWARK = 1,
+ SAY_ELEMENTIUM_SPIKE_SHIELD = 2,
+ SAY_ENRAGE = 3,
+ SAY_DEATH = 4,
+};
+
+enum Events
+{
+ EVENT_NONE,
+
+ EVENT_ELEMENTIUM_BULWARK,
+ EVENT_GROUND_SLAM,
+ EVENT_ELEMENTIUM_SPIKE_SHIELD,
+ EVENT_SHATTER,
+ EVENT_ENRAGE,
+
+ EVENT_START_ATTACK,
+};
+
+// TO-DO:
+// - Find heroic sniffs and spawn Ruptures using spells commented above.
+// - Make Bouncer Spikes enter ozruk without jump animation.
+
+class boss_ozruk : public CreatureScript
+{
+ public:
+ boss_ozruk() : CreatureScript("boss_ozruk") { }
+
+ struct boss_ozrukAI : public BossAI
+ {
+ boss_ozrukAI(Creature* creature) : BossAI(creature, DATA_OZRUK) { }
+
+ void Reset() override
+ {
+ _Reset();
+
+ me->SetReactState(REACT_AGGRESSIVE);
+
+ events.ScheduleEvent(EVENT_ELEMENTIUM_BULWARK, 5000);
+ events.ScheduleEvent(EVENT_GROUND_SLAM, 10000);
+ events.ScheduleEvent(EVENT_ELEMENTIUM_SPIKE_SHIELD, 13000);
+
+ RemoveBouncerSpikes();
+ }
+
+ void EnterCombat(Unit* /*victim*/) override
+ {
+ _EnterCombat();
+
+ Talk(SAY_AGGRO);
+ }
+
+ void JustSummoned(Creature* summon) override
+ {
+ if (summon->GetEntry() != NPC_RUPTURE_CONTROLLER)
+ return;
+
+ summon->SetReactState(REACT_PASSIVE);
+ summon->CastSpell(summon, SPELL_RUPTURE, true);
+ summon->DespawnOrUnsummon(10000);
+ }
+
+ void DamageTaken(Unit* /*attacker*/, uint32 &damage) override
+ {
+ if (!me->HealthBelowPctDamaged(25, damage) || me->HasAura(SPELL_ENRAGE))
+ return;
+
+ DoCast(me, SPELL_ENRAGE);
+ me->Say(SAY_ENRAGE);
+ }
+
+ void JustDied(Unit* killer) override
+ {
+ me->Say(SAY_DEATH, killer); // receiver is the killer, sniff source!
+
+ RemoveBouncerSpikes();
+ }
+
+ void UpdateAI(uint32 diff) override
+ {
+ if (!UpdateVictim())
+ return;
+
+ events.Update(diff);
+
+ if (me->HasUnitState(UNIT_STATE_CASTING) || me->HasAura(SPELL_ELEMENTIUM_SPIKE_SHIELD))
+ return;
+
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case EVENT_ELEMENTIUM_BULWARK:
+ DoCast(me, SPELL_ELEMENTIUM_BULWARK);
+ Talk(SAY_ELEMENTIUM_BULWARK);
+ break;
+ case EVENT_GROUND_SLAM:
+ me->SetReactState(REACT_PASSIVE);
+ me->AttackStop();
+ DoCast(me, SPELL_GROUND_SLAM);
+ events.ScheduleEvent(EVENT_START_ATTACK, 4600);
+ break;
+ case EVENT_ELEMENTIUM_SPIKE_SHIELD:
+ DoCast(me, SPELL_ELEMENTIUM_SPIKE_SHIELD);
+ Talk(SAY_ELEMENTIUM_SPIKE_SHIELD);
+ events.ScheduleEvent(EVENT_SHATTER, 10000);
+ break;
+ case EVENT_SHATTER:
+ RemoveBouncerSpikes();
+ me->SetReactState(REACT_PASSIVE);
+ me->AttackStop();
+ DoCast(me, SPELL_SHATTER);
+ events.ScheduleEvent(EVENT_START_ATTACK, 4600);
+ // Spells are cast in same order everytime after Shatter, so we schedule them here
+ events.ScheduleEvent(EVENT_ELEMENTIUM_BULWARK, urand(3000,4000));
+ events.ScheduleEvent(EVENT_GROUND_SLAM, urand(7000,9000));
+ events.ScheduleEvent(EVENT_ELEMENTIUM_SPIKE_SHIELD, urand(10000,12000));
+ break;
+ case EVENT_START_ATTACK:
+ me->SetReactState(REACT_AGGRESSIVE);
+ break;
+ default:
+ break;
+ }
+ }
+
+ DoMeleeAttackIfReady();
+ }
+
+ void RemoveBouncerSpikes()
+ {
+ Vehicle* vehicle = me->GetVehicleKit();
+ if (!vehicle)
+ return;
+
+ for (uint8 i = 0; i < vehicle->GetAvailableSeatCount(); i++)
+ if (Unit* passenger = vehicle->GetPassenger(i))
+ if (Creature* creature = passenger->ToCreature())
+ creature->RemoveFromWorld();
+ }
+ };
+
+ CreatureAI* GetAI(Creature* creature) const override
+ {
+ return GetInstanceAI<boss_ozrukAI>(creature);
+ }
+};
+
+// 92393 - Rupture
+class spell_rupture : public SpellScriptLoader
+{
+public:
+ spell_rupture() : SpellScriptLoader("spell_rupture") { }
+
+ class spell_rupture_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_rupture_AuraScript);
+
+ void HandleEffectPeriodic(AuraEffect const* aurEff)
+ {
+ Unit* caster = GetCaster();
+
+ float dist = aurEff->GetTickNumber() * 8.0f;
+
+ // probably hack, should use spells (see Spells enum above)
+ Position pos = caster->GetNearPosition(dist, 0.0f);
+ SummonRupture(caster, pos);
+
+ pos = caster->GetNearPosition(dist, 0.2f);
+ SummonRupture(caster, pos);
+
+ pos = caster->GetNearPosition(dist, -0.2f);
+ SummonRupture(caster, pos);
+ }
+
+ void SummonRupture(Unit* caster, Position pos)
+ {
+ Creature* rupture = caster->SummonCreature(NPC_RUPTURE, pos, TEMPSUMMON_TIMED_DESPAWN, 2500);
+ if (!rupture)
+ return;
+
+ rupture->SetReactState(REACT_PASSIVE);
+ rupture->CastSpell(rupture, SPELL_RUPTURE_DAMAGE, true);
+ }
+
+ void Register()
+ {
+ OnEffectPeriodic += AuraEffectPeriodicFn(spell_rupture_AuraScript::HandleEffectPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL);
+ }
+ };
+
+ AuraScript* GetAuraScript() const
+ {
+ return new spell_rupture_AuraScript();
+ }
+};
+
+// 78835 - Elementium Spike Shield
+class spell_elementium_spike_shield : public SpellScriptLoader
+{
+public:
+ spell_elementium_spike_shield() : SpellScriptLoader("spell_elementium_spike_shield") { }
+
+ class spell_elementium_spike_shield_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_elementium_spike_shield_SpellScript);
+
+ void HandleBouncerSpikes()
+ {
+ Unit* caster = GetCaster();
+ Vehicle* vehicle = caster->GetVehicleKit();
+ if (!vehicle)
+ return;
+
+ for (uint8 i = 0; i < vehicle->GetAvailableSeatCount(); i++)
+ if (Creature* summon = caster->SummonCreature(NPC_BOUNCER_SPIKE, caster->GetPosition(), TEMPSUMMON_TIMED_DESPAWN, 10000))
+ summon->EnterVehicle(caster, i);
+ }
+
+ void Register() override
+ {
+ OnCast += SpellCastFn(spell_elementium_spike_shield_SpellScript::HandleBouncerSpikes);
+ }
+ };
+
+ SpellScript* GetSpellScript() const override
+ {
+ return new spell_elementium_spike_shield_SpellScript();
+ }
+};
+
+void AddSC_boss_ozruk()
+{
+ new boss_ozruk();
+ new spell_rupture();
+ new spell_elementium_spike_shield();
+}
diff --git a/src/server/scripts/Maelstrom/Stonecore/boss_slabhide.cpp b/src/server/scripts/Maelstrom/Stonecore/boss_slabhide.cpp
new file mode 100644
index 00000000000..6827312deef
--- /dev/null
+++ b/src/server/scripts/Maelstrom/Stonecore/boss_slabhide.cpp
@@ -0,0 +1,599 @@
+/*
+ * 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 "ScriptMgr.h"
+#include "ScriptedCreature.h"
+#include "SpellScript.h"
+#include "stonecore.h"
+
+enum Spells
+{
+ SPELL_FACE_RANDOM_PLAYER = 82530,
+
+ // Stalactite Trigger - Trash, On Ground
+ SPELL_STALACTITE_SUMMON_TRIGGER = 81028,
+
+ // Slabhide
+ SPELL_LAVA_FISSURE = 80803,
+ SPELL_SAND_BLAST = 80807,
+ SPELL_STALACTITE_SUMMON = 80656,
+// SPELL_COOLDOWN_5S = 95323, Cooldown: Creature Special 1 (5s)?
+ SPELL_CRYSTAL_STORM = 92305,
+ SPELL_CRYSTAL_STORM_TRIGGER = 92265,
+
+ // Lava Fissure
+ SPELL_LAVA_FISSURE_CRACK = 80798,
+ SPELL_LAVA_FISSURE_ERUPTION = 80800,
+
+ // Stalactite Trigger - Boss
+ SPELL_STALACTITE_SHADE = 80654,
+ SPELL_STALACTITE_MISSLE = 80643,
+ SPELL_STALACTITE_CREATE = 80647,
+};
+
+enum Entries
+{
+ NPC_LAVA_FISSURE = 43242,
+ NPC_STALACTITE_TRIGGER_GROUND = 43357,
+ NPC_STALACTITE_TRIGGER = 43159,
+ GO_STALACTITE = 204337,
+};
+
+enum Actions
+{
+ ACTION_STALACTITE_MISSLE,
+};
+
+enum Events
+{
+ EVENT_NONE,
+
+ // Intro events
+ EVENT_ROAR_EMOTE,
+
+ // Slabhide combat
+ EVENT_HANDLE_ROCK_WALLS,
+ EVENT_LAVA_FISSURE,
+ EVENT_SAND_BLAST,
+ EVENT_AIR_PHASE,
+ EVENT_TAKEOFF,
+ EVENT_STALACTITE,
+ EVENT_LAND,
+ EVENT_ATTACK,
+
+ // Lava Fissure
+ EVENT_LAVA_FISSURE_ERUPTION,
+
+ // Stalactite Trigger - Boss
+ EVENT_STALACTITE_MISSLE,
+};
+
+enum MovementPoints
+{
+ POINT_NONE,
+
+ POINT_SLABHIDE_INTRO,
+ POINT_SLABHIDE_INTRO_LAND,
+
+ POINT_SLABHIDE_MIDDLE,
+ POINT_SLABHIDE_IN_AIR,
+ POINT_SLABHIDE_LAND,
+};
+
+Position const SlabhideIntroPos = { 1292.27f, 1226.16f, 265.573f };
+Position const SlabhideIntroLandPos = { 1292.352f, 1226.478f, 247.6368f, 3.630285f };
+
+Position const SlabhideMiddlePos = { 1280.73f, 1212.31f, 247.3837f };
+Position const SlabhideInAirPos = { 1280.73f, 1212.31f, 257.3837f };
+Position const SlabhideLandPos = { 1282.7f, 1229.77f, 247.155f, 3.82227f };
+
+class boss_slabhide : public CreatureScript
+{
+ public:
+ boss_slabhide() : CreatureScript("boss_slabhide") { }
+
+ struct boss_slabhideAI : public BossAI
+ {
+ boss_slabhideAI(Creature* creature) : BossAI(creature, DATA_SLABHIDE)
+ {
+ me->setActive(true);
+ me->SetCanFly(true);
+ me->SetDisableGravity(true);
+ me->SetByteFlag(UNIT_FIELD_BYTES_1, 3, UNIT_BYTE1_FLAG_ALWAYS_STAND | UNIT_BYTE1_FLAG_HOVER);
+ me->SetReactState(REACT_PASSIVE);
+ instance->SetData(DATA_SLABHIDE_INTRO, NOT_STARTED);
+ }
+
+ void Reset()
+ {
+ if (instance->GetData(DATA_SLABHIDE_INTRO) == NOT_STARTED)
+ return;
+
+ _Reset();
+ DespawnAll();
+
+ me->SetCanFly(false);
+ me->SetDisableGravity(false);
+ me->RemoveByteFlag(UNIT_FIELD_BYTES_1, 3, UNIT_BYTE1_FLAG_ALWAYS_STAND | UNIT_BYTE1_FLAG_HOVER);
+ me->SetReactState(REACT_AGGRESSIVE);
+ }
+
+ void EnterCombat(Unit* /*victim*/) override
+ {
+ _EnterCombat();
+
+ events.ScheduleEvent(EVENT_HANDLE_ROCK_WALLS, 4000);
+ events.ScheduleEvent(EVENT_LAVA_FISSURE, urand(6000, 8000));
+ events.ScheduleEvent(EVENT_SAND_BLAST, urand(8000, 10000));
+ events.ScheduleEvent(EVENT_AIR_PHASE, 10000);
+ }
+
+ void JustDied(Unit* /*killer*/) override
+ {
+ _JustDied();
+
+ // Despawn related npcs and gameobjects
+ DespawnAll();
+ }
+
+ void DoAction(int32 action) override
+ {
+ switch (action)
+ {
+ case ACTION_SLABHIDE_INTRO:
+ {
+ if (instance->GetData(DATA_SLABHIDE_INTRO) != NOT_STARTED)
+ return;
+
+ instance->SetData(DATA_SLABHIDE_INTRO, IN_PROGRESS);
+
+ // Execute Slabhide intro event
+ me->GetMotionMaster()->MovePoint(POINT_SLABHIDE_INTRO, SlabhideIntroPos);
+ break;
+ }
+ default:
+ break;
+ }
+ }
+
+ void MovementInform(uint32 type, uint32 id) override
+ {
+ if (type != POINT_MOTION_TYPE && type != EFFECT_MOTION_TYPE)
+ return;
+
+ switch (id)
+ {
+ case POINT_SLABHIDE_INTRO:
+ me->SetFacingTo(SlabhideIntroLandPos.GetOrientation());
+ me->GetMotionMaster()->MoveLand(POINT_SLABHIDE_INTRO_LAND, SlabhideIntroLandPos);
+ break;
+ case POINT_SLABHIDE_INTRO_LAND:
+ me->SetCanFly(false);
+ me->SetDisableGravity(false);
+ me->RemoveByteFlag(UNIT_FIELD_BYTES_1, 3, UNIT_BYTE1_FLAG_ALWAYS_STAND | UNIT_BYTE1_FLAG_HOVER);
+ me->SetHover(false);
+ me->SetHomePosition(SlabhideIntroLandPos);
+ me->HandleEmoteCommand(EMOTE_ONESHOT_ROAR);
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ me->SetReactState(REACT_AGGRESSIVE);
+ instance->SetData(DATA_SLABHIDE_INTRO, DONE);
+ break;
+ case POINT_SLABHIDE_MIDDLE:
+ events.ScheduleEvent(EVENT_TAKEOFF, 100);
+ break;
+ case POINT_SLABHIDE_IN_AIR:
+ events.ScheduleEvent(EVENT_STALACTITE, 400);
+ break;
+ case POINT_SLABHIDE_LAND:
+ //DoCast(SPELL_COOLDOWN_5S); // unknown purpose
+ events.ScheduleEvent(EVENT_ATTACK, 1200);
+ break;
+ default:
+ break;
+ }
+ }
+
+ void UpdateAI(uint32 diff) override
+ {
+ if (!UpdateVictim())
+ return;
+
+ events.Update(diff);
+
+ if (me->HasUnitState(UNIT_STATE_CASTING))
+ return;
+
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case EVENT_HANDLE_ROCK_WALLS: // Close rock walls
+ instance->SetData(DATA_SLABHIDE_ROCK_WALL, false);
+ break;
+ case EVENT_LAVA_FISSURE:
+ DoCast(SPELL_LAVA_FISSURE);
+ events.ScheduleEvent(EVENT_LAVA_FISSURE, urand(6000, 8000));
+ break;
+ case EVENT_SAND_BLAST:
+ DoCast(SPELL_SAND_BLAST);
+ events.ScheduleEvent(EVENT_SAND_BLAST, urand(8000, 11000));
+ break;
+ case EVENT_AIR_PHASE:
+ events.Reset();
+ me->SetReactState(REACT_PASSIVE);
+ me->AttackStop();
+ me->GetMotionMaster()->MovePoint(POINT_SLABHIDE_MIDDLE, SlabhideMiddlePos);
+ events.ScheduleEvent(EVENT_AIR_PHASE, 60000);
+ break;
+ case EVENT_TAKEOFF:
+ me->GetMotionMaster()->MoveTakeoff(POINT_SLABHIDE_IN_AIR, SlabhideInAirPos);
+ break;
+ case EVENT_STALACTITE:
+ me->SetCanFly(true);
+ me->SetDisableGravity(true);
+ me->SetByteFlag(UNIT_FIELD_BYTES_1, 3, UNIT_BYTE1_FLAG_ALWAYS_STAND | UNIT_BYTE1_FLAG_HOVER);
+ me->SetHover(true);
+
+ DoCast(SPELL_STALACTITE_SUMMON);
+
+ events.ScheduleEvent(EVENT_LAND, 8000);
+ break;
+ case EVENT_LAND:
+ {
+ Position pos = me->GetPosition();
+ pos.m_positionZ = me->GetMap()->GetHeight(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ());
+ me->GetMotionMaster()->MoveLand(POINT_SLABHIDE_LAND, pos);
+ break;
+ }
+ case EVENT_ATTACK:
+ me->SetCanFly(false);
+ me->SetDisableGravity(false);
+ me->RemoveByteFlag(UNIT_FIELD_BYTES_1, 3, UNIT_BYTE1_FLAG_ALWAYS_STAND | UNIT_BYTE1_FLAG_HOVER);
+ me->SetHover(false);
+
+ events.ScheduleEvent(EVENT_LAVA_FISSURE, urand(6000, 8000));
+ events.ScheduleEvent(EVENT_SAND_BLAST, urand(8000, 10000));
+ DoCast(SPELL_CRYSTAL_STORM);
+ me->SetReactState(REACT_AGGRESSIVE);
+ break;
+ default:
+ break;
+ }
+ }
+
+ DoMeleeAttackIfReady();
+ }
+
+ private:
+ void DespawnAll()
+ {
+ // Despawn stalactite triggers npcs
+ std::list<Creature*> listStalactiteTrigger;
+ me->GetCreatureListWithEntryInGrid(listStalactiteTrigger, NPC_STALACTITE_TRIGGER, 200.0f);
+ if (!listStalactiteTrigger.empty())
+ for (std::list<Creature*>::const_iterator itr = listStalactiteTrigger.begin(); itr != listStalactiteTrigger.end(); ++itr)
+ (*itr)->DespawnOrUnsummon();
+
+ // Despawn stalactite objects
+ std::list<GameObject*> listStalactite;
+ me->GetGameObjectListWithEntryInGrid(listStalactite, GO_STALACTITE, 200.0f);
+ if (!listStalactite.empty())
+ for (std::list<GameObject*>::const_iterator itr = listStalactite.begin(); itr != listStalactite.end(); ++itr)
+ (*itr)->Delete();
+ }
+
+ EventMap events;
+ };
+
+ CreatureAI* GetAI(Creature* creature) const override
+ {
+ return GetInstanceAI<boss_slabhideAI>(creature);
+ }
+};
+
+// 43242 - Lava Fissure
+class npc_lava_fissure : public CreatureScript
+{
+public:
+ npc_lava_fissure() : CreatureScript("npc_lava_fissure") { }
+
+ struct npc_lava_fissureAI : public ScriptedAI
+ {
+ npc_lava_fissureAI(Creature* creature) : ScriptedAI(creature)
+ {
+ me->SetReactState(REACT_PASSIVE);
+ me->CastSpell(me, SPELL_LAVA_FISSURE_CRACK, true);
+ events.ScheduleEvent(EVENT_LAVA_FISSURE_ERUPTION, 6000);
+ }
+
+ void UpdateAI(uint32 diff) override
+ {
+ events.Update(diff);
+
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case EVENT_LAVA_FISSURE_ERUPTION:
+ me->RemoveAurasDueToSpell(SPELL_LAVA_FISSURE_CRACK);
+ me->CastSpell(me, SPELL_LAVA_FISSURE_ERUPTION, true);
+ me->DespawnOrUnsummon(14000);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ private:
+ EventMap events;
+ };
+
+ CreatureAI* GetAI(Creature* creature) const override
+ {
+ return GetInstanceAI<npc_lava_fissureAI>(creature);
+ }
+};
+
+// 43159 - Stalactite Trigger - Boss
+class npc_stalactite_trigger : public CreatureScript
+{
+public:
+ npc_stalactite_trigger() : CreatureScript("npc_stalactite_trigger") { }
+
+ struct npc_stalactite_triggerAI : public ScriptedAI
+ {
+ npc_stalactite_triggerAI(Creature* creature) : ScriptedAI(creature)
+ {
+ me->SetReactState(REACT_PASSIVE);
+ me->SetDisableGravity(true);
+ me->CastSpell(me, SPELL_STALACTITE_SHADE, true);
+ events.ScheduleEvent(EVENT_STALACTITE_MISSLE, 5600);
+ }
+
+ void UpdateAI(uint32 diff) override
+ {
+ events.Update(diff);
+
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case EVENT_STALACTITE_MISSLE:
+ DoCast(SPELL_STALACTITE_MISSLE);
+ me->DespawnOrUnsummon(11000);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ private:
+ EventMap events;
+ };
+
+ CreatureAI* GetAI(Creature* creature) const override
+ {
+ return GetInstanceAI<npc_stalactite_triggerAI>(creature);
+ }
+};
+
+// 81035 - Stalactite (check if player is near to summon stalactite)
+class NotPlayerCheck
+{
+ public:
+ bool operator()(WorldObject* object) const
+ {
+ return (object->GetTypeId() != TYPEID_PLAYER);
+ }
+};
+
+class spell_s81035_stalactite : public SpellScriptLoader
+{
+public:
+ spell_s81035_stalactite() : SpellScriptLoader("spell_s81035_stalactite") { }
+
+ class spell_s81035_stalactite_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_s81035_stalactite_SpellScript);
+
+ void FilterTargets(std::list<WorldObject*>& targets)
+ {
+ targets.remove_if(NotPlayerCheck());
+ }
+
+ void SummonStalactiteTrigger()
+ {
+ Unit* caster = GetCaster();
+ caster->CastSpell(caster, SPELL_STALACTITE_SUMMON_TRIGGER, true);
+ }
+
+ void Register() override
+ {
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_s81035_stalactite_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
+ OnHit += SpellHitFn(spell_s81035_stalactite_SpellScript::SummonStalactiteTrigger);
+ }
+ };
+
+ SpellScript* GetSpellScript() const override
+ {
+ return new spell_s81035_stalactite_SpellScript();
+ }
+};
+
+// 81028 - Stalactite (summons "Stalactite Trigger - Boss", 20 yard radius)
+// 80650 - Stalactite (summons "Stalactite Trigger - Boss", 40 yard radius)
+class spell_s81028_s80650_stalactite : public SpellScriptLoader
+{
+public:
+ spell_s81028_s80650_stalactite() : SpellScriptLoader("spell_s81028_s80650_stalactite") { }
+
+ class spell_s81028_s80650_stalactite_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_s81028_s80650_stalactite_SpellScript);
+
+ void ModDestHeight(SpellDestination& dest)
+ {
+ // All stalactite triggers should have Z position 301.3837f, but no way to relocate (not relocateoffset!) height only.
+ Position offset = { 0.0f, 0.0f, 50.0f, 0.0f };
+ dest.RelocateOffset(offset);
+ }
+
+ void Register() override
+ {
+ OnDestinationTargetSelect += SpellDestinationTargetSelectFn(spell_s81028_s80650_stalactite_SpellScript::ModDestHeight, EFFECT_0, TARGET_DEST_CASTER_RANDOM);
+ }
+ };
+
+ SpellScript* GetSpellScript() const override
+ {
+ return new spell_s81028_s80650_stalactite_SpellScript();
+ }
+};
+
+// 80654 - Stalactite (creates visual shade on ground)
+// 80643/92653 - Stalactite (launches missle to the ground)
+// 80647/92309 - Stalactite (creates stalactite object)
+class spell_stalactite_mod_dest_height : public SpellScriptLoader
+{
+public:
+ spell_stalactite_mod_dest_height() : SpellScriptLoader("spell_stalactite_mod_dest_height") { }
+
+ class spell_stalactite_mod_dest_height_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_stalactite_mod_dest_height_SpellScript);
+
+ void ModDestHeight(SpellDestination& dest)
+ {
+ Unit* caster = GetCaster();
+ Position pos = caster->GetPosition();
+ pos.m_positionZ = caster->GetMap()->GetHeight(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), true, 100.0f);
+ dest.Relocate(pos);
+ }
+
+ void Register() override
+ {
+ OnDestinationTargetSelect += SpellDestinationTargetSelectFn(spell_stalactite_mod_dest_height_SpellScript::ModDestHeight, EFFECT_0, TARGET_DEST_CASTER);
+ }
+ };
+
+ SpellScript* GetSpellScript() const override
+ {
+ return new spell_stalactite_mod_dest_height_SpellScript();
+ }
+};
+
+// 92306 - Crystal storm (heroic mode check)
+class spell_s92306_crystal_storm : public SpellScriptLoader
+{
+public:
+ spell_s92306_crystal_storm() : SpellScriptLoader("spell_s92306_crystal_storm") { }
+
+ class spell_s92306_crystal_storm_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_s92306_crystal_storm_SpellScript);
+
+ bool Validate(SpellInfo const* /*spellInfo*/) override
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_CRYSTAL_STORM_TRIGGER))
+ return false;
+ return true;
+ }
+
+ void HandleDummyEffect(SpellEffIndex /*eff*/)
+ {
+ Unit* caster = GetCaster();
+ if (caster->GetMap()->IsHeroic())
+ caster->CastSpell(caster, SPELL_CRYSTAL_STORM_TRIGGER, true);
+ }
+
+ void Register() override
+ {
+ OnEffectHitTarget += SpellEffectFn(spell_s92306_crystal_storm_SpellScript::HandleDummyEffect, EFFECT_0, SPELL_EFFECT_APPLY_AURA);
+ }
+ };
+
+ SpellScript* GetSpellScript() const override
+ {
+ return new spell_s92306_crystal_storm_SpellScript();
+ }
+};
+
+// 92300 - Crystal Storm (damage)
+class BehindObjectCheck
+{
+ public:
+ BehindObjectCheck(Unit* caster, std::list<GameObject*> objectList) : caster(caster), objectList(objectList) { }
+
+ bool operator()(WorldObject* unit)
+ {
+ for (std::list<GameObject*>::const_iterator itr = objectList.begin(); itr != objectList.end(); ++itr)
+ if (!(*itr)->IsInvisibleDueToDespawn() && (*itr)->IsInBetween(caster, unit, 1.5f))
+ return true;
+ return false;
+ }
+
+ private:
+ Unit* caster;
+ std::list<GameObject*> objectList;
+};
+
+class spell_s92300_crystal_storm : public SpellScriptLoader
+{
+public:
+ spell_s92300_crystal_storm() : SpellScriptLoader("spell_s92300_crystal_storm") { }
+
+ class spell_s92300_crystal_storm_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_s92300_crystal_storm_SpellScript);
+
+ void FilterTargets(std::list<WorldObject*>& unitList)
+ {
+ Unit* caster = GetCaster();
+
+ std::list<GameObject*> goList;
+ caster->GetGameObjectListWithEntryInGrid(goList, GO_STALACTITE, 40.0f);
+ if (goList.empty())
+ return;
+
+ unitList.remove_if(BehindObjectCheck(caster, goList));
+ }
+
+ void Register() override
+ {
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_s92300_crystal_storm_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
+ }
+ };
+
+ SpellScript* GetSpellScript() const override
+ {
+ return new spell_s92300_crystal_storm_SpellScript();
+ }
+};
+
+void AddSC_boss_slabhide()
+{
+ new boss_slabhide();
+ new npc_lava_fissure();
+ new npc_stalactite_trigger();
+ new spell_s81035_stalactite();
+ new spell_s81028_s80650_stalactite();
+ new spell_stalactite_mod_dest_height();
+ new spell_s92306_crystal_storm();
+ new spell_s92300_crystal_storm();
+}
diff --git a/src/server/scripts/Maelstrom/Stonecore/instance_stonecore.cpp b/src/server/scripts/Maelstrom/Stonecore/instance_stonecore.cpp
new file mode 100644
index 00000000000..ca5e40ab117
--- /dev/null
+++ b/src/server/scripts/Maelstrom/Stonecore/instance_stonecore.cpp
@@ -0,0 +1,262 @@
+/*
+* Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
+* Copyright (C) 2006-2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+*
+* This program is free software; you can redistribute it and/or modify it
+* under the terms of the GNU General Public License as published by the
+* Free Software Foundation; either version 2 of the License, or (at your
+* option) any later version.
+*
+* This program is distributed in the hope that it will be useful, but WITHOUT
+* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+* more details.
+*
+* You should have received a copy of the GNU General Public License along
+* with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "ScriptMgr.h"
+#include "Player.h"
+#include "CreatureGroups.h"
+#include "InstanceScript.h"
+#include "stonecore.h"
+
+#define MAX_ENCOUNTER 4
+
+/* Stonecore encounters:
+0 - Corborus
+1 - Slabhide
+2 - Ozruk
+3 - High Priestess Azil
+*/
+
+// TO-DO:
+// - Find out spell IDs for both Stonecore Teleporters (spellclick).
+
+class instance_stonecore : public InstanceMapScript
+{
+ public:
+ instance_stonecore() : InstanceMapScript(SCScriptName, 725) { }
+
+ struct instance_stonecore_InstanceScript : public InstanceScript
+ {
+ instance_stonecore_InstanceScript(Map* map) : InstanceScript(map)
+ {
+ SetHeaders(DataHeader);
+ SetBossNumber(MAX_ENCOUNTER);
+ }
+
+ void OnGameObjectCreate(GameObject* go) override
+ {
+ switch (go->GetEntry())
+ {
+ case GAMEOBJECT_CORBORUS_ROCKDOOR:
+ corborusRockDoorGUID = go->GetGUID();
+ go->SetGoState(GetBossState(DATA_CORBORUS) != DONE ? GO_STATE_READY : GO_STATE_ACTIVE);
+ break;
+ case GAMEOBJECT_SLABHIDE_ROCK_WALL:
+ slabhideRockWallGUIDs.push_back(go->GetGUID());
+ break;
+ default:
+ break;
+ }
+ }
+
+ void OnCreatureCreate(Creature* creature) override
+ {
+ switch (creature->GetEntry())
+ {
+ case NPC_MILLHOUSE_MANASTORM:
+ millhouseGUID = creature->GetGUID();
+ break;
+ case NPC_CORBORUS:
+ corobrusGUID = creature->GetGUID();
+ break;
+ case NPC_SLABHIDE:
+ slabhideGUID = creature->GetGUID();
+ break;
+ case NPC_HIGH_PRIESTESS_AZIL:
+ highPriestessAzilGUID = creature->GetGUID();
+ break;
+ case NPC_STONECORE_TELEPORTER:
+ case NPC_STONECORE_TELEPORTER_2:
+ if (GetBossState(DATA_SLABHIDE) != DONE)
+ stonecoreTeleporterGUID[creature->GetEntry() - NPC_STONECORE_TELEPORTER] = creature->GetGUID();
+ else // If Slabhide is already dead, no need to store teleporter guids
+ {
+ creature->CastSpell(creature, SPELL_TELEPORTER_ACTIVE_VISUAL, true);
+ creature->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK);
+ }
+ break;
+ default:
+ break;
+ }
+
+ // Check if creature is part of Millhouse event
+ creature->SearchFormation();
+ if (CreatureGroup* group = creature->GetFormation()) // TO-DO: Fix formations
+ {
+ switch (group->GetId())
+ {
+ case CREATURE_FORMATION_MILLHOUSE_EVENT_TRASH:
+ millhouseTrashGUIDs.push_back(creature->GetGUID());
+ break;
+ case CREATURE_FORMATION_MILLHOUSE_EVENT_LAST_GROUP:
+ millhouseLastGroupGUIDs.push_back(creature->GetGUID());
+ creature->SetReactState(REACT_PASSIVE);
+ creature->SetMeleeAnimKitId(ANIM_READY2H);
+ break;
+ }
+ }
+ }
+
+ bool SetBossState(uint32 type, EncounterState state) override
+ {
+ switch (type)
+ {
+ case DATA_SLABHIDE:
+ // Open rock walls (Slabhide AI handles closing because it must be delayed)
+ if (state != IN_PROGRESS)
+ SetData(DATA_SLABHIDE_ROCK_WALL, true);
+
+ // Activate teleporters
+ if (state == DONE)
+ {
+ for (int8 i = 0; i < MAX_STONECORE_TELEPORTERS; i++)
+ {
+ if (Creature* teleporter = instance->GetCreature(stonecoreTeleporterGUID[i]))
+ {
+ teleporter->CastSpell(teleporter, SPELL_TELEPORTER_ACTIVE_VISUAL, true);
+ teleporter->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK);
+ }
+ }
+ }
+
+ break;
+ default:
+ break;
+ }
+
+ return InstanceScript::SetBossState(type, state);
+ }
+
+ uint32 GetData(uint32 type) const override
+ {
+ switch (type)
+ {
+ case DATA_SLABHIDE_INTRO:
+ return slabhideIntro;
+ default:
+ break;
+ }
+
+ return 0;
+ }
+
+ void SetData(uint32 type, uint32 data) override
+ {
+ switch (type)
+ {
+ case DATA_MILLHOUSE_EVENT_FACE:
+ MillhouseEvent_Face();
+ break;
+ case DATA_MILLHOUSE_EVENT_KNOCKBACK:
+ MillhouseEvent_Knockback();
+ break;
+ case DATA_MILLHOUSE_EVENT_DESPAWN:
+ MillhouseEvent_Despawn();
+ break;
+ case DATA_SLABHIDE_INTRO:
+ slabhideIntro = EncounterState(data);
+ break;
+ case DATA_SLABHIDE_ROCK_WALL: // Handles rock walls
+ for (std::vector<ObjectGuid>::iterator itr = slabhideRockWallGUIDs.begin(); itr != slabhideRockWallGUIDs.end(); ++itr)
+ HandleGameObject((*itr), data ? true : false);
+ break;
+ default:
+ break;
+ }
+ }
+
+ ObjectGuid GetGuidData(uint32 type) const override
+ {
+ switch (type)
+ {
+ case DATA_MILLHOUSE_MANASTORM:
+ return millhouseGUID;
+ case GAMEOBJECT_CORBORUS_ROCKDOOR:
+ return corborusRockDoorGUID;
+ case DATA_CORBORUS:
+ return corobrusGUID;
+ case DATA_SLABHIDE:
+ return slabhideGUID;
+ case DATA_HIGH_PRIESTESS_AZIL:
+ return highPriestessAzilGUID;
+ case NPC_STONECORE_TELEPORTER:
+ case NPC_STONECORE_TELEPORTER_2:
+ return stonecoreTeleporterGUID[type - NPC_STONECORE_TELEPORTER];
+ default:
+ break;
+ }
+
+ return ObjectGuid::Empty;
+ }
+
+ private:
+ // Face Millhouse and other nearby mobs to Corborus
+ void MillhouseEvent_Face()
+ {
+ if (Creature* Millhouse = instance->GetCreature(millhouseGUID))
+ Millhouse->SetFacingTo(1.570796f);
+ for (GuidVector::const_iterator i = millhouseLastGroupGUIDs.begin(); i != millhouseLastGroupGUIDs.end(); ++i)
+ if (Creature* creature = instance->GetCreature(*i))
+ creature->SetFacingTo(1.570796f);
+ }
+
+ // Knock back Millhouse and other mobs
+ void MillhouseEvent_Knockback()
+ {
+ if (Creature* Millhouse = instance->GetCreature(millhouseGUID))
+ Millhouse->CastSpell(Millhouse, SPELL_RING_WYRM_KNOCKBACK, true);
+ for (GuidVector::const_iterator itr = millhouseLastGroupGUIDs.begin(); itr != millhouseLastGroupGUIDs.end(); ++itr)
+ if (Creature* creature = instance->GetCreature(*itr))
+ creature->CastSpell(creature, SPELL_RING_WYRM_KNOCKBACK, true);
+ }
+
+ // Despawn all mobs
+ void MillhouseEvent_Despawn()
+ {
+ if (Creature* Millhouse = instance->GetCreature(millhouseGUID))
+ Millhouse->DespawnOrUnsummon(3000);
+ for (GuidVector::const_iterator itr = millhouseTrashGUIDs.begin(); itr != millhouseTrashGUIDs.end(); ++itr)
+ if (Creature* creature = instance->GetCreature(*itr))
+ creature->DespawnOrUnsummon(3000);
+ for (GuidVector::const_iterator itr = millhouseLastGroupGUIDs.begin(); itr != millhouseLastGroupGUIDs.end(); ++itr)
+ if (Creature* creature = instance->GetCreature(*itr))
+ creature->DespawnOrUnsummon(3000);
+ }
+
+ ObjectGuid millhouseGUID;
+ GuidVector millhouseTrashGUIDs;
+ GuidVector millhouseLastGroupGUIDs;
+ ObjectGuid corborusRockDoorGUID;
+ ObjectGuid corobrusGUID;
+ ObjectGuid slabhideGUID;
+ ObjectGuid highPriestessAzilGUID;
+ ObjectGuid stonecoreTeleporterGUID[2];
+ GuidVector slabhideRockWallGUIDs;
+
+ EncounterState slabhideIntro;
+ };
+
+ InstanceScript* GetInstanceScript(InstanceMap* map) const override
+ {
+ return new instance_stonecore_InstanceScript(map);
+ }
+};
+
+void AddSC_instance_stonecore()
+{
+ new instance_stonecore();
+}
diff --git a/src/server/scripts/Maelstrom/Stonecore/stonecore.cpp b/src/server/scripts/Maelstrom/Stonecore/stonecore.cpp
new file mode 100644
index 00000000000..4ed84732eff
--- /dev/null
+++ b/src/server/scripts/Maelstrom/Stonecore/stonecore.cpp
@@ -0,0 +1,442 @@
+/*
+ * 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 "ObjectGuid.h"
+#include "ObjectMgr.h"
+#include "ScriptMgr.h"
+#include "ScriptedCreature.h"
+#include "SpellScript.h"
+#include "Player.h"
+#include "stonecore.h"
+
+enum Texts
+{
+ // Millhouse Manastorm
+ SAY_MILLHOUSE_EVENT_1 = 0,
+ SAY_MILLHOUSE_EVENT_2 = 1,
+};
+
+enum NPCs
+{
+ NPC_GENERIC_TRIGGER_LAB = 40350,
+};
+
+enum Spells
+{
+ // Millhouse Manastorm
+ SPELL_SHADOW_BOLT = 81439,
+ SPELL_FROSTBOLT_VOLLEY = 81440,
+ SPELL_SHADOWFURY = 81441,
+ SPELL_FEAR = 81442,
+// SPELL_MILLHOUSE_SAFE_CHECK = 81213, // unknown purpose
+ SPELL_CLEAR_ALL_DEBUFFS = 34098,
+ SPELL_BLUR = 81216,
+ SPELL_ANCHOR_HERE = 45313,
+ SPELL_TIGULE_AND_FORORS_SPECIAL_BLEND = 81220,
+ SPELL_IMPENDING_DOOM = 86838,
+ SPELL_IMPENDING_DOOM_CHANNEL = 86830,
+
+// SPELL_PORTAL_VISUAL = 79754,
+};
+
+enum Events
+{
+ EVENT_NONE,
+
+ // Millhouse Manastorm
+ EVENT_FROSTBOLT_VOLLEY,
+ EVENT_SHADOWFURY,
+ EVENT_FEAR,
+
+ EVENT_READY_FOR_COMBAT,
+ EVENT_CAST_IMPENDING_DOOM,
+ EVENT_INTERRUPT_IMPENDING_DOOM,
+};
+
+enum Phase
+{
+ PHASE_NONE,
+
+ PHASE_MILLHOUSE_GROUP_1,
+ PHASE_MILLHOUSE_GROUP_2,
+ PHASE_MILLHOUSE_GROUP_3,
+ PHASE_MILLHOUSE_GROUP_4,
+
+ PHASE_MASK_MILLHOUSE_GROUP_1 = (1 << (PHASE_MILLHOUSE_GROUP_1 - 1)),
+ PHASE_MASK_MILLHOUSE_GROUP_2 = (1 << (PHASE_MILLHOUSE_GROUP_2 - 1)),
+ PHASE_MASK_MILLHOUSE_GROUP_3 = (1 << (PHASE_MILLHOUSE_GROUP_3 - 1)),
+ PHASE_MASK_MILLHOUSE_GROUP_4 = (1 << (PHASE_MILLHOUSE_GROUP_4 - 1)),
+};
+
+enum MovementPoints
+{
+ POINT_NONE,
+
+ POINT_MILLHOUSE_GROUP_2,
+ POINT_MILLHOUSE_GROUP_3,
+ POINT_MILLHOUSE_GROUP_4,
+};
+
+// Millhouse trash groups
+Position const MillhousePointGroup2 = { 977.3045f, 895.2347f, 306.3298f };
+Position const MillhousePointGroup3 = { 1049.823f, 871.4349f, 295.006f };
+Position const MillhousePointGroup4 = { 1149.04f, 884.431f, 284.9406f };
+
+// 43391 - Millhouse Manastorm
+class npc_sc_millhouse_manastorm : public CreatureScript
+{
+ public:
+ npc_sc_millhouse_manastorm() : CreatureScript("npc_sc_millhouse_manastorm") { }
+
+ struct npc_sc_millhouse_manastormAI : public ScriptedAI
+ {
+ npc_sc_millhouse_manastormAI(Creature* creature) : ScriptedAI(creature),
+ _instance(creature->GetInstanceScript())
+ {
+ events.SetPhase(PHASE_MILLHOUSE_GROUP_1);
+ }
+
+ void ScheduleEvents()
+ {
+ events.ScheduleEvent(EVENT_SHADOWFURY, 3000);
+ events.ScheduleEvent(EVENT_FROSTBOLT_VOLLEY, 5000);
+ events.ScheduleEvent(EVENT_FEAR, 8000);
+ }
+
+ void DamageTaken(Unit* /*attacker*/, uint32& damage) override
+ {
+ if (damage >= me->GetHealth())
+ damage = me->GetHealth() - 1;
+
+ if (!HealthBelowPct(50) || me->HasAura(SPELL_BLUR))
+ return;
+
+ switch (events.GetPhaseMask())
+ {
+ case PHASE_MASK_MILLHOUSE_GROUP_1:
+ events.Reset();
+ events.SetPhase(PHASE_MILLHOUSE_GROUP_2);
+ me->SetReactState(REACT_PASSIVE);
+ me->InterruptNonMeleeSpells(true);
+ DoCast(me, SPELL_CLEAR_ALL_DEBUFFS);
+ DoCast(me, SPELL_BLUR);
+ Talk(SAY_MILLHOUSE_EVENT_1);
+ me->GetMotionMaster()->MovePoint(POINT_MILLHOUSE_GROUP_2, MillhousePointGroup2);
+ break;
+ case PHASE_MASK_MILLHOUSE_GROUP_2:
+ events.Reset();
+ events.SetPhase(PHASE_MILLHOUSE_GROUP_3);
+ me->SetReactState(REACT_PASSIVE);
+ me->InterruptNonMeleeSpells(true);
+ DoCast(me, SPELL_CLEAR_ALL_DEBUFFS);
+ DoCast(me, SPELL_BLUR);
+ Talk(SAY_MILLHOUSE_EVENT_1);
+ me->GetMotionMaster()->MovePoint(POINT_MILLHOUSE_GROUP_3, MillhousePointGroup3);
+ break;
+ case PHASE_MASK_MILLHOUSE_GROUP_3:
+ events.Reset();
+ events.SetPhase(PHASE_MILLHOUSE_GROUP_4);
+ me->SetReactState(REACT_PASSIVE);
+ me->InterruptNonMeleeSpells(true);
+ DoCast(me, SPELL_CLEAR_ALL_DEBUFFS);
+ DoCast(me, SPELL_BLUR);
+ me->GetMotionMaster()->MovePoint(POINT_MILLHOUSE_GROUP_4, MillhousePointGroup4);
+ break;
+ default:
+ break;
+ }
+
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IN_COMBAT);
+ }
+
+ void MovementInform(uint32 type, uint32 pointId) override
+ {
+ if (type != POINT_MOTION_TYPE)
+ return;
+
+ if (pointId < POINT_MILLHOUSE_GROUP_2 || pointId > POINT_MILLHOUSE_GROUP_4)
+ return;
+
+ me->RemoveAllAuras();
+ me->CombatStop(true);
+ me->DeleteThreatList();
+
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IN_COMBAT);
+ me->SetReactState(REACT_AGGRESSIVE);
+
+ switch (pointId)
+ {
+ case POINT_MILLHOUSE_GROUP_2:
+ if (Creature* worldtrigger = me->FindNearestCreature(NPC_WORLDTRIGGER, 150.0f))
+ me->SetFacingToObject(worldtrigger); // o: 5.497359f (sniff data)
+ me->CastSpell(me, SPELL_ANCHOR_HERE, true);
+ me->AddAura(SPELL_TIGULE_AND_FORORS_SPECIAL_BLEND, me);
+ events.ScheduleEvent(EVENT_READY_FOR_COMBAT, 10000);
+ break;
+ case POINT_MILLHOUSE_GROUP_3:
+ me->SetFacingTo(5.931499f);
+ me->CastSpell(me, SPELL_ANCHOR_HERE, true);
+ me->AddAura(SPELL_TIGULE_AND_FORORS_SPECIAL_BLEND, me);
+ events.ScheduleEvent(EVENT_READY_FOR_COMBAT, 10000);
+ break;
+ case POINT_MILLHOUSE_GROUP_4:
+ me->SetFacingTo(3.455752f);
+ me->CastSpell(me, SPELL_ANCHOR_HERE, true);
+ Talk(SAY_MILLHOUSE_EVENT_2);
+ events.ScheduleEvent(EVENT_CAST_IMPENDING_DOOM, 1000);
+ break;
+ default:
+ break;
+ }
+ }
+
+ void UpdateAI(uint32 diff) override
+ {
+ // Only update events if Millhouse is aggressive
+ if (me->GetReactState() != REACT_AGGRESSIVE)
+ return;
+
+ events.Update(diff);
+
+ // Impending Doom is exception because it needs to be interrupted.
+ if (me->HasUnitState(UNIT_STATE_CASTING) && !me->GetCurrentSpell(SPELL_IMPENDING_DOOM))
+ return;
+
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case EVENT_FROSTBOLT_VOLLEY:
+ DoCast(SPELL_FROSTBOLT_VOLLEY);
+ events.ScheduleEvent(EVENT_FROSTBOLT_VOLLEY, 7000);
+ break;
+ case EVENT_SHADOWFURY:
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true))
+ DoCast(target, SPELL_SHADOWFURY);
+ events.ScheduleEvent(EVENT_SHADOWFURY, 7000);
+ break;
+ case EVENT_FEAR:
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true))
+ DoCast(target, SPELL_FEAR);
+ events.ScheduleEvent(EVENT_FEAR, 18000);
+ break;
+ case EVENT_READY_FOR_COMBAT:
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IN_COMBAT);
+ me->SetReactState(REACT_AGGRESSIVE);
+ ScheduleEvents();
+ break;
+ case EVENT_CAST_IMPENDING_DOOM:
+ DoCast(SPELL_IMPENDING_DOOM);
+ DoCast(SPELL_IMPENDING_DOOM_CHANNEL);
+ events.ScheduleEvent(EVENT_INTERRUPT_IMPENDING_DOOM, urand(15000,20000));
+ break;
+ case EVENT_INTERRUPT_IMPENDING_DOOM:
+ me->InterruptNonMeleeSpells(true);
+ me->RemoveAllAuras();
+ me->HandleEmoteCommand(EMOTE_ONESHOT_KNOCKDOWN);
+ events.ScheduleEvent(EVENT_CAST_IMPENDING_DOOM, 3000);
+ break;
+ default:
+ break;
+ }
+ }
+
+ DoSpellAttackIfReady(SPELL_SHADOW_BOLT);
+ }
+
+ private:
+ InstanceScript* _instance;
+ EventMap events;
+ };
+
+ CreatureAI* GetAI(Creature* creature) const override
+ {
+ return GetInstanceAI<npc_sc_millhouse_manastormAI>(creature);
+ }
+};
+
+// 81459 - Force of Earth
+class spell_force_of_earth : public SpellScriptLoader
+{
+ public:
+ spell_force_of_earth() : SpellScriptLoader("spell_force_of_earth") { }
+
+ class spell_force_of_earth_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_force_of_earth_SpellScript);
+
+ void DummyEffect(SpellEffIndex /*effIndex*/)
+ {
+ GetCaster()->SetDisplayId(26693); // can be moved to SAI part, need sniffs to see what this dummy does (note: npc 43552)
+ }
+
+ void Register()
+ {
+ OnEffectLaunch += SpellEffectFn(spell_force_of_earth_SpellScript::DummyEffect, EFFECT_0, SPELL_EFFECT_DUMMY);
+ }
+ };
+
+ SpellScript* GetSpellScript() const override
+ {
+ return new spell_force_of_earth_SpellScript();
+ }
+};
+
+// 45313 - Anchor Here
+class spell_sc_anchor_here : public SpellScriptLoader
+{
+public:
+ spell_sc_anchor_here() : SpellScriptLoader("spell_sc_anchor_here") { }
+
+ class spell_sc_anchor_here_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_sc_anchor_here_SpellScript);
+
+ void HandleScript(SpellEffIndex /*effIndex*/)
+ {
+ if (Creature* creature = GetHitUnit()->ToCreature())
+ creature->SetHomePosition(creature->GetPositionX(), creature->GetPositionY(), creature->GetPositionZ(), creature->GetOrientation());
+ }
+
+ void Register() override
+ {
+ OnEffectHitTarget += SpellEffectFn(spell_sc_anchor_here_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
+ }
+ };
+
+ SpellScript* GetSpellScript() const override
+ {
+ return new spell_sc_anchor_here_SpellScript();
+ }
+};
+
+// 93167 - Twilight Documents
+class spell_sc_twilight_documents : public SpellScriptLoader
+{
+ public:
+ spell_sc_twilight_documents() : SpellScriptLoader("spell_sc_twilight_documents") { }
+
+ class spell_sc_twilight_documents_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_sc_twilight_documents_SpellScript);
+
+ bool Validate(SpellInfo const* /*spell*/) override
+ {
+ if (!sObjectMgr->GetGameObjectTemplate(GAMEOBJECT_TWILIGHT_DOCUMENTS))
+ return false;
+ return true;
+ }
+
+ void SetTarget(WorldObject*& target)
+ {
+ target = GetCaster()->FindNearestCreature(NPC_GENERIC_TRIGGER_LAB, 100.0f);
+ }
+
+ void SpawnGameObject(SpellEffIndex /*effIndex*/)
+ {
+ if (WorldLocation* loc = GetHitDest())
+ GetCaster()->SummonGameObject(GAMEOBJECT_TWILIGHT_DOCUMENTS, loc->GetPositionX(), loc->GetPositionY(), loc->GetPositionZ(), loc->GetOrientation(), 0, 0, 0, 0, 7200);
+ }
+
+ void Register() override
+ {
+ OnObjectTargetSelect += SpellObjectTargetSelectFn(spell_sc_twilight_documents_SpellScript::SetTarget, EFFECT_0, TARGET_DEST_NEARBY_ENTRY);
+ OnEffectHit += SpellEffectFn(spell_sc_twilight_documents_SpellScript::SpawnGameObject, EFFECT_0, SPELL_EFFECT_DUMMY);
+ }
+ };
+
+ SpellScript* GetSpellScript() const override
+ {
+ return new spell_sc_twilight_documents_SpellScript();
+ }
+};
+
+// 81008 - Quake
+class JumpCheck
+{
+ public:
+ bool operator()(WorldObject* object) const
+ {
+ Player* player = object->ToPlayer();
+ return (player && player->HasUnitState(UNIT_STATE_JUMPING));
+ }
+};
+
+class spell_sc_quake : public SpellScriptLoader
+{
+ public:
+ spell_sc_quake() : SpellScriptLoader("spell_sc_quake") { }
+
+ class spell_sc_quake_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_sc_quake_SpellScript);
+
+ void FilterTargets(std::list<WorldObject*>& unitList)
+ {
+ unitList.remove_if(JumpCheck());
+ }
+
+ void Register() override
+ {
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_sc_quake_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
+ }
+ };
+
+ SpellScript* GetSpellScript() const override
+ {
+ return new spell_sc_quake_SpellScript();
+ }
+};
+
+class at_sc_corborus_intro : public AreaTriggerScript
+{
+public:
+ at_sc_corborus_intro() : AreaTriggerScript("at_sc_corborus_intro") { }
+
+ bool OnTrigger(Player* player, AreaTriggerEntry const* /*areaTrigger*/) override
+ {
+ if (InstanceScript* instance = player->GetInstanceScript())
+ if (Creature* corborus = ObjectAccessor::GetCreature(*player, instance->GetGuidData(DATA_CORBORUS)))
+ corborus->AI()->DoAction(ACTION_CORBORUS_INTRO);
+ return true;
+ }
+};
+
+class at_sc_slabhide_intro : public AreaTriggerScript
+{
+public:
+ at_sc_slabhide_intro() : AreaTriggerScript("at_sc_slabhide_intro") { }
+
+ bool OnTrigger(Player* player, AreaTriggerEntry const* /*areaTrigger*/) override
+ {
+ if (InstanceScript* instance = player->GetInstanceScript())
+ if (Creature* slabhide = ObjectAccessor::GetCreature(*player, instance->GetGuidData(DATA_SLABHIDE)))
+ slabhide->AI()->DoAction(ACTION_SLABHIDE_INTRO);
+ return true;
+ }
+};
+
+void AddSC_stonecore()
+{
+ new npc_sc_millhouse_manastorm();
+ new spell_force_of_earth();
+ new spell_sc_anchor_here();
+ new spell_sc_twilight_documents();
+ new spell_sc_quake();
+ new at_sc_corborus_intro();
+ new at_sc_slabhide_intro();
+}
diff --git a/src/server/scripts/Maelstrom/Stonecore/stonecore.h b/src/server/scripts/Maelstrom/Stonecore/stonecore.h
new file mode 100644
index 00000000000..98a9878e0d3
--- /dev/null
+++ b/src/server/scripts/Maelstrom/Stonecore/stonecore.h
@@ -0,0 +1,72 @@
+/*
+* 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 DEF_STONECORE_H
+#define DEF_STONECORE_H
+
+#define SCScriptName "instance_stonecore"
+#define DataHeader "SC"
+
+enum DataTypes
+{
+ // Encounter States/Boss GUIDs
+ DATA_CORBORUS,
+ DATA_SLABHIDE,
+ DATA_OZRUK,
+ DATA_HIGH_PRIESTESS_AZIL,
+
+ // Additional Data
+ DATA_MILLHOUSE_MANASTORM,
+ DATA_MILLHOUSE_EVENT_FACE,
+ DATA_MILLHOUSE_EVENT_KNOCKBACK,
+ DATA_MILLHOUSE_EVENT_DESPAWN,
+
+ DATA_SLABHIDE_INTRO,
+ DATA_SLABHIDE_ROCK_WALL,
+};
+
+enum Misc
+{
+ ACTION_CORBORUS_INTRO,
+ ACTION_SLABHIDE_INTRO,
+
+ NPC_WORLDTRIGGER = 22515,
+ NPC_MILLHOUSE_MANASTORM = 43391,
+
+ NPC_CORBORUS = 43438,
+ NPC_SLABHIDE = 43214,
+ NPC_OZRUK = 42188,
+ NPC_HIGH_PRIESTESS_AZIL = 42333,
+
+ // Stonecore Teleporter misc
+ MAX_STONECORE_TELEPORTERS = 2,
+ NPC_STONECORE_TELEPORTER = 51396, // Entrance teleporter
+ NPC_STONECORE_TELEPORTER_2 = 51397, // Slabhide teleporter
+ SPELL_TELEPORTER_ACTIVE_VISUAL = 95298,
+
+ GAMEOBJECT_TWILIGHT_DOCUMENTS = 207415,
+ GAMEOBJECT_CORBORUS_ROCKDOOR = 207343,
+ GAMEOBJECT_SLABHIDE_ROCK_WALL = 204381,
+
+ SPELL_RING_WYRM_KNOCKBACK = 81235,
+
+ // Creature Formation IDs
+ CREATURE_FORMATION_MILLHOUSE_EVENT_TRASH = 340418,
+ CREATURE_FORMATION_MILLHOUSE_EVENT_LAST_GROUP = 340492,
+};
+
+#endif // DEF_STONECORE
diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/instance_ulduar.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/instance_ulduar.cpp
index 5e8273dce67..cdbbf755390 100644
--- a/src/server/scripts/Northrend/Ulduar/Ulduar/instance_ulduar.cpp
+++ b/src/server/scripts/Northrend/Ulduar/Ulduar/instance_ulduar.cpp
@@ -83,6 +83,7 @@ class instance_ulduar : public InstanceMapScript
IsDriveMeCrazyEligible = true;
_algalonSummoned = false;
_summonAlgalon = false;
+ _CoUAchivePlayerDeathMask = 0;
memset(_summonObservationRingKeeper, 0, sizeof(_summonObservationRingKeeper));
memset(_summonYSKeeper, 0, sizeof(_summonYSKeeper));
@@ -592,6 +593,19 @@ class instance_ulduar : public InstanceMapScript
void OnUnitDeath(Unit* unit) override
{
+ // Champion/Conqueror of Ulduar
+ if (unit->GetTypeId() == TYPEID_PLAYER)
+ {
+ for (uint8 i = 0; i < BOSS_ALGALON; i++)
+ {
+ if (GetBossState(i) == IN_PROGRESS)
+ {
+ _CoUAchivePlayerDeathMask |= (1 << i);
+ SaveToDB();
+ }
+ }
+ }
+
Creature* creature = unit->ToCreature();
if (!creature)
return;
@@ -1007,6 +1021,45 @@ class instance_ulduar : public InstanceMapScript
case CRITERIA_ALONE_IN_THE_DARKNESS_10:
case CRITERIA_ALONE_IN_THE_DARKNESS_25:
return keepersCount == 0;
+ case CRITERIA_C_O_U_LEVIATHAN_10:
+ case CRITERIA_C_O_U_LEVIATHAN_25:
+ return (_CoUAchivePlayerDeathMask & (1 << BOSS_LEVIATHAN)) == 0;
+ case CRITERIA_C_O_U_IGNIS_10:
+ case CRITERIA_C_O_U_IGNIS_25:
+ return (_CoUAchivePlayerDeathMask & (1 << BOSS_IGNIS)) == 0;
+ case CRITERIA_C_O_U_RAZORSCALE_10:
+ case CRITERIA_C_O_U_RAZORSCALE_25:
+ return (_CoUAchivePlayerDeathMask & (1 << BOSS_RAZORSCALE)) == 0;
+ case CRITERIA_C_O_U_XT002_10:
+ case CRITERIA_C_O_U_XT002_25:
+ return (_CoUAchivePlayerDeathMask & (1 << BOSS_XT002)) == 0;
+ case CRITERIA_C_O_U_IRON_COUNCIL_10:
+ case CRITERIA_C_O_U_IRON_COUNCIL_25:
+ return (_CoUAchivePlayerDeathMask & (1 << BOSS_ASSEMBLY_OF_IRON)) == 0;
+ case CRITERIA_C_O_U_KOLOGARN_10:
+ case CRITERIA_C_O_U_KOLOGARN_25:
+ return (_CoUAchivePlayerDeathMask & (1 << BOSS_KOLOGARN)) == 0;
+ case CRITERIA_C_O_U_AURIAYA_10:
+ case CRITERIA_C_O_U_AURIAYA_25:
+ return (_CoUAchivePlayerDeathMask & (1 << BOSS_AURIAYA)) == 0;
+ case CRITERIA_C_O_U_HODIR_10:
+ case CRITERIA_C_O_U_HODIR_25:
+ return (_CoUAchivePlayerDeathMask & (1 << BOSS_HODIR)) == 0;
+ case CRITERIA_C_O_U_THORIM_10:
+ case CRITERIA_C_O_U_THORIM_25:
+ return (_CoUAchivePlayerDeathMask & (1 << BOSS_THORIM)) == 0;
+ case CRITERIA_C_O_U_FREYA_10:
+ case CRITERIA_C_O_U_FREYA_25:
+ return (_CoUAchivePlayerDeathMask & (1 << BOSS_FREYA)) == 0;
+ case CRITERIA_C_O_U_MIMIRON_10:
+ case CRITERIA_C_O_U_MIMIRON_25:
+ return (_CoUAchivePlayerDeathMask & (1 << BOSS_MIMIRON)) == 0;
+ case CRITERIA_C_O_U_VEZAX_10:
+ case CRITERIA_C_O_U_VEZAX_25:
+ return (_CoUAchivePlayerDeathMask & (1 << BOSS_VEZAX)) == 0;
+ case CRITERIA_C_O_U_YOGG_SARON_10:
+ case CRITERIA_C_O_U_YOGG_SARON_25:
+ return (_CoUAchivePlayerDeathMask & (1 << BOSS_YOGG_SARON)) == 0;
}
return false;
@@ -1018,6 +1071,8 @@ class instance_ulduar : public InstanceMapScript
for (uint8 i = 0; i < 4; ++i)
data << ' ' << uint32(!KeeperGUIDs[i].IsEmpty() ? 1 : 0);
+
+ data << ' ' << _CoUAchivePlayerDeathMask;
}
void ReadSaveDataMore(std::istringstream& data) override
@@ -1056,6 +1111,8 @@ class instance_ulduar : public InstanceMapScript
_summonObservationRingKeeper[2] = true;
if (GetBossState(BOSS_MIMIRON) == DONE && !_summonYSKeeper[3])
_summonObservationRingKeeper[3] = true;
+
+ data >> _CoUAchivePlayerDeathMask;
}
void Update(uint32 diff) override
@@ -1095,6 +1152,7 @@ class instance_ulduar : public InstanceMapScript
bool _summonYSKeeper[4];
uint32 _maxArmorItemLevel;
uint32 _maxWeaponItemLevel;
+ uint32 _CoUAchivePlayerDeathMask;
};
InstanceScript* GetInstanceScript(InstanceMap* map) const override
diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/ulduar.h b/src/server/scripts/Northrend/Ulduar/Ulduar/ulduar.h
index 82c4ef140f1..1b4330b0faf 100644
--- a/src/server/scripts/Northrend/Ulduar/Ulduar/ulduar.h
+++ b/src/server/scripts/Northrend/Ulduar/Ulduar/ulduar.h
@@ -36,16 +36,16 @@ enum UlduarBosses
BOSS_ASSEMBLY_OF_IRON = 4,
BOSS_KOLOGARN = 5,
BOSS_AURIAYA = 6,
- BOSS_MIMIRON = 7,
- BOSS_HODIR = 8,
- BOSS_THORIM = 9,
- BOSS_FREYA = 10,
- BOSS_BRIGHTLEAF = 11,
- BOSS_IRONBRANCH = 12,
- BOSS_STONEBARK = 13,
- BOSS_VEZAX = 14,
- BOSS_YOGG_SARON = 15,
- BOSS_ALGALON = 16,
+ BOSS_HODIR = 7,
+ BOSS_THORIM = 8,
+ BOSS_FREYA = 9,
+ BOSS_MIMIRON = 10,
+ BOSS_VEZAX = 11,
+ BOSS_YOGG_SARON = 12,
+ BOSS_ALGALON = 13,
+ BOSS_BRIGHTLEAF = 14,
+ BOSS_IRONBRANCH = 15,
+ BOSS_STONEBARK = 16,
};
enum UlduarNPCs
@@ -295,6 +295,35 @@ enum UlduarAchievementCriteriaIds
CRITERIA_ALONE_IN_THE_DARKNESS_10 = 10412,
CRITERIA_ALONE_IN_THE_DARKNESS_25 = 10417,
CRITERIA_HERALD_OF_TITANS = 10678,
+
+ // Champion of Ulduar
+ CRITERIA_C_O_U_LEVIATHAN_10 = 10042,
+ CRITERIA_C_O_U_IGNIS_10 = 10342,
+ CRITERIA_C_O_U_RAZORSCALE_10 = 10340,
+ CRITERIA_C_O_U_XT002_10 = 10341,
+ CRITERIA_C_O_U_IRON_COUNCIL_10 = 10598,
+ CRITERIA_C_O_U_KOLOGARN_10 = 10348,
+ CRITERIA_C_O_U_AURIAYA_10 = 10351,
+ CRITERIA_C_O_U_HODIR_10 = 10439,
+ CRITERIA_C_O_U_THORIM_10 = 10403,
+ CRITERIA_C_O_U_FREYA_10 = 10582,
+ CRITERIA_C_O_U_MIMIRON_10 = 10347,
+ CRITERIA_C_O_U_VEZAX_10 = 10349,
+ CRITERIA_C_O_U_YOGG_SARON_10 = 10350,
+ // Conqueror of Ulduar
+ CRITERIA_C_O_U_LEVIATHAN_25 = 10352,
+ CRITERIA_C_O_U_IGNIS_25 = 10355,
+ CRITERIA_C_O_U_RAZORSCALE_25 = 10353,
+ CRITERIA_C_O_U_XT002_25 = 10354,
+ CRITERIA_C_O_U_IRON_COUNCIL_25 = 10599,
+ CRITERIA_C_O_U_KOLOGARN_25 = 10357,
+ CRITERIA_C_O_U_AURIAYA_25 = 10363,
+ CRITERIA_C_O_U_HODIR_25 = 10719,
+ CRITERIA_C_O_U_THORIM_25 = 10404,
+ CRITERIA_C_O_U_FREYA_25 = 10583,
+ CRITERIA_C_O_U_MIMIRON_25 = 10361,
+ CRITERIA_C_O_U_VEZAX_25 = 10362,
+ CRITERIA_C_O_U_YOGG_SARON_25 = 10364
};
enum UlduarData
diff --git a/src/server/shared/CMakeLists.txt b/src/server/shared/CMakeLists.txt
index 7a02e415d69..1ad85acb601 100644
--- a/src/server/shared/CMakeLists.txt
+++ b/src/server/shared/CMakeLists.txt
@@ -20,6 +20,7 @@ file(GLOB_RECURSE sources_Dynamic Dynamic/*.cpp Dynamic/*.h)
file(GLOB_RECURSE sources_Logging Logging/*.cpp Logging/*.h)
file(GLOB_RECURSE sources_Networking Networking/*.cpp Networking/*.h)
file(GLOB_RECURSE sources_Packets Packets/*.cpp Packets/*.h)
+file(GLOB_RECURSE sources_Realm Realm/*.cpp Realm/*.h)
file(GLOB_RECURSE sources_Threading Threading/*.cpp Threading/*.h)
file(GLOB_RECURSE sources_Utilities Utilities/*.cpp Utilities/*.h)
@@ -50,6 +51,7 @@ set(shared_STAT_SRCS
${sources_Logging}
${sources_Networking}
${sources_Packets}
+ ${sources_Realm}
${sources_Threading}
${sources_Utilities}
${sources_localdir}
@@ -72,6 +74,7 @@ include_directories(
${CMAKE_CURRENT_SOURCE_DIR}/Logging
${CMAKE_CURRENT_SOURCE_DIR}/Networking
${CMAKE_CURRENT_SOURCE_DIR}/Packets
+ ${CMAKE_CURRENT_SOURCE_DIR}/Realm
${CMAKE_CURRENT_SOURCE_DIR}/Threading
${CMAKE_CURRENT_SOURCE_DIR}/Utilities
${CMAKE_SOURCE_DIR}/src/server/game/Entities/Object
diff --git a/src/server/shared/Cryptography/Authentication/WorldPacketCrypt.cpp b/src/server/shared/Cryptography/Authentication/WorldPacketCrypt.cpp
index 69198c18df0..b84de24741c 100644
--- a/src/server/shared/Cryptography/Authentication/WorldPacketCrypt.cpp
+++ b/src/server/shared/Cryptography/Authentication/WorldPacketCrypt.cpp
@@ -29,12 +29,17 @@ WorldPacketCrypt::WorldPacketCrypt() : PacketCrypt(SHA_DIGEST_LENGTH)
void WorldPacketCrypt::Init(BigNumber* K)
{
uint8 ServerEncryptionKey[SEED_KEY_SIZE] = { 0x08, 0xF1, 0x95, 0x9F, 0x47, 0xE5, 0xD2, 0xDB, 0xA1, 0x3D, 0x77, 0x8F, 0x3F, 0x3E, 0xE7, 0x00 };
- HmacSha1 serverEncryptHmac(SEED_KEY_SIZE, (uint8*)ServerEncryptionKey);
- uint8 *encryptHash = serverEncryptHmac.ComputeHash(K);
-
uint8 ServerDecryptionKey[SEED_KEY_SIZE] = { 0x40, 0xAA, 0xD3, 0x92, 0x26, 0x71, 0x43, 0x47, 0x3A, 0x31, 0x08, 0xA6, 0xE7, 0xDC, 0x98, 0x2A };
- HmacSha1 clientDecryptHmac(SEED_KEY_SIZE, (uint8*)ServerDecryptionKey);
- uint8 *decryptHash = clientDecryptHmac.ComputeHash(K);
+ Init(K, ServerEncryptionKey, ServerDecryptionKey);
+}
+
+void WorldPacketCrypt::Init(BigNumber* k, uint8 const* serverKey, uint8 const* clientKey)
+{
+ HmacSha1 serverEncryptHmac(SEED_KEY_SIZE, (uint8*)serverKey);
+ uint8 *encryptHash = serverEncryptHmac.ComputeHash(k);
+
+ HmacSha1 clientDecryptHmac(SEED_KEY_SIZE, (uint8*)clientKey);
+ uint8 *decryptHash = clientDecryptHmac.ComputeHash(k);
_clientDecrypt.Init(decryptHash);
_serverEncrypt.Init(encryptHash);
diff --git a/src/server/shared/Cryptography/Authentication/WorldPacketCrypt.h b/src/server/shared/Cryptography/Authentication/WorldPacketCrypt.h
index 7ccca11f09d..58c4003418e 100644
--- a/src/server/shared/Cryptography/Authentication/WorldPacketCrypt.h
+++ b/src/server/shared/Cryptography/Authentication/WorldPacketCrypt.h
@@ -29,6 +29,7 @@ class WorldPacketCrypt : public PacketCrypt
WorldPacketCrypt();
void Init(BigNumber* K) override;
+ void Init(BigNumber* k, uint8 const* serverKey, uint8 const* clientKey);
};
#endif // _WORLDPACKETCRYPT_H
diff --git a/src/server/shared/Database/Field.cpp b/src/server/shared/Database/Field.cpp
index f1741f98cc3..da547d3a151 100644
--- a/src/server/shared/Database/Field.cpp
+++ b/src/server/shared/Database/Field.cpp
@@ -46,7 +46,7 @@ void Field::SetByteValue(const void* newValue, const size_t newSize, enum_field_
data.raw = true;
}
-void Field::SetStructuredValue(char* newValue, enum_field_types newType, uint32 length, bool isBinary)
+void Field::SetStructuredValue(char* newValue, enum_field_types newType, uint32 length)
{
if (data.value)
CleanUp();
@@ -54,15 +54,9 @@ void Field::SetStructuredValue(char* newValue, enum_field_types newType, uint32
// This value stores somewhat structured data that needs function style casting
if (newValue)
{
- if (!isBinary)
- {
- data.value = new char[length + 1];
- *(reinterpret_cast<char*>(data.value) + length) = '\0';
- }
- else
- data.value = new char[length];
-
+ data.value = new char[length + 1];
memcpy(data.value, newValue, length);
+ *(reinterpret_cast<char*>(data.value) + length) = '\0';
data.length = length;
}
diff --git a/src/server/shared/Database/Field.h b/src/server/shared/Database/Field.h
index 99f98572a56..352db10c539 100644
--- a/src/server/shared/Database/Field.h
+++ b/src/server/shared/Database/Field.h
@@ -239,9 +239,11 @@ class Field
{
char const* string = GetCString();
if (!string)
- string = "";
+ return "";
+
return std::string(string, data.length);
}
+
return std::string((char*)data.value, data.length);
}
@@ -284,7 +286,7 @@ class Field
#endif
void SetByteValue(void const* newValue, size_t const newSize, enum_field_types newType, uint32 length);
- void SetStructuredValue(char* newValue, enum_field_types newType, uint32 length, bool isBinary);
+ void SetStructuredValue(char* newValue, enum_field_types newType, uint32 length);
void CleanUp()
{
diff --git a/src/server/shared/Database/PreparedStatement.cpp b/src/server/shared/Database/PreparedStatement.cpp
index 1f036b5bf0a..3ea3c969a4c 100644
--- a/src/server/shared/Database/PreparedStatement.cpp
+++ b/src/server/shared/Database/PreparedStatement.cpp
@@ -72,6 +72,7 @@ void PreparedStatement::BindParameters()
break;
case TYPE_BINARY:
m_stmt->setBinary(i, statement_data[i].binary, false);
+ break;
case TYPE_NULL:
m_stmt->setNull(i);
break;
@@ -357,7 +358,7 @@ void MySQLPreparedStatement::setBinary(const uint8 index, const std::vector<uint
m_paramsSet[index] = true;
MYSQL_BIND* param = &m_bind[index];
size_t len = value.size();
- param->buffer_type = MYSQL_TYPE_VAR_STRING;
+ param->buffer_type = MYSQL_TYPE_BLOB;
delete [] static_cast<char *>(param->buffer);
param->buffer = new char[len];
param->buffer_length = len;
@@ -365,7 +366,10 @@ void MySQLPreparedStatement::setBinary(const uint8 index, const std::vector<uint
delete param->length;
param->length = new unsigned long(len);
if (isString)
+ {
*param->length -= 1;
+ param->buffer_type = MYSQL_TYPE_VAR_STRING;
+ }
memcpy(param->buffer, value.data(), len);
}
diff --git a/src/server/shared/Database/QueryResult.cpp b/src/server/shared/Database/QueryResult.cpp
index a6d9c64622a..154cf5cda41 100644
--- a/src/server/shared/Database/QueryResult.cpp
+++ b/src/server/shared/Database/QueryResult.cpp
@@ -172,7 +172,7 @@ bool ResultSet::NextRow()
}
for (uint32 i = 0; i < _fieldCount; i++)
- _currentRow[i].SetStructuredValue(row[i], _fields[i].type, lengths[i], (_fields[i].flags & BINARY_FLAG) != 0);
+ _currentRow[i].SetStructuredValue(row[i], _fields[i].type, lengths[i]);
return true;
}
diff --git a/src/server/shared/Networking/SocketMgr.h b/src/server/shared/Networking/SocketMgr.h
index dbe2b8ec902..92c16d96882 100644
--- a/src/server/shared/Networking/SocketMgr.h
+++ b/src/server/shared/Networking/SocketMgr.h
@@ -33,6 +33,7 @@ class SocketMgr
public:
virtual ~SocketMgr()
{
+ delete _acceptor;
delete[] _threads;
}
diff --git a/src/server/shared/Realm/Realm.cpp b/src/server/shared/Realm/Realm.cpp
new file mode 100644
index 00000000000..79b10843773
--- /dev/null
+++ b/src/server/shared/Realm/Realm.cpp
@@ -0,0 +1,53 @@
+/*
+ * 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 "Realm.h"
+
+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;
+}
diff --git a/src/server/shared/Realm/Realm.h b/src/server/shared/Realm/Realm.h
new file mode 100644
index 00000000000..9476f137947
--- /dev/null
+++ b/src/server/shared/Realm/Realm.h
@@ -0,0 +1,86 @@
+/*
+ * 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 Realm_h__
+#define Realm_h__
+
+#include "Common.h"
+#include <boost/asio/ip/address.hpp>
+#include <boost/asio/ip/tcp.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;
+ }
+ };
+}
+
+#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;
+};
+
+#endif // Realm_h__
diff --git a/src/server/worldserver/Main.cpp b/src/server/worldserver/Main.cpp
index c5127b8f3e2..821e1f5bd83 100644
--- a/src/server/worldserver/Main.cpp
+++ b/src/server/worldserver/Main.cpp
@@ -30,7 +30,6 @@
#include "OpenSSLCrypto.h"
#include "ProcessPriority.h"
#include "BigNumber.h"
-#include "RealmList.h"
#include "World.h"
#include "MapManager.h"
#include "InstanceSaveMgr.h"
@@ -44,6 +43,7 @@
#include "WorldSocket.h"
#include "WorldSocketMgr.h"
#include "BattlenetServerManager.h"
+#include "Realm/Realm.h"
#include <openssl/opensslv.h>
#include <openssl/crypto.h>
#include <boost/asio/io_service.hpp>
@@ -82,6 +82,7 @@ WorldDatabaseWorkerPool WorldDatabase; ///< Accessor to the
CharacterDatabaseWorkerPool CharacterDatabase; ///< Accessor to the character database
LoginDatabaseWorkerPool LoginDatabase; ///< Accessor to the realm/login database
Battlenet::RealmHandle realmHandle; ///< Id of the realm
+Realm realm;
void SignalHandler(const boost::system::error_code& error, int signalNumber);
void FreezeDetectorHandler(const boost::system::error_code& error);
@@ -92,6 +93,7 @@ void WorldUpdateLoop();
void ClearOnlineAccounts();
void ShutdownCLIThread(std::thread* cliThread);
void ShutdownThreadPool(std::vector<std::thread>& threadPool);
+bool LoadRealmInfo();
variables_map GetConsoleArguments(int argc, char** argv, std::string& cfg_file, std::string& cfg_service);
/// Launch the Trinity server
@@ -192,6 +194,8 @@ 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, realmHandle.Index);
+ LoadRealmInfo();
+
// Initialize the World
sWorld->SetInitialWorldSettings();
@@ -226,6 +230,8 @@ extern int main(int argc, char** argv)
// Set server online (allow connecting now)
LoginDatabase.DirectPExecute("UPDATE realmlist SET flag = flag & ~%u, population = 0 WHERE id = '%u'", REALM_FLAG_INVALID, realmHandle.Index);
+ realm.PopulationLevel = 0.0f;
+ realm.Flags = RealmFlags(realm.Flags & ~uint32(REALM_FLAG_INVALID));
// Start the freeze check callback cycle in 5 seconds (cycle itself is 1 sec)
if (int coreStuckTime = sConfigMgr->GetIntDefault("MaxCoreStuckTime", 0))
@@ -452,6 +458,62 @@ AsyncAcceptor* StartRaSocketAcceptor(boost::asio::io_service& ioService)
return acceptor;
}
+bool LoadRealmInfo()
+{
+ boost::asio::ip::tcp::resolver resolver(_ioService);
+ boost::asio::ip::tcp::resolver::iterator end;
+
+ QueryResult result = LoginDatabase.PQuery("SELECT id, name, address, localAddress, localSubnetMask, port, icon, flag, timezone, allowedSecurityLevel, population, gamebuild, Region, Battlegroup FROM realmlist WHERE id = %u", realmHandle.Index);
+ if (!result)
+ return false;
+
+ Field* fields = result->Fetch();
+ realm.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("server.worldserver", "Could not resolve address %s", fields[2].GetString().c_str());
+ return false;
+ }
+
+ realm.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("server.worldserver", "Could not resolve address %s", fields[3].GetString().c_str());
+ return false;
+ }
+
+ realm.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("server.worldserver", "Could not resolve address %s", fields[4].GetString().c_str());
+ return false;
+ }
+
+ realm.LocalSubnetMask = (*endPoint).endpoint().address();
+
+ realm.Port = fields[5].GetUInt16();
+ realm.Type = fields[6].GetUInt8();
+ realm.Flags = RealmFlags(fields[7].GetUInt8());
+ realm.Timezone = fields[8].GetUInt8();
+ realm.AllowedSecurityLevel = AccountTypes(fields[9].GetUInt8());
+ realm.PopulationLevel = fields[10].GetFloat();
+ realm.Id.Index = fields[0].GetUInt32();
+ realm.Id.Build = fields[11].GetUInt32();
+ realm.Id.Region = fields[12].GetUInt8();
+ realm.Id.Battlegroup = fields[13].GetUInt8();
+ return true;
+}
+
/// Initialize connection to the databases
bool StartDB()
{
diff --git a/src/server/worldserver/worldserver.conf.dist b/src/server/worldserver/worldserver.conf.dist
index 4d40365451e..e4406e7ecce 100644
--- a/src/server/worldserver/worldserver.conf.dist
+++ b/src/server/worldserver/worldserver.conf.dist
@@ -141,6 +141,13 @@ MaxPingTime = 30
WorldServerPort = 8085
#
+# InstanceServerPort
+# Description: TCP port to for second world connection.
+# Default: 8086
+
+InstanceServerPort = 8086
+
+#
# BindIP
# Description: Bind world server to IP/hostname.
# Default: "0.0.0.0" - (Bind to all IPs on the system)
@@ -2258,9 +2265,9 @@ Arena.QueueAnnouncer.Enable = 0
#
# Arena.ArenaSeason.ID
# Description: Current arena season id shown in clients.
-# Default: 8
+# Default: 15
-Arena.ArenaSeason.ID = 8
+Arena.ArenaSeason.ID = 15
#
# Arena.ArenaSeason.InProgress