aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/server/CMakeLists.txt2
-rw-r--r--src/server/authserver/Authentication/AuthCodes.h57
-rw-r--r--src/server/authserver/CMakeLists.txt1
-rw-r--r--src/server/authserver/Main.cpp13
-rw-r--r--src/server/authserver/PrecompiledHeaders/authPCH.h3
-rw-r--r--src/server/authserver/Realms/RealmList.cpp24
-rw-r--r--src/server/authserver/Realms/RealmList.h10
-rw-r--r--src/server/authserver/Server/BattlenetPackets/ConnectionPackets.h55
-rw-r--r--src/server/authserver/authserver.conf.dist7
-rw-r--r--src/server/bnetserver/Authentication/AuthCodes.cpp55
-rw-r--r--src/server/bnetserver/Authentication/AuthCodes.h128
-rw-r--r--src/server/bnetserver/Authentication/BattlenetPacketCrypt.cpp (renamed from src/server/authserver/Server/BattlenetPacketCrypt.cpp)0
-rw-r--r--src/server/bnetserver/Authentication/BattlenetPacketCrypt.h (renamed from src/server/authserver/Server/BattlenetPacketCrypt.h)6
-rw-r--r--src/server/bnetserver/CMakeLists.txt121
-rw-r--r--src/server/bnetserver/Main.cpp244
-rw-r--r--src/server/bnetserver/Packets/AchievementPackets.h42
-rw-r--r--src/server/bnetserver/Packets/AuthenticationPackets.cpp (renamed from src/server/authserver/Server/BattlenetPackets/AuthenticationPackets.cpp)94
-rw-r--r--src/server/bnetserver/Packets/AuthenticationPackets.h (renamed from src/server/authserver/Server/BattlenetPackets/AuthenticationPackets.h)55
-rw-r--r--src/server/bnetserver/Packets/BitStream.cpp (renamed from src/server/authserver/Server/BattlenetBitStream.cpp)2
-rw-r--r--src/server/bnetserver/Packets/BitStream.h (renamed from src/server/authserver/Server/BattlenetBitStream.h)18
-rw-r--r--src/server/bnetserver/Packets/CachePackets.cpp82
-rw-r--r--src/server/bnetserver/Packets/CachePackets.h79
-rw-r--r--src/server/bnetserver/Packets/ChatPackets.h63
-rw-r--r--src/server/bnetserver/Packets/ConnectionPackets.cpp109
-rw-r--r--src/server/bnetserver/Packets/ConnectionPackets.h153
-rw-r--r--src/server/bnetserver/Packets/FriendsPackets.cpp138
-rw-r--r--src/server/bnetserver/Packets/FriendsPackets.h138
-rw-r--r--src/server/bnetserver/Packets/PacketManager.cpp243
-rw-r--r--src/server/bnetserver/Packets/PacketManager.h105
-rw-r--r--src/server/bnetserver/Packets/Packets.h (renamed from src/server/authserver/Server/BattlenetPackets/BattlenetPackets.h)13
-rw-r--r--src/server/bnetserver/Packets/PacketsBase.cpp (renamed from src/server/authserver/Server/BattlenetPackets/BattlenetPacketsBase.cpp)8
-rw-r--r--src/server/bnetserver/Packets/PacketsBase.h (renamed from src/server/authserver/Server/BattlenetPackets/BattlenetPacketsBase.h)15
-rw-r--r--src/server/bnetserver/Packets/PresencePackets.cpp38
-rw-r--r--src/server/bnetserver/Packets/PresencePackets.h63
-rw-r--r--src/server/bnetserver/Packets/ProfilePackets.h44
-rw-r--r--src/server/bnetserver/Packets/SupportPackets.h (renamed from src/server/authserver/Server/BattlenetPackets/ConnectionPackets.cpp)17
-rw-r--r--src/server/bnetserver/Packets/WoWRealmPackets.cpp (renamed from src/server/authserver/Server/BattlenetPackets/WoWRealmPackets.cpp)90
-rw-r--r--src/server/bnetserver/Packets/WoWRealmPackets.h (renamed from src/server/authserver/Server/BattlenetPackets/WoWRealmPackets.h)69
-rw-r--r--src/server/bnetserver/PrecompiledHeaders/bnetPCH.cpp1
-rw-r--r--src/server/bnetserver/PrecompiledHeaders/bnetPCH.h10
-rw-r--r--src/server/bnetserver/Realms/RealmList.cpp252
-rw-r--r--src/server/bnetserver/Realms/RealmList.h127
-rw-r--r--src/server/bnetserver/Realms/WorldListener.cpp109
-rw-r--r--src/server/bnetserver/Realms/WorldListener.h63
-rw-r--r--src/server/bnetserver/Server/ComponentManager.cpp55
-rw-r--r--src/server/bnetserver/Server/ComponentManager.h61
-rw-r--r--src/server/bnetserver/Server/ModuleManager.cpp (renamed from src/server/authserver/Server/BattlenetManager.cpp)56
-rw-r--r--src/server/bnetserver/Server/ModuleManager.h (renamed from src/server/authserver/Server/BattlenetManager.h)64
-rw-r--r--src/server/bnetserver/Server/Session.cpp (renamed from src/server/authserver/Server/BattlenetSession.cpp)606
-rw-r--r--src/server/bnetserver/Server/Session.h (renamed from src/server/authserver/Server/BattlenetSession.h)46
-rw-r--r--src/server/bnetserver/Server/SessionManager.cpp70
-rw-r--r--src/server/bnetserver/Server/SessionManager.h (renamed from src/server/authserver/Server/BattlenetSessionManager.h)35
-rw-r--r--src/server/bnetserver/bnetserver.conf.dist260
-rw-r--r--src/server/bnetserver/bnetserver.icobin0 -> 136606 bytes
-rw-r--r--src/server/bnetserver/bnetserver.rc94
-rw-r--r--src/server/bnetserver/resource.h15
-rw-r--r--src/server/collision/CMakeLists.txt1
-rw-r--r--src/server/collision/Management/MMapFactory.cpp8
-rw-r--r--src/server/collision/Management/VMapManager2.cpp17
-rw-r--r--src/server/collision/Management/VMapManager2.h17
-rw-r--r--src/server/game/AI/SmartScripts/SmartScript.cpp57
-rw-r--r--src/server/game/AI/SmartScripts/SmartScript.h15
-rw-r--r--src/server/game/AI/SmartScripts/SmartScriptMgr.cpp132
-rw-r--r--src/server/game/AI/SmartScripts/SmartScriptMgr.h38
-rw-r--r--src/server/game/Accounts/AccountMgr.cpp2
-rw-r--r--src/server/game/AuctionHouse/AuctionHouseMgr.cpp14
-rw-r--r--src/server/game/Battlefield/Battlefield.cpp2
-rw-r--r--src/server/game/Battlefield/Zones/BattlefieldWG.cpp28
-rw-r--r--src/server/game/Battlegrounds/Arena.cpp2
-rw-r--r--src/server/game/Battlegrounds/ArenaTeam.cpp16
-rw-r--r--src/server/game/Battlegrounds/Battleground.cpp45
-rw-r--r--src/server/game/Battlegrounds/BattlegroundQueue.cpp18
-rw-r--r--src/server/game/CMakeLists.txt3
-rw-r--r--src/server/game/Calendar/CalendarMgr.cpp18
-rw-r--r--src/server/game/Chat/Channels/Channel.cpp20
-rw-r--r--src/server/game/Chat/Chat.cpp12
-rw-r--r--src/server/game/Conditions/DisableMgr.cpp29
-rw-r--r--src/server/game/Conditions/DisableMgr.h11
-rw-r--r--src/server/game/DungeonFinding/LFGMgr.cpp136
-rw-r--r--src/server/game/DungeonFinding/LFGMgr.h2
-rw-r--r--src/server/game/DungeonFinding/LFGScripts.cpp6
-rw-r--r--src/server/game/Entities/Creature/Creature.cpp15
-rw-r--r--src/server/game/Entities/Creature/Creature.h2
-rw-r--r--src/server/game/Entities/GameObject/GameObject.cpp2
-rw-r--r--src/server/game/Entities/Player/Player.cpp11
-rw-r--r--src/server/game/Entities/Player/SocialMgr.cpp2
-rw-r--r--src/server/game/Entities/Transport/Transport.cpp14
-rw-r--r--src/server/game/Globals/ObjectAccessor.cpp23
-rw-r--r--src/server/game/Globals/ObjectAccessor.h4
-rw-r--r--src/server/game/Globals/ObjectMgr.cpp38
-rw-r--r--src/server/game/Grids/Notifiers/GridNotifiers.cpp2
-rw-r--r--src/server/game/Groups/Group.cpp40
-rw-r--r--src/server/game/Guilds/Guild.cpp10
-rw-r--r--src/server/game/Guilds/Guild.h3
-rw-r--r--src/server/game/Handlers/ArenaTeamHandler.cpp2
-rw-r--r--src/server/game/Handlers/CalendarHandler.cpp2
-rw-r--r--src/server/game/Handlers/CharacterHandler.cpp9
-rw-r--r--src/server/game/Handlers/ChatHandler.cpp4
-rw-r--r--src/server/game/Handlers/GroupHandler.cpp12
-rw-r--r--src/server/game/Handlers/LFGHandler.cpp16
-rw-r--r--src/server/game/Handlers/MailHandler.cpp4
-rw-r--r--src/server/game/Handlers/MiscHandler.cpp11
-rw-r--r--src/server/game/Handlers/PetitionsHandler.cpp8
-rw-r--r--src/server/game/Handlers/QueryHandler.cpp2
-rw-r--r--src/server/game/Instances/InstanceSaveMgr.cpp4
-rw-r--r--src/server/game/Instances/InstanceSaveMgr.h11
-rw-r--r--src/server/game/Loot/LootMgr.cpp25
-rw-r--r--src/server/game/Loot/LootMgr.h3
-rw-r--r--src/server/game/Mails/Mail.cpp2
-rw-r--r--src/server/game/Maps/Map.cpp9
-rw-r--r--src/server/game/Maps/Map.h2
-rw-r--r--src/server/game/Movement/MovementGenerators/RandomMovementGenerator.cpp7
-rw-r--r--src/server/game/Movement/PathGenerator.cpp4
-rw-r--r--src/server/game/Server/BattlenetServerManager.cpp66
-rw-r--r--src/server/game/Server/BattlenetServerManager.h55
-rw-r--r--src/server/game/Server/WorldSession.cpp18
-rw-r--r--src/server/game/Server/WorldSession.h1
-rw-r--r--src/server/game/Server/WorldSocket.cpp20
-rw-r--r--src/server/game/Spells/Spell.cpp5
-rw-r--r--src/server/game/Spells/SpellMgr.cpp10
-rw-r--r--src/server/game/World/World.cpp26
-rw-r--r--src/server/game/World/World.h5
-rw-r--r--src/server/ipc/CMakeLists.txt24
-rw-r--r--src/server/ipc/Commands.cpp81
-rw-r--r--src/server/ipc/Commands.h83
-rw-r--r--src/server/ipc/ZMQTask.cpp93
-rw-r--r--src/server/ipc/ZMQTask.h52
-rw-r--r--src/server/ipc/ZmqContext.cpp52
-rw-r--r--src/server/ipc/ZmqContext.h55
-rw-r--r--src/server/ipc/ZmqListener.cpp69
-rw-r--r--src/server/ipc/ZmqListener.h (renamed from src/server/authserver/Server/BattlenetSessionManager.cpp)44
-rw-r--r--src/server/ipc/ZmqMux.cpp67
-rw-r--r--src/server/ipc/ZmqMux.h47
-rw-r--r--src/server/ipc/ZmqWorker.cpp70
-rw-r--r--src/server/ipc/ZmqWorker.h44
-rw-r--r--src/server/scripts/CMakeLists.txt1
-rw-r--r--src/server/scripts/Commands/cs_ban.cpp2
-rw-r--r--src/server/scripts/Commands/cs_character.cpp2
-rw-r--r--src/server/scripts/Commands/cs_debug.cpp22
-rw-r--r--src/server/scripts/Commands/cs_gm.cpp4
-rw-r--r--src/server/scripts/Commands/cs_group.cpp2
-rw-r--r--src/server/scripts/Commands/cs_message.cpp2
-rw-r--r--src/server/scripts/Commands/cs_misc.cpp13
-rw-r--r--src/server/scripts/Commands/cs_mmaps.cpp3
-rw-r--r--src/server/scripts/Commands/cs_rbac.cpp2
-rw-r--r--src/server/scripts/Commands/cs_reset.cpp2
-rw-r--r--src/server/scripts/Commands/cs_ticket.cpp36
-rw-r--r--src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/instance_culling_of_stratholme.cpp2
-rw-r--r--src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_anubarak_trial.cpp1
-rw-r--r--src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/instance_trial_of_the_crusader.cpp25
-rw-r--r--src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/trial_of_the_crusader.cpp19
-rw-r--r--src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/trial_of_the_crusader.h16
-rw-r--r--src/server/scripts/Northrend/IcecrownCitadel/boss_rotface.cpp2
-rw-r--r--src/server/scripts/Northrend/Ulduar/HallsOfStone/instance_halls_of_stone.cpp4
-rw-r--r--src/server/scripts/Outland/Auchindoun/SethekkHalls/boss_darkweaver_syth.cpp2
-rw-r--r--src/server/scripts/Outland/BlackTemple/boss_reliquary_of_souls.cpp2
-rw-r--r--src/server/scripts/World/go_scripts.cpp20
-rw-r--r--src/server/shared/Database/Implementation/WorldDatabase.cpp2
-rw-r--r--src/server/shared/Database/Implementation/WorldDatabase.h2
-rw-r--r--src/server/shared/Logging/Log.cpp2
-rw-r--r--src/server/shared/Logging/Log.h2
-rw-r--r--src/server/worldserver/CMakeLists.txt6
-rw-r--r--src/server/worldserver/Main.cpp49
-rw-r--r--src/server/worldserver/worldserver.conf.dist47
-rw-r--r--src/tools/mmaps_generator/MapBuilder.cpp8
-rw-r--r--src/tools/mmaps_generator/PathCommon.h2
166 files changed, 5271 insertions, 1300 deletions
diff --git a/src/server/CMakeLists.txt b/src/server/CMakeLists.txt
index 05cbe51b15d..e691b9527a5 100644
--- a/src/server/CMakeLists.txt
+++ b/src/server/CMakeLists.txt
@@ -25,6 +25,8 @@ if( SERVERS )
add_subdirectory(game)
add_subdirectory(collision)
add_subdirectory(authserver)
+ add_subdirectory(ipc)
+ add_subdirectory(bnetserver)
add_subdirectory(scripts)
add_subdirectory(worldserver)
else()
diff --git a/src/server/authserver/Authentication/AuthCodes.h b/src/server/authserver/Authentication/AuthCodes.h
index c42a11007d8..bc7f0c43f17 100644
--- a/src/server/authserver/Authentication/AuthCodes.h
+++ b/src/server/authserver/Authentication/AuthCodes.h
@@ -104,63 +104,6 @@ enum GameAccountFlags
GAMEACCOUNT_FLAG_DEATH_KNIGHT_OK = 0x20000000,
};
-namespace Battlenet
-{
- enum AuthResult
- {
- AUTH_OK = 0,
- AUTH_INTERNAL_ERROR = 100,
- AUTH_CORRUPTED_MODULE = 101,
- AUTH_NO_BATTLETAGS = 102,
- AUTH_BAD_SERVER_PROOF = 103,
- AUTH_UNKNOWN_ACCOUNT = 104,
- AUTH_CLOSED = 105,
- AUTH_LOGIN_TIMEOUT = 106,
- AUTH_NO_GAME_ACCOUNTS = 107,
- AUTH_INVALID_TOKEN = 108,
- AUTH_INVALID_PROGRAM = 109,
- AUTH_INVALID_OS = 110,
- AUTH_UNSUPPORTED_LANGUAGE = 111,
- AUTH_REGION_BAD_VERSION = 112,
- AUTH_TEMP_OUTAGE = 113,
- AUTH_CANT_DOWNLOAD_MODULE = 114,
- AUTH_DUPLICATE_LOGON = 115,
- AUTH_BAD_CREDENTIALS_2 = 116,
- AUTH_VERSION_CHECK_SUCCEEDED = 117,
- AUTH_BAD_VERSION_HASH = 118,
- AUTH_CANT_RETRIEVE_PORTAL_LIST = 119,
- AUTH_DARK_PORTAL_DOES_NOT_EXIST = 120,
- AUTH_DARK_PORTAL_FILE_CORRUPTED = 121,
- AUTH_BATTLENET_MAINTENANCE = 122,
- AUTH_LOGON_TOO_FAST = 123,
- AUTH_USE_GRUNT_LOGON = 124,
- AUTH_NO_GAME_ACCOUNTS_IN_REGION = 140,
- AUTH_ACCOUNT_LOCKED = 141,
-
- LOGIN_SERVER_BUSY = 200,
- LOGIN_NO_GAME_ACCOUNT = 201,
- LOGIN_BANNED = 202,
- LOGIN_SUSPENDED = 203,
- LOGIN_GAME_ACCOUNT_LOCKED = 204,
- LOGIN_ALREADY_ONLINE = 205,
- LOGIN_NOTIME = 206,
- LOGIN_EXPIRED = 207,
- LOGIN_EXPIRED_2 = 208,
- LOGIN_PARENTALCONTROL = 209,
- LOGIN_TRIAL_EXPIRED = 210,
- LOGIN_ANTI_INDULGENCE = 211,
- LOGIN_INCORRECT_REGION = 212,
- LOGIN_LOCKED_ENFORCED = 213,
- LOGIN_CHARGEBACK = 214,
- LOGIN_IGR_WITHOUT_BNET = 215,
- LOGIN_UNLOCKABLE_LOCK = 216,
- LOGIN_IGR_REQUIRED = 217,
- LOGIN_PAYMENT_CHANGED = 218,
- LOGIN_INVALID_PAYMENT = 219,
- LOGIN_INVALID_ACCOUNT_STATE = 220
- };
-}
-
enum ExpansionFlags
{
POST_BC_EXP_FLAG = 0x2,
diff --git a/src/server/authserver/CMakeLists.txt b/src/server/authserver/CMakeLists.txt
index ae706973ff7..b40b8c906f4 100644
--- a/src/server/authserver/CMakeLists.txt
+++ b/src/server/authserver/CMakeLists.txt
@@ -58,7 +58,6 @@ include_directories(
${CMAKE_CURRENT_SOURCE_DIR}/Authentication
${CMAKE_CURRENT_SOURCE_DIR}/Realms
${CMAKE_CURRENT_SOURCE_DIR}/Server
- ${CMAKE_CURRENT_SOURCE_DIR}/Server/BattlenetPackets
${MYSQL_INCLUDE_DIR}
${OPENSSL_INCLUDE_DIR}
${VALGRIND_INCLUDE_DIR}
diff --git a/src/server/authserver/Main.cpp b/src/server/authserver/Main.cpp
index e614b2b79fa..5f08ebe3127 100644
--- a/src/server/authserver/Main.cpp
+++ b/src/server/authserver/Main.cpp
@@ -25,8 +25,6 @@
*/
#include "AuthSocketMgr.h"
-#include "BattlenetManager.h"
-#include "BattlenetSessionManager.h"
#include "Common.h"
#include "Config.h"
#include "DatabaseEnv.h"
@@ -117,18 +115,9 @@ int main(int argc, char** argv)
return 1;
}
- int32 bnport = sConfigMgr->GetIntDefault("BattlenetPort", 1119);
- if (bnport < 0 || bnport > 0xFFFF)
- {
- TC_LOG_ERROR("server.authserver", "Specified battle.net port (%d) out of allowed range (1-65535)", bnport);
- StopDB();
- return 1;
- }
-
std::string bindIp = sConfigMgr->GetStringDefault("BindIP", "0.0.0.0");
sAuthSocketMgr.StartNetwork(_ioService, bindIp, port);
- sBattlenetSessionMgr.StartNetwork(_ioService, bindIp, bnport);
// Set signal handlers
boost::asio::signal_set signals(_ioService, SIGINT, SIGTERM);
@@ -145,8 +134,6 @@ int main(int argc, char** argv)
_dbPingTimer.expires_from_now(boost::posix_time::minutes(_dbPingInterval));
_dbPingTimer.async_wait(KeepDatabaseAliveHandler);
- sBattlenetMgr->Load();
-
// Start the io service worker loop
_ioService.run();
diff --git a/src/server/authserver/PrecompiledHeaders/authPCH.h b/src/server/authserver/PrecompiledHeaders/authPCH.h
index b509f8caaa0..90424161344 100644
--- a/src/server/authserver/PrecompiledHeaders/authPCH.h
+++ b/src/server/authserver/PrecompiledHeaders/authPCH.h
@@ -2,9 +2,6 @@
#include "Configuration/Config.h"
#include "Database/DatabaseEnv.h"
#include "Log.h"
-#include "BattlenetManager.h"
#include "RealmList.h"
#include "ByteBuffer.h"
-#include "BattlenetPackets.h"
#include "AuthSession.h"
-#include "BattlenetSession.h"
diff --git a/src/server/authserver/Realms/RealmList.cpp b/src/server/authserver/Realms/RealmList.cpp
index 2110dc1fecc..15302c74ac6 100644
--- a/src/server/authserver/Realms/RealmList.cpp
+++ b/src/server/authserver/Realms/RealmList.cpp
@@ -19,7 +19,6 @@
#include <boost/asio/ip/tcp.hpp>
#include "Common.h"
#include "RealmList.h"
-#include "BattlenetManager.h"
#include "Database/DatabaseEnv.h"
#include "Util.h"
@@ -78,7 +77,7 @@ void RealmList::Initialize(boost::asio::io_service& ioService, uint32 updateInte
}
void RealmList::UpdateRealm(uint32 id, const std::string& name, ip::address const& address, ip::address const& localAddr,
- ip::address const& localSubmask, uint16 port, uint8 icon, RealmFlags flag, uint8 timezone, AccountTypes allowedSecurityLevel, float population, uint32 build, uint8 region, uint8 battlegroup)
+ ip::address const& localSubmask, uint16 port, uint8 icon, RealmFlags flag, uint8 timezone, AccountTypes allowedSecurityLevel, float population, uint32 build)
{
// Create new if not exist or update existed
Realm& realm = m_realms[name];
@@ -91,15 +90,11 @@ void RealmList::UpdateRealm(uint32 id, const std::string& name, ip::address cons
realm.allowedSecurityLevel = allowedSecurityLevel;
realm.populationLevel = population;
- // Append port to IP address.
-
realm.ExternalAddress = address;
realm.LocalAddress = localAddr;
realm.LocalSubnetMask = localSubmask;
realm.port = port;
realm.gamebuild = build;
- realm.Region = region;
- realm.Battlegroup = battlegroup;
}
void RealmList::UpdateIfNeed()
@@ -175,11 +170,9 @@ void RealmList::UpdateRealms(bool init)
uint8 allowedSecurityLevel = fields[9].GetUInt8();
float pop = fields[10].GetFloat();
uint32 build = fields[11].GetUInt32();
- uint8 region = fields[12].GetUInt8();
- uint8 battlegroup = fields[13].GetUInt8();
UpdateRealm(realmId, name, externalAddress, localAddress, localSubmask, port, icon, flag, timezone,
- (allowedSecurityLevel <= SEC_ADMINISTRATOR ? AccountTypes(allowedSecurityLevel) : SEC_ADMINISTRATOR), pop, build, region, battlegroup);
+ (allowedSecurityLevel <= SEC_ADMINISTRATOR ? AccountTypes(allowedSecurityLevel) : SEC_ADMINISTRATOR), pop, build);
if (init)
TC_LOG_INFO("server.authserver", "Added realm \"%s\" at %s:%u.", name.c_str(), m_realms[name].ExternalAddress.to_string().c_str(), port);
@@ -193,16 +186,3 @@ void RealmList::UpdateRealms(bool init)
while (result->NextRow());
}
}
-
-Realm const* RealmList::GetRealm(Battlenet::RealmId const& id) const
-{
- auto itr = std::find_if(m_realms.begin(), m_realms.end(), [id](RealmMap::value_type const& pair)
- {
- return pair.second.Region == id.Region && pair.second.Battlegroup == id.Battlegroup && pair.second.m_ID == id.Index;
- });
-
- if (itr != m_realms.end())
- return &itr->second;
-
- return NULL;
-}
diff --git a/src/server/authserver/Realms/RealmList.h b/src/server/authserver/Realms/RealmList.h
index 0063b1a60c8..9d5771144a9 100644
--- a/src/server/authserver/Realms/RealmList.h
+++ b/src/server/authserver/Realms/RealmList.h
@@ -54,17 +54,10 @@ struct Realm
AccountTypes allowedSecurityLevel;
float populationLevel;
uint32 gamebuild;
- uint8 Region;
- uint8 Battlegroup;
ip::tcp::endpoint GetAddressForClient(ip::address const& clientAddr) const;
};
-namespace Battlenet
-{
- struct RealmId;
-}
-
/// Storage object for the list of realms on the server
class RealmList
{
@@ -88,14 +81,13 @@ public:
RealmMap::const_iterator begin() const { return m_realms.begin(); }
RealmMap::const_iterator end() const { return m_realms.end(); }
uint32 size() const { return m_realms.size(); }
- Realm const* GetRealm(Battlenet::RealmId const& id) const;
private:
RealmList();
void UpdateRealms(bool init = false);
void UpdateRealm(uint32 id, const std::string& name, ip::address const& address, ip::address const& localAddr,
- ip::address const& localSubmask, uint16 port, uint8 icon, RealmFlags flag, uint8 timezone, AccountTypes allowedSecurityLevel, float population, uint32 build, uint8 region, uint8 battlegroup);
+ ip::address const& localSubmask, uint16 port, uint8 icon, RealmFlags flag, uint8 timezone, AccountTypes allowedSecurityLevel, float population, uint32 build);
RealmMap m_realms;
uint32 m_UpdateInterval;
diff --git a/src/server/authserver/Server/BattlenetPackets/ConnectionPackets.h b/src/server/authserver/Server/BattlenetPackets/ConnectionPackets.h
deleted file mode 100644
index 50ec9416ec1..00000000000
--- a/src/server/authserver/Server/BattlenetPackets/ConnectionPackets.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef ConnectionPackets_h__
-#define ConnectionPackets_h__
-
-#include "BattlenetPacketsBase.h"
-
-namespace Battlenet
-{
- namespace Connection
- {
- enum Opcode
- {
- CMSG_PING = 0x0,
- CMSG_ENABLE_ENCRYPTION = 0x5,
- CMSG_LOGOUT_REQUEST = 0x6,
- CMSG_DISCONNECT_REQUEST = 0x7, // Not implemented
- CMSG_CONNECTION_CLOSING = 0x9, // Not implemented
-
- SMSG_PONG = 0x0,
- SMSG_BOOM = 0x1, // Not implemented
- SMSG_REGULATOR_UPDATE = 0x2, // Not implemented
- SMSG_SERVER_VERSION = 0x3, // Not implemented
- SMSG_STUN_SERVERS = 0x4 // Not implemented
- };
-
- class Pong final : public ServerPacket
- {
- public:
- Pong() : ServerPacket(PacketHeader(SMSG_PONG, CONNECTION))
- {
- }
-
- void Write() override { }
- std::string ToString() const override;
- };
- }
-}
-
-#endif // ConnectionPackets_h__
diff --git a/src/server/authserver/authserver.conf.dist b/src/server/authserver/authserver.conf.dist
index e0ef6982353..b7dee9ac08b 100644
--- a/src/server/authserver/authserver.conf.dist
+++ b/src/server/authserver/authserver.conf.dist
@@ -54,13 +54,6 @@ MaxPingTime = 30
RealmServerPort = 3724
#
-# BattlenetPort
-# Description: TCP port to reach the auth server for battle.net connections.
-# Default: 1119
-
-BattlenetPort = 1119
-
-#
#
# BindIP
# Description: Bind auth server to IP/hostname
diff --git a/src/server/bnetserver/Authentication/AuthCodes.cpp b/src/server/bnetserver/Authentication/AuthCodes.cpp
new file mode 100644
index 00000000000..908bc30b719
--- /dev/null
+++ b/src/server/bnetserver/Authentication/AuthCodes.cpp
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "AuthCodes.h"
+#include <cstddef>
+
+namespace AuthHelper
+{
+ static RealmBuildInfo const PostBcAcceptedClientBuilds[] =
+ {
+ {15595, 4, 3, 4, ' '},
+ {14545, 4, 2, 2, ' '},
+ {13623, 4, 0, 6, 'a'},
+ {13930, 3, 3, 5, 'a'}, // 3.3.5a China Mainland build
+ {12340, 3, 3, 5, 'a'},
+ {11723, 3, 3, 3, 'a'},
+ {11403, 3, 3, 2, ' '},
+ {11159, 3, 3, 0, 'a'},
+ {10505, 3, 2, 2, 'a'},
+ {9947, 3, 1, 3, ' '},
+ {8606, 2, 4, 3, ' '},
+ {6141, 1, 12, 3, ' '},
+ {6005, 1, 12, 2, ' '},
+ {5875, 1, 12, 1, ' '},
+ {0, 0, 0, 0, ' '} // terminator
+ };
+
+ RealmBuildInfo const* GetBuildInfo(int build)
+ {
+ for (int i = 0; PostBcAcceptedClientBuilds[i].Build; ++i)
+ if (PostBcAcceptedClientBuilds[i].Build == build)
+ return &PostBcAcceptedClientBuilds[i];
+
+ return nullptr;
+ }
+
+ bool IsBuildSupportingBattlenet(int build)
+ {
+ return build >= 15595;
+ }
+}
diff --git a/src/server/bnetserver/Authentication/AuthCodes.h b/src/server/bnetserver/Authentication/AuthCodes.h
new file mode 100644
index 00000000000..3c3b002551c
--- /dev/null
+++ b/src/server/bnetserver/Authentication/AuthCodes.h
@@ -0,0 +1,128 @@
+/*
+ * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _AUTHCODES_H
+#define _AUTHCODES_H
+
+enum GameAccountFlags
+{
+ GAMEACCOUNT_FLAG_GM = 0x00000001,
+ GAMEACCOUNT_FLAG_NOKICK = 0x00000002,
+ GAMEACCOUNT_FLAG_COLLECTOR = 0x00000004,
+ GAMEACCOUNT_FLAG_WOW_TRIAL = 0x00000008,
+ GAMEACCOUNT_FLAG_CANCELLED = 0x00000010,
+ GAMEACCOUNT_FLAG_IGR = 0x00000020,
+ GAMEACCOUNT_FLAG_WHOLESALER = 0x00000040,
+ GAMEACCOUNT_FLAG_PRIVILEGED = 0x00000080,
+ GAMEACCOUNT_FLAG_EU_FORBID_ELV = 0x00000100,
+ GAMEACCOUNT_FLAG_EU_FORBID_BILLING = 0x00000200,
+ GAMEACCOUNT_FLAG_WOW_RESTRICTED = 0x00000400,
+ GAMEACCOUNT_FLAG_REFERRAL = 0x00000800,
+ GAMEACCOUNT_FLAG_BLIZZARD = 0x00001000,
+ GAMEACCOUNT_FLAG_RECURRING_BILLING = 0x00002000,
+ GAMEACCOUNT_FLAG_NOELECTUP = 0x00004000,
+ GAMEACCOUNT_FLAG_KR_CERTIFICATE = 0x00008000,
+ GAMEACCOUNT_FLAG_EXPANSION_COLLECTOR = 0x00010000,
+ GAMEACCOUNT_FLAG_DISABLE_VOICE = 0x00020000,
+ GAMEACCOUNT_FLAG_DISABLE_VOICE_SPEAK = 0x00040000,
+ GAMEACCOUNT_FLAG_REFERRAL_RESURRECT = 0x00080000,
+ GAMEACCOUNT_FLAG_EU_FORBID_CC = 0x00100000,
+ GAMEACCOUNT_FLAG_OPENBETA_DELL = 0x00200000,
+ GAMEACCOUNT_FLAG_PROPASS = 0x00400000,
+ GAMEACCOUNT_FLAG_PROPASS_LOCK = 0x00800000,
+ GAMEACCOUNT_FLAG_PENDING_UPGRADE = 0x01000000,
+ GAMEACCOUNT_FLAG_RETAIL_FROM_TRIAL = 0x02000000,
+ GAMEACCOUNT_FLAG_EXPANSION2_COLLECTOR = 0x04000000,
+ GAMEACCOUNT_FLAG_OVERMIND_LINKED = 0x08000000,
+ GAMEACCOUNT_FLAG_DEMOS = 0x10000000,
+ GAMEACCOUNT_FLAG_DEATH_KNIGHT_OK = 0x20000000,
+};
+
+namespace Battlenet
+{
+ enum AuthResult
+ {
+ AUTH_OK = 0,
+ AUTH_INTERNAL_ERROR = 100,
+ AUTH_CORRUPTED_MODULE = 101,
+ AUTH_NO_BATTLETAGS = 102,
+ AUTH_BAD_SERVER_PROOF = 103,
+ AUTH_UNKNOWN_ACCOUNT = 104,
+ AUTH_CLOSED = 105,
+ AUTH_LOGIN_TIMEOUT = 106,
+ AUTH_NO_GAME_ACCOUNTS = 107,
+ AUTH_INVALID_TOKEN = 108,
+ AUTH_INVALID_PROGRAM = 109,
+ AUTH_INVALID_OS = 110,
+ AUTH_UNSUPPORTED_LANGUAGE = 111,
+ AUTH_REGION_BAD_VERSION = 112,
+ AUTH_TEMP_OUTAGE = 113,
+ AUTH_CANT_DOWNLOAD_MODULE = 114,
+ AUTH_DUPLICATE_LOGON = 115,
+ AUTH_BAD_CREDENTIALS_2 = 116,
+ AUTH_VERSION_CHECK_SUCCEEDED = 117,
+ AUTH_BAD_VERSION_HASH = 118,
+ AUTH_CANT_RETRIEVE_PORTAL_LIST = 119,
+ AUTH_DARK_PORTAL_DOES_NOT_EXIST = 120,
+ AUTH_DARK_PORTAL_FILE_CORRUPTED = 121,
+ AUTH_BATTLENET_MAINTENANCE = 122,
+ AUTH_LOGON_TOO_FAST = 123,
+ AUTH_USE_GRUNT_LOGON = 124,
+ AUTH_NO_GAME_ACCOUNTS_IN_REGION = 140,
+ AUTH_ACCOUNT_LOCKED = 141,
+
+ LOGIN_SERVER_BUSY = 200,
+ LOGIN_NO_GAME_ACCOUNT = 201,
+ LOGIN_BANNED = 202,
+ LOGIN_SUSPENDED = 203,
+ LOGIN_GAME_ACCOUNT_LOCKED = 204,
+ LOGIN_ALREADY_ONLINE = 205,
+ LOGIN_NOTIME = 206,
+ LOGIN_EXPIRED = 207,
+ LOGIN_EXPIRED_2 = 208,
+ LOGIN_PARENTALCONTROL = 209,
+ LOGIN_TRIAL_EXPIRED = 210,
+ LOGIN_ANTI_INDULGENCE = 211,
+ LOGIN_INCORRECT_REGION = 212,
+ LOGIN_LOCKED_ENFORCED = 213,
+ LOGIN_CHARGEBACK = 214,
+ LOGIN_IGR_WITHOUT_BNET = 215,
+ LOGIN_UNLOCKABLE_LOCK = 216,
+ LOGIN_IGR_REQUIRED = 217,
+ LOGIN_PAYMENT_CHANGED = 218,
+ LOGIN_INVALID_PAYMENT = 219,
+ LOGIN_INVALID_ACCOUNT_STATE = 220
+ };
+}
+
+struct RealmBuildInfo
+{
+ int Build;
+ int MajorVersion;
+ int MinorVersion;
+ int BugfixVersion;
+ int HotfixVersion;
+};
+
+namespace AuthHelper
+{
+ RealmBuildInfo const* GetBuildInfo(int build);
+ bool IsBuildSupportingBattlenet(int build);
+}
+
+#endif
diff --git a/src/server/authserver/Server/BattlenetPacketCrypt.cpp b/src/server/bnetserver/Authentication/BattlenetPacketCrypt.cpp
index de4cf73f71c..de4cf73f71c 100644
--- a/src/server/authserver/Server/BattlenetPacketCrypt.cpp
+++ b/src/server/bnetserver/Authentication/BattlenetPacketCrypt.cpp
diff --git a/src/server/authserver/Server/BattlenetPacketCrypt.h b/src/server/bnetserver/Authentication/BattlenetPacketCrypt.h
index dde687651d3..a09d3417dfe 100644
--- a/src/server/authserver/Server/BattlenetPacketCrypt.h
+++ b/src/server/bnetserver/Authentication/BattlenetPacketCrypt.h
@@ -15,8 +15,8 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef __BATTLENETPACKETCRYPT_H__
-#define __BATTLENETPACKETCRYPT_H__
+#ifndef BattlenetPacketCrypt_h__
+#define BattlenetPacketCrypt_h__
#include "PacketCrypt.h"
@@ -32,5 +32,5 @@ namespace Battlenet
void Init(BigNumber* K) override;
};
}
+#endif // BattlenetPacketCrypt_h__
-#endif // __BATTLENETPACKETCRYPT_H__
diff --git a/src/server/bnetserver/CMakeLists.txt b/src/server/bnetserver/CMakeLists.txt
new file mode 100644
index 00000000000..5b854018d47
--- /dev/null
+++ b/src/server/bnetserver/CMakeLists.txt
@@ -0,0 +1,121 @@
+# Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
+#
+# This file is free software; as a special exception the author gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+########### bnetserver ###############
+
+file(GLOB_RECURSE sources_authentication Authentication/*.cpp Authentication/*.h)
+file(GLOB_RECURSE sources_realms Realms/*.cpp Realms/*.h)
+file(GLOB_RECURSE sources_server Server/*.cpp Server/*.h)
+file(GLOB_RECURSE sources_packets Packets/*.cpp Packets/*.h)
+file(GLOB sources_localdir *.cpp *.h)
+
+if (USE_COREPCH)
+ set(bnetserver_PCH_HDR PrecompiledHeaders/bnetPCH.h)
+ set(bnetserver_PCH_SRC PrecompiledHeaders/bnetPCH.cpp)
+endif()
+
+set(bnetserver_SRCS
+ ${bnetserver_SRCS}
+ ${sources_authentication}
+ ${sources_realms}
+ ${sources_server}
+ ${sources_packets}
+ ${sources_localdir}
+)
+
+if( WIN32 )
+ set(bnetserver_SRCS
+ ${bnetserver_SRCS}
+ ${sources_windows_Debugging}
+ )
+ if ( MSVC )
+ set(bnetserver_SRCS
+ ${bnetserver_SRCS}
+ bnetserver.rc
+ )
+ endif ()
+endif()
+
+include_directories(
+ ${CMAKE_BINARY_DIR}
+ ${CMAKE_SOURCE_DIR}/dep/zmqpp
+ ${CMAKE_SOURCE_DIR}/src/server/shared
+ ${CMAKE_SOURCE_DIR}/src/server/shared/Configuration
+ ${CMAKE_SOURCE_DIR}/src/server/shared/Database
+ ${CMAKE_SOURCE_DIR}/src/server/shared/Debugging
+ ${CMAKE_SOURCE_DIR}/src/server/shared/Packets
+ ${CMAKE_SOURCE_DIR}/src/server/shared/Cryptography
+ ${CMAKE_SOURCE_DIR}/src/server/shared/Cryptography/Authentication
+ ${CMAKE_SOURCE_DIR}/src/server/shared/Logging
+ ${CMAKE_SOURCE_DIR}/src/server/shared/Networking
+ ${CMAKE_SOURCE_DIR}/src/server/shared/Threading
+ ${CMAKE_SOURCE_DIR}/src/server/shared/Utilities
+ ${CMAKE_SOURCE_DIR}/src/server/ipc
+ ${CMAKE_CURRENT_SOURCE_DIR}
+ ${CMAKE_CURRENT_SOURCE_DIR}/Authentication
+ ${CMAKE_CURRENT_SOURCE_DIR}/Realms
+ ${CMAKE_CURRENT_SOURCE_DIR}/Server
+ ${CMAKE_CURRENT_SOURCE_DIR}/Packets
+ ${MYSQL_INCLUDE_DIR}
+ ${OPENSSL_INCLUDE_DIR}
+ ${VALGRIND_INCLUDE_DIR}
+ ${ZMQ_INCLUDE_DIR}
+)
+
+add_executable(bnetserver
+ ${bnetserver_SRCS}
+ ${bnetserver_PCH_SRC}
+)
+
+add_dependencies(bnetserver revision.h)
+
+if( NOT WIN32 )
+ set_target_properties(bnetserver PROPERTIES
+ COMPILE_DEFINITIONS _TRINITY_BNET_CONFIG="${CONF_DIR}/bnetserver.conf"
+ )
+endif()
+
+target_link_libraries(bnetserver
+ ipc
+ shared
+ zmqpp
+ ${MYSQL_LIBRARY}
+ ${OPENSSL_LIBRARIES}
+ ${ZMQ_LIBRARY}
+ ${CMAKE_THREAD_LIBS_INIT}
+ ${Boost_LIBRARIES}
+)
+
+if( WIN32 )
+ if ( MSVC )
+ add_custom_command(TARGET bnetserver
+ POST_BUILD
+ COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/bnetserver.conf.dist ${CMAKE_BINARY_DIR}/bin/$(ConfigurationName)/
+ )
+ elseif ( MINGW )
+ add_custom_command(TARGET bnetserver
+ POST_BUILD
+ COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/bnetserver.conf.dist ${CMAKE_BINARY_DIR}/bin/
+ )
+ endif()
+endif()
+
+if( UNIX )
+ install(TARGETS bnetserver DESTINATION bin)
+ install(FILES bnetserver.conf.dist DESTINATION ${CONF_DIR})
+elseif( WIN32 )
+ install(TARGETS bnetserver DESTINATION "${CMAKE_INSTALL_PREFIX}")
+ install(FILES bnetserver.conf.dist DESTINATION "${CMAKE_INSTALL_PREFIX}")
+endif()
+
+# Generate precompiled header
+if (USE_COREPCH)
+ add_cxx_pch(bnetserver ${bnetserver_PCH_HDR} ${bnetserver_PCH_SRC})
+endif()
diff --git a/src/server/bnetserver/Main.cpp b/src/server/bnetserver/Main.cpp
new file mode 100644
index 00000000000..ce90019c011
--- /dev/null
+++ b/src/server/bnetserver/Main.cpp
@@ -0,0 +1,244 @@
+/*
+ * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/**
+* @file main.cpp
+* @brief Authentication Server main program
+*
+* This file contains the main program for the
+* authentication server
+*/
+
+#include "ComponentManager.h"
+#include "ModuleManager.h"
+#include "SessionManager.h"
+#include "Common.h"
+#include "Config.h"
+#include "DatabaseEnv.h"
+#include "Log.h"
+#include "ProcessPriority.h"
+#include "RealmList.h"
+#include "SystemConfig.h"
+#include "Util.h"
+#include "ZmqContext.h"
+#include <cstdlib>
+#include <iostream>
+#include <boost/date_time/posix_time/posix_time.hpp>
+#include <boost/program_options.hpp>
+#include <openssl/opensslv.h>
+#include <openssl/crypto.h>
+
+using boost::asio::ip::tcp;
+using namespace boost::program_options;
+
+#ifndef _TRINITY_BNET_CONFIG
+# define _TRINITY_BNET_CONFIG "bnetserver.conf"
+#endif
+
+bool StartDB();
+void StopDB();
+void SignalHandler(const boost::system::error_code& error, int signalNumber);
+void KeepDatabaseAliveHandler(const boost::system::error_code& error);
+variables_map GetConsoleArguments(int argc, char** argv, std::string& configFile);
+
+boost::asio::io_service _ioService;
+boost::asio::deadline_timer _dbPingTimer(_ioService);
+uint32 _dbPingInterval;
+LoginDatabaseWorkerPool LoginDatabase;
+
+int main(int argc, char** argv)
+{
+ std::string configFile = _TRINITY_BNET_CONFIG;
+ auto vm = GetConsoleArguments(argc, argv, configFile);
+ // exit if help is enabled
+ if (vm.count("help"))
+ return 0;
+
+ std::string configError;
+ if (!sConfigMgr->LoadInitial(configFile, configError))
+ {
+ printf("Error in config file: %s\n", configError.c_str());
+ return 1;
+ }
+
+ TC_LOG_INFO("server.bnetserver", "%s (bnetserver)", _FULLVERSION);
+ TC_LOG_INFO("server.bnetserver", "<Ctrl-C> to stop.\n");
+ TC_LOG_INFO("server.bnetserver", "Using configuration file %s.", configFile.c_str());
+ TC_LOG_INFO("server.bnetserver", "Using SSL version: %s (library: %s)", OPENSSL_VERSION_TEXT, SSLeay_version(SSLEAY_VERSION));
+ TC_LOG_INFO("server.bnetserver", "Using Boost version: %i.%i.%i", BOOST_VERSION / 100000, BOOST_VERSION / 100 % 1000, BOOST_VERSION % 100);
+
+ // bnetserver PID file creation
+ std::string pidFile = sConfigMgr->GetStringDefault("PidFile", "");
+ if (!pidFile.empty())
+ {
+ if (uint32 pid = CreatePIDFile(pidFile))
+ TC_LOG_INFO("server.bnetserver", "Daemon PID: %u\n", pid);
+ else
+ {
+ TC_LOG_ERROR("server.bnetserver", "Cannot create PID file %s.\n", pidFile.c_str());
+ return 1;
+ }
+ }
+
+ int32 worldListenPort = sConfigMgr->GetIntDefault("WorldserverListenPort", 1118);
+ if (worldListenPort < 0 || worldListenPort > 0xFFFF)
+ {
+ TC_LOG_ERROR("server.bnetserver", "Specified worldserver listen port (%d) out of allowed range (1-65535)", worldListenPort);
+ return 1;
+ }
+
+ // Initialize the database connection
+ if (!StartDB())
+ return 1;
+
+ sIpcContext->Initialize();
+
+ // Get the list of realms for the server
+ sRealmList->Initialize(_ioService, sConfigMgr->GetIntDefault("RealmsStateUpdateDelay", 10), worldListenPort);
+
+ // Start the listening port (acceptor) for auth connections
+ int32 bnport = sConfigMgr->GetIntDefault("BattlenetPort", 1119);
+ if (bnport < 0 || bnport > 0xFFFF)
+ {
+ TC_LOG_ERROR("server.bnetserver", "Specified battle.net port (%d) out of allowed range (1-65535)", bnport);
+ StopDB();
+ return 1;
+ }
+
+ std::string bindIp = sConfigMgr->GetStringDefault("BindIP", "0.0.0.0");
+
+ sSessionMgr.StartNetwork(_ioService, bindIp, bnport);
+
+ // Set signal handlers
+ boost::asio::signal_set signals(_ioService, SIGINT, SIGTERM);
+#if PLATFORM == PLATFORM_WINDOWS
+ signals.add(SIGBREAK);
+#endif
+ signals.async_wait(SignalHandler);
+
+ // Set process priority according to configuration settings
+ SetProcessPriority("server.bnetserver");
+
+ // Enabled a timed callback for handling the database keep alive ping
+ _dbPingInterval = sConfigMgr->GetIntDefault("MaxPingTime", 30);
+ _dbPingTimer.expires_from_now(boost::posix_time::minutes(_dbPingInterval));
+ _dbPingTimer.async_wait(KeepDatabaseAliveHandler);
+
+ sComponentMgr->Load();
+ sModuleMgr->Load();
+
+ // Start the io service worker loop
+ _ioService.run();
+
+ sIpcContext->Close();
+
+ sRealmList->Close();
+
+ // Close the Database Pool and library
+ StopDB();
+
+ TC_LOG_INFO("server.bnetserver", "Halting process...");
+ return 0;
+}
+
+
+/// Initialize connection to the database
+bool StartDB()
+{
+ MySQL::Library_Init();
+
+ std::string dbstring = sConfigMgr->GetStringDefault("LoginDatabaseInfo", "");
+ if (dbstring.empty())
+ {
+ TC_LOG_ERROR("server.bnetserver", "Database not specified");
+ return false;
+ }
+
+ int32 worker_threads = sConfigMgr->GetIntDefault("LoginDatabase.WorkerThreads", 1);
+ if (worker_threads < 1 || worker_threads > 32)
+ {
+ TC_LOG_ERROR("server.bnetserver", "Improper value specified for LoginDatabase.WorkerThreads, defaulting to 1.");
+ worker_threads = 1;
+ }
+
+ int32 synch_threads = sConfigMgr->GetIntDefault("LoginDatabase.SynchThreads", 1);
+ if (synch_threads < 1 || synch_threads > 32)
+ {
+ TC_LOG_ERROR("server.bnetserver", "Improper value specified for LoginDatabase.SynchThreads, defaulting to 1.");
+ synch_threads = 1;
+ }
+
+ if (!LoginDatabase.Open(dbstring, uint8(worker_threads), uint8(synch_threads)))
+ {
+ TC_LOG_ERROR("server.bnetserver", "Cannot connect to database");
+ return false;
+ }
+
+ TC_LOG_INFO("server.bnetserver", "Started auth database connection pool.");
+ sLog->SetRealmId(0); // Enables DB appenders when realm is set.
+ return true;
+}
+
+/// Close the connection to the database
+void StopDB()
+{
+ LoginDatabase.Close();
+ MySQL::Library_End();
+}
+
+void SignalHandler(const boost::system::error_code& error, int /*signalNumber*/)
+{
+ if (!error)
+ _ioService.stop();
+}
+
+void KeepDatabaseAliveHandler(const boost::system::error_code& error)
+{
+ if (!error)
+ {
+ TC_LOG_INFO("server.bnetserver", "Ping MySQL to keep connection alive");
+ LoginDatabase.KeepAlive();
+
+ _dbPingTimer.expires_from_now(boost::posix_time::minutes(_dbPingInterval));
+ _dbPingTimer.async_wait(KeepDatabaseAliveHandler);
+ }
+}
+
+variables_map GetConsoleArguments(int argc, char** argv, std::string& configFile)
+{
+ options_description all("Allowed options");
+ all.add_options()
+ ("help,h", "print usage message")
+ ("config,c", value<std::string>(&configFile)->default_value(_TRINITY_BNET_CONFIG), "use <arg> as configuration file")
+ ;
+ variables_map variablesMap;
+ try
+ {
+ store(command_line_parser(argc, argv).options(all).allow_unregistered().run(), variablesMap);
+ notify(variablesMap);
+ }
+ catch (std::exception& e) {
+ std::cerr << e.what() << "\n";
+ }
+
+ if (variablesMap.count("help")) {
+ std::cout << all << "\n";
+ }
+
+ return variablesMap;
+}
diff --git a/src/server/bnetserver/Packets/AchievementPackets.h b/src/server/bnetserver/Packets/AchievementPackets.h
new file mode 100644
index 00000000000..99a0f19d0a2
--- /dev/null
+++ b/src/server/bnetserver/Packets/AchievementPackets.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef AchievementPackets_h__
+#define AchievementPackets_h__
+
+#include "PacketsBase.h"
+
+namespace Battlenet
+{
+ namespace Achievement
+ {
+ enum Opcode
+ {
+ CMSG_LISTEN_REQUEST = 0x0, // Not implemented
+ CMSG_CRITERIA_FLUSH_REQUEST = 0x3, // Not implemented
+ CMSG_CHANGE_TROPHY_CASE_REQUEST = 0x5, // Not implemented
+
+ SMSG_DATA = 0x2, // Not implemented
+ SMSG_CRITERIA_FLUSH_RESPONSE = 0x3, // Not implemented
+ SMSG_ACHIEVEMENT_HANDLE_UPDATE = 0x4, // Not implemented
+ SMSG_CHANGE_TROPHY_CASE_RESULT = 0x6 // Not implemented
+ };
+ }
+}
+
+#endif // AchievementPackets_h__
+
diff --git a/src/server/authserver/Server/BattlenetPackets/AuthenticationPackets.cpp b/src/server/bnetserver/Packets/AuthenticationPackets.cpp
index 4d9c4476295..f6743a7c2f0 100644
--- a/src/server/authserver/Server/BattlenetPackets/AuthenticationPackets.cpp
+++ b/src/server/bnetserver/Packets/AuthenticationPackets.cpp
@@ -16,44 +16,9 @@
*/
#include "AuthenticationPackets.h"
+#include "Session.h"
#include "Util.h"
-void Battlenet::Authentication::LogonRequest3::Read()
-{
- Program = _stream.ReadFourCC();
- Platform = _stream.ReadFourCC();
- Locale = _stream.ReadFourCC();
-
- Components.resize(_stream.Read<uint32>(6));
- for (size_t i = 0; i < Components.size(); ++i)
- {
- Component& component = Components[i];
- component.Program = _stream.ReadFourCC();
- component.Platform = _stream.ReadFourCC();
- component.Build = _stream.Read<uint32>(32);
- }
-
- if (_stream.Read<uint32>(1))
- Login = _stream.ReadString(9, 3);
-
- Compatibility = _stream.Read<uint64>(64);
-}
-
-std::string Battlenet::Authentication::LogonRequest3::ToString() const
-{
- std::ostringstream stream;
- stream << "Battlenet::Authentication::LogonRequest3 Program: " << Program << ", Platform: " << Platform << ", Locale: " << Locale;
- for (Component const& component : Components)
- stream << std::endl << "Battlenet::Component Program: " << component.Program << ", Platform: " << component.Platform << ", Build: " << component.Build;
-
- if (!Login.empty())
- stream << std::endl << " Login: " << Login;
-
- stream << " Compatibility: " << Compatibility;
-
- return stream.str();
-}
-
void Battlenet::Authentication::ResumeRequest::Read()
{
Program = _stream.ReadFourCC();
@@ -81,13 +46,18 @@ std::string Battlenet::Authentication::ResumeRequest::ToString() const
for (Component const& component : Components)
stream << std::endl << "Battlenet::Component Program: " << component.Program << ", Platform: " << component.Platform << ", Build: " << component.Build;
- stream << std::endl << "Battlenet::Authentication::ResumeRequest Login: " << Login;
- stream << std::endl << "Battlenet::Authentication::ResumeRequest Region: " << uint32(Region);
- stream << std::endl << "Battlenet::Authentication::ResumeRequest GameAccountName: " << GameAccountName;
+ stream << std::endl << "Login: " << Login;
+ stream << std::endl << "Region: " << uint32(Region);
+ stream << std::endl << "GameAccountName: " << GameAccountName;
return stream.str();
}
+void Battlenet::Authentication::ResumeRequest::CallHandler(Session* session)
+{
+ session->HandleResumeRequest(*this);
+}
+
Battlenet::Authentication::ProofRequest::~ProofRequest()
{
for (size_t i = 0; i < Modules.size(); ++i)
@@ -147,6 +117,52 @@ std::string Battlenet::Authentication::ProofResponse::ToString() const
return stream.str();
}
+void Battlenet::Authentication::ProofResponse::CallHandler(Session* session)
+{
+ session->HandleProofResponse(*this);
+}
+
+void Battlenet::Authentication::LogonRequest3::Read()
+{
+ Program = _stream.ReadFourCC();
+ Platform = _stream.ReadFourCC();
+ Locale = _stream.ReadFourCC();
+
+ Components.resize(_stream.Read<uint32>(6));
+ for (size_t i = 0; i < Components.size(); ++i)
+ {
+ Component& component = Components[i];
+ component.Program = _stream.ReadFourCC();
+ component.Platform = _stream.ReadFourCC();
+ component.Build = _stream.Read<uint32>(32);
+ }
+
+ if (_stream.Read<uint32>(1))
+ Login = _stream.ReadString(9, 3);
+
+ Compatibility = _stream.Read<uint64>(64);
+}
+
+std::string Battlenet::Authentication::LogonRequest3::ToString() const
+{
+ std::ostringstream stream;
+ stream << "Battlenet::Authentication::LogonRequest3 Program: " << Program << ", Platform: " << Platform << ", Locale: " << Locale;
+ for (Component const& component : Components)
+ stream << std::endl << "Battlenet::Component Program: " << component.Program << ", Platform: " << component.Platform << ", Build: " << component.Build;
+
+ if (!Login.empty())
+ stream << std::endl << " Login: " << Login;
+
+ stream << " Compatibility: " << Compatibility;
+
+ return stream.str();
+}
+
+void Battlenet::Authentication::LogonRequest3::CallHandler(Session* session)
+{
+ session->HandleLogonRequest(*this);
+}
+
Battlenet::Authentication::LogonResponse::~LogonResponse()
{
for (ModuleInfo* m : Modules)
diff --git a/src/server/authserver/Server/BattlenetPackets/AuthenticationPackets.h b/src/server/bnetserver/Packets/AuthenticationPackets.h
index 44e3d7e18b8..bcaa0e72011 100644
--- a/src/server/authserver/Server/BattlenetPackets/AuthenticationPackets.h
+++ b/src/server/bnetserver/Packets/AuthenticationPackets.h
@@ -18,7 +18,9 @@
#ifndef AuthenticationPackets_h__
#define AuthenticationPackets_h__
-#include "BattlenetPacketsBase.h"
+#include "PacketsBase.h"
+#include "ComponentManager.h"
+#include "ModuleManager.h"
namespace Battlenet
{
@@ -41,25 +43,6 @@ namespace Battlenet
SMSG_GENERATE_SINGLE_SIGN_ON_TOKEN_REQUEST_2 = 0x8 // Not implemented
};
- class LogonRequest3 final : public ClientPacket
- {
- public:
- LogonRequest3(PacketHeader const& header, BitStream& stream) : ClientPacket(header, stream)
- {
- ASSERT(header == PacketHeader(CMSG_LOGON_REQUEST_3, AUTHENTICATION) && "Invalid packet header for LogonRequest3");
- }
-
- void Read() override;
- std::string ToString() const override;
-
- std::string Program;
- std::string Platform;
- std::string Locale;
- std::vector<Component> Components;
- std::string Login;
- uint64 Compatibility;
- };
-
class ResumeRequest final : public ClientPacket
{
public:
@@ -70,6 +53,7 @@ namespace Battlenet
void Read() override;
std::string ToString() const override;
+ void CallHandler(Session* session) override;
std::string Program;
std::string Platform;
@@ -92,20 +76,29 @@ namespace Battlenet
void Read() override;
std::string ToString() const override;
+ void CallHandler(Session* session) override;
std::vector<BitStream*> Modules;
};
- class ProofRequest final : public ServerPacket
+ class LogonRequest3 final : public ClientPacket
{
public:
- ProofRequest() : ServerPacket(PacketHeader(SMSG_PROOF_REQUEST, AUTHENTICATION)) { }
- ~ProofRequest();
+ LogonRequest3(PacketHeader const& header, BitStream& stream) : ClientPacket(header, stream)
+ {
+ ASSERT(header == PacketHeader(CMSG_LOGON_REQUEST_3, AUTHENTICATION) && "Invalid packet header for LogonRequest3");
+ }
- void Write() override;
+ void Read() override;
std::string ToString() const override;
+ void CallHandler(Session* session) override;
- std::vector<ModuleInfo*> Modules;
+ std::string Program;
+ std::string Platform;
+ std::string Locale;
+ std::vector<Component> Components;
+ std::string Login;
+ uint64 Compatibility;
};
class ResponseFailure
@@ -192,6 +185,18 @@ namespace Battlenet
int32 PingTimeout;
Regulator RegulatorRules;
};
+
+ class ProofRequest final : public ServerPacket
+ {
+ public:
+ ProofRequest() : ServerPacket(PacketHeader(SMSG_PROOF_REQUEST, AUTHENTICATION)) { }
+ ~ProofRequest();
+
+ void Write() override;
+ std::string ToString() const override;
+
+ std::vector<ModuleInfo*> Modules;
+ };
}
}
diff --git a/src/server/authserver/Server/BattlenetBitStream.cpp b/src/server/bnetserver/Packets/BitStream.cpp
index 712c9e58f08..5f002f6b1d9 100644
--- a/src/server/authserver/Server/BattlenetBitStream.cpp
+++ b/src/server/bnetserver/Packets/BitStream.cpp
@@ -15,7 +15,7 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "BattlenetBitStream.h"
+#include "BitStream.h"
template<>
bool Battlenet::BitStream::Read<bool>(uint32 /*bitCount*/)
diff --git a/src/server/authserver/Server/BattlenetBitStream.h b/src/server/bnetserver/Packets/BitStream.h
index 3601c3b0b0c..54c61ab3bbf 100644
--- a/src/server/authserver/Server/BattlenetBitStream.h
+++ b/src/server/bnetserver/Packets/BitStream.h
@@ -15,8 +15,8 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef __BATTLENETBITSTREAM_H__
-#define __BATTLENETBITSTREAM_H__
+#ifndef BitStream_h__
+#define BitStream_h__
#include "Common.h"
#include "ByteConverter.h"
@@ -212,14 +212,6 @@ namespace Battlenet
}
}
- void SetReadPos(uint32 bits)
- {
- if (bits > _writePos)
- throw BitStreamPositionException(true, bits, 0, _writePos);
-
- _readPos = bits;
- }
-
bool IsRead() const { return _readPos >= _writePos; }
uint8* GetBuffer() { return _buffer.data(); }
@@ -227,6 +219,10 @@ namespace Battlenet
size_t GetSize() const { return ((_writePos + 7) & ~7) / 8; }
+ // These methods are meant to only be used when their corresponding actions in the client ignore the value completely
+ void ReadSkip(uint32 bitCount) { _readPos += bitCount; }
+ void WriteSkip(uint32 bitCount) { Write(0, bitCount); }
+
private:
uint32 _writePos;
uint32 _readPos;
@@ -240,4 +236,4 @@ namespace Battlenet
void BitStream::Write<bool>(bool value, uint32 bitCount);
}
-#endif // __BATTLENETBITSTREAM_H__
+#endif // BitStream_h__
diff --git a/src/server/bnetserver/Packets/CachePackets.cpp b/src/server/bnetserver/Packets/CachePackets.cpp
new file mode 100644
index 00000000000..deacfd34065
--- /dev/null
+++ b/src/server/bnetserver/Packets/CachePackets.cpp
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "Session.h"
+#include "Util.h"
+#include "CachePackets.h"
+
+void Battlenet::Cache::GetStreamItemsRequest::Read()
+{
+ _stream.WriteSkip(31);
+ Index = _stream.Read<uint32>(32);
+ ReferenceTime = _stream.Read<int32>(32) - std::numeric_limits<int32>::min();
+ _stream.Read<bool>(1); // StreamDirection
+ _stream.Read<uint8>(6); // Module count, always 0
+ Locale = _stream.ReadFourCC();
+ if (_stream.Read<bool>(1))
+ {
+ ItemName = _stream.ReadFourCC();
+ Channel = _stream.ReadFourCC();
+ }
+ else
+ _stream.Read<uint16>(16);
+}
+
+std::string Battlenet::Cache::GetStreamItemsRequest::ToString() const
+{
+ std::ostringstream stream;
+ stream << "Battlenet::Cache::GetStreamItemsRequest Channel: " << Channel << ", ItemName: " << ItemName
+ << ", Locale: " << Locale << ", Index: " << Index;
+ return stream.str();
+}
+
+void Battlenet::Cache::GetStreamItemsRequest::CallHandler(Session* session)
+{
+ session->HandleGetStreamItemsRequest(*this);
+}
+
+Battlenet::Cache::GetStreamItemsResponse::~GetStreamItemsResponse()
+{
+ for (size_t i = 0; i < Modules.size(); ++i)
+ delete Modules[i];
+}
+
+void Battlenet::Cache::GetStreamItemsResponse::Write()
+{
+ _stream.Write(0, 16);
+ _stream.Write(1, 16);
+ _stream.Write(Index, 32);
+ _stream.Write(Modules.size(), 6);
+ for (ModuleInfo const* info : Modules)
+ {
+ _stream.WriteBytes(info->Type.c_str(), 4);
+ _stream.WriteFourCC(info->Region);
+ _stream.WriteBytes(info->ModuleId, 32);
+ _stream.WriteSkip(27);
+ _stream.WriteBytes(info->Data, 4);
+ }
+}
+
+std::string Battlenet::Cache::GetStreamItemsResponse::ToString() const
+{
+ std::ostringstream stream;
+ stream << "Battlenet::Cache::GetStreamItemsResponse modules " << Modules.size();
+ for (ModuleInfo const* module : Modules)
+ stream << std::endl << "Battlenet::ModuleInfo Locale " << module->Region.c_str() << ", ModuleId " << ByteArrayToHexStr(module->ModuleId, 32) << ", Data " << ByteArrayToHexStr(module->Data, module->DataSize);
+
+ return stream.str();
+}
diff --git a/src/server/bnetserver/Packets/CachePackets.h b/src/server/bnetserver/Packets/CachePackets.h
new file mode 100644
index 00000000000..a65ab2651c8
--- /dev/null
+++ b/src/server/bnetserver/Packets/CachePackets.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef CachePackets_h__
+#define CachePackets_h__
+
+#include "ModuleManager.h"
+#include "PacketsBase.h"
+
+namespace Battlenet
+{
+ namespace Cache
+ {
+ enum Opcode
+ {
+ CMSG_GATEWAY_LOOKUP_REQUEST = 0x2, // Not implemented
+ CMSG_CONNECT_REQUEST = 0x4, // Not implemented
+ CMSG_DATA_CHUNK = 0x7, // Not implemented
+ CMSG_GET_STREAM_ITEMS_REQUEST = 0x9,
+
+ SMSG_GATEWAY_LOOKUP_RESPONSE = 0x3, // Not implemented
+ SMSG_CONNECT_RESPONSE = 0x4, // Not implemented
+ SMSG_PUBLISH_LIST_RESPONSE = 0x7, // Not implemented
+ SMSG_RESULT = 0x8, // Not implemented
+ SMSG_GET_STREAM_ITEMS_RESPONSE = 0x9
+ };
+
+ class GetStreamItemsRequest final : public ClientPacket
+ {
+ public:
+ GetStreamItemsRequest(PacketHeader const& header, BitStream& stream) : ClientPacket(header, stream)
+ {
+ ASSERT(header == PacketHeader(CMSG_GET_STREAM_ITEMS_REQUEST, CACHE) && "Invalid packet header for GetStreamItemsRequest");
+ }
+
+ void Read() override;
+ std::string ToString() const override;
+ void CallHandler(Session* session);
+
+ std::string Channel;
+ std::string ItemName;
+ std::string Locale;
+ uint32 Index;
+ int32 ReferenceTime;
+ };
+
+ class GetStreamItemsResponse final : public ServerPacket
+ {
+ public:
+ GetStreamItemsResponse() : ServerPacket(PacketHeader(SMSG_GET_STREAM_ITEMS_RESPONSE, CACHE))
+ {
+ }
+
+ ~GetStreamItemsResponse();
+
+ void Write() override;
+ std::string ToString() const override;
+
+ uint32 Index;
+ std::vector<ModuleInfo*> Modules;
+ };
+ }
+}
+
+#endif // CachePackets_h__
diff --git a/src/server/bnetserver/Packets/ChatPackets.h b/src/server/bnetserver/Packets/ChatPackets.h
new file mode 100644
index 00000000000..fc4b638754c
--- /dev/null
+++ b/src/server/bnetserver/Packets/ChatPackets.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef ChatPackets_h__
+#define ChatPackets_h__
+
+#include "PacketsBase.h"
+
+namespace Battlenet
+{
+ namespace Chat
+ {
+ enum Opcode
+ {
+ CMSG_JOIN_REQUEST_2 = 0x00, // Not implemented
+ CMSG_LEAVE_REQUEST = 0x02, // Not implemented
+ CMSG_INVITE_REQUEST = 0x03, // Not implemented
+ CMSG_CREATE_AND_INVITE_REQUEST = 0x0A, // Not implemented
+ CMSG_MESSAGE_SEND = 0x0B, // Not implemented
+ CMSG_DATAGRAM_CONNECTION_UPDATE = 0x0D, // Not implemented
+ CMSG_REPORT_SPAM_REQUEST = 0x0E, // Not implemented
+ CMSG_WHISPER_SEND = 0x13, // Not implemented
+ CMSG_ENUM_CATEGORY_DESCRIPTIONS = 0x15, // Not implemented
+ CMSG_ENUM_CONFERENCE_DESCRIPTIONS = 0x17, // Not implemented
+ CMSG_ENUM_CONFERENCE_MEMBER_COUNTS = 0x19, // Not implemented
+ CMSG_MODIFY_CHANNEL_LIST_REQUEST = 0x1B, // Not implemented
+
+ SMSG_MEMBERSHIP_CHANGE_NOTIFY = 0x01, // Not implemented
+ SMSG_INVITE_NOTIFY = 0x04, // Not implemented
+ SMSG_INVITE_CANCELED = 0x07, // Not implemented
+ SMSG_MESSAGE_RECV = 0x0B, // Not implemented
+ SMSG_MESSAGE_UNDELIVERABLE = 0x0C, // Not implemented
+ SMSG_DATAGRAM_CONNECTION_UPDATE = 0x0D, // Not implemented
+ SMSG_INVITE_FAILURE = 0x0F, // Not implemented
+ SMSG_SYSTEM_MESSAGE = 0x10, // Not implemented
+ SMSG_MESSAGE_BLOCKED = 0x12, // Not implemented
+ SMSG_WHISPER_RECV = 0x13, // Not implemented
+ SMSG_WHISPER_UNDELIVERABLE = 0x14, // Not implemented
+ SMSG_CATEGORY_DESCRIPTIONS = 0x16, // Not implemented
+ SMSG_CONFERENCE_DESCRIPTIONS = 0x18, // Not implemented
+ SMSG_CONFERENCE_MEMBER_COUNTS = 0x1A, // Not implemented
+ SMSG_JOIN_NOTIFY_2 = 0x1B, // Not implemented
+ SMSG_MODIFY_CHANNEL_LIST_RESPONSE = 0x1C, // Not implemented
+ SMSG_CONFIG_CHANGED = 0x1D // Not implemented
+ };
+ }
+}
+
+#endif // ChatPackets_h__
diff --git a/src/server/bnetserver/Packets/ConnectionPackets.cpp b/src/server/bnetserver/Packets/ConnectionPackets.cpp
new file mode 100644
index 00000000000..3b7a9949552
--- /dev/null
+++ b/src/server/bnetserver/Packets/ConnectionPackets.cpp
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "Session.h"
+#include "ConnectionPackets.h"
+
+std::string Battlenet::Connection::Ping::ToString() const
+{
+ return "Battlenet::Connection::Ping";
+}
+
+void Battlenet::Connection::Ping::CallHandler(Session* session)
+{
+ session->HandlePing(*this);
+}
+
+std::string Battlenet::Connection::EnableEncryption::ToString() const
+{
+ return "Battlenet::Connection::EnableEncryption";
+}
+
+void Battlenet::Connection::EnableEncryption::CallHandler(Session* session)
+{
+ session->HandleEnableEncryption(*this);
+}
+
+std::string Battlenet::Connection::LogoutRequest::ToString() const
+{
+ return "Battlenet::Connection::LogoutRequest";
+}
+
+void Battlenet::Connection::LogoutRequest::CallHandler(Session* session)
+{
+ session->HandleLogoutRequest(*this);
+}
+
+void Battlenet::Connection::DisconnectRequest::Read()
+{
+ Timeout = _stream.Read<uint16>(16);
+ Tick = _stream.Read<uint32>(32);
+}
+
+std::string Battlenet::Connection::DisconnectRequest::ToString() const
+{
+ std::ostringstream str;
+ str << "Battlenet::Connection::DisconnectRequest Timeout: " << Timeout << ", Tick: " << Tick;
+ return str.str();
+}
+
+void Battlenet::Connection::ConnectionClosing::Read()
+{
+ Packets.resize(_stream.Read<uint8>(6));
+ for (size_t i = 0; i < Packets.size(); ++i)
+ {
+ PacketInfo& info = Packets[i];
+ info.CommandName = _stream.ReadFourCC();
+ info.Timestamp = _stream.Read<uint32>(32);
+ info.Size = _stream.Read<uint32>(16);
+ info.Channel = _stream.ReadFourCC();
+ info.LayerId = _stream.Read<uint32>(16);
+ }
+
+ Reason = _stream.Read<ClosingReason>(4);
+ _stream.ReadBytes(_stream.Read<uint8>(8)); // BadData
+
+ if (_stream.Read<bool>(1)) // HasHeader
+ {
+ Header.Opcode = _stream.Read<uint32>(6);
+ if (_stream.Read<bool>(1))
+ Header.Channel = _stream.Read<int32>(4);
+ }
+
+ Now = _stream.Read<time_t>(32);
+}
+
+std::string Battlenet::Connection::ConnectionClosing::ToString() const
+{
+ std::ostringstream stream;
+ stream << "Battlenet::Connection::ConnectionClosing Reason: " << Reason << ", Now: " << Now << ", Packet history size: " << Packets.size();
+ for (PacketInfo const& packet : Packets)
+ stream << std::endl << "Battlenet::Connection::ConnectionClosing::PacketInfo LayerId: " << packet.LayerId
+ << ", Channel: " << packet.Channel << ", CommandName: " << packet.CommandName << ", Size: " << packet.Size << ", Timestamp: " << packet.Timestamp;
+
+ return stream.str();
+}
+
+void Battlenet::Connection::ConnectionClosing::CallHandler(Session* session)
+{
+ session->HandleConnectionClosing(*this);
+}
+
+std::string Battlenet::Connection::Pong::ToString() const
+{
+ return "Battlenet::Connection::Pong";
+}
diff --git a/src/server/bnetserver/Packets/ConnectionPackets.h b/src/server/bnetserver/Packets/ConnectionPackets.h
new file mode 100644
index 00000000000..8572cd5d854
--- /dev/null
+++ b/src/server/bnetserver/Packets/ConnectionPackets.h
@@ -0,0 +1,153 @@
+/*
+ * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef ConnectionPackets_h__
+#define ConnectionPackets_h__
+
+#include "PacketsBase.h"
+
+namespace Battlenet
+{
+ namespace Connection
+ {
+ enum Opcode
+ {
+ CMSG_PING = 0x0,
+ CMSG_ENABLE_ENCRYPTION = 0x5,
+ CMSG_LOGOUT_REQUEST = 0x6,
+ CMSG_DISCONNECT_REQUEST = 0x7, // Not handled
+ CMSG_CONNECTION_CLOSING = 0x9,
+
+ SMSG_PONG = 0x0,
+ SMSG_BOOM = 0x1, // Not implemented
+ SMSG_REGULATOR_UPDATE = 0x2, // Not implemented
+ SMSG_SERVER_VERSION = 0x3, // Not implemented
+ SMSG_STUN_SERVERS = 0x4 // Not implemented
+ };
+
+ class Ping final : public ClientPacket
+ {
+ public:
+ Ping(PacketHeader const& header, BitStream& stream) : ClientPacket(header, stream)
+ {
+ ASSERT(header == PacketHeader(CMSG_PING, CONNECTION) && "Invalid packet header for Ping");
+ }
+
+ void Read() override { }
+ std::string ToString() const override;
+ void CallHandler(Session* session) override;
+ };
+
+ class EnableEncryption final : public ClientPacket
+ {
+ public:
+ EnableEncryption(PacketHeader const& header, BitStream& stream) : ClientPacket(header, stream)
+ {
+ ASSERT(header == PacketHeader(CMSG_ENABLE_ENCRYPTION, CONNECTION) && "Invalid packet header for EnableEncryption");
+ }
+
+ void Read() override { }
+ std::string ToString() const override;
+ void CallHandler(Session* session) override;
+ };
+
+ class LogoutRequest final : public ClientPacket
+ {
+ public:
+ LogoutRequest(PacketHeader const& header, BitStream& stream) : ClientPacket(header, stream)
+ {
+ ASSERT(header == PacketHeader(CMSG_LOGOUT_REQUEST, CONNECTION) && "Invalid packet header for LogoutRequest");
+ }
+
+ void Read() override { }
+ std::string ToString() const override;
+ void CallHandler(Session* session) override;
+ };
+
+ class DisconnectRequest final : public ClientPacket
+ {
+ public:
+ DisconnectRequest(PacketHeader const& header, BitStream& stream) : ClientPacket(header, stream)
+ {
+ ASSERT(header == PacketHeader(CMSG_DISCONNECT_REQUEST, CONNECTION) && "Invalid packet header for DisconnectRequest");
+ }
+
+ void Read() override;
+ std::string ToString() const override;
+
+ uint16 Timeout;
+ uint32 Tick;
+ };
+
+ class ConnectionClosing final : public ClientPacket
+ {
+ public:
+ enum ClosingReason
+ {
+ PACKET_TOO_LARGE,
+ PACKET_CORRUPT,
+ PACKET_INVALID,
+ PACKET_INCORRECT,
+ HEADER_CORRUPT,
+ HEADER_IGNORED,
+ HEADER_INCORRECT,
+ PACKET_REJECTED,
+ CHANNEL_UNHANDLED,
+ COMMAND_UNHANDLED,
+ COMMAND_BAD_PERMISSIONS,
+ DIRECT_CALL,
+ TIMEOUT,
+ };
+
+ struct PacketInfo
+ {
+ uint16 LayerId;
+ std::string Channel;
+ uint32 Timestamp;
+ std::string CommandName;
+ uint16 Size;
+ };
+
+ ConnectionClosing(PacketHeader const& header, BitStream& stream) : ClientPacket(header, stream)
+ {
+ ASSERT(header == PacketHeader(CMSG_CONNECTION_CLOSING, CONNECTION) && "Invalid packet header for ConnectionClosing");
+ }
+
+ void Read() override;
+ std::string ToString() const override;
+ void CallHandler(Session* session) override;
+
+ PacketHeader Header;
+ ClosingReason Reason;
+ std::vector<PacketInfo> Packets;
+ time_t Now;
+ };
+
+ class Pong final : public ServerPacket
+ {
+ public:
+ Pong() : ServerPacket(PacketHeader(SMSG_PONG, CONNECTION))
+ {
+ }
+
+ void Write() override { }
+ std::string ToString() const override;
+ };
+ }
+}
+
+#endif // ConnectionPackets_h__
diff --git a/src/server/bnetserver/Packets/FriendsPackets.cpp b/src/server/bnetserver/Packets/FriendsPackets.cpp
new file mode 100644
index 00000000000..2659ec6204f
--- /dev/null
+++ b/src/server/bnetserver/Packets/FriendsPackets.cpp
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "Session.h"
+#include "FriendsPackets.h"
+
+void Battlenet::Friends::GetFriendsOfFriend::Read()
+{
+ uint8 unk = _stream.Read<uint8>(2);
+ uint32 unk1 = _stream.Read<uint32>(32);
+}
+
+std::string Battlenet::Friends::GetFriendsOfFriend::ToString() const
+{
+ return "Battlenet::Friends::GetFriendsOfFriend";
+}
+
+void Battlenet::Friends::SocialNetworkCheckConnected::Read()
+{
+ SocialNetworkId = _stream.Read<uint32>(32);
+}
+
+std::string Battlenet::Friends::SocialNetworkCheckConnected::ToString() const
+{
+ return "Battlenet::Friends::SocialNetworkCheckConnected SocialNetworkId " + std::to_string(SocialNetworkId);
+}
+
+void Battlenet::Friends::SocialNetworkCheckConnected::CallHandler(Session* session)
+{
+ session->HandleSocialNetworkCheckConnected(*this);
+}
+
+void Battlenet::Friends::RealIdFriendInvite::Read()
+{
+ _stream.Read<uint32>(32);
+ uint8 type = _stream.Read<uint8>(3);
+
+ switch (type)
+ {
+ case 0:
+ {
+ _stream.Read<uint32>(32); // Presence Id?
+ break;
+ }
+ case 1: // GameAccount?
+ {
+ _stream.Read<uint8>(8);
+ _stream.Read<uint32>(32);
+ _stream.Read<uint32>(32);
+ uint8 size = _stream.Read<uint8>(7); // Only if *(a1 + 16) <= 0x64
+ _stream.ReadBytes(size);
+ break;
+ }
+ case 2:
+ Email = _stream.ReadString(9, 3);
+ break;
+ case 3:
+ {
+ _stream.Read<uint32>(32);
+ break;
+ }
+ case 4:
+ {
+ _stream.Read<uint64>(64);
+ _stream.Read<uint32>(32);
+ break;
+ }
+ }
+
+ _stream.Read<uint8>(1);
+
+ if (_stream.Read<uint8>(1))
+ Message = _stream.ReadString(9);
+
+ _stream.Read<uint32>(32);
+}
+
+std::string Battlenet::Friends::RealIdFriendInvite::ToString() const
+{
+ return "Battlenet::Friends::RealIdFriendInvite Mail: " + Email + " Message: " + Message;
+}
+
+std::string Battlenet::Friends::FriendInviteResult::ToString() const
+{
+ return "Battlenet::Friends::RealIdFriendInviteResult";
+}
+
+void Battlenet::Friends::FriendInviteResult::Write()
+{
+ bool hasNames = false;
+ _stream.Write(hasNames, 1);
+ if (hasNames)
+ {
+ _stream.WriteString("Testing1", 8);
+ _stream.WriteString("Testing2", 8);
+ }
+ _stream.Write(5, 32);
+
+ _stream.Write(0, 0xC); // Ignored
+
+ _stream.Write(1, 16);
+
+ bool moreInfo = true;
+ _stream.Write(moreInfo, 1);
+ if (moreInfo)
+ {
+ _stream.Write(0, 8);
+ _stream.Write(4, 32);
+ _stream.Write(3, 32);
+ _stream.WriteString("Testing3", 7, 2);
+ }
+}
+
+std::string Battlenet::Friends::SocialNetworkCheckConnectedResult::ToString() const
+{
+ return "Battlenet::Friends::SocialNetworkCheckConnectedResult";
+}
+
+void Battlenet::Friends::SocialNetworkCheckConnectedResult::Write()
+{
+ _stream.WriteSkip(23);
+ _stream.Write(Result, 16);
+ _stream.Write(SocialNetworkId, 32);
+}
diff --git a/src/server/bnetserver/Packets/FriendsPackets.h b/src/server/bnetserver/Packets/FriendsPackets.h
new file mode 100644
index 00000000000..ea4d6d2ea92
--- /dev/null
+++ b/src/server/bnetserver/Packets/FriendsPackets.h
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef FriendsPackets_h__
+#define FriendsPackets_h__
+
+#include "PacketsBase.h"
+
+namespace Battlenet
+{
+ namespace Friends
+ {
+ enum Opcode
+ {
+ CMSG_FRIEND_INVITE = 0x01, // Not implemented
+ CMSG_FRIEND_INVITE_RESPONSE = 0x02, // Not implemented
+ CMSG_FRIEND_REMOVE = 0x04, // Not implemented
+ CMSG_FRIEND_NOTE = 0x05, // Not implemented
+ CMSG_TOONS_OF_FRIEND_REQUEST = 0x06, // Not implemented
+ CMSG_BLOCK_ADD = 0x08, // Not implemented
+ CMSG_BLOCK_REMOVE = 0x0A, // Not implemented
+ CMSG_GET_FRIENDS_OF_FRIEND = 0x0B, // Not implemented
+ CMSG_GET_SOCIAL_NETWORK_FRIENDS = 0x0D, // Won't support
+ CMSG_SOCIAL_NETWORK_CONNECT = 0x0F, // Won't support
+ CMSG_SOCIAL_NETWORK_DISCONNECT = 0x11, // Won't support
+ CMSG_SOCIAL_NETWORK_CHECK_CONNECTED = 0x13,
+ CMSG_REALID_FRIEND_INVITE = 0x16, // Not implemented
+
+ SMSG_FRIEND_INVITE_NOTIFY = 0x01, // Not implemented
+ SMSG_FRIEND_INVITE_RESULT = 0x03, // Not implemented
+ SMSG_TOONS_OF_FRIEND_NOTIFY = 0x06, // Not implemented
+ SMSG_BLOCK_INVITE_NOTIFY = 0x07, // Not implemented
+ SMSG_BLOCK_ADD_FAILURE = 0x09, // Not implemented
+ SMSG_FRIENDS_OF_FRIEND = 0x0C, // Not implemented
+ SMSG_SOCIAL_NETWORK_FRIENDS = 0x0E, // Won't support
+ SMSG_SOCIAL_NETWORK_CONNECT_RESULT = 0x10, // Won't support
+ SMSG_SOCIAL_NETWORK_DISCONNECT_RESULT = 0x12, // Won't support
+ SMSG_SOCIAL_NETWORK_CHECK_CONNECTED_RESULT = 0x14,
+ SMSG_MAX_FRIENDS_NOTIFY = 0x15, // Not implemented
+ SMSG_FRIENDS_LIST_NOTIFY_3 = 0x18 // Not implemented
+ };
+
+ class GetFriendsOfFriend final : public ClientPacket
+ {
+ public:
+ GetFriendsOfFriend(PacketHeader const& header, BitStream& stream) : ClientPacket(header, stream)
+ {
+ ASSERT(header == PacketHeader(CMSG_GET_FRIENDS_OF_FRIEND, FRIENDS) && "Invalid packet header for GetFriendsOfFriend");
+ }
+
+ void Read() override;
+ std::string ToString() const override;
+ };
+
+ class SocialNetworkCheckConnected final : public ClientPacket
+ {
+ public:
+ SocialNetworkCheckConnected(PacketHeader const& header, BitStream& stream) : ClientPacket(header, stream)
+ {
+ ASSERT(header == PacketHeader(CMSG_SOCIAL_NETWORK_CHECK_CONNECTED, FRIENDS) && "Invalid packet header for SocialNetworkCheckConnected");
+ }
+
+ void Read() override;
+ std::string ToString() const override;
+ void CallHandler(Session* session) override;
+
+ uint32 SocialNetworkId;
+ };
+
+ class RealIdFriendInvite final : public ClientPacket
+ {
+ public:
+ RealIdFriendInvite(PacketHeader const& header, BitStream& stream) : ClientPacket(header, stream)
+ {
+ ASSERT(header == PacketHeader(CMSG_REALID_FRIEND_INVITE, FRIENDS) && "Invalid packet header for RealIdFriendInvite");
+ }
+
+ void Read() override;
+ std::string ToString() const override;
+
+ std::string Email;
+ std::string Message;
+ };
+
+ class FriendInviteResult final : public ServerPacket
+ {
+ public:
+ FriendInviteResult() : ServerPacket(PacketHeader(SMSG_FRIEND_INVITE_RESULT, FRIENDS))
+ {
+ }
+
+ void Write() override;
+ std::string ToString() const override;
+ };
+
+ class FriendsOfFriend final : public ServerPacket
+ {
+ public:
+ FriendsOfFriend() : ServerPacket(PacketHeader(SMSG_FRIENDS_OF_FRIEND, FRIENDS))
+ {
+ }
+
+ void Write() override;
+ std::string ToString() const override;
+ };
+
+ class SocialNetworkCheckConnectedResult final : public ServerPacket
+ {
+ public:
+ SocialNetworkCheckConnectedResult() : ServerPacket(PacketHeader(SMSG_SOCIAL_NETWORK_CHECK_CONNECTED_RESULT, FRIENDS)),
+ Result(4601), SocialNetworkId(0) // 4601 = The Facebook add friend service is unavailable right now. Please try again later.
+ {
+ }
+
+ void Write() override;
+ std::string ToString() const override;
+
+ uint16 Result;
+ uint32 SocialNetworkId;
+ };
+ }
+}
+
+#endif // FriendsPackets_h__
diff --git a/src/server/bnetserver/Packets/PacketManager.cpp b/src/server/bnetserver/Packets/PacketManager.cpp
new file mode 100644
index 00000000000..cbfd0c8b2b6
--- /dev/null
+++ b/src/server/bnetserver/Packets/PacketManager.cpp
@@ -0,0 +1,243 @@
+/*
+ * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "PacketManager.h"
+
+Battlenet::ClientPacket* Battlenet::PacketManager::CreateClientPacket(PacketHeader const& header, BitStream& stream)
+{
+ auto packetInfo = _clientPacketTable.find(header);
+ if (packetInfo == _clientPacketTable.end())
+ return nullptr;
+
+ if (!packetInfo->second.Constructor)
+ return nullptr;
+
+ ClientPacket* packet = packetInfo->second.Constructor(header, stream);
+ packet->Read();
+ return packet;
+}
+
+char const* Battlenet::PacketManager::GetClientPacketName(PacketHeader const& header)
+{
+ auto packetInfo = _clientPacketTable.find(header);
+ if (packetInfo == _clientPacketTable.end())
+ return nullptr;
+
+ return packetInfo->second.Name;
+}
+
+char const* Battlenet::PacketManager::GetServerPacketName(PacketHeader const& header)
+{
+ auto packetInfo = _serverPacketTable.find(header);
+ if (packetInfo == _serverPacketTable.end())
+ return nullptr;
+
+ return packetInfo->second.Name;
+}
+
+bool Battlenet::PacketManager::IsHandled(PacketHeader const& header)
+{
+ auto packetInfo = _clientPacketTable.find(header);
+ if (packetInfo == _clientPacketTable.end())
+ return false;
+
+ return packetInfo->second.HasHandler;
+}
+
+Battlenet::PacketManager::PacketManager()
+{
+ RegisterAuthenticationPackets();
+ RegisterConnectionPackets();
+ RegisterWoWRealmPackets();
+ RegisterFriendsPackets();
+ RegisterPresencePackets();
+ RegisterChatPackets();
+ RegisterSupportPackets();
+ RegisterCachePackets();
+ RegisterAchievementPackets();
+ RegisterProfilePackets();
+}
+
+#define REGISTER_CLIENT_PACKET(header, packetClass) RegisterClientPacket<packetClass>(header, #packetClass)
+#define REGISTER_SERVER_PACKET(header, packetClass) RegisterPacketName(_serverPacketTable, header, #packetClass)
+#define REGISTER_CLIENT_PACKET_NAME(header, name) RegisterPacketName(_clientPacketTable, header, name)
+#define REGISTER_SERVER_PACKET_NAME(header, name) RegisterPacketName(_serverPacketTable, header, name)
+
+void Battlenet::PacketManager::RegisterAuthenticationPackets()
+{
+ REGISTER_CLIENT_PACKET_NAME(PacketHeader(Authentication::CMSG_LOGON_REQUEST, AUTHENTICATION), "Authentication::LogonRequest3");
+ REGISTER_CLIENT_PACKET(PacketHeader(Authentication::CMSG_RESUME_REQUEST, AUTHENTICATION), Authentication::ResumeRequest);
+ REGISTER_CLIENT_PACKET(PacketHeader(Authentication::CMSG_PROOF_RESPONSE, AUTHENTICATION), Authentication::ProofResponse);
+ REGISTER_CLIENT_PACKET(PacketHeader(Authentication::CMSG_LOGON_REQUEST_3, AUTHENTICATION), Authentication::LogonRequest3);
+
+ REGISTER_SERVER_PACKET(PacketHeader(Authentication::SMSG_LOGON_RESPONSE, AUTHENTICATION), Authentication::LogonResponse);
+ REGISTER_SERVER_PACKET(PacketHeader(Authentication::SMSG_RESUME_RESPONSE, AUTHENTICATION), Authentication::ResumeResponse);
+ REGISTER_SERVER_PACKET(PacketHeader(Authentication::SMSG_PROOF_REQUEST, AUTHENTICATION), Authentication::ProofRequest);
+ REGISTER_SERVER_PACKET_NAME(PacketHeader(Authentication::SMSG_PATCH, AUTHENTICATION), "Authentication::Patch");
+ REGISTER_SERVER_PACKET_NAME(PacketHeader(Authentication::SMSG_AUTHORIZED_LICENSES, AUTHENTICATION), "Authentication::AuthorizedLicenses");
+}
+
+void Battlenet::PacketManager::RegisterConnectionPackets()
+{
+ REGISTER_CLIENT_PACKET(PacketHeader(Connection::CMSG_PING, CONNECTION), Connection::Ping);
+ REGISTER_CLIENT_PACKET(PacketHeader(Connection::CMSG_ENABLE_ENCRYPTION, CONNECTION), Connection::EnableEncryption);
+ REGISTER_CLIENT_PACKET(PacketHeader(Connection::CMSG_LOGOUT_REQUEST, CONNECTION), Connection::LogoutRequest);
+ REGISTER_CLIENT_PACKET(PacketHeader(Connection::CMSG_DISCONNECT_REQUEST, CONNECTION), Connection::DisconnectRequest);
+ REGISTER_CLIENT_PACKET(PacketHeader(Connection::CMSG_CONNECTION_CLOSING, CONNECTION), Connection::ConnectionClosing);
+
+ REGISTER_SERVER_PACKET(PacketHeader(Connection::SMSG_PONG, CONNECTION), Connection::Pong);
+ REGISTER_SERVER_PACKET_NAME(PacketHeader(Connection::SMSG_BOOM, CONNECTION), "Connection::Boom");
+ REGISTER_SERVER_PACKET_NAME(PacketHeader(Connection::SMSG_REGULATOR_UPDATE, CONNECTION), "Connection::RegulatorUpdate");
+ REGISTER_SERVER_PACKET_NAME(PacketHeader(Connection::SMSG_SERVER_VERSION, CONNECTION), "Connection::ServerVersion");
+ REGISTER_SERVER_PACKET_NAME(PacketHeader(Connection::SMSG_STUN_SERVERS, CONNECTION), "Connection::STUNServers");
+}
+
+void Battlenet::PacketManager::RegisterWoWRealmPackets()
+{
+ REGISTER_CLIENT_PACKET(PacketHeader(WoWRealm::CMSG_LIST_SUBSCRIBE_REQUEST, WOWREALM), WoWRealm::ListSubscribeRequest);
+ REGISTER_CLIENT_PACKET(PacketHeader(WoWRealm::CMSG_LIST_UNSUBSCRIBE, WOWREALM), WoWRealm::ListUnsubscribe);
+ REGISTER_CLIENT_PACKET(PacketHeader(WoWRealm::CMSG_JOIN_REQUEST_V2, WOWREALM), WoWRealm::JoinRequestV2);
+ REGISTER_CLIENT_PACKET_NAME(PacketHeader(WoWRealm::CMSG_MULTI_LOGON_REQUEST_V2, WOWREALM), "WoWRealm::MultiLogonRequestV2");
+
+ REGISTER_SERVER_PACKET(PacketHeader(WoWRealm::SMSG_LIST_SUBSCRIBE_RESPONSE, WOWREALM), WoWRealm::ListSubscribeResponse);
+ REGISTER_SERVER_PACKET(PacketHeader(WoWRealm::SMSG_LIST_UPDATE, WOWREALM), WoWRealm::ListUpdate);
+ REGISTER_SERVER_PACKET(PacketHeader(WoWRealm::SMSG_LIST_COMPLETE, WOWREALM), WoWRealm::ListComplete);
+ REGISTER_SERVER_PACKET(PacketHeader(WoWRealm::SMSG_TOON_READY, WOWREALM), WoWRealm::ToonReady);
+ REGISTER_SERVER_PACKET(PacketHeader(WoWRealm::SMSG_TOON_LOGGED_OUT, WOWREALM), WoWRealm::ToonLoggedOut);
+ REGISTER_SERVER_PACKET(PacketHeader(WoWRealm::SMSG_JOIN_RESPONSE_V2, WOWREALM), WoWRealm::JoinResponseV2);
+}
+
+void Battlenet::PacketManager::RegisterFriendsPackets()
+{
+ REGISTER_CLIENT_PACKET_NAME(PacketHeader(Friends::CMSG_FRIEND_INVITE, FRIENDS), "Friends::FriendInvite");
+ REGISTER_CLIENT_PACKET_NAME(PacketHeader(Friends::CMSG_FRIEND_INVITE_RESPONSE, FRIENDS), "Friends::FriendInviteResponse");
+ REGISTER_CLIENT_PACKET_NAME(PacketHeader(Friends::CMSG_FRIEND_REMOVE, FRIENDS), "Friends::FriendRemove");
+ REGISTER_CLIENT_PACKET_NAME(PacketHeader(Friends::CMSG_FRIEND_NOTE, FRIENDS), "Friends::FriendNote");
+ REGISTER_CLIENT_PACKET_NAME(PacketHeader(Friends::CMSG_TOONS_OF_FRIEND_REQUEST, FRIENDS), "Friends::ToonsOfFriendRequest");
+ REGISTER_CLIENT_PACKET_NAME(PacketHeader(Friends::CMSG_BLOCK_ADD, FRIENDS), "Friends::BlockAdd");
+ REGISTER_CLIENT_PACKET_NAME(PacketHeader(Friends::CMSG_BLOCK_REMOVE, FRIENDS), "Friends::BlockRemove");
+ REGISTER_CLIENT_PACKET_NAME(PacketHeader(Friends::CMSG_GET_FRIENDS_OF_FRIEND, FRIENDS), "Friends::GetFriendsOfFriend");
+ REGISTER_CLIENT_PACKET_NAME(PacketHeader(Friends::CMSG_GET_SOCIAL_NETWORK_FRIENDS, FRIENDS), "Friends::GetSocialNetworkFriends");
+ REGISTER_CLIENT_PACKET_NAME(PacketHeader(Friends::CMSG_SOCIAL_NETWORK_CONNECT, FRIENDS), "Friends::SocialNetworkConnect");
+ REGISTER_CLIENT_PACKET_NAME(PacketHeader(Friends::CMSG_SOCIAL_NETWORK_DISCONNECT, FRIENDS), "Friends::SocialNetworkDisconnect");
+ REGISTER_CLIENT_PACKET(PacketHeader(Friends::CMSG_SOCIAL_NETWORK_CHECK_CONNECTED, FRIENDS), Friends::SocialNetworkCheckConnected);
+ REGISTER_CLIENT_PACKET(PacketHeader(Friends::CMSG_GET_FRIENDS_OF_FRIEND, FRIENDS), Friends::GetFriendsOfFriend);
+ REGISTER_CLIENT_PACKET(PacketHeader(Friends::CMSG_REALID_FRIEND_INVITE, FRIENDS), Friends::RealIdFriendInvite);
+
+ REGISTER_SERVER_PACKET_NAME(PacketHeader(Friends::SMSG_FRIEND_INVITE_NOTIFY, FRIENDS), "Friends::FriendInviteNotify");
+ REGISTER_SERVER_PACKET(PacketHeader(Friends::SMSG_FRIEND_INVITE_RESULT, FRIENDS), Friends::FriendInviteResult);
+ REGISTER_SERVER_PACKET_NAME(PacketHeader(Friends::SMSG_TOONS_OF_FRIEND_NOTIFY, FRIENDS), "Friends::ToonsOfFriendNotify");
+ REGISTER_SERVER_PACKET_NAME(PacketHeader(Friends::SMSG_BLOCK_INVITE_NOTIFY, FRIENDS), "Friends::BlockInviteNotify");
+ REGISTER_SERVER_PACKET_NAME(PacketHeader(Friends::SMSG_BLOCK_ADD_FAILURE, FRIENDS), "Friends::BlockAddFailure");
+ REGISTER_SERVER_PACKET_NAME(PacketHeader(Friends::SMSG_FRIENDS_OF_FRIEND, FRIENDS), "Friends::FriendsOfFriend");
+ REGISTER_SERVER_PACKET_NAME(PacketHeader(Friends::SMSG_SOCIAL_NETWORK_FRIENDS, FRIENDS), "Friends::SocialNetworkFriends");
+ REGISTER_SERVER_PACKET_NAME(PacketHeader(Friends::SMSG_SOCIAL_NETWORK_CONNECT_RESULT, FRIENDS), "Friends::SocialNetworkConnectResult");
+ REGISTER_SERVER_PACKET_NAME(PacketHeader(Friends::SMSG_SOCIAL_NETWORK_DISCONNECT_RESULT, FRIENDS), "Friends::SocialNetworkDisconnectResult");
+ REGISTER_SERVER_PACKET(PacketHeader(Friends::SMSG_SOCIAL_NETWORK_CHECK_CONNECTED_RESULT, FRIENDS), Friends::SocialNetworkCheckConnectedResult);
+ REGISTER_SERVER_PACKET_NAME(PacketHeader(Friends::SMSG_MAX_FRIENDS_NOTIFY, FRIENDS), "Friends::MaxFriendsNotify");
+ REGISTER_SERVER_PACKET_NAME(PacketHeader(Friends::SMSG_FRIENDS_LIST_NOTIFY_3, FRIENDS), "Friends::FriendsListNotify3");
+}
+
+void Battlenet::PacketManager::RegisterPresencePackets()
+{
+ REGISTER_CLIENT_PACKET(PacketHeader(Presence::CMSG_UPDATE_REQUEST, PRESENCE), Presence::UpdateRequest);
+ REGISTER_CLIENT_PACKET(PacketHeader(Presence::CMSG_STATISTIC_SUBSCRIBE, PRESENCE), Presence::StatisticSubscribe);
+
+ REGISTER_SERVER_PACKET_NAME(PacketHeader(Presence::SMSG_UPDATE_NOTIFY, PRESENCE), "Presence::UpdateNotify");
+ REGISTER_SERVER_PACKET_NAME(PacketHeader(Presence::SMSG_FIELD_SPEC_ANNOUNCE, PRESENCE), "Presence::FieldSpecAnnounce");
+ REGISTER_SERVER_PACKET_NAME(PacketHeader(Presence::SMSG_STATISTICS_UPDATE, PRESENCE), "Presence::StatisticsUpdate");
+}
+
+void Battlenet::PacketManager::RegisterChatPackets()
+{
+ REGISTER_CLIENT_PACKET_NAME(PacketHeader(Chat::CMSG_JOIN_REQUEST_2, CHAT), "Chat::JoinRequest2");
+ REGISTER_CLIENT_PACKET_NAME(PacketHeader(Chat::CMSG_LEAVE_REQUEST, CHAT), "Chat::LeaveRequest");
+ REGISTER_CLIENT_PACKET_NAME(PacketHeader(Chat::CMSG_INVITE_REQUEST, CHAT), "Chat::InviteRequest");
+ REGISTER_CLIENT_PACKET_NAME(PacketHeader(Chat::CMSG_CREATE_AND_INVITE_REQUEST, CHAT), "Chat::CreateAndInviteRequest");
+ REGISTER_CLIENT_PACKET_NAME(PacketHeader(Chat::CMSG_MESSAGE_SEND, CHAT), "Chat::MessageSend");
+ REGISTER_CLIENT_PACKET_NAME(PacketHeader(Chat::CMSG_DATAGRAM_CONNECTION_UPDATE, CHAT), "Chat::DatagramConnectionUpdate");
+ REGISTER_CLIENT_PACKET_NAME(PacketHeader(Chat::CMSG_REPORT_SPAM_REQUEST, CHAT), "Chat::ReportSpamRequest");
+ REGISTER_CLIENT_PACKET_NAME(PacketHeader(Chat::CMSG_WHISPER_SEND, CHAT), "Chat::WhisperSend");
+ REGISTER_CLIENT_PACKET_NAME(PacketHeader(Chat::CMSG_ENUM_CATEGORY_DESCRIPTIONS, CHAT), "Chat::EnumCategoryDescriptions");
+ REGISTER_CLIENT_PACKET_NAME(PacketHeader(Chat::CMSG_ENUM_CONFERENCE_DESCRIPTIONS, CHAT), "Chat::EnumConferenceDescriptions");
+ REGISTER_CLIENT_PACKET_NAME(PacketHeader(Chat::CMSG_ENUM_CONFERENCE_MEMBER_COUNTS, CHAT), "Chat::EnumConferenceMemberCounts");
+ REGISTER_CLIENT_PACKET_NAME(PacketHeader(Chat::CMSG_MODIFY_CHANNEL_LIST_REQUEST, CHAT), "Chat::ModifyChannelListRequest");
+
+ REGISTER_SERVER_PACKET_NAME(PacketHeader(Chat::SMSG_MEMBERSHIP_CHANGE_NOTIFY, CHAT), "Chat::MembershipChangeNotify");
+ REGISTER_SERVER_PACKET_NAME(PacketHeader(Chat::SMSG_INVITE_NOTIFY, CHAT), "Chat::InviteNotify");
+ REGISTER_SERVER_PACKET_NAME(PacketHeader(Chat::SMSG_INVITE_CANCELED, CHAT), "Chat::InviteCanceled");
+ REGISTER_SERVER_PACKET_NAME(PacketHeader(Chat::SMSG_MESSAGE_RECV, CHAT), "Chat::MessageRecv");
+ REGISTER_SERVER_PACKET_NAME(PacketHeader(Chat::SMSG_MESSAGE_UNDELIVERABLE, CHAT), "Chat::MessageUndeliverable");
+ REGISTER_SERVER_PACKET_NAME(PacketHeader(Chat::SMSG_DATAGRAM_CONNECTION_UPDATE, CHAT), "Chat::DatagramConnectionUpdate");
+ REGISTER_SERVER_PACKET_NAME(PacketHeader(Chat::SMSG_INVITE_FAILURE, CHAT), "Chat::InviteFailed");
+ REGISTER_SERVER_PACKET_NAME(PacketHeader(Chat::SMSG_SYSTEM_MESSAGE, CHAT), "Chat::SystemMessage");
+ REGISTER_SERVER_PACKET_NAME(PacketHeader(Chat::SMSG_MESSAGE_BLOCKED, CHAT), "Chat::MessageBlocked");
+ REGISTER_SERVER_PACKET_NAME(PacketHeader(Chat::SMSG_WHISPER_RECV, CHAT), "Chat::WhisperRecv");
+ REGISTER_SERVER_PACKET_NAME(PacketHeader(Chat::SMSG_WHISPER_UNDELIVERABLE, CHAT), "Chat::WhisperUndeliverable");
+ REGISTER_SERVER_PACKET_NAME(PacketHeader(Chat::SMSG_CATEGORY_DESCRIPTIONS, CHAT), "Chat::CategoryDescriptions");
+ REGISTER_SERVER_PACKET_NAME(PacketHeader(Chat::SMSG_CONFERENCE_DESCRIPTIONS, CHAT), "Chat::ConferenceDescriptions");
+ REGISTER_SERVER_PACKET_NAME(PacketHeader(Chat::SMSG_CONFERENCE_MEMBER_COUNTS, CHAT), "Chat::ConferenceMemberCounts");
+ REGISTER_SERVER_PACKET_NAME(PacketHeader(Chat::SMSG_JOIN_NOTIFY_2, CHAT), "Chat::JoinNotify2");
+ REGISTER_SERVER_PACKET_NAME(PacketHeader(Chat::SMSG_MODIFY_CHANNEL_LIST_RESPONSE, CHAT), "Chat::ModifyChannelListResponse");
+ REGISTER_SERVER_PACKET_NAME(PacketHeader(Chat::SMSG_CONFIG_CHANGED, CHAT), "Chat::ConfigChanged");
+}
+
+void Battlenet::PacketManager::RegisterSupportPackets()
+{
+ REGISTER_CLIENT_PACKET_NAME(PacketHeader(Support::CMSG_COMPLAINT_REQUEST, SUPPORT), "Support::ComplaintRequest");
+}
+
+void Battlenet::PacketManager::RegisterAchievementPackets()
+{
+ REGISTER_CLIENT_PACKET_NAME(PacketHeader(Achievement::CMSG_LISTEN_REQUEST, ACHIEVEMENT), "Achievement::ListenRequest");
+ REGISTER_CLIENT_PACKET_NAME(PacketHeader(Achievement::CMSG_CRITERIA_FLUSH_REQUEST, ACHIEVEMENT), "Achievement::CriteriaFlushRequest");
+ REGISTER_CLIENT_PACKET_NAME(PacketHeader(Achievement::CMSG_CHANGE_TROPHY_CASE_REQUEST, ACHIEVEMENT), "Achievement::ChangeTrophyCaseRequest");
+
+ REGISTER_SERVER_PACKET_NAME(PacketHeader(Achievement::SMSG_DATA, ACHIEVEMENT), "Achievement::Data");
+ REGISTER_SERVER_PACKET_NAME(PacketHeader(Achievement::SMSG_CRITERIA_FLUSH_RESPONSE, ACHIEVEMENT), "Achievement::CriteriaFlushResponse");
+ REGISTER_SERVER_PACKET_NAME(PacketHeader(Achievement::SMSG_ACHIEVEMENT_HANDLE_UPDATE, ACHIEVEMENT), "Achievement::AchievementHandleUpdate");
+ REGISTER_SERVER_PACKET_NAME(PacketHeader(Achievement::SMSG_CHANGE_TROPHY_CASE_RESULT, ACHIEVEMENT), "Achievement::ChangeTrophyCaseResult");
+}
+
+void Battlenet::PacketManager::RegisterCachePackets()
+{
+ REGISTER_CLIENT_PACKET_NAME(PacketHeader(Cache::CMSG_GATEWAY_LOOKUP_REQUEST, CACHE), "Cache::GatewayLookupRequest");
+ REGISTER_CLIENT_PACKET_NAME(PacketHeader(Cache::CMSG_CONNECT_REQUEST, CACHE), "Cache::ConnectRequest");
+ REGISTER_CLIENT_PACKET_NAME(PacketHeader(Cache::CMSG_DATA_CHUNK, CACHE), "Cache::DataChunk");
+ REGISTER_CLIENT_PACKET(PacketHeader(Cache::CMSG_GET_STREAM_ITEMS_REQUEST, CACHE), Cache::GetStreamItemsRequest);
+
+ REGISTER_SERVER_PACKET_NAME(PacketHeader(Cache::SMSG_GATEWAY_LOOKUP_RESPONSE, CACHE), "Cache::GatewayLookupResponse");
+ REGISTER_SERVER_PACKET_NAME(PacketHeader(Cache::SMSG_CONNECT_RESPONSE, CACHE), "Cache::ConnectResponse");
+ REGISTER_SERVER_PACKET_NAME(PacketHeader(Cache::SMSG_PUBLISH_LIST_RESPONSE, CACHE), "Cache::PublishListResponse");
+ REGISTER_SERVER_PACKET_NAME(PacketHeader(Cache::SMSG_RESULT, CACHE), "Cache::Result");
+ REGISTER_SERVER_PACKET(PacketHeader(Cache::SMSG_GET_STREAM_ITEMS_RESPONSE, CACHE), Cache::GetStreamItemsResponse);
+}
+
+void Battlenet::PacketManager::RegisterProfilePackets()
+{
+ REGISTER_CLIENT_PACKET_NAME(PacketHeader(Profile::CMSG_READ_REQUEST, PROFILE), "Profile::ReadRequest");
+ REGISTER_CLIENT_PACKET_NAME(PacketHeader(Profile::CMSG_ADDRESS_QUERY_REQUEST, PROFILE), "Profile::AddressQueryRequest");
+ REGISTER_CLIENT_PACKET_NAME(PacketHeader(Profile::CMSG_RESOLVE_TOON_HANDLE_TO_NAME_REQUEST, PROFILE), "Profile::ResolveHandleToToonNameRequest");
+ REGISTER_CLIENT_PACKET_NAME(PacketHeader(Profile::CMSG_RESOLVE_TOON_NAME_TO_HANDLE_REQUEST, PROFILE), "Profile::ResolveToonNameToHandleRequest");
+ REGISTER_CLIENT_PACKET_NAME(PacketHeader(Profile::CMSG_CHANGE_SETTINGS, PROFILE), "Profile::ChangeSettings");
+
+ REGISTER_SERVER_PACKET_NAME(PacketHeader(Profile::SMSG_READ_RESPONSE, PROFILE), "Profile::ReadResponse");
+ REGISTER_SERVER_PACKET_NAME(PacketHeader(Profile::SMSG_ADDRESS_QUERY_RESPONSE, PROFILE), "Profile::AddressQueryResponse");
+ REGISTER_SERVER_PACKET_NAME(PacketHeader(Profile::SMSG_RESOLVE_TOON_HANDLE_TO_NAME_RESPONSE, PROFILE), "Profile::ResolveHandleToToonNameResponse");
+ REGISTER_SERVER_PACKET_NAME(PacketHeader(Profile::SMSG_RESOLVE_TOON_NAME_TO_HANDLE_RESPONSE, PROFILE), "Profile::ResolveToonNameToHandleResponse");
+ REGISTER_SERVER_PACKET_NAME(PacketHeader(Profile::SMSG_SETTINGS_AVAILABLE, PROFILE), "Profile::SettingsAvailable");
+}
diff --git a/src/server/bnetserver/Packets/PacketManager.h b/src/server/bnetserver/Packets/PacketManager.h
new file mode 100644
index 00000000000..1e64e6a502c
--- /dev/null
+++ b/src/server/bnetserver/Packets/PacketManager.h
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef PacketManager_h__
+#define PacketManager_h__
+
+#include "Packets.h"
+#include <map>
+#include <type_traits>
+
+template<typename T>
+struct has_call_handler
+{
+ template<typename U, void(U::*)(Battlenet::Session*)> struct test_has_call_handler { };
+ template<typename U> static char Test(test_has_call_handler<U, &U::CallHandler>*);
+ template<typename U> static int Test(...);
+ static const bool value = sizeof(Test<T>(nullptr)) == sizeof(char);
+};
+
+namespace Battlenet
+{
+ class PacketManager
+ {
+ typedef ClientPacket*(*PacketCreateFn)(PacketHeader const& header, BitStream& stream);
+
+ struct PacketInfo
+ {
+ PacketCreateFn Constructor;
+ char const* Name;
+ bool HasHandler;
+ };
+
+ PacketManager();
+
+ void RegisterAuthenticationPackets();
+ void RegisterConnectionPackets();
+ void RegisterWoWRealmPackets();
+ void RegisterFriendsPackets();
+ void RegisterPresencePackets();
+ void RegisterChatPackets();
+ void RegisterSupportPackets();
+ void RegisterAchievementPackets();
+ void RegisterCachePackets();
+ void RegisterProfilePackets();
+
+ template<class PacketType>
+ static ClientPacket* New(PacketHeader const& header, BitStream& stream)
+ {
+ return new PacketType(header, stream);
+ }
+
+ void RegisterPacketName(std::map<PacketHeader, PacketInfo>& packetTable, PacketHeader const& header, char const* name)
+ {
+ PacketInfo& info = packetTable[header];
+ info.Constructor = nullptr;
+ info.Name = name;
+ info.HasHandler = false;
+ }
+
+ template<class PacketType>
+ void RegisterClientPacket(PacketHeader const& header, char const* name)
+ {
+ PacketInfo& info = _clientPacketTable[header];
+ info.Constructor = &New<PacketType>;
+ info.Name = name;
+ info.HasHandler = has_call_handler<PacketType>::value;
+ }
+
+ public:
+ ClientPacket* CreateClientPacket(PacketHeader const& header, BitStream& stream);
+
+ char const* GetClientPacketName(PacketHeader const& header);
+ char const* GetServerPacketName(PacketHeader const& header);
+
+ bool IsHandled(PacketHeader const& header);
+
+ static PacketManager& Instance()
+ {
+ static PacketManager instance;
+ return instance;
+ }
+
+ private:
+ std::map<PacketHeader, PacketInfo> _clientPacketTable;
+ std::map<PacketHeader, PacketInfo> _serverPacketTable;
+ };
+}
+
+#define sPacketManager Battlenet::PacketManager::Instance()
+
+#endif // PacketManager_h__
diff --git a/src/server/authserver/Server/BattlenetPackets/BattlenetPackets.h b/src/server/bnetserver/Packets/Packets.h
index 15c609b3ba4..f62ba6f65cd 100644
--- a/src/server/authserver/Server/BattlenetPackets/BattlenetPackets.h
+++ b/src/server/bnetserver/Packets/Packets.h
@@ -15,11 +15,18 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef BattlenetPackets_h__
-#define BattlenetPackets_h__
+#ifndef Packets_h__
+#define Packets_h__
#include "AuthenticationPackets.h"
#include "ConnectionPackets.h"
#include "WoWRealmPackets.h"
+#include "FriendsPackets.h"
+#include "PresencePackets.h"
+#include "ChatPackets.h"
+#include "SupportPackets.h"
+#include "AchievementPackets.h"
+#include "CachePackets.h"
+#include "ProfilePackets.h"
-#endif // BattlenetPackets_h__
+#endif // Packets_h__
diff --git a/src/server/authserver/Server/BattlenetPackets/BattlenetPacketsBase.cpp b/src/server/bnetserver/Packets/PacketsBase.cpp
index 034bb8ba0a4..fd3bebcf471 100644
--- a/src/server/authserver/Server/BattlenetPackets/BattlenetPacketsBase.cpp
+++ b/src/server/bnetserver/Packets/PacketsBase.cpp
@@ -15,7 +15,8 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "BattlenetPackets.h"
+#include "Packets.h"
+#include "Session.h"
#include <sstream>
std::string Battlenet::PacketHeader::ToString() const
@@ -36,3 +37,8 @@ Battlenet::ServerPacket::~ServerPacket()
{
delete &_stream;
}
+
+void Battlenet::ClientPacket::CallHandler(Session* session)
+{
+ session->LogUnhandledPacket(GetHeader());
+}
diff --git a/src/server/authserver/Server/BattlenetPackets/BattlenetPacketsBase.h b/src/server/bnetserver/Packets/PacketsBase.h
index af02eb91f43..0f86621d6a6 100644
--- a/src/server/authserver/Server/BattlenetPackets/BattlenetPacketsBase.h
+++ b/src/server/bnetserver/Packets/PacketsBase.h
@@ -15,12 +15,11 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef BattlenetPacketsBase_h__
-#define BattlenetPacketsBase_h__
+#ifndef PacketsBase_h__
+#define PacketsBase_h__
#include "AuthCodes.h"
-#include "BattlenetBitStream.h"
-#include "BattlenetManager.h"
+#include "BitStream.h"
#include "Define.h"
#include "Errors.h"
#include <string>
@@ -31,13 +30,14 @@ using boost::asio::ip::tcp;
namespace Battlenet
{
class BitStream;
+ class Session;
enum Channel
{
AUTHENTICATION = 0,
CONNECTION = 1,
WOWREALM = 2,
- FRIEND = 3,
+ FRIENDS = 3,
PRESENCE = 4,
CHAT = 5,
SUPPORT = 7,
@@ -99,7 +99,8 @@ namespace Battlenet
public:
ClientPacket(PacketHeader const& header, BitStream& stream) : Packet(header, stream) { }
- void Write() override final { ASSERT(!"Write not implemented for this packet."); }
+ void Write() override final { ASSERT(!"Write not implemented for client packets."); }
+ virtual void CallHandler(Session* session);
};
class ServerPacket : public Packet
@@ -116,4 +117,4 @@ namespace Battlenet
};
}
-#endif // BattlenetPacketsBase_h__
+#endif // PacketsBase_h__
diff --git a/src/server/bnetserver/Packets/PresencePackets.cpp b/src/server/bnetserver/Packets/PresencePackets.cpp
new file mode 100644
index 00000000000..b72bf8daca8
--- /dev/null
+++ b/src/server/bnetserver/Packets/PresencePackets.cpp
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "Session.h"
+#include "PresencePackets.h"
+
+void Battlenet::Presence::UpdateRequest::Read()
+{
+
+}
+
+std::string Battlenet::Presence::UpdateRequest::ToString() const
+{
+ return "Battlenet::Presence::UpdateRequest";
+}
+
+void Battlenet::Presence::StatisticSubscribe::Read()
+{
+}
+
+std::string Battlenet::Presence::StatisticSubscribe::ToString() const
+{
+ return "Battlenet::Presence::StatisticSubscribe";
+}
diff --git a/src/server/bnetserver/Packets/PresencePackets.h b/src/server/bnetserver/Packets/PresencePackets.h
new file mode 100644
index 00000000000..45b8f3e0e82
--- /dev/null
+++ b/src/server/bnetserver/Packets/PresencePackets.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef PresencePackets_h__
+#define PresencePackets_h__
+
+#include "PacketsBase.h"
+
+namespace Battlenet
+{
+ namespace Presence
+ {
+ enum Opcode
+ {
+ CMSG_UPDATE_REQUEST = 0x0, // Not implemented
+ CMSG_STATISTIC_SUBSCRIBE = 0x2, // Not implemented
+
+ SMSG_UPDATE_NOTIFY = 0x0, // Not implemented
+ SMSG_FIELD_SPEC_ANNOUNCE = 0x1, // Not implemented
+ SMSG_STATISTICS_UPDATE = 0x3 // Not implemented
+ };
+
+ class UpdateRequest final : public ClientPacket
+ {
+ public:
+ UpdateRequest(PacketHeader const& header, BitStream& stream) : ClientPacket(header, stream)
+ {
+ ASSERT(header == PacketHeader(CMSG_UPDATE_REQUEST, PRESENCE) && "Invalid packet header for UpdateRequest");
+ }
+
+ void Read() override;
+ std::string ToString() const override;
+ };
+
+ class StatisticSubscribe final : public ClientPacket
+ {
+ public:
+ StatisticSubscribe(PacketHeader const& header, BitStream& stream) : ClientPacket(header, stream)
+ {
+ ASSERT(header == PacketHeader(CMSG_STATISTIC_SUBSCRIBE, PRESENCE) && "Invalid packet header for StatisticSubscribe");
+ }
+
+ void Read() override;
+ std::string ToString() const override;
+ };
+ }
+}
+
+#endif // PresencePackets_h__
diff --git a/src/server/bnetserver/Packets/ProfilePackets.h b/src/server/bnetserver/Packets/ProfilePackets.h
new file mode 100644
index 00000000000..bf413471f62
--- /dev/null
+++ b/src/server/bnetserver/Packets/ProfilePackets.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef ProfilePackets_h__
+#define ProfilePackets_h__
+
+#include "PacketsBase.h"
+
+namespace Battlenet
+{
+ namespace Profile
+ {
+ enum Opcode
+ {
+ CMSG_READ_REQUEST = 0x0, // Not implemented
+ CMSG_ADDRESS_QUERY_REQUEST = 0x1, // Not implemented
+ CMSG_RESOLVE_TOON_HANDLE_TO_NAME_REQUEST = 0x2, // Not implemented
+ CMSG_RESOLVE_TOON_NAME_TO_HANDLE_REQUEST = 0x3, // Not implemented
+ CMSG_CHANGE_SETTINGS = 0x5, // Not implemented
+
+ SMSG_READ_RESPONSE = 0x0, // Not implemented
+ SMSG_ADDRESS_QUERY_RESPONSE = 0x1, // Not implemented
+ SMSG_RESOLVE_TOON_HANDLE_TO_NAME_RESPONSE = 0x2, // Not implemented
+ SMSG_RESOLVE_TOON_NAME_TO_HANDLE_RESPONSE = 0x3, // Not implemented
+ SMSG_SETTINGS_AVAILABLE = 0x4 // Not implemented
+ };
+ }
+}
+
+#endif // ProfilePackets_h__
diff --git a/src/server/authserver/Server/BattlenetPackets/ConnectionPackets.cpp b/src/server/bnetserver/Packets/SupportPackets.h
index 9f53961c6ab..43f51bd564e 100644
--- a/src/server/authserver/Server/BattlenetPackets/ConnectionPackets.cpp
+++ b/src/server/bnetserver/Packets/SupportPackets.h
@@ -15,9 +15,20 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "ConnectionPackets.h"
+#ifndef SupportPackets_h__
+#define SupportPackets_h__
-std::string Battlenet::Connection::Pong::ToString() const
+#include "PacketsBase.h"
+
+namespace Battlenet
{
- return "Battlenet::Connection::Pong";
+ namespace Support
+ {
+ enum Opcode
+ {
+ CMSG_COMPLAINT_REQUEST = 0x0 // Not implemented
+ };
+ }
}
+
+#endif // SupportPackets_h__
diff --git a/src/server/authserver/Server/BattlenetPackets/WoWRealmPackets.cpp b/src/server/bnetserver/Packets/WoWRealmPackets.cpp
index 76577670a50..714c43b8eb4 100644
--- a/src/server/authserver/Server/BattlenetPackets/WoWRealmPackets.cpp
+++ b/src/server/bnetserver/Packets/WoWRealmPackets.cpp
@@ -16,9 +16,50 @@
*/
#include "WoWRealmPackets.h"
+#include "Session.h"
#include <boost/lexical_cast.hpp>
#include <boost/asio/ip/address.hpp>
+std::string Battlenet::WoWRealm::ListSubscribeRequest::ToString() const
+{
+ return "Battlenet::WoWRealm::ListSubscribeRequest";
+}
+
+void Battlenet::WoWRealm::ListSubscribeRequest::CallHandler(Session* session)
+{
+ session->HandleListSubscribeRequest(*this);
+}
+
+std::string Battlenet::WoWRealm::ListUnsubscribe::ToString() const
+{
+ return "Battlenet::WoWRealm::ListUnsubscribe";
+}
+
+void Battlenet::WoWRealm::ListUnsubscribe::CallHandler(Session* session)
+{
+ session->HandleListUnsubscribe(*this);
+}
+
+void Battlenet::WoWRealm::JoinRequestV2::Read()
+{
+ Realm.Battlegroup = _stream.Read<uint8>(8);
+ Realm.Index = _stream.Read<uint32>(32);
+ Realm.Region = _stream.Read<uint8>(8);
+ ClientSeed = _stream.Read<uint32>(32);
+}
+
+std::string Battlenet::WoWRealm::JoinRequestV2::ToString() const
+{
+ std::ostringstream stream;
+ stream << "Battlenet::WoWRealm::JoinRequestV2 ClientSeed " << ClientSeed << " Region " << uint32(Realm.Region) << " Battlegroup " << uint32(Realm.Battlegroup) << " Index " << Realm.Index;
+ return stream.str().c_str();
+}
+
+void Battlenet::WoWRealm::JoinRequestV2::CallHandler(Session* session)
+{
+ session->HandleJoinRequestV2(*this);
+}
+
Battlenet::WoWRealm::ListSubscribeResponse::~ListSubscribeResponse()
{
for (ServerPacket* realmData : RealmData)
@@ -86,7 +127,7 @@ void Battlenet::WoWRealm::ListUpdate::Write()
if (!Version.empty())
{
_stream.WriteString(Version, 5);
- _stream.Write(Build, 32);
+ _stream.Write(Id.Build, 32);
boost::asio::ip::address_v4::bytes_type ip = Address.address().to_v4().to_bytes();
uint16 port = Address.port();
@@ -101,38 +142,53 @@ void Battlenet::WoWRealm::ListUpdate::Write()
_stream.Write(Flags, 8);
}
- _stream.Write(Region, 8);
+ _stream.Write(Id.Region, 8);
_stream.Write(0, 12);
- _stream.Write(Battlegroup, 8);
- _stream.Write(Index, 32);
+ _stream.Write(Id.Battlegroup, 8);
+ _stream.Write(Id.Index, 32);
}
std::string Battlenet::WoWRealm::ListUpdate::ToString() const
{
std::ostringstream stream;
- stream << "Battlenet::WoWRealm::ListUpdate Timezone " << Timezone << " Population " << Population << " Lock " << uint32(Lock) << " Type " << Type << " Name " << Name
- << " Flags " << uint32(Flags) << " Region " << uint32(Region) << " Battlegroup " << uint32(Battlegroup) << " Index " << Index;
+ stream << "Battlenet::WoWRealm::ListUpdate";
+ if (UpdateState == UPDATE)
+ {
+ stream << " Timezone: " << Timezone << " Population: " << Population << " Lock: " << uint32(Lock) << " Type: " << Type << " Name: " << Name
+ << " Flags: " << uint32(Flags) << " Region: " << uint32(Id.Region) << " Battlegroup: " << uint32(Id.Battlegroup) << " Index: " << Id.Index;
- if (!Version.empty())
- stream << " Version " << Version;
+ if (!Version.empty())
+ stream << " Version: " << Version;
+ }
+ else
+ stream << " Delete realm [Region: " << uint32(Id.Region) << " Battlegroup : " << uint32(Id.Battlegroup) << " Index : " << Id.Index << "]";
return stream.str().c_str();
}
-void Battlenet::WoWRealm::JoinRequestV2::Read()
+void Battlenet::WoWRealm::ToonReady::Write()
{
- ClientSeed = _stream.Read<uint32>(32);
- _stream.Read<uint32>(20);
- Realm.Region = _stream.Read<uint8>(8);
- _stream.Read<uint32>(12);
- Realm.Battlegroup = _stream.Read<uint8>(8);
- Realm.Index = _stream.Read<uint32>(32);
+ _stream.Write(Realm.Region, 8);
+ _stream.WriteFourCC(Game);
+ uint32 realmAddress = ((Realm.Battlegroup << 16) & 0xFF0000) | uint16(Realm.Index);
+ _stream.Write(realmAddress, 32);
+ _stream.WriteString(Name, 7, -2);
+ _stream.WriteSkip(21);
+ _stream.Write(0, 64); // Unknown
+ _stream.Write(0, 32); // Unknown
+ _stream.Write(Guid, 64);
+ _stream.Write(realmAddress, 32);
+ _stream.Write(Realm.Region, 8);
+ _stream.WriteFourCC(Game);
}
-std::string Battlenet::WoWRealm::JoinRequestV2::ToString() const
+std::string Battlenet::WoWRealm::ToonReady::ToString() const
{
std::ostringstream stream;
- stream << "Battlenet::WoWRealm::JoinRequestV2 ClientSeed " << ClientSeed << " Region " << uint32(Realm.Region) << " Battlegroup " << uint32(Realm.Battlegroup) << " Index " << Realm.Index;
+ stream << "Battlenet::WoWRealm::ToonReady" << " Game: " << Game
+ << ", Region: " << uint32(Realm.Region) << ", Battlegroup: " << uint32(Realm.Battlegroup) << ", Index: " << Realm.Index
+ << ", Guid: " << Guid << ", Name: " << Name;
+
return stream.str().c_str();
}
diff --git a/src/server/authserver/Server/BattlenetPackets/WoWRealmPackets.h b/src/server/bnetserver/Packets/WoWRealmPackets.h
index 881ddd3186a..b411c63100a 100644
--- a/src/server/authserver/Server/BattlenetPackets/WoWRealmPackets.h
+++ b/src/server/bnetserver/Packets/WoWRealmPackets.h
@@ -18,7 +18,8 @@
#ifndef WoWRealmPackets_h__
#define WoWRealmPackets_h__
-#include "BattlenetPacketsBase.h"
+#include "PacketsBase.h"
+#include "RealmList.h"
namespace Battlenet
{
@@ -27,7 +28,7 @@ namespace Battlenet
enum Opcode
{
CMSG_LIST_SUBSCRIBE_REQUEST = 0x0,
- CMSG_LIST_UNSUBSCRIBE = 0x1, // Not implemented
+ CMSG_LIST_UNSUBSCRIBE = 0x1,
CMSG_JOIN_REQUEST_V2 = 0x8,
CMSG_MULTI_LOGON_REQUEST_V2 = 0x9, // Not implemented
@@ -39,6 +40,32 @@ namespace Battlenet
SMSG_JOIN_RESPONSE_V2 = 0x8
};
+ class ListSubscribeRequest final : public ClientPacket
+ {
+ public:
+ ListSubscribeRequest(PacketHeader const& header, BitStream& stream) : ClientPacket(header, stream)
+ {
+ ASSERT(header == PacketHeader(CMSG_LIST_SUBSCRIBE_REQUEST, WOWREALM) && "Invalid packet header for ListSubscribeRequest");
+ }
+
+ void Read() override { }
+ std::string ToString() const override;
+ void CallHandler(Session* session) override;
+ };
+
+ class ListUnsubscribe final : public ClientPacket
+ {
+ public:
+ ListUnsubscribe(PacketHeader const& header, BitStream& stream) : ClientPacket(header, stream)
+ {
+ ASSERT(header == PacketHeader(CMSG_LIST_UNSUBSCRIBE, WOWREALM) && "Invalid packet header for ListUnsubscribe");
+ }
+
+ void Read() override { }
+ std::string ToString() const override;
+ void CallHandler(Session* session) override;
+ };
+
class JoinRequestV2 final : public ClientPacket
{
public:
@@ -49,6 +76,7 @@ namespace Battlenet
void Read() override;
std::string ToString() const override;
+ void CallHandler(Session* session) override;
uint32 ClientSeed;
RealmId Realm;
@@ -95,8 +123,7 @@ namespace Battlenet
};
ListUpdate() : ServerPacket(PacketHeader(SMSG_LIST_UPDATE, WOWREALM)), UpdateState(UPDATE),
- Timezone(0), Population(0.0f), Lock(0), Type(0), Name(""), Version(""),
- Flags(0), Region(0), Battlegroup(0), Index(0), Build(0)
+ Timezone(0), Population(0.0f), Lock(0), Type(0), Name(""), Version(""), Flags(0)
{
}
@@ -112,10 +139,7 @@ namespace Battlenet
std::string Version;
tcp::endpoint Address;
uint8 Flags;
- uint8 Region;
- uint8 Battlegroup;
- uint32 Index;
- uint32 Build;
+ RealmId Id;
};
class ListComplete final : public ServerPacket
@@ -129,6 +153,33 @@ namespace Battlenet
std::string ToString() const override { return "Battlenet::WoWRealm::ListComplete"; }
};
+ class ToonReady final : public ServerPacket
+ {
+ public:
+ ToonReady() : ServerPacket(PacketHeader(SMSG_TOON_READY, WOWREALM)), Game("WoW"), Guid(0)
+ {
+ }
+
+ void Write() override;
+ std::string ToString() const override;
+
+ std::string Game;
+ RealmId Realm;
+ uint64 Guid;
+ std::string Name;
+ };
+
+ class ToonLoggedOut final : public ServerPacket
+ {
+ public:
+ ToonLoggedOut() : ServerPacket(PacketHeader(SMSG_TOON_LOGGED_OUT, WOWREALM))
+ {
+ }
+
+ void Write() override { }
+ std::string ToString() const override { return "Battlenet::WoWRealm::ToonLoggedOut"; }
+ };
+
class JoinResponseV2 final : public ServerPacket
{
public:
@@ -139,7 +190,7 @@ namespace Battlenet
};
JoinResponseV2() : ServerPacket(PacketHeader(SMSG_JOIN_RESPONSE_V2, WOWREALM)),
- ServerSeed(0), Response(SUCCESS), ResponseCode(26)
+ Response(SUCCESS), ResponseCode(26), ServerSeed(0)
{
}
diff --git a/src/server/bnetserver/PrecompiledHeaders/bnetPCH.cpp b/src/server/bnetserver/PrecompiledHeaders/bnetPCH.cpp
new file mode 100644
index 00000000000..60b1d41a1a8
--- /dev/null
+++ b/src/server/bnetserver/PrecompiledHeaders/bnetPCH.cpp
@@ -0,0 +1 @@
+#include "bnetPCH.h"
diff --git a/src/server/bnetserver/PrecompiledHeaders/bnetPCH.h b/src/server/bnetserver/PrecompiledHeaders/bnetPCH.h
new file mode 100644
index 00000000000..82cd5393489
--- /dev/null
+++ b/src/server/bnetserver/PrecompiledHeaders/bnetPCH.h
@@ -0,0 +1,10 @@
+#include "Common.h"
+#include "Configuration/Config.h"
+#include "Database/DatabaseEnv.h"
+#include "Log.h"
+#include "ComponentManager.h"
+#include "ModuleManager.h"
+#include "RealmList.h"
+#include "ByteBuffer.h"
+#include "Packets.h"
+#include "Session.h"
diff --git a/src/server/bnetserver/Realms/RealmList.cpp b/src/server/bnetserver/Realms/RealmList.cpp
new file mode 100644
index 00000000000..cc7e1d492a8
--- /dev/null
+++ b/src/server/bnetserver/Realms/RealmList.cpp
@@ -0,0 +1,252 @@
+/*
+ * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "Common.h"
+#include "Database/DatabaseEnv.h"
+#include "SessionManager.h"
+#include "Util.h"
+#include "Commands.h"
+#include "RealmList.h"
+#include <boost/asio/ip/tcp.hpp>
+
+Battlenet::RealmId& Battlenet::RealmId::operator=(Battlenet::RealmHandle const& handle)
+{
+ Region = handle.Region;
+ Battlegroup = handle.Battlegroup;
+ Index = handle.Index;
+ return *this;
+}
+
+ip::tcp::endpoint Realm::GetAddressForClient(ip::address const& clientAddr) const
+{
+ ip::address realmIp;
+
+ // Attempt to send best address for client
+ if (clientAddr.is_loopback())
+ {
+ // Try guessing if realm is also connected locally
+ if (LocalAddress.is_loopback() || ExternalAddress.is_loopback())
+ realmIp = clientAddr;
+ else
+ {
+ // Assume that user connecting from the machine that bnetserver is located on
+ // has all realms available in his local network
+ realmIp = LocalAddress;
+ }
+ }
+ else
+ {
+ if (clientAddr.is_v4() &&
+ (clientAddr.to_v4().to_ulong() & LocalSubnetMask.to_v4().to_ulong()) ==
+ (LocalAddress.to_v4().to_ulong() & LocalSubnetMask.to_v4().to_ulong()))
+ {
+ realmIp = LocalAddress;
+ }
+ else
+ realmIp = ExternalAddress;
+ }
+
+ ip::tcp::endpoint endpoint(realmIp, Port);
+
+ // Return external IP
+ return endpoint;
+}
+
+RealmList::RealmList() : _updateInterval(0), _updateTimer(nullptr), _resolver(nullptr), _worldListener(nullptr)
+{
+}
+
+RealmList::~RealmList()
+{
+ delete _updateTimer;
+ delete _resolver;
+ delete _worldListener;
+}
+
+// Load the realm list from the database
+void RealmList::Initialize(boost::asio::io_service& ioService, uint32 updateInterval, uint16 worldListenPort)
+{
+ _updateInterval = updateInterval;
+ _updateTimer = new boost::asio::deadline_timer(ioService);
+ _resolver = new boost::asio::ip::tcp::resolver(ioService);
+
+ // Get the content of the realmlist table in the database
+ UpdateRealms(boost::system::error_code());
+
+ _worldListener = new WorldListener(worldListenPort);
+ _worldListener->Start();
+}
+
+void RealmList::Close()
+{
+ _worldListener->End();
+}
+
+template<typename FieldType>
+inline void UpdateField(FieldType& out, FieldType const& in, bool& changed)
+{
+ if (out != in)
+ {
+ out = in;
+ changed = true;
+ }
+}
+
+void RealmList::UpdateRealm(Battlenet::RealmId const& id, const std::string& name, ip::address const& address, ip::address const& localAddr,
+ ip::address const& localSubmask, uint16 port, uint8 icon, RealmFlags flag, uint8 timezone, AccountTypes allowedSecurityLevel,
+ float population)
+{
+ // Create new if not exist or update existed
+ Realm& realm = _realms[id];
+
+ realm.Keep = true;
+
+ realm.Id = id;
+ UpdateField(realm.Name, name, realm.Updated);
+ UpdateField(realm.Type, icon, realm.Updated);
+ UpdateField(realm.Flags, flag, realm.Updated);
+ UpdateField(realm.Timezone, timezone, realm.Updated);
+ UpdateField(realm.AllowedSecurityLevel, allowedSecurityLevel, realm.Updated);
+ UpdateField(realm.PopulationLevel, population, realm.Updated);
+ UpdateField(realm.ExternalAddress, address, realm.Updated);
+ UpdateField(realm.LocalAddress, localAddr, realm.Updated);
+ UpdateField(realm.LocalSubnetMask, localSubmask, realm.Updated);
+ UpdateField(realm.Port, port, realm.Updated);
+}
+
+void RealmList::UpdateRealms(boost::system::error_code const& error)
+{
+ if (error)
+ return;
+
+ TC_LOG_DEBUG("realmlist", "Updating Realm List...");
+
+ PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_REALMLIST);
+ PreparedQueryResult result = LoginDatabase.Query(stmt);
+
+ // Circle through results and add them to the realm map
+ if (result)
+ {
+ do
+ {
+ try
+ {
+ boost::asio::ip::tcp::resolver::iterator end;
+
+ Field* fields = result->Fetch();
+ std::string name = fields[1].GetString();
+ boost::asio::ip::tcp::resolver::query externalAddressQuery(ip::tcp::v4(), fields[2].GetString(), "");
+
+ boost::system::error_code ec;
+ boost::asio::ip::tcp::resolver::iterator endPoint = _resolver->resolve(externalAddressQuery, ec);
+ if (endPoint == end || ec)
+ {
+ TC_LOG_ERROR("realmlist", "Could not resolve address %s", fields[2].GetString().c_str());
+ continue;
+ }
+
+ ip::address externalAddress = (*endPoint).endpoint().address();
+
+ boost::asio::ip::tcp::resolver::query localAddressQuery(ip::tcp::v4(), fields[3].GetString(), "");
+ endPoint = _resolver->resolve(localAddressQuery, ec);
+ if (endPoint == end || ec)
+ {
+ TC_LOG_ERROR("realmlist", "Could not resolve address %s", fields[3].GetString().c_str());
+ continue;
+ }
+
+ ip::address localAddress = (*endPoint).endpoint().address();
+
+ boost::asio::ip::tcp::resolver::query localSubmaskQuery(ip::tcp::v4(), fields[4].GetString(), "");
+ endPoint = _resolver->resolve(localSubmaskQuery, ec);
+ if (endPoint == end || ec)
+ {
+ TC_LOG_ERROR("realmlist", "Could not resolve address %s", fields[4].GetString().c_str());
+ continue;
+ }
+
+ ip::address localSubmask = (*endPoint).endpoint().address();
+
+ uint16 port = fields[5].GetUInt16();
+ uint8 icon = fields[6].GetUInt8();
+ RealmFlags flag = RealmFlags(fields[7].GetUInt8());
+ uint8 timezone = fields[8].GetUInt8();
+ uint8 allowedSecurityLevel = fields[9].GetUInt8();
+ float pop = fields[10].GetFloat();
+ uint32 realmId = fields[0].GetUInt32();
+ uint32 build = fields[11].GetUInt32();
+ uint8 region = fields[12].GetUInt8();
+ uint8 battlegroup = fields[13].GetUInt8();
+
+ Battlenet::RealmId id{ region, battlegroup, realmId, build };
+
+ UpdateRealm(id, name, externalAddress, localAddress, localSubmask, port, icon, flag, timezone,
+ (allowedSecurityLevel <= SEC_ADMINISTRATOR ? AccountTypes(allowedSecurityLevel) : SEC_ADMINISTRATOR), pop);
+
+ TC_LOG_TRACE("realmlist", "Realm \"%s\" at %s:%u.", name.c_str(), externalAddress.to_string().c_str(), port);
+ }
+ catch (std::exception& ex)
+ {
+ TC_LOG_ERROR("realmlist", "Realmlist::UpdateRealms has thrown an exception: %s", ex.what());
+ ASSERT(false);
+ }
+ }
+ while (result->NextRow());
+ }
+
+ std::vector<Realm const*> updatedRealms;
+ std::vector<Battlenet::RealmId> deletedRealms;
+
+ for (RealmMap::value_type& pair : _realms)
+ {
+ if (pair.second.Updated)
+ updatedRealms.push_back(&pair.second);
+ else if (!pair.second.Keep)
+ deletedRealms.push_back(pair.first);
+
+ pair.second.Updated = false;
+ pair.second.Keep = false;
+ }
+
+ for (Battlenet::RealmId const& deleted : deletedRealms)
+ _realms.erase(deleted);
+
+ if (!updatedRealms.empty() || !deletedRealms.empty())
+ {
+ sSessionMgr.LockedForEach([&updatedRealms, &deletedRealms](Battlenet::Session* session)
+ {
+ if (session->IsSubscribedToRealmListUpdates())
+ session->UpdateRealms(updatedRealms, deletedRealms);
+ });
+ }
+
+ if (_updateInterval)
+ {
+ _updateTimer->expires_from_now(boost::posix_time::seconds(_updateInterval));
+ _updateTimer->async_wait(std::bind(&RealmList::UpdateRealms, this, std::placeholders::_1));
+ }
+}
+
+Realm const* RealmList::GetRealm(Battlenet::RealmId const& id) const
+{
+ auto itr = _realms.find(id);
+ if (itr != _realms.end())
+ return &itr->second;
+
+ return NULL;
+}
diff --git a/src/server/bnetserver/Realms/RealmList.h b/src/server/bnetserver/Realms/RealmList.h
new file mode 100644
index 00000000000..dc78a00dfdd
--- /dev/null
+++ b/src/server/bnetserver/Realms/RealmList.h
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _REALMLIST_H
+#define _REALMLIST_H
+
+#include "Common.h"
+#include "WorldListener.h"
+#include <boost/asio/ip/address.hpp>
+#include <boost/asio/ip/tcp.hpp>
+#include <boost/asio/io_service.hpp>
+#include <boost/asio/deadline_timer.hpp>
+
+using namespace boost::asio;
+
+enum RealmFlags
+{
+ REALM_FLAG_NONE = 0x00,
+ REALM_FLAG_INVALID = 0x01,
+ REALM_FLAG_OFFLINE = 0x02,
+ REALM_FLAG_SPECIFYBUILD = 0x04,
+ REALM_FLAG_UNK1 = 0x08,
+ REALM_FLAG_UNK2 = 0x10,
+ REALM_FLAG_RECOMMENDED = 0x20,
+ REALM_FLAG_NEW = 0x40,
+ REALM_FLAG_FULL = 0x80
+};
+
+#pragma pack(push, 1)
+
+namespace Battlenet
+{
+ struct RealmHandle;
+
+ struct RealmId
+ {
+ RealmId() : Region(0), Battlegroup(0), Index(0), Build(0) { }
+ RealmId(uint8 region, uint8 battlegroup, uint32 index, uint32 build)
+ : Region(region), Battlegroup(battlegroup), Index(index), Build(build) { }
+
+ uint8 Region;
+ uint8 Battlegroup;
+ uint32 Index;
+ uint32 Build;
+
+ bool operator<(RealmId const& r) const
+ {
+ return memcmp(this, &r, sizeof(RealmId) - sizeof(Build)) < 0;
+ }
+
+ RealmId& operator=(RealmHandle const& handle);
+ };
+}
+
+#pragma pack(pop)
+
+// Storage object for a realm
+struct Realm
+{
+ Battlenet::RealmId Id;
+ ip::address ExternalAddress;
+ ip::address LocalAddress;
+ ip::address LocalSubnetMask;
+ uint16 Port;
+ std::string Name;
+ uint8 Type;
+ RealmFlags Flags;
+ uint8 Timezone;
+ AccountTypes AllowedSecurityLevel;
+ float PopulationLevel;
+ bool Updated;
+ bool Keep;
+
+ ip::tcp::endpoint GetAddressForClient(ip::address const& clientAddr) const;
+};
+
+/// Storage object for the list of realms on the server
+class RealmList
+{
+public:
+ typedef std::map<Battlenet::RealmId, Realm> RealmMap;
+
+ static RealmList* instance()
+ {
+ static RealmList instance;
+ return &instance;
+ }
+
+ ~RealmList();
+
+ void Initialize(boost::asio::io_service& ioService, uint32 updateInterval, uint16 worldListenPort);
+ void Close();
+
+ RealmMap const& GetRealms() const { return _realms; }
+ Realm const* GetRealm(Battlenet::RealmId const& id) const;
+
+private:
+ RealmList();
+
+ void UpdateRealms(boost::system::error_code const& error);
+ void UpdateRealm(Battlenet::RealmId const& id, const std::string& name, ip::address const& address, ip::address const& localAddr,
+ ip::address const& localSubmask, uint16 port, uint8 icon, RealmFlags flag, uint8 timezone, AccountTypes allowedSecurityLevel, float population);
+
+ RealmMap _realms;
+ uint32 _updateInterval;
+ boost::asio::deadline_timer* _updateTimer;
+ boost::asio::ip::tcp::resolver* _resolver;
+ WorldListener* _worldListener;
+};
+
+#define sRealmList RealmList::instance()
+#endif
diff --git a/src/server/bnetserver/Realms/WorldListener.cpp b/src/server/bnetserver/Realms/WorldListener.cpp
new file mode 100644
index 00000000000..30886a67310
--- /dev/null
+++ b/src/server/bnetserver/Realms/WorldListener.cpp
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "Log.h"
+#include "SessionManager.h"
+#include "WoWRealmPackets.h"
+#include "ZmqContext.h"
+#include "WorldListener.h"
+
+WorldListener::HandlerTable const WorldListener::_handlers;
+
+WorldListener::HandlerTable::HandlerTable()
+{
+#define DEFINE_HANDLER(opc, func) _handlers[opc] = { func, #opc }
+
+ DEFINE_HANDLER(BNET_CHANGE_TOON_ONLINE_STATE, &WorldListener::HandleToonOnlineStatusChange);
+
+#undef DEFINE_HANDLER
+}
+
+WorldListener::WorldListener(uint16 worldListenPort) : _worldListenPort(worldListenPort)
+{
+ _worldSocket = sIpcContext->CreateNewSocket(zmqpp::socket_type::pull);
+}
+
+WorldListener::~WorldListener()
+{
+ delete _worldSocket;
+}
+
+void WorldListener::Run()
+{
+ while (!ProcessExit())
+ {
+ _poller->poll();
+ if (_poller->events(*_worldSocket) & zmqpp::poller::poll_in)
+ {
+ int32 op1;
+ do
+ {
+ zmqpp::message msg;
+ _worldSocket->receive(msg);
+ Dispatch(msg);
+ _worldSocket->get(zmqpp::socket_option::events, op1);
+ } while (op1 & zmqpp::poller::poll_in);
+ }
+ }
+}
+
+void WorldListener::HandleOpen()
+{
+ _worldSocket->bind(std::string("tcp://*:") + std::to_string(_worldListenPort));
+ _poller->add(*_worldSocket);
+ TC_LOG_INFO("server.ipc", "Listening on connections from worldservers...");
+}
+
+void WorldListener::HandleClose()
+{
+ _worldSocket->close();
+ TC_LOG_INFO("server.ipc", "Shutting down connections from worldservers...");
+}
+
+void WorldListener::Dispatch(zmqpp::message& msg) const
+{
+ Battlenet::Header ipcHeader;
+ msg >> ipcHeader;
+
+ if (ipcHeader.Ipc.Channel != IPC_CHANNEL_BNET)
+ return;
+
+ if (ipcHeader.Ipc.Command < IPC_BNET_MAX_COMMAND)
+ (this->*_handlers[ipcHeader.Ipc.Command].Handler)(ipcHeader.Realm, msg);
+}
+
+void WorldListener::HandleToonOnlineStatusChange(Battlenet::RealmHandle const& realm, zmqpp::message& msg) const
+{
+ Battlenet::ToonHandle toonHandle;
+ bool online;
+ msg >> toonHandle;
+ msg >> online;
+
+ if (Battlenet::Session* session = sSessionMgr.GetSession(toonHandle.AccountId, toonHandle.GameAccountId))
+ {
+ if (online)
+ {
+ Battlenet::WoWRealm::ToonReady* toonReady = new Battlenet::WoWRealm::ToonReady();
+ toonReady->Realm = realm;
+ toonReady->Guid = toonHandle.Guid;
+ toonReady->Name = toonHandle.Name;
+ session->AsyncWrite(toonReady);
+ }
+ else
+ session->AsyncWrite(new Battlenet::WoWRealm::ToonLoggedOut());
+ }
+}
diff --git a/src/server/bnetserver/Realms/WorldListener.h b/src/server/bnetserver/Realms/WorldListener.h
new file mode 100644
index 00000000000..04d5342449c
--- /dev/null
+++ b/src/server/bnetserver/Realms/WorldListener.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef WorldListener_h__
+#define WorldListener_h__
+
+#include "ZMQTask.h"
+#include "Commands.h"
+
+class WorldListener : public ZMQTask
+{
+public:
+ explicit WorldListener(uint16 worldListenPort);
+ ~WorldListener();
+ void Run() override;
+
+protected:
+ void HandleOpen() override;
+ void HandleClose() override;
+
+private:
+ void Dispatch(zmqpp::message& msg) const;
+
+ typedef void(WorldListener::*PacketHandler)(Battlenet::RealmHandle const& realm, zmqpp::message& msg) const;
+ class HandlerTable
+ {
+ public:
+ HandlerTable();
+
+ struct HandlerInfo
+ {
+ PacketHandler Handler;
+ char const* Name;
+ };
+
+ HandlerInfo const& operator[](uint8 opcode) const { return _handlers[opcode]; }
+
+ private:
+ HandlerInfo _handlers[IPC_BNET_MAX_COMMAND];
+ };
+
+ void HandleToonOnlineStatusChange(Battlenet::RealmHandle const& realm, zmqpp::message& msg) const;
+
+ zmqpp::socket* _worldSocket;
+ uint16 _worldListenPort;
+ static HandlerTable const _handlers;
+};
+
+#endif // WorldListener_h__
diff --git a/src/server/bnetserver/Server/ComponentManager.cpp b/src/server/bnetserver/Server/ComponentManager.cpp
new file mode 100644
index 00000000000..be1f22022f4
--- /dev/null
+++ b/src/server/bnetserver/Server/ComponentManager.cpp
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "ComponentManager.h"
+#include "DatabaseEnv.h"
+
+Battlenet::ComponentMgr::~ComponentMgr()
+{
+ for (Component* component : _components)
+ delete component;
+}
+
+void Battlenet::ComponentMgr::Load()
+{
+ QueryResult result = LoginDatabase.Query("SELECT Program, Platform, Build FROM battlenet_components");
+ if (result)
+ {
+ do
+ {
+ Field* fields = result->Fetch();
+ Component* component = new Component();
+ component->Program = fields[0].GetString();
+ component->Platform = fields[1].GetString();
+ component->Build = fields[2].GetUInt32();
+
+ _components.insert(component);
+ _programs.insert(component->Program);
+ _platforms.insert(component->Platform);
+
+ } while (result->NextRow());
+ }
+}
+
+bool Battlenet::ComponentMgr::HasComponent(Battlenet::Component const* component) const
+{
+ for (Component const* c : _components)
+ if (component->Program == c->Program && component->Platform == c->Platform && component->Build == c->Build)
+ return true;
+
+ return false;
+}
diff --git a/src/server/bnetserver/Server/ComponentManager.h b/src/server/bnetserver/Server/ComponentManager.h
new file mode 100644
index 00000000000..865cfca7f62
--- /dev/null
+++ b/src/server/bnetserver/Server/ComponentManager.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef ComponentManager_h__
+#define ComponentManager_h__
+
+#include "Define.h"
+#include <cstring>
+#include <string>
+#include <set>
+
+namespace Battlenet
+{
+ struct Component
+ {
+ std::string Program;
+ std::string Platform;
+ uint32 Build;
+ };
+
+ class ComponentMgr
+ {
+ ComponentMgr() { }
+ ~ComponentMgr();
+
+ public:
+ void Load();
+ bool HasComponent(Component const* component) const;
+ bool HasProgram(std::string const& program) const { return _programs.count(program) != 0; }
+ bool HasPlatform(std::string const& platform) const { return _platforms.count(platform) != 0; }
+
+ static ComponentMgr* instance()
+ {
+ static ComponentMgr instance;
+ return &instance;
+ }
+
+ private:
+ std::set<Component*> _components;
+ std::set<std::string> _programs;
+ std::set<std::string> _platforms;
+ };
+}
+
+#define sComponentMgr Battlenet::ComponentMgr::instance()
+
+#endif // ComponentManager_h__
diff --git a/src/server/authserver/Server/BattlenetManager.cpp b/src/server/bnetserver/Server/ModuleManager.cpp
index f470c365b56..05cee2ff42e 100644
--- a/src/server/authserver/Server/BattlenetManager.cpp
+++ b/src/server/bnetserver/Server/ModuleManager.cpp
@@ -15,46 +15,16 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "BattlenetManager.h"
+#include "ModuleManager.h"
#include "DatabaseEnv.h"
-BattlenetMgr::~BattlenetMgr()
+Battlenet::ModuleManager::~ModuleManager()
{
- for (Battlenet::Component* component : _components)
- delete component;
-
for (auto const& m : _modules)
delete m.second;
}
-void BattlenetMgr::Load()
-{
- LoadComponents();
- LoadModules();
-}
-
-void BattlenetMgr::LoadComponents()
-{
- QueryResult result = LoginDatabase.Query("SELECT Program, Platform, Build FROM battlenet_components");
- if (result)
- {
- do
- {
- Field* fields = result->Fetch();
- Battlenet::Component* component = new Battlenet::Component();
- component->Program = fields[0].GetString();
- component->Platform = fields[1].GetString();
- component->Build = fields[2].GetUInt32();
-
- _components.insert(component);
- _programs.insert(component->Program);
- _platforms.insert(component->Platform);
-
- } while (result->NextRow());
- }
-}
-
-void BattlenetMgr::LoadModules()
+void Battlenet::ModuleManager::Load()
{
QueryResult result = LoginDatabase.Query("SELECT `Hash`, `Name`, `Type`, `System`, `Data` FROM battlenet_modules");
if (result)
@@ -62,7 +32,7 @@ void BattlenetMgr::LoadModules()
do
{
Field* fields = result->Fetch();
- Battlenet::ModuleInfo* module = new Battlenet::ModuleInfo();
+ ModuleInfo* module = new ModuleInfo();
module->Type = fields[2].GetString();
HexStrToByteArray(fields[0].GetString(), module->ModuleId);
std::string data = fields[4].GetString();
@@ -78,19 +48,11 @@ void BattlenetMgr::LoadModules()
}
}
-bool BattlenetMgr::HasComponent(Battlenet::Component const* component) const
-{
- for (Battlenet::Component const* c : _components)
- if (component->Program == c->Program && component->Platform == c->Platform && component->Build == c->Build)
- return true;
-
- return false;
-}
-
-Battlenet::ModuleInfo* BattlenetMgr::CreateModule(std::string const& os, std::string const& name) const
+Battlenet::ModuleInfo* Battlenet::ModuleManager::CreateModule(std::string const& os, std::string const& name) const
{
- Battlenet::ModuleKey key { os, name };
- ASSERT(_modules.count(key));
+ ModuleKey key { os, name };
+ if (!_modules.count(key))
+ return nullptr;
- return new Battlenet::ModuleInfo(*_modules.at(key));
+ return new ModuleInfo(*_modules.at(key));
}
diff --git a/src/server/authserver/Server/BattlenetManager.h b/src/server/bnetserver/Server/ModuleManager.h
index bd01619ef06..36ffb2fec3f 100644
--- a/src/server/authserver/Server/BattlenetManager.h
+++ b/src/server/bnetserver/Server/ModuleManager.h
@@ -15,24 +15,16 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef __BATTLENETMANAGER_H__
-#define __BATTLENETMANAGER_H__
+#ifndef ModuleManager_h__
+#define ModuleManager_h__
#include "Define.h"
#include <cstring>
#include <string>
-#include <set>
#include <map>
namespace Battlenet
{
- struct Component
- {
- std::string Program;
- std::string Platform;
- uint32 Build;
- };
-
struct ModuleKey
{
std::string Platform;
@@ -74,43 +66,29 @@ namespace Battlenet
uint8* Data;
};
- struct RealmId
+ class ModuleManager
{
- uint8 Region;
- uint8 Battlegroup;
- uint32 Index;
- uint32 Build;
- };
-}
+ ModuleManager() { }
+ ~ModuleManager();
-class BattlenetMgr
-{
- BattlenetMgr() { }
- ~BattlenetMgr();
+ public:
+ void Load();
+ ModuleInfo* CreateModule(std::string const& os, std::string const& name) const;
-public:
- void Load();
- bool HasComponent(Battlenet::Component const* component) const;
- bool HasProgram(std::string const& program) const { return _programs.count(program) != 0; }
- bool HasPlatform(std::string const& platform) const { return _platforms.count(platform) != 0; }
- Battlenet::ModuleInfo* CreateModule(std::string const& os, std::string const& name) const;
-
- static BattlenetMgr* instance()
- {
- static BattlenetMgr instance;
- return &instance;
- }
+ static ModuleManager* instance()
+ {
+ static ModuleManager instance;
+ return &instance;
+ }
-private:
- void LoadComponents();
- void LoadModules();
+ private:
+ void LoadComponents();
+ void LoadModules();
- std::set<Battlenet::Component*> _components;
- std::set<std::string> _programs;
- std::set<std::string> _platforms;
- std::map<Battlenet::ModuleKey, Battlenet::ModuleInfo*> _modules;
-};
+ std::map<ModuleKey, ModuleInfo*> _modules;
+ };
+}
-#define sBattlenetMgr BattlenetMgr::instance()
+#define sModuleMgr Battlenet::ModuleManager::instance()
-#endif // __BATTLENETMANAGER_H__
+#endif // ModuleManager_h__
diff --git a/src/server/authserver/Server/BattlenetSession.cpp b/src/server/bnetserver/Server/Session.cpp
index 860c557b46a..edd00e5db2d 100644
--- a/src/server/authserver/Server/BattlenetSession.cpp
+++ b/src/server/bnetserver/Server/Session.cpp
@@ -16,35 +16,15 @@
*/
#include "AuthCodes.h"
-#include "BattlenetBitStream.h"
-#include "BattlenetSessionManager.h"
+#include "BitStream.h"
+#include "PacketManager.h"
+#include "SessionManager.h"
#include "Database/DatabaseEnv.h"
#include "HmacHash.h"
#include "Log.h"
#include "RealmList.h"
#include "SHA256.h"
#include <map>
-#include <boost/asio/write.hpp>
-
-std::map<Battlenet::PacketHeader, Battlenet::Session::PacketHandler> InitHandlers()
-{
- std::map<Battlenet::PacketHeader, Battlenet::Session::PacketHandler> handlers;
-
- handlers[Battlenet::PacketHeader(Battlenet::Authentication::CMSG_LOGON_REQUEST_3, Battlenet::AUTHENTICATION)] = &Battlenet::Session::HandleLogonRequest;
- handlers[Battlenet::PacketHeader(Battlenet::Authentication::CMSG_RESUME_REQUEST, Battlenet::AUTHENTICATION)] = &Battlenet::Session::HandleResumeRequest;
- handlers[Battlenet::PacketHeader(Battlenet::Authentication::CMSG_PROOF_RESPONSE, Battlenet::AUTHENTICATION)] = &Battlenet::Session::HandleProofResponse;
-
- handlers[Battlenet::PacketHeader(Battlenet::Connection::CMSG_PING, Battlenet::CONNECTION)] = &Battlenet::Session::HandlePing;
- handlers[Battlenet::PacketHeader(Battlenet::Connection::CMSG_ENABLE_ENCRYPTION, Battlenet::CONNECTION)] = &Battlenet::Session::HandleEnableEncryption;
- handlers[Battlenet::PacketHeader(Battlenet::Connection::CMSG_LOGOUT_REQUEST, Battlenet::CONNECTION)] = &Battlenet::Session::HandleLogoutRequest;
-
- handlers[Battlenet::PacketHeader(Battlenet::WoWRealm::CMSG_LIST_SUBSCRIBE_REQUEST, Battlenet::WOWREALM)] = &Battlenet::Session::HandleListSubscribeRequest;
- handlers[Battlenet::PacketHeader(Battlenet::WoWRealm::CMSG_JOIN_REQUEST_V2, Battlenet::WOWREALM)] = &Battlenet::Session::HandleJoinRequestV2;
-
- return handlers;
-}
-
-std::map<Battlenet::PacketHeader, Battlenet::Session::PacketHandler> Handlers = InitHandlers();
Battlenet::Session::ModuleHandler const Battlenet::Session::ModuleHandlers[MODULE_COUNT] =
{
@@ -58,7 +38,7 @@ Battlenet::Session::ModuleHandler const Battlenet::Session::ModuleHandlers[MODUL
Battlenet::Session::Session(tcp::socket&& socket) : Socket(std::move(socket)), _accountId(0), _accountName(), _locale(),
_os(), _build(0), _gameAccountId(0), _gameAccountName(), _accountSecurityLevel(SEC_PLAYER), I(), s(), v(), b(), B(), K(),
- _reconnectProof(), _crypt(), _authed(false)
+ _reconnectProof(), _crypt(), _authed(false), _subscribedToRealmListUpdates(false)
{
static uint8 const N_Bytes[] =
{
@@ -83,8 +63,7 @@ Battlenet::Session::Session(tcp::socket&& socket) : Socket(std::move(socket)), _
Battlenet::Session::~Session()
{
- sBattlenetSessionMgr.RemoveSession(this);
- TC_LOG_TRACE("server.battlenet", "Battlenet::Session::OnClose");
+ sSessionMgr.RemoveSession(this);
}
void Battlenet::Session::_SetVSFields(std::string const& pstr)
@@ -109,7 +88,12 @@ void Battlenet::Session::_SetVSFields(std::string const& pstr)
LoginDatabase.Execute(stmt);
}
-bool Battlenet::Session::HandleLogonRequest(PacketHeader& header, BitStream& packet)
+void Battlenet::Session::LogUnhandledPacket(PacketHeader const& header)
+{
+ TC_LOG_DEBUG("session.packets", "%s Received unhandled packet %s", GetClientInfo().c_str(), sPacketManager.GetClientPacketName(header));
+}
+
+void Battlenet::Session::HandleLogonRequest(Authentication::LogonRequest3 const& logonRequest)
{
// Verify that this IP is not in the ip_banned table
LoginDatabase.Execute(LoginDatabase.GetPreparedStatement(LOGIN_DEL_EXPIRED_IP_BANS));
@@ -119,68 +103,65 @@ bool Battlenet::Session::HandleLogonRequest(PacketHeader& header, BitStream& pac
stmt->setString(0, ip_address);
if (PreparedQueryResult result = LoginDatabase.Query(stmt))
{
- Authentication::LogonResponse* complete = new Authentication::LogonResponse();
- complete->SetAuthResult(LOGIN_BANNED);
- AsyncWrite(complete);
- TC_LOG_DEBUG("server.battlenet", "[Battlenet::AuthChallenge] Banned ip '%s:%d' tries to login!", ip_address.c_str(), GetRemotePort());
- return true;
+ Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse();
+ logonResponse->SetAuthResult(LOGIN_BANNED);
+ AsyncWrite(logonResponse);
+ TC_LOG_DEBUG("session", "[Battlenet::LogonRequest] Banned ip '%s:%d' tries to login!", ip_address.c_str(), GetRemotePort());
+ return;
}
- Authentication::LogonRequest3 info(header, packet);
- info.Read();
-
- if (info.Program != "WoW")
+ if (logonRequest.Program != "WoW")
{
- Authentication::LogonResponse* complete = new Authentication::LogonResponse();
- complete->SetAuthResult(AUTH_INVALID_PROGRAM);
- AsyncWrite(complete);
- return true;
+ Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse();
+ logonResponse->SetAuthResult(AUTH_INVALID_PROGRAM);
+ AsyncWrite(logonResponse);
+ return;
}
- if (!sBattlenetMgr->HasPlatform(info.Platform))
+ if (!sComponentMgr->HasPlatform(logonRequest.Platform))
{
- Authentication::LogonResponse* complete = new Authentication::LogonResponse();
- complete->SetAuthResult(AUTH_INVALID_OS);
- AsyncWrite(complete);
- return true;
+ Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse();
+ logonResponse->SetAuthResult(AUTH_INVALID_OS);
+ AsyncWrite(logonResponse);
+ return;
}
- if (!sBattlenetMgr->HasPlatform(info.Locale))
+ if (!sComponentMgr->HasPlatform(logonRequest.Locale))
{
- Authentication::LogonResponse* complete = new Authentication::LogonResponse();
- complete->SetAuthResult(AUTH_UNSUPPORTED_LANGUAGE);
- AsyncWrite(complete);
- return true;
+ Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse();
+ logonResponse->SetAuthResult(AUTH_UNSUPPORTED_LANGUAGE);
+ AsyncWrite(logonResponse);
+ return;
}
- for (Component const& component : info.Components)
+ for (Component const& component : logonRequest.Components)
{
- if (!sBattlenetMgr->HasComponent(&component))
+ if (!sComponentMgr->HasComponent(&component))
{
- Authentication::LogonResponse* complete = new Authentication::LogonResponse();
- if (!sBattlenetMgr->HasProgram(component.Program))
- complete->SetAuthResult(AUTH_INVALID_PROGRAM);
- else if (!sBattlenetMgr->HasPlatform(component.Platform))
- complete->SetAuthResult(AUTH_INVALID_OS);
+ Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse();
+ if (!sComponentMgr->HasProgram(component.Program))
+ logonResponse->SetAuthResult(AUTH_INVALID_PROGRAM);
+ else if (!sComponentMgr->HasPlatform(component.Platform))
+ logonResponse->SetAuthResult(AUTH_INVALID_OS);
else
{
if (component.Program != "WoW" || AuthHelper::IsBuildSupportingBattlenet(component.Build))
- complete->SetAuthResult(AUTH_REGION_BAD_VERSION);
+ logonResponse->SetAuthResult(AUTH_REGION_BAD_VERSION);
else
- complete->SetAuthResult(AUTH_USE_GRUNT_LOGON);
+ logonResponse->SetAuthResult(AUTH_USE_GRUNT_LOGON);
}
- AsyncWrite(complete);
- return true;
+ AsyncWrite(logonResponse);
+ return;
}
if (component.Platform == "base")
_build = component.Build;
}
- _accountName = info.Login;
- _locale = info.Locale;
- _os = info.Platform;
+ _accountName = logonRequest.Login;
+ _locale = logonRequest.Locale;
+ _os = logonRequest.Platform;
Utf8ToUpperOnlyLatin(_accountName);
stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_BNET_ACCOUNT_INFO);
@@ -189,10 +170,10 @@ bool Battlenet::Session::HandleLogonRequest(PacketHeader& header, BitStream& pac
PreparedQueryResult result = LoginDatabase.Query(stmt);
if (!result)
{
- Authentication::LogonResponse* complete = new Authentication::LogonResponse();
- complete->SetAuthResult(AUTH_UNKNOWN_ACCOUNT);
- AsyncWrite(complete);
- return true;
+ Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse();
+ logonResponse->SetAuthResult(AUTH_UNKNOWN_ACCOUNT);
+ AsyncWrite(logonResponse);
+ return;
}
Field* fields = result->Fetch();
@@ -202,22 +183,22 @@ bool Battlenet::Session::HandleLogonRequest(PacketHeader& header, BitStream& pac
// If the IP is 'locked', check that the player comes indeed from the correct IP address
if (fields[2].GetUInt8() == 1) // if ip is locked
{
- TC_LOG_DEBUG("server.battlenet", "[Battlenet::AuthChallenge] Account '%s' is locked to IP - '%s' is logging in from '%s'", _accountName.c_str(), fields[4].GetCString(), ip_address.c_str());
+ TC_LOG_DEBUG("session", "[Battlenet::LogonRequest] Account '%s' is locked to IP - '%s' is logging in from '%s'", _accountName.c_str(), fields[4].GetCString(), ip_address.c_str());
if (strcmp(fields[4].GetCString(), ip_address.c_str()) != 0)
{
- Authentication::LogonResponse* complete = new Authentication::LogonResponse();
- complete->SetAuthResult(AUTH_ACCOUNT_LOCKED);
- AsyncWrite(complete);
- return true;
+ Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse();
+ logonResponse->SetAuthResult(AUTH_ACCOUNT_LOCKED);
+ AsyncWrite(logonResponse);
+ return;
}
}
else
{
- TC_LOG_DEBUG("server.battlenet", "[Battlenet::AuthChallenge] Account '%s' is not locked to ip", _accountName.c_str());
+ TC_LOG_DEBUG("session", "[Battlenet::LogonRequest] Account '%s' is not locked to ip", _accountName.c_str());
std::string accountCountry = fields[3].GetString();
if (accountCountry.empty() || accountCountry == "00")
- TC_LOG_DEBUG("server.battlenet", "[Battlenet::AuthChallenge] Account '%s' is not locked to country", _accountName.c_str());
+ TC_LOG_DEBUG("session", "[Battlenet::LogonRequest] Account '%s' is not locked to country", _accountName.c_str());
else if (!accountCountry.empty())
{
uint32 ip = inet_addr(ip_address.c_str());
@@ -228,13 +209,13 @@ bool Battlenet::Session::HandleLogonRequest(PacketHeader& header, BitStream& pac
if (PreparedQueryResult sessionCountryQuery = LoginDatabase.Query(stmt))
{
std::string loginCountry = (*sessionCountryQuery)[0].GetString();
- TC_LOG_DEBUG("server.battlenet", "[Battlenet::AuthChallenge] Account '%s' is locked to country: '%s' Player country is '%s'", _accountName.c_str(), accountCountry.c_str(), loginCountry.c_str());
+ TC_LOG_DEBUG("session", "[Battlenet::LogonRequest] Account '%s' is locked to country: '%s' Player country is '%s'", _accountName.c_str(), accountCountry.c_str(), loginCountry.c_str());
if (loginCountry != accountCountry)
{
- Authentication::LogonResponse* complete = new Authentication::LogonResponse();
- complete->SetAuthResult(AUTH_ACCOUNT_LOCKED);
- AsyncWrite(complete);
- return true;
+ Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse();
+ logonResponse->SetAuthResult(AUTH_ACCOUNT_LOCKED);
+ AsyncWrite(logonResponse);
+ return;
}
}
}
@@ -252,19 +233,19 @@ bool Battlenet::Session::HandleLogonRequest(PacketHeader& header, BitStream& pac
Field* fields = banresult->Fetch();
if (fields[0].GetUInt32() == fields[1].GetUInt32())
{
- Authentication::LogonResponse* complete = new Authentication::LogonResponse();
- complete->SetAuthResult(LOGIN_BANNED);
- AsyncWrite(complete);
- TC_LOG_DEBUG("server.battlenet", "'%s:%d' [Battlenet::AuthChallenge] Banned account %s tried to login!", ip_address.c_str(), GetRemotePort(), _accountName.c_str());
- return true;
+ Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse();
+ logonResponse->SetAuthResult(LOGIN_BANNED);
+ AsyncWrite(logonResponse);
+ TC_LOG_DEBUG("session", "'%s:%d' [Battlenet::LogonRequest] Banned account %s tried to login!", ip_address.c_str(), GetRemotePort(), _accountName.c_str());
+ return;
}
else
{
- Authentication::LogonResponse* complete = new Authentication::LogonResponse();
- complete->SetAuthResult(LOGIN_SUSPENDED);
- AsyncWrite(complete);
- TC_LOG_DEBUG("server.battlenet", "'%s:%d' [Battlenet::AuthChallenge] Temporarily banned account %s tried to login!", ip_address.c_str(), GetRemotePort(), _accountName.c_str());
- return true;
+ Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse();
+ logonResponse->SetAuthResult(LOGIN_SUSPENDED);
+ AsyncWrite(logonResponse);
+ TC_LOG_DEBUG("session", "'%s:%d' [Battlenet::LogonRequest] Temporarily banned account %s tried to login!", ip_address.c_str(), GetRemotePort(), _accountName.c_str());
+ return;
}
}
@@ -274,8 +255,8 @@ bool Battlenet::Session::HandleLogonRequest(PacketHeader& header, BitStream& pac
I.SetBinary(sha.GetDigest(), sha.GetLength());
- ModuleInfo* password = sBattlenetMgr->CreateModule(_os, "Password");
- ModuleInfo* thumbprint = sBattlenetMgr->CreateModule(_os, "Thumbprint");
+ ModuleInfo* password = sModuleMgr->CreateModule(_os, "Password");
+ ModuleInfo* thumbprint = sModuleMgr->CreateModule(_os, "Thumbprint");
std::string pStr = fields[0].GetString();
@@ -309,39 +290,33 @@ bool Battlenet::Session::HandleLogonRequest(PacketHeader& header, BitStream& pac
_modulesWaitingForData.push(MODULE_PASSWORD);
- Authentication::ProofRequest* request = new Authentication::ProofRequest();
- request->Modules.push_back(password);
+ Authentication::ProofRequest* proofRequest = new Authentication::ProofRequest();
+ proofRequest->Modules.push_back(password);
// if has authenticator, send Token module
- request->Modules.push_back(thumbprint);
- AsyncWrite(request);
- return true;
+ proofRequest->Modules.push_back(thumbprint);
+ AsyncWrite(proofRequest);
}
-bool Battlenet::Session::HandleResumeRequest(PacketHeader& header, BitStream& packet)
+void Battlenet::Session::HandleResumeRequest(Authentication::ResumeRequest const& resumeRequest)
{
- Authentication::ResumeRequest reconnect(header, packet);
- reconnect.Read();
-
- TC_LOG_DEBUG("server.battlenet", "%s", reconnect.ToString().c_str());
-
- _accountName = reconnect.Login;
- _locale = reconnect.Locale;
- _os = reconnect.Platform;
- auto baseComponent = std::find_if(reconnect.Components.begin(), reconnect.Components.end(), [](Component const& c) { return c.Program == "base"; });
- if (baseComponent != reconnect.Components.end())
+ _accountName = resumeRequest.Login;
+ _locale = resumeRequest.Locale;
+ _os = resumeRequest.Platform;
+ auto baseComponent = std::find_if(resumeRequest.Components.begin(), resumeRequest.Components.end(), [](Component const& c) { return c.Program == "base"; });
+ if (baseComponent != resumeRequest.Components.end())
_build = baseComponent->Build;
Utf8ToUpperOnlyLatin(_accountName);
PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_BNET_RECONNECT_INFO);
stmt->setString(0, _accountName);
- stmt->setString(1, reconnect.GameAccountName);
+ stmt->setString(1, resumeRequest.GameAccountName);
PreparedQueryResult result = LoginDatabase.Query(stmt);
if (!result)
{
- Authentication::ResumeResponse* resume = new Authentication::ResumeResponse();
- resume->SetAuthResult(AUTH_UNKNOWN_ACCOUNT);
- AsyncWrite(resume);
- return false;
+ Authentication::ResumeResponse* resumeResponse = new Authentication::ResumeResponse();
+ resumeResponse->SetAuthResult(AUTH_UNKNOWN_ACCOUNT);
+ AsyncWrite(resumeResponse);
+ return;
}
Field* fields = result->Fetch();
@@ -349,10 +324,10 @@ bool Battlenet::Session::HandleResumeRequest(PacketHeader& header, BitStream& pa
_accountId = fields[0].GetUInt32();
K.SetHexStr(fields[1].GetString().c_str());
_gameAccountId = fields[2].GetUInt32();
- _gameAccountName = reconnect.GameAccountName;
+ _gameAccountName = resumeRequest.GameAccountName;
- ModuleInfo* thumbprint = sBattlenetMgr->CreateModule(_os, "Thumbprint");
- ModuleInfo* resume = sBattlenetMgr->CreateModule(_os, "Resume");
+ ModuleInfo* thumbprint = sModuleMgr->CreateModule(_os, "Thumbprint");
+ ModuleInfo* resume = sModuleMgr->CreateModule(_os, "Resume");
BitStream resumeData;
uint8 state = 0;
_reconnectProof.SetRand(16 * 8);
@@ -366,30 +341,26 @@ bool Battlenet::Session::HandleResumeRequest(PacketHeader& header, BitStream& pa
_modulesWaitingForData.push(MODULE_RESUME);
- Authentication::ProofRequest* request = new Authentication::ProofRequest();
- request->Modules.push_back(thumbprint);
- request->Modules.push_back(resume);
- AsyncWrite(request);
- return true;
+ Authentication::ProofRequest* proofRequest = new Authentication::ProofRequest();
+ proofRequest->Modules.push_back(thumbprint);
+ proofRequest->Modules.push_back(resume);
+ AsyncWrite(proofRequest);
}
-bool Battlenet::Session::HandleProofResponse(PacketHeader& header, BitStream& packet)
+void Battlenet::Session::HandleProofResponse(Authentication::ProofResponse const& proofResponse)
{
- Authentication::ProofResponse proof(header, packet);
- proof.Read();
-
- if (_modulesWaitingForData.size() < proof.Modules.size())
+ if (_modulesWaitingForData.size() < proofResponse.Modules.size())
{
Authentication::LogonResponse* complete = new Authentication::LogonResponse();
complete->SetAuthResult(AUTH_CORRUPTED_MODULE);
AsyncWrite(complete);
- return true;
+ return;
}
ServerPacket* response = nullptr;
- for (size_t i = 0; i < proof.Modules.size(); ++i)
+ for (size_t i = 0; i < proofResponse.Modules.size(); ++i)
{
- if (!(this->*(ModuleHandlers[_modulesWaitingForData.front()]))(proof.Modules[i], &response))
+ if (!(this->*(ModuleHandlers[_modulesWaitingForData.front()]))(proofResponse.Modules[i], &response))
break;
_modulesWaitingForData.pop();
@@ -402,36 +373,35 @@ bool Battlenet::Session::HandleProofResponse(PacketHeader& header, BitStream& pa
}
AsyncWrite(response);
- return true;
+ return;
}
-bool Battlenet::Session::HandlePing(PacketHeader& /*header*/, BitStream& /*packet*/)
+void Battlenet::Session::HandlePing(Connection::Ping const& /*ping*/)
{
AsyncWrite(new Connection::Pong());
- return true;
}
-bool Battlenet::Session::HandleEnableEncryption(PacketHeader& /*header*/, BitStream& /*packet*/)
+void Battlenet::Session::HandleEnableEncryption(Connection::EnableEncryption const& /*enableEncryption*/)
{
_crypt.Init(&K);
- return true;
}
-bool Battlenet::Session::HandleLogoutRequest(PacketHeader& /*header*/, BitStream& /*packet*/)
+void Battlenet::Session::HandleLogoutRequest(Connection::LogoutRequest const& /*logoutRequest*/)
{
PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_BNET_SESSION_KEY);
stmt->setString(0, "");
stmt->setBool(1, false);
stmt->setUInt32(2, _accountId);
LoginDatabase.Execute(stmt);
- return true;
}
-bool Battlenet::Session::HandleListSubscribeRequest(PacketHeader& /*header*/, BitStream& /*packet*/)
+void Battlenet::Session::HandleConnectionClosing(Connection::ConnectionClosing const& /*connectionClosing*/)
{
- sRealmList->UpdateIfNeed();
+}
- WoWRealm::ListSubscribeResponse* counts = new WoWRealm::ListSubscribeResponse();
+void Battlenet::Session::HandleListSubscribeRequest(WoWRealm::ListSubscribeRequest const& /*listSubscribeRequest*/)
+{
+ WoWRealm::ListSubscribeResponse* listSubscribeResponse = new WoWRealm::ListSubscribeResponse();
PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_BNET_CHARACTER_COUNTS);
stmt->setUInt32(0, _gameAccountId);
@@ -442,87 +412,50 @@ bool Battlenet::Session::HandleListSubscribeRequest(PacketHeader& /*header*/, Bi
{
Field* fields = countResult->Fetch();
uint32 build = fields[4].GetUInt32();
- counts->CharacterCounts.push_back({ { fields[2].GetUInt8(), fields[3].GetUInt8(), fields[1].GetUInt32(), (_build != build ? build : 0) }, fields[0].GetUInt8() });
+ listSubscribeResponse->CharacterCounts.push_back({ RealmId(fields[2].GetUInt8(), fields[3].GetUInt8(), fields[1].GetUInt32(), (_build != build ? build : 0)), fields[0].GetUInt8() });
} while (countResult->NextRow());
}
- for (RealmList::RealmMap::const_iterator i = sRealmList->begin(); i != sRealmList->end(); ++i)
- {
- Realm const& realm = i->second;
-
- uint32 flag = realm.flag;
- RealmBuildInfo const* buildInfo = AuthHelper::GetBuildInfo(realm.gamebuild);
- if (realm.gamebuild != _build)
- {
- if (!buildInfo)
- continue;
-
- flag |= REALM_FLAG_OFFLINE | REALM_FLAG_SPECIFYBUILD; // tell the client what build the realm is for
- }
-
- if (!buildInfo)
- flag &= ~REALM_FLAG_SPECIFYBUILD;
-
- WoWRealm::ListUpdate* update = new WoWRealm::ListUpdate();
- update->Timezone = realm.timezone;
- update->Population = realm.populationLevel;
- update->Lock = (realm.allowedSecurityLevel > _accountSecurityLevel) ? 1 : 0;
- update->Type = realm.icon;
- update->Name = realm.name;
-
- if (flag & REALM_FLAG_SPECIFYBUILD)
- {
- std::ostringstream version;
- version << buildInfo->MajorVersion << '.' << buildInfo->MinorVersion << '.' << buildInfo->BugfixVersion << '.' << buildInfo->Build;
-
- update->Version = version.str();
- update->Address = realm.GetAddressForClient(GetRemoteIpAddress());
- update->Build = buildInfo->Build;
- }
-
- update->Flags = flag;
- update->Region = realm.Region;
- update->Battlegroup = realm.Battlegroup;
- update->Index = realm.m_ID;
-
- counts->RealmData.push_back(update);
- }
+ for (RealmList::RealmMap::value_type const& i : sRealmList->GetRealms())
+ listSubscribeResponse->RealmData.push_back(BuildListUpdate(&i.second));
- counts->RealmData.push_back(new WoWRealm::ListComplete());
+ listSubscribeResponse->RealmData.push_back(new WoWRealm::ListComplete());
- AsyncWrite(counts);
- return true;
+ AsyncWrite(listSubscribeResponse);
+ _subscribedToRealmListUpdates = true;
}
-bool Battlenet::Session::HandleJoinRequestV2(PacketHeader& header, BitStream& packet)
+void Battlenet::Session::HandleListUnsubscribe(WoWRealm::ListUnsubscribe const& /*listUnsubscribe*/)
{
- WoWRealm::JoinRequestV2 join(header, packet);
- join.Read();
+ _subscribedToRealmListUpdates = false;
+}
- WoWRealm::JoinResponseV2* result = new WoWRealm::JoinResponseV2();
- Realm const* realm = sRealmList->GetRealm(join.Realm);
- if (!realm || realm->flag & (REALM_FLAG_INVALID | REALM_FLAG_OFFLINE))
+void Battlenet::Session::HandleJoinRequestV2(WoWRealm::JoinRequestV2 const& joinRequest)
+{
+ WoWRealm::JoinResponseV2* joinResponse = new WoWRealm::JoinResponseV2();
+ Realm const* realm = sRealmList->GetRealm(joinRequest.Realm);
+ if (!realm || realm->Flags & (REALM_FLAG_INVALID | REALM_FLAG_OFFLINE))
{
- result->Response = WoWRealm::JoinResponseV2::FAILURE;
- AsyncWrite(result);
- return true;
+ joinResponse->Response = WoWRealm::JoinResponseV2::FAILURE;
+ AsyncWrite(joinResponse);
+ return;
}
- result->ServerSeed = uint32(rand32());
+ joinResponse->ServerSeed = uint32(rand32());
uint8 sessionKey[40];
HmacSha1 hmac(K.GetNumBytes(), K.AsByteArray().get());
hmac.UpdateData((uint8*)"WoW\0", 4);
- hmac.UpdateData((uint8*)&join.ClientSeed, 4);
- hmac.UpdateData((uint8*)&result->ServerSeed, 4);
+ hmac.UpdateData((uint8*)&joinRequest.ClientSeed, 4);
+ hmac.UpdateData((uint8*)&joinResponse->ServerSeed, 4);
hmac.Finalize();
memcpy(sessionKey, hmac.GetDigest(), hmac.GetLength());
HmacSha1 hmac2(K.GetNumBytes(), K.AsByteArray().get());
hmac2.UpdateData((uint8*)"WoW\0", 4);
- hmac2.UpdateData((uint8*)&result->ServerSeed, 4);
- hmac2.UpdateData((uint8*)&join.ClientSeed, 4);
+ hmac2.UpdateData((uint8*)&joinResponse->ServerSeed, 4);
+ hmac2.UpdateData((uint8*)&joinRequest.ClientSeed, 4);
hmac2.Finalize();
memcpy(sessionKey + hmac.GetLength(), hmac2.GetDigest(), hmac2.GetLength());
@@ -530,53 +463,92 @@ bool Battlenet::Session::HandleJoinRequestV2(PacketHeader& header, BitStream& pa
LoginDatabase.DirectPExecute("UPDATE account SET sessionkey = '%s', last_ip = '%s', last_login = NOW(), locale = %u, failed_logins = 0, os = '%s' WHERE id = %u",
ByteArrayToHexStr(sessionKey, 40, true).c_str(), GetRemoteIpAddress().to_string().c_str(), GetLocaleByName(_locale), _os.c_str(), _gameAccountId);
- result->IPv4.emplace_back(realm->ExternalAddress, realm->port);
+ joinResponse->IPv4.emplace_back(realm->ExternalAddress, realm->Port);
if (realm->ExternalAddress != realm->LocalAddress)
- result->IPv4.emplace_back(realm->LocalAddress, realm->port);
+ joinResponse->IPv4.emplace_back(realm->LocalAddress, realm->Port);
- AsyncWrite(result);
- return true;
+ AsyncWrite(joinResponse);
+}
+
+void Battlenet::Session::HandleSocialNetworkCheckConnected(Friends::SocialNetworkCheckConnected const& socialNetworkCheckConnected)
+{
+ Friends::SocialNetworkCheckConnectedResult* socialNetworkCheckConnectedResult = new Friends::SocialNetworkCheckConnectedResult();
+ socialNetworkCheckConnectedResult->SocialNetworkId = socialNetworkCheckConnected.SocialNetworkId;
+ AsyncWrite(socialNetworkCheckConnectedResult);
+}
+
+void Battlenet::Session::HandleGetStreamItemsRequest(Cache::GetStreamItemsRequest const& getStreamItemsRequest)
+{
+ if (ModuleInfo* module = sModuleMgr->CreateModule(getStreamItemsRequest.Locale, getStreamItemsRequest.ItemName))
+ {
+ Cache::GetStreamItemsResponse* getStreamItemsResponse = new Cache::GetStreamItemsResponse();
+ getStreamItemsResponse->Index = getStreamItemsRequest.Index;
+ getStreamItemsResponse->Modules.push_back(module);
+ AsyncWrite(getStreamItemsResponse);
+ }
+}
+
+inline std::string PacketToStringHelper(Battlenet::ClientPacket const* packet)
+{
+ if (sLog->ShouldLog("session.packets", LOG_LEVEL_TRACE))
+ return packet->ToString();
+
+ return sPacketManager.GetClientPacketName(packet->GetHeader());
+}
+
+inline std::string PacketToStringHelper(Battlenet::ServerPacket const* packet)
+{
+ if (sLog->ShouldLog("session.packets", LOG_LEVEL_TRACE))
+ return packet->ToString();
+
+ return sPacketManager.GetServerPacketName(packet->GetHeader());
}
void Battlenet::Session::ReadHandler()
{
- BitStream packet(std::move(GetReadBuffer()));
- _crypt.DecryptRecv(packet.GetBuffer(), packet.GetSize());
+ BitStream stream(std::move(GetReadBuffer()));
+ _crypt.DecryptRecv(stream.GetBuffer(), stream.GetSize());
- while (!packet.IsRead())
+ while (!stream.IsRead())
{
try
{
PacketHeader header;
- header.Opcode = packet.Read<uint32>(6);
- if (packet.Read<bool>(1))
- header.Channel = packet.Read<int32>(4);
+ header.Opcode = stream.Read<uint32>(6);
+ if (stream.Read<bool>(1))
+ header.Channel = stream.Read<int32>(4);
if (header.Channel != AUTHENTICATION && !_authed)
{
- TC_LOG_DEBUG("server.battlenet", "Battlenet::Session::ReadDataHandler Received not allowed packet %s", header.ToString().c_str());
+ TC_LOG_DEBUG("session.packets", "%s Received not allowed %s. Client has not authed yet.", GetClientInfo().c_str(), header.ToString().c_str());
CloseSocket();
return;
}
- TC_LOG_TRACE("server.battlenet", "Battlenet::Session::ReadDataHandler %s", header.ToString().c_str());
- std::map<PacketHeader, PacketHandler>::const_iterator itr = Handlers.find(header);
- if (itr != Handlers.end())
+ if (ClientPacket* packet = sPacketManager.CreateClientPacket(header, stream))
{
- if ((this->*(itr->second))(header, packet))
- break;
+ if (sPacketManager.IsHandled(header))
+ TC_LOG_DEBUG("session.packets", "%s Received %s", GetClientInfo().c_str(), PacketToStringHelper(packet).c_str());
+
+ packet->CallHandler(this);
+ delete packet;
+ }
+ else if (sPacketManager.GetClientPacketName(header))
+ {
+ LogUnhandledPacket(header);
+ break;
}
else
{
- TC_LOG_DEBUG("server.battlenet", "Battlenet::Session::ReadDataHandler Unhandled opcode %s", header.ToString().c_str());
+ TC_LOG_DEBUG("session.packets", "%s Received unknown %s", GetClientInfo().c_str(), header.ToString().c_str());
break;
}
- packet.AlignToNextByte();
+ stream.AlignToNextByte();
}
catch (BitStreamPositionException const& e)
{
- TC_LOG_ERROR("server.battlenet", "Battlenet::Session::ReadDataHandler Exception: %s", e.what());
+ TC_LOG_ERROR("session.packets", "%s Exception thrown during packet processing %s", GetClientInfo().c_str(), e.what());
CloseSocket();
return;
}
@@ -588,7 +560,7 @@ void Battlenet::Session::ReadHandler()
void Battlenet::Session::Start()
{
- TC_LOG_TRACE("server.battlenet", "Battlenet::Session::Start");
+ TC_LOG_TRACE("session", "Accepted connection from %s", GetRemoteIpAddress().to_string().c_str());
AsyncRead();
}
@@ -600,7 +572,7 @@ void Battlenet::Session::AsyncWrite(ServerPacket* packet)
return;
}
- TC_LOG_TRACE("server.battlenet", "Battlenet::Session::AsyncWrite %s", packet->ToString().c_str());
+ TC_LOG_DEBUG("session.packets", "%s Sending %s", GetClientInfo().c_str(), PacketToStringHelper(packet).c_str());
packet->Write();
@@ -627,17 +599,17 @@ bool Battlenet::Session::HandlePasswordModule(BitStream* dataStream, ServerPacke
{
if (dataStream->GetSize() != 1 + 128 + 32 + 128)
{
- Authentication::LogonResponse* complete = new Authentication::LogonResponse();
- complete->SetAuthResult(AUTH_CORRUPTED_MODULE);
- ReplaceResponse(response, complete);
+ Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse();
+ logonResponse->SetAuthResult(AUTH_CORRUPTED_MODULE);
+ ReplaceResponse(response, logonResponse);
return false;
}
if (dataStream->Read<uint8>(8) != 2) // State
{
- Authentication::LogonResponse* complete = new Authentication::LogonResponse();
- complete->SetAuthResult(AUTH_CORRUPTED_MODULE);
- ReplaceResponse(response, complete);
+ Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse();
+ logonResponse->SetAuthResult(AUTH_CORRUPTED_MODULE);
+ ReplaceResponse(response, logonResponse);
return false;
}
@@ -649,9 +621,9 @@ bool Battlenet::Session::HandlePasswordModule(BitStream* dataStream, ServerPacke
if (A.isZero())
{
- Authentication::LogonResponse* complete = new Authentication::LogonResponse();
- complete->SetAuthResult(AUTH_CORRUPTED_MODULE);
- ReplaceResponse(response, complete);
+ Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse();
+ logonResponse->SetAuthResult(AUTH_CORRUPTED_MODULE);
+ ReplaceResponse(response, logonResponse);
return false;
}
@@ -725,9 +697,9 @@ bool Battlenet::Session::HandlePasswordModule(BitStream* dataStream, ServerPacke
stmt->setString(0, _accountName);
LoginDatabase.Execute(stmt);
- Authentication::LogonResponse* complete = new Authentication::LogonResponse();
- complete->SetAuthResult(AUTH_UNKNOWN_ACCOUNT);
- ReplaceResponse(response, complete);
+ Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse();
+ logonResponse->SetAuthResult(AUTH_UNKNOWN_ACCOUNT);
+ ReplaceResponse(response, logonResponse);
return false;
}
@@ -740,9 +712,9 @@ bool Battlenet::Session::HandlePasswordModule(BitStream* dataStream, ServerPacke
if (!numAccounts)
{
- Authentication::LogonResponse* noAccounts = new Authentication::LogonResponse();
- noAccounts->SetAuthResult(LOGIN_NO_GAME_ACCOUNT);
- ReplaceResponse(response, noAccounts);
+ Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse();
+ logonResponse->SetAuthResult(LOGIN_NO_GAME_ACCOUNT);
+ ReplaceResponse(response, logonResponse);
return false;
}
@@ -761,7 +733,7 @@ bool Battlenet::Session::HandlePasswordModule(BitStream* dataStream, ServerPacke
serverProof.SetRand(128 * 8); // just send garbage, server signature check is patched out in client
BitStream stream;
- ModuleInfo* password = sBattlenetMgr->CreateModule(_os, "Password");
+ ModuleInfo* password = sModuleMgr->CreateModule(_os, "Password");
uint8 state = 3;
stream.WriteBytes(&state, 1);
@@ -772,8 +744,8 @@ bool Battlenet::Session::HandlePasswordModule(BitStream* dataStream, ServerPacke
password->Data = new uint8[password->DataSize];
memcpy(password->Data, stream.GetBuffer(), password->DataSize);
- Authentication::ProofRequest* request = new Authentication::ProofRequest();
- request->Modules.push_back(password);
+ Authentication::ProofRequest* proofRequest = new Authentication::ProofRequest();
+ proofRequest->Modules.push_back(password);
if (numAccounts > 1)
{
BitStream accounts;
@@ -794,43 +766,43 @@ bool Battlenet::Session::HandlePasswordModule(BitStream* dataStream, ServerPacke
accounts.WriteString(name.str(), 8);
} while (result->NextRow());
- ModuleInfo* selectGameAccount = sBattlenetMgr->CreateModule(_os, "SelectGameAccount");
+ ModuleInfo* selectGameAccount = sModuleMgr->CreateModule(_os, "SelectGameAccount");
selectGameAccount->DataSize = accounts.GetSize();
selectGameAccount->Data = new uint8[selectGameAccount->DataSize];
memcpy(selectGameAccount->Data, accounts.GetBuffer(), selectGameAccount->DataSize);
- request->Modules.push_back(selectGameAccount);
+ proofRequest->Modules.push_back(selectGameAccount);
_modulesWaitingForData.push(MODULE_SELECT_GAME_ACCOUNT);
}
else
{
if (fields[4].GetBool())
{
- delete request;
+ delete proofRequest;
- Authentication::LogonResponse* complete = new Authentication::LogonResponse();
+ Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse();
if (fields[2].GetUInt32() == fields[3].GetUInt32())
{
- complete->SetAuthResult(LOGIN_BANNED);
- TC_LOG_DEBUG("server.battlenet", "'%s:%d' [Battlenet::AuthChallenge] Banned account %s tried to login!", GetRemoteIpAddress().to_string().c_str(), GetRemotePort(), _accountName.c_str());
+ logonResponse->SetAuthResult(LOGIN_BANNED);
+ TC_LOG_DEBUG("session", "'%s:%d' [Battlenet::Password] Banned account %s tried to login!", GetRemoteIpAddress().to_string().c_str(), GetRemotePort(), _accountName.c_str());
}
else
{
- complete->SetAuthResult(LOGIN_SUSPENDED);
- TC_LOG_DEBUG("server.battlenet", "'%s:%d' [Battlenet::AuthChallenge] Temporarily banned account %s tried to login!", GetRemoteIpAddress().to_string().c_str(), GetRemotePort(), _accountName.c_str());
+ logonResponse->SetAuthResult(LOGIN_SUSPENDED);
+ TC_LOG_DEBUG("session", "'%s:%d' [Battlenet::Password] Temporarily banned account %s tried to login!", GetRemoteIpAddress().to_string().c_str(), GetRemotePort(), _accountName.c_str());
}
- ReplaceResponse(response, complete);
+ ReplaceResponse(response, logonResponse);
return false;
}
_gameAccountId = fields[0].GetUInt32();
_gameAccountName = fields[1].GetString();
- request->Modules.push_back(sBattlenetMgr->CreateModule(_os, "RiskFingerprint"));
+ proofRequest->Modules.push_back(sModuleMgr->CreateModule(_os, "RiskFingerprint"));
_modulesWaitingForData.push(MODULE_RISK_FINGERPRINT);
}
- ReplaceResponse(response, request);
+ ReplaceResponse(response, proofRequest);
return true;
}
@@ -838,9 +810,9 @@ bool Battlenet::Session::HandleSelectGameAccountModule(BitStream* dataStream, Se
{
if (dataStream->Read<uint8>(8) != 1)
{
- Authentication::LogonResponse* complete = new Authentication::LogonResponse();
- complete->SetAuthResult(AUTH_CORRUPTED_MODULE);
- ReplaceResponse(response, complete);
+ Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse();
+ logonResponse->SetAuthResult(AUTH_CORRUPTED_MODULE);
+ ReplaceResponse(response, logonResponse);
return false;
}
@@ -848,9 +820,9 @@ bool Battlenet::Session::HandleSelectGameAccountModule(BitStream* dataStream, Se
std::string account = dataStream->ReadString(8);
if (account.empty())
{
- Authentication::LogonResponse* complete = new Authentication::LogonResponse();
- complete->SetAuthResult(LOGIN_NO_GAME_ACCOUNT);
- ReplaceResponse(response, complete);
+ Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse();
+ logonResponse->SetAuthResult(LOGIN_NO_GAME_ACCOUNT);
+ ReplaceResponse(response, logonResponse);
return false;
}
@@ -879,28 +851,28 @@ bool Battlenet::Session::HandleSelectGameAccountModule(BitStream* dataStream, Se
Field* fields = result->Fetch();
if (fields[4].GetBool())
{
- Authentication::LogonResponse* complete = new Authentication::LogonResponse();
+ Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse();
if (fields[2].GetUInt32() == fields[3].GetUInt32())
{
- complete->SetAuthResult(LOGIN_BANNED);
- TC_LOG_DEBUG("server.battlenet", "'%s:%d' [Battlenet::SelectGameAccount] Banned account %s tried to login!", GetRemoteIpAddress().to_string().c_str(), GetRemotePort(), _accountName.c_str());
+ logonResponse->SetAuthResult(LOGIN_BANNED);
+ TC_LOG_DEBUG("session", "'%s:%d' [Battlenet::SelectGameAccount] Banned account %s tried to login!", GetRemoteIpAddress().to_string().c_str(), GetRemotePort(), _accountName.c_str());
}
else
{
- complete->SetAuthResult(LOGIN_SUSPENDED);
- TC_LOG_DEBUG("server.battlenet", "'%s:%d' [Battlenet::SelectGameAccount] Temporarily banned account %s tried to login!", GetRemoteIpAddress().to_string().c_str(), GetRemotePort(), _accountName.c_str());
+ logonResponse->SetAuthResult(LOGIN_SUSPENDED);
+ TC_LOG_DEBUG("session", "'%s:%d' [Battlenet::SelectGameAccount] Temporarily banned account %s tried to login!", GetRemoteIpAddress().to_string().c_str(), GetRemotePort(), _accountName.c_str());
}
- ReplaceResponse(response, complete);
+ ReplaceResponse(response, logonResponse);
return false;
}
_gameAccountId = fields[0].GetUInt32();
_gameAccountName = fields[1].GetString();
- Authentication::ProofRequest* request = new Authentication::ProofRequest();
- request->Modules.push_back(sBattlenetMgr->CreateModule(_os, "RiskFingerprint"));
- ReplaceResponse(response, request);
+ Authentication::ProofRequest* proofRequest = new Authentication::ProofRequest();
+ proofRequest->Modules.push_back(sModuleMgr->CreateModule(_os, "RiskFingerprint"));
+ ReplaceResponse(response, proofRequest);
_modulesWaitingForData.push(MODULE_RISK_FINGERPRINT);
return true;
@@ -908,16 +880,16 @@ bool Battlenet::Session::HandleSelectGameAccountModule(BitStream* dataStream, Se
bool Battlenet::Session::HandleRiskFingerprintModule(BitStream* dataStream, ServerPacket** response)
{
- Authentication::LogonResponse* complete = new Authentication::LogonResponse();
+ Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse();
if (dataStream->Read<uint8>(8) == 1)
{
- complete->AccountId = _accountId;
- complete->GameAccountName = _gameAccountName;
- complete->GameAccountFlags = GAMEACCOUNT_FLAG_PROPASS_LOCK;
+ logonResponse->AccountId = _accountId;
+ logonResponse->GameAccountName = _gameAccountName;
+ logonResponse->GameAccountFlags = GAMEACCOUNT_FLAG_PROPASS_LOCK;
PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_BNET_FAILED_LOGINS);
stmt->setUInt32(0, _accountId);
if (PreparedQueryResult failedLoginsResult = LoginDatabase.Query(stmt))
- complete->FailedLogins = (*failedLoginsResult)[0].GetUInt32();
+ logonResponse->FailedLogins = (*failedLoginsResult)[0].GetUInt32();
SQLTransaction trans = LoginDatabase.BeginTransaction();
@@ -937,12 +909,12 @@ bool Battlenet::Session::HandleRiskFingerprintModule(BitStream* dataStream, Serv
LoginDatabase.CommitTransaction(trans);
_authed = true;
- sBattlenetSessionMgr.AddSession(this);
+ sSessionMgr.AddSession(this);
}
else
- complete->SetAuthResult(AUTH_BAD_VERSION_HASH);
+ logonResponse->SetAuthResult(AUTH_BAD_VERSION_HASH);
- ReplaceResponse(response, complete);
+ ReplaceResponse(response, logonResponse);
return true;
}
@@ -950,9 +922,9 @@ bool Battlenet::Session::HandleResumeModule(BitStream* dataStream, ServerPacket*
{
if (dataStream->Read<uint8>(8) != 1)
{
- Authentication::ResumeResponse* complete = new Authentication::ResumeResponse();
- complete->SetAuthResult(AUTH_CORRUPTED_MODULE);
- ReplaceResponse(response, complete);
+ Authentication::ResumeResponse* resumeResponse = new Authentication::ResumeResponse();
+ resumeResponse->SetAuthResult(AUTH_CORRUPTED_MODULE);
+ ReplaceResponse(response, resumeResponse);
return false;
}
@@ -994,10 +966,10 @@ bool Battlenet::Session::HandleResumeModule(BitStream* dataStream, ServerPacket*
stmt->setString(0, _accountName);
LoginDatabase.Execute(stmt);
- TC_LOG_DEBUG("server.battlenet", "[Battlenet::Resume] Invalid proof!");
- Authentication::ResumeResponse* result = new Authentication::ResumeResponse();
- result->SetAuthResult(AUTH_UNKNOWN_ACCOUNT);
- ReplaceResponse(response, result);
+ TC_LOG_DEBUG("session", "[Battlenet::Resume] Invalid proof!");
+ Authentication::ResumeResponse* resumeResponse = new Authentication::ResumeResponse();
+ resumeResponse->SetAuthResult(AUTH_UNKNOWN_ACCOUNT);
+ ReplaceResponse(response, resumeResponse);
return false;
}
@@ -1013,7 +985,7 @@ bool Battlenet::Session::HandleResumeModule(BitStream* dataStream, ServerPacket*
serverProof.UpdateData(clientChallenge.get(), 16);
serverProof.Finalize();
- ModuleInfo* resume = sBattlenetMgr->CreateModule(_os, "Resume");
+ ModuleInfo* resume = sModuleMgr->CreateModule(_os, "Resume");
BitStream resumeData;
uint8 state = 2;
@@ -1024,18 +996,80 @@ bool Battlenet::Session::HandleResumeModule(BitStream* dataStream, ServerPacket*
resume->Data = new uint8[resume->DataSize];
memcpy(resume->Data, resumeData.GetBuffer(), resume->DataSize);
- Authentication::ResumeResponse* result = new Authentication::ResumeResponse();
- result->Modules.push_back(resume);
- ReplaceResponse(response, result);
+ Authentication::ResumeResponse* resumeResponse = new Authentication::ResumeResponse();
+ resumeResponse->Modules.push_back(resume);
+ ReplaceResponse(response, resumeResponse);
_authed = true;
- sBattlenetSessionMgr.AddSession(this);
+ sSessionMgr.AddSession(this);
return true;
}
bool Battlenet::Session::UnhandledModule(BitStream* /*dataStream*/, ServerPacket** response)
{
- Authentication::LogonResponse* complete = new Authentication::LogonResponse();
- complete->SetAuthResult(AUTH_CORRUPTED_MODULE);
- ReplaceResponse(response, complete);
+ TC_LOG_ERROR("session.packets", "Unhandled module.");
+ Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse();
+ logonResponse->SetAuthResult(AUTH_CORRUPTED_MODULE);
+ ReplaceResponse(response, logonResponse);
return false;
}
+
+void Battlenet::Session::UpdateRealms(std::vector<Realm const*>& realms, std::vector<RealmId>& deletedRealms)
+{
+ for (Realm const* realm : realms)
+ AsyncWrite(BuildListUpdate(realm));
+
+ for (RealmId& deleted : deletedRealms)
+ {
+ WoWRealm::ListUpdate* listUpdate = new WoWRealm::ListUpdate();
+ listUpdate->UpdateState = WoWRealm::ListUpdate::DELETED;
+ listUpdate->Id = deleted;
+ AsyncWrite(listUpdate);
+ }
+}
+
+Battlenet::WoWRealm::ListUpdate* Battlenet::Session::BuildListUpdate(Realm const* realm) const
+{
+ uint32 flag = realm->Flags & ~REALM_FLAG_SPECIFYBUILD;
+ RealmBuildInfo const* buildInfo = AuthHelper::GetBuildInfo(realm->Id.Build);
+ if (realm->Id.Build != _build)
+ {
+ flag |= REALM_FLAG_INVALID;
+ if (buildInfo)
+ flag |= REALM_FLAG_SPECIFYBUILD; // tell the client what build the realm is for
+ }
+
+ WoWRealm::ListUpdate* listUpdate = new WoWRealm::ListUpdate();
+ listUpdate->Timezone = realm->Timezone;
+ listUpdate->Population = realm->PopulationLevel;
+ listUpdate->Lock = (realm->AllowedSecurityLevel > _accountSecurityLevel) ? 1 : 0;
+ listUpdate->Type = realm->Type;
+ listUpdate->Name = realm->Name;
+
+ if (flag & REALM_FLAG_SPECIFYBUILD)
+ {
+ std::ostringstream version;
+ version << buildInfo->MajorVersion << '.' << buildInfo->MinorVersion << '.' << buildInfo->BugfixVersion << '.' << buildInfo->Build;
+
+ listUpdate->Version = version.str();
+ listUpdate->Address = realm->GetAddressForClient(GetRemoteIpAddress());
+ }
+
+ listUpdate->Flags = flag;
+ listUpdate->Id = realm->Id;
+ return listUpdate;
+}
+
+std::string Battlenet::Session::GetClientInfo() const
+{
+ std::ostringstream stream;
+ stream << '[' << GetRemoteIpAddress() << ':' << GetRemotePort();
+ if (!_accountName.empty())
+ stream << ", Account: " << _accountName;
+
+ if (!_gameAccountName.empty())
+ stream << ", Game account: " << _gameAccountName;
+
+ stream << ']';
+
+ return stream.str();
+}
diff --git a/src/server/authserver/Server/BattlenetSession.h b/src/server/bnetserver/Server/Session.h
index c3e4afee19b..ded5170ae32 100644
--- a/src/server/authserver/Server/BattlenetSession.h
+++ b/src/server/bnetserver/Server/Session.h
@@ -15,16 +15,17 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef _BATTLENETSOCKET_H
-#define _BATTLENETSOCKET_H
+#ifndef Session_h__
+#define Session_h__
-#include "BattlenetPackets.h"
+#include "Packets.h"
#include "BattlenetPacketCrypt.h"
#include "Socket.h"
#include "BigNumber.h"
#include <memory>
#include <boost/asio/ip/tcp.hpp>
+struct Realm;
using boost::asio::ip::tcp;
namespace Battlenet
@@ -59,24 +60,39 @@ namespace Battlenet
explicit Session(tcp::socket&& socket);
~Session();
- typedef bool(Session::*PacketHandler)(PacketHeader& socket, BitStream& packet);
+ void LogUnhandledPacket(PacketHeader const& header);
// Authentication
- bool HandleLogonRequest(PacketHeader& header, BitStream& packet);
- bool HandleResumeRequest(PacketHeader& header, BitStream& packet);
- bool HandleProofResponse(PacketHeader& header, BitStream& packet);
+ void HandleLogonRequest(Authentication::LogonRequest3 const& logonRequest);
+ void HandleResumeRequest(Authentication::ResumeRequest const& resumeRequest);
+ void HandleProofResponse(Authentication::ProofResponse const& proofResponse);
// Connection
- bool HandlePing(PacketHeader& header, BitStream& packet);
- bool HandleEnableEncryption(PacketHeader& header, BitStream& packet);
- bool HandleLogoutRequest(PacketHeader& header, BitStream& packet);
+ void HandlePing(Connection::Ping const& ping);
+ void HandleEnableEncryption(Connection::EnableEncryption const& enableEncryption);
+ void HandleLogoutRequest(Connection::LogoutRequest const& logoutRequest);
+ void HandleConnectionClosing(Connection::ConnectionClosing const& connectionClosing);
// WoWRealm
- bool HandleListSubscribeRequest(PacketHeader& header, BitStream& packet);
- bool HandleJoinRequestV2(PacketHeader& header, BitStream& packet);
+ void HandleListSubscribeRequest(WoWRealm::ListSubscribeRequest const& listSubscribeRequest);
+ void HandleListUnsubscribe(WoWRealm::ListUnsubscribe const& listUnsubscribe);
+ void HandleJoinRequestV2(WoWRealm::JoinRequestV2 const& joinRequest);
+
+ // Friends
+ void HandleSocialNetworkCheckConnected(Friends::SocialNetworkCheckConnected const& socialNetworkCheckConnected);
+
+ // Cache
+ void HandleGetStreamItemsRequest(Cache::GetStreamItemsRequest const& getStreamItemsRequest);
void Start() override;
+ void UpdateRealms(std::vector<Realm const*>& realms, std::vector<RealmId>& deletedRealms);
+
+ uint32 GetAccountId() const { return _accountId; }
+ uint32 GetGameAccountId() const { return _gameAccountId; }
+
+ bool IsSubscribedToRealmListUpdates() const { return _subscribedToRealmListUpdates; }
+
void AsyncWrite(ServerPacket* packet);
protected:
@@ -94,6 +110,9 @@ namespace Battlenet
bool HandleResumeModule(BitStream* dataStream, ServerPacket** response);
bool UnhandledModule(BitStream* dataStream, ServerPacket** response);
+ WoWRealm::ListUpdate* BuildListUpdate(Realm const* realm) const;
+ std::string GetClientInfo() const;
+
uint32 _accountId;
std::string _accountName;
std::string _locale;
@@ -121,8 +140,9 @@ namespace Battlenet
PacketCrypt _crypt;
bool _authed;
+ bool _subscribedToRealmListUpdates;
};
}
-#endif // _BATTLENETSOCKET_H
+#endif // Session_h__
diff --git a/src/server/bnetserver/Server/SessionManager.cpp b/src/server/bnetserver/Server/SessionManager.cpp
new file mode 100644
index 00000000000..9e5836dab8d
--- /dev/null
+++ b/src/server/bnetserver/Server/SessionManager.cpp
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "SessionManager.h"
+
+bool Battlenet::SessionManager::StartNetwork(boost::asio::io_service& service, std::string const& bindIp, uint16 port)
+{
+ if (!BaseSocketMgr::StartNetwork(service, bindIp, port))
+ return false;
+
+ _acceptor->AsyncAcceptManaged(&OnSocketAccept);
+ return true;
+}
+
+NetworkThread<Battlenet::Session>* Battlenet::SessionManager::CreateThreads() const
+{
+ return new NetworkThread<Session>[GetNetworkThreadCount()];
+}
+
+void Battlenet::SessionManager::OnSocketAccept(tcp::socket&& sock)
+{
+ sSessionMgr.OnSocketOpen(std::forward<tcp::socket>(sock));
+}
+
+void Battlenet::SessionManager::AddSession(Session* session)
+{
+ std::unique_lock<boost::shared_mutex> lock(_sessionMutex);
+ _sessions[{ session->GetAccountId(), session->GetGameAccountId() }] = session;
+ _sessionsByAccountId[session->GetAccountId()].push_back(session);
+}
+
+void Battlenet::SessionManager::RemoveSession(Session* session)
+{
+ std::unique_lock<boost::shared_mutex> lock(_sessionMutex);
+ _sessions.erase({ session->GetAccountId(), session->GetGameAccountId() });
+ _sessionsByAccountId[session->GetAccountId()].remove(session);
+}
+
+Battlenet::Session* Battlenet::SessionManager::GetSession(uint32 accountId, uint32 gameAccountId) const
+{
+ auto itr = _sessions.find({ accountId, gameAccountId });
+ if (itr != _sessions.end())
+ return itr->second;
+
+ return nullptr;
+}
+
+std::list<Battlenet::Session*> Battlenet::SessionManager::GetSessions(uint32 accountId) const
+{
+ std::list<Session*> sessions;
+ auto itr = _sessionsByAccountId.find(accountId);
+ if (itr != _sessionsByAccountId.end())
+ sessions = itr->second;
+
+ return sessions;
+}
diff --git a/src/server/authserver/Server/BattlenetSessionManager.h b/src/server/bnetserver/Server/SessionManager.h
index b5a54438ef1..08ca5ce2b4e 100644
--- a/src/server/authserver/Server/BattlenetSessionManager.h
+++ b/src/server/bnetserver/Server/SessionManager.h
@@ -15,11 +15,13 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef BattlenetSessionManager_h__
-#define BattlenetSessionManager_h__
+#ifndef SessionManager_h__
+#define SessionManager_h__
-#include "BattlenetSession.h"
+#include "Session.h"
#include "SocketMgr.h"
+#include <boost/thread/locks.hpp>
+#include <boost/thread/shared_mutex.hpp>
namespace Battlenet
{
@@ -28,7 +30,7 @@ namespace Battlenet
struct SessionInfo
{
uint32 AccountId;
- uint32 GameAccountIndex;
+ uint32 GameAccountId;
bool operator<(SessionInfo const& right) const
{
@@ -41,6 +43,8 @@ namespace Battlenet
class SessionManager : SocketMgr<Session>
{
typedef SocketMgr<Session> BaseSocketMgr;
+ typedef std::map<SessionInfo, Session*> SessionMap;
+ typedef std::map<uint32, std::list<Session*>> SessionByAccountMap;
public:
static SessionManager& Instance()
@@ -52,9 +56,20 @@ namespace Battlenet
bool StartNetwork(boost::asio::io_service& service, std::string const& bindIp, uint16 port) override;
// noop for now, will be needed later to broadcast realmlist updates for example
- void AddSession(Session* /*session*/) { }
+ void AddSession(Session* /*session*/);
- void RemoveSession(Session* /*session*/) { }
+ void RemoveSession(Session* /*session*/);
+
+ Session* GetSession(uint32 accountId, uint32 gameAccountId) const;
+ std::list<Session*> GetSessions(uint32 accountId) const;
+
+ template<typename Iterator>
+ void LockedForEach(Iterator iterator)
+ {
+ boost::shared_lock<boost::shared_mutex> lock(_sessionMutex);
+ for (SessionMap::value_type const& pair : _sessions)
+ iterator(pair.second);
+ }
protected:
NetworkThread<Session>* CreateThreads() const override;
@@ -62,10 +77,12 @@ namespace Battlenet
private:
static void OnSocketAccept(tcp::socket&& sock);
- std::map<SessionInfo, Session> _sessions;
+ SessionMap _sessions;
+ SessionByAccountMap _sessionsByAccountId;
+ boost::shared_mutex _sessionMutex;
};
}
-#define sBattlenetSessionMgr Battlenet::SessionManager::Instance()
+#define sSessionMgr Battlenet::SessionManager::Instance()
-#endif // BattlenetSessionManager_h__
+#endif // SessionManager_h__
diff --git a/src/server/bnetserver/bnetserver.conf.dist b/src/server/bnetserver/bnetserver.conf.dist
new file mode 100644
index 00000000000..102ddb9906a
--- /dev/null
+++ b/src/server/bnetserver/bnetserver.conf.dist
@@ -0,0 +1,260 @@
+###############################################
+# Trinity Core Auth Server configuration file #
+###############################################
+[authserver]
+
+###################################################################################################
+# SECTION INDEX
+#
+# EXAMPLE CONFIG
+# AUTH SERVER SETTINGS
+# MYSQL SETTINGS
+# LOGGING SYSTEM SETTINGS
+#
+###################################################################################################
+
+###################################################################################################
+# EXAMPLE CONFIG
+#
+# Variable
+# Description: Brief description what the variable is doing.
+# Important: Annotation for important things about this variable.
+# Example: "Example, i.e. if the value is a string"
+# Default: 10 - (Enabled|Comment|Variable name in case of grouped config options)
+# 0 - (Disabled|Comment|Variable name in case of grouped config options)
+#
+# Note to developers:
+# - Copy this example to keep the formatting.
+# - Line breaks should be at column 100.
+###################################################################################################
+
+###################################################################################################
+# AUTH SERVER SETTINGS
+#
+# LogsDir
+# Description: Logs directory setting.
+# Important: LogsDir needs to be quoted, as the string might contain space characters.
+# Logs directory must exists, or log file creation will be disabled.
+# Default: "" - (Log files will be stored in the current path)
+
+LogsDir = ""
+
+#
+# MaxPingTime
+# Description: Time (in minutes) between database pings.
+# Default: 30
+
+MaxPingTime = 30
+
+#
+# WorldserverListenPort
+# Description: TCP port to listen on for incoming worldserver IPC.
+# Default: 1118
+
+WorldserverListenPort = 1118
+
+#
+# BattlenetPort
+# Description: TCP port to reach the auth server for battle.net connections.
+# Default: 1119
+
+BattlenetPort = 1119
+
+#
+#
+# BindIP
+# Description: Bind auth server to IP/hostname
+# Default: "0.0.0.0" - (Bind to all IPs on the system)
+
+BindIP = "0.0.0.0"
+
+#
+# PidFile
+# Description: Auth server PID file.
+# Example: "./authserver.pid" - (Enabled)
+# Default: "" - (Disabled)
+
+PidFile = ""
+
+#
+# UseProcessors
+# Description: Processors mask for Windows and Linux based multi-processor systems.
+# Example: A computer with 2 CPUs:
+# 1 - 1st CPU only, 2 - 2nd CPU only, 3 - 1st and 2nd CPU, because 1 | 2 is 3
+# Default: 0 - (Selected by OS)
+# 1+ - (Bit mask value of selected processors)
+
+UseProcessors = 0
+
+#
+# ProcessPriority
+# Description: Process priority setting for Windows and Linux based systems.
+# Details: On Linux, a nice value of -15 is used. (requires superuser). On Windows, process is set to HIGH class.
+# Default: 0 - (Normal)
+# 1 - (High)
+
+ProcessPriority = 0
+
+#
+# RealmsStateUpdateDelay
+# Description: Time (in seconds) between realm list updates.
+# Default: 10
+# 0 - (Disabled)
+
+RealmsStateUpdateDelay = 10
+
+#
+# WrongPass.MaxCount
+# Description: Number of login attemps with wrong password before the account or IP will be
+# banned.
+# Default: 0 - (Disabled)
+# 1+ - (Enabled)
+
+WrongPass.MaxCount = 0
+
+#
+# WrongPass.BanTime
+# Description: Time (in seconds) for banning account or IP for invalid login attempts.
+# Default: 600 - (10 minutes)
+# 0 - (Permanent ban)
+
+WrongPass.BanTime = 600
+
+#
+# WrongPass.BanType
+# Description: Ban type for invalid login attempts.
+# Default: 0 - (Ban IP)
+# 1 - (Ban Account)
+
+WrongPass.BanType = 0
+
+#
+###################################################################################################
+
+###################################################################################################
+# MYSQL SETTINGS
+#
+# LoginDatabaseInfo
+# Description: Database connection settings for the realm server.
+# Example: "hostname;port;username;password;database"
+# ".;somenumber;username;password;database" - (Use named pipes on Windows
+# "enable-named-pipe" to [mysqld]
+# section my.ini)
+# ".;/path/to/unix_socket;username;password;database" - (use Unix sockets on
+# Unix/Linux)
+# Default: "127.0.0.1;3306;trinity;trinity;auth"
+
+LoginDatabaseInfo = "127.0.0.1;3306;trinity;trinity;auth"
+
+#
+# LoginDatabase.WorkerThreads
+# Description: The amount of worker threads spawned to handle asynchronous (delayed) MySQL
+# statements. Each worker thread is mirrored with its own connection to the
+# Default: 1
+
+LoginDatabase.WorkerThreads = 1
+
+#
+# Wrong.Password.Login.Logging
+# Description: Additionally log attempted wrong password logging
+# Default: 0 - (Disabled)
+# 1 - (Enabled)
+
+Wrong.Password.Login.Logging = 0
+#
+###################################################################################################
+
+###################################################################################################
+#
+# LOGGING SYSTEM SETTINGS
+#
+# Appender config values: Given a appender "name"
+# Appender.name
+# Description: Defines 'where to log'
+# Format: Type,LogLevel,Flags,optional1,optional2,optional3
+#
+# Type
+# 0 - (None)
+# 1 - (Console)
+# 2 - (File)
+# 3 - (DB)
+#
+# LogLevel
+# 0 - (Disabled)
+# 1 - (Trace)
+# 2 - (Debug)
+# 3 - (Info)
+# 4 - (Warn)
+# 5 - (Error)
+# 6 - (Fatal)
+#
+# Flags:
+# 0 - None
+# 1 - Prefix Timestamp to the text
+# 2 - Prefix Log Level to the text
+# 4 - Prefix Log Filter type to the text
+# 8 - Append timestamp to the log file name. Format: YYYY-MM-DD_HH-MM-SS (Only used with Type = 2)
+# 16 - Make a backup of existing file before overwrite (Only used with Mode = w)
+#
+# Colors (read as optional1 if Type = Console)
+# Format: "fatal error warn info debug trace"
+# 0 - BLACK
+# 1 - RED
+# 2 - GREEN
+# 3 - BROWN
+# 4 - BLUE
+# 5 - MAGENTA
+# 6 - CYAN
+# 7 - GREY
+# 8 - YELLOW
+# 9 - LRED
+# 10 - LGREEN
+# 11 - LBLUE
+# 12 - LMAGENTA
+# 13 - LCYAN
+# 14 - WHITE
+# Example: "13 11 9 5 3 1"
+#
+# File: Name of the file (read as optional1 if Type = File)
+# Allows to use one "%s" to create dynamic files
+#
+# Mode: Mode to open the file (read as optional2 if Type = File)
+# a - (Append)
+# w - (Overwrite)
+#
+# MaxFileSize: Maximum file size of the log file before creating a new log file
+# (read as optional3 if Type = File)
+# Size is measured in bytes expressed in a 64-bit unsigned integer.
+# Maximum value is 4294967295 (4 gb). Leave blank for no limit.
+# NOTE: Does not work with dynamic filenames.
+# Example: 536870912 (512 mb)
+#
+
+Appender.Console=1,2,0
+Appender.Bnet=2,2,0,Bnet.log,w
+
+# Logger config values: Given a logger "name"
+# Logger.name
+# Description: Defines 'What to log'
+# Format: LogLevel,AppenderList
+#
+# LogLevel
+# 0 - (Disabled)
+# 1 - (Trace)
+# 2 - (Debug)
+# 3 - (Info)
+# 4 - (Warn)
+# 5 - (Error)
+# 6 - (Fatal)
+#
+# AppenderList: List of appenders linked to logger
+# (Using spaces as separator).
+#
+
+Logger.root=3,Console Bnet
+Logger.realmlist=3,Console Bnet
+Logger.session=3,Console Bnet
+Logger.session.packets=3,Console Bnet
+
+#
+###################################################################################################
diff --git a/src/server/bnetserver/bnetserver.ico b/src/server/bnetserver/bnetserver.ico
new file mode 100644
index 00000000000..da318f48a8c
--- /dev/null
+++ b/src/server/bnetserver/bnetserver.ico
Binary files differ
diff --git a/src/server/bnetserver/bnetserver.rc b/src/server/bnetserver/bnetserver.rc
new file mode 100644
index 00000000000..f030203fdcd
--- /dev/null
+++ b/src/server/bnetserver/bnetserver.rc
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "resource.h"
+#include "revision.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "windows.h" //"afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Icon
+//
+
+// Icon with lowest ID value placed first to ensure application icon
+// remains consistent on all systems.
+IDI_APPICON ICON "bnetserver.ico"
+
+/////////////////////////////////////////////////////////////////////////////
+// Neutre (Par défaut système) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_NEUSD)
+#ifdef _WIN32
+LANGUAGE LANG_NEUTRAL, SUBLANG_SYS_DEFAULT
+#pragma code_page(1252)
+#endif //_WIN32
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+FILEVERSION VER_FILEVERSION
+PRODUCTVERSION VER_PRODUCTVERSION
+
+FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
+
+#ifndef _DEBUG
+ FILEFLAGS 0
+#else
+ #define VER_PRERELEASE VS_FF_PRERELEASE
+ #define VER_PRIVATEBUILD VS_FF_PRIVATEBUILD
+ #define VER_DEBUG 0
+ FILEFLAGS (VER_PRIVATEBUILD|VER_PRERELEASE|VER_DEBUG)
+#endif
+
+FILEOS VOS_NT_WINDOWS32
+FILETYPE VFT_APP
+
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "080004b0"
+ BEGIN
+ VALUE "CompanyName", VER_COMPANYNAME_STR
+ VALUE "FileDescription", "TrinityCore Battle.net Server Daemon"
+ VALUE "FileVersion", VER_FILEVERSION_STR
+ VALUE "InternalName", "bnetserver"
+ VALUE "LegalCopyright", VER_LEGALCOPYRIGHT_STR
+ VALUE "OriginalFilename", "bnetserver.exe"
+ VALUE "ProductName", "TrinityCore Battle.net Server"
+ VALUE "ProductVersion", VER_PRODUCTVERSION_STR
+ END
+ END
+
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x800, 1200
+ END
+END
+#endif
diff --git a/src/server/bnetserver/resource.h b/src/server/bnetserver/resource.h
new file mode 100644
index 00000000000..7dc5cb9ef7b
--- /dev/null
+++ b/src/server/bnetserver/resource.h
@@ -0,0 +1,15 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by TrinityCore.rc
+//
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 101
+#define _APS_NEXT_COMMAND_VALUE 40001
+#define _APS_NEXT_CONTROL_VALUE 1000
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/src/server/collision/CMakeLists.txt b/src/server/collision/CMakeLists.txt
index 1c5fcbee52e..3aac255be29 100644
--- a/src/server/collision/CMakeLists.txt
+++ b/src/server/collision/CMakeLists.txt
@@ -47,6 +47,7 @@ include_directories(
${CMAKE_SOURCE_DIR}/src/server/shared/Packets
${CMAKE_SOURCE_DIR}/src/server/shared/Utilities
${CMAKE_SOURCE_DIR}/src/server/shared/DataStores
+ ${CMAKE_SOURCE_DIR}/src/server/ipc
${CMAKE_SOURCE_DIR}/src/server/game/Addons
${CMAKE_SOURCE_DIR}/src/server/game/Conditions
${CMAKE_SOURCE_DIR}/src/server/game/Entities/Item
diff --git a/src/server/collision/Management/MMapFactory.cpp b/src/server/collision/Management/MMapFactory.cpp
index b08cd92d638..51f016f6e96 100644
--- a/src/server/collision/Management/MMapFactory.cpp
+++ b/src/server/collision/Management/MMapFactory.cpp
@@ -17,9 +17,7 @@
*/
#include "MMapFactory.h"
-#include "World.h"
#include "Config.h"
-#include "DisableMgr.h"
namespace MMAP
{
@@ -35,12 +33,6 @@ namespace MMAP
return g_MMapManager;
}
- bool MMapFactory::IsPathfindingEnabled(uint32 mapId)
- {
- return sWorld->getBoolConfig(CONFIG_ENABLE_MMAPS)
- && !DisableMgr::IsDisabledFor(DISABLE_TYPE_MMAP, mapId, NULL, MMAP_DISABLE_PATHFINDING);
- }
-
void MMapFactory::clear()
{
if (g_MMapManager)
diff --git a/src/server/collision/Management/VMapManager2.cpp b/src/server/collision/Management/VMapManager2.cpp
index 484fdcd8ea4..b9ac7e204da 100644
--- a/src/server/collision/Management/VMapManager2.cpp
+++ b/src/server/collision/Management/VMapManager2.cpp
@@ -25,10 +25,9 @@
#include "ModelInstance.h"
#include "WorldModel.h"
#include <G3D/Vector3.h>
-#include "DisableMgr.h"
-#include "DBCStores.h"
#include "Log.h"
#include "VMapDefinitions.h"
+#include "Errors.h"
using G3D::Vector3;
@@ -36,6 +35,8 @@ namespace VMAP
{
VMapManager2::VMapManager2()
{
+ GetLiquidFlagsPtr = &GetLiquidFlagsDummy;
+ IsVMAPDisabledForPtr = &IsVMAPDisabledForDummy;
}
VMapManager2::~VMapManager2(void)
@@ -134,7 +135,7 @@ namespace VMAP
bool VMapManager2::isInLineOfSight(unsigned int mapId, float x1, float y1, float z1, float x2, float y2, float z2)
{
- if (!isLineOfSightCalcEnabled() || DisableMgr::IsDisabledFor(DISABLE_TYPE_VMAP, mapId, NULL, VMAP_DISABLE_LOS))
+ if (!isLineOfSightCalcEnabled() || IsVMAPDisabledForPtr(mapId, VMAP_DISABLE_LOS))
return true;
InstanceTreeMap::iterator instanceTree = iInstanceMapTrees.find(mapId);
@@ -157,7 +158,7 @@ namespace VMAP
*/
bool VMapManager2::getObjectHitPos(unsigned int mapId, float x1, float y1, float z1, float x2, float y2, float z2, float& rx, float &ry, float& rz, float modifyDist)
{
- if (isLineOfSightCalcEnabled() && !DisableMgr::IsDisabledFor(DISABLE_TYPE_VMAP, mapId, NULL, VMAP_DISABLE_LOS))
+ if (isLineOfSightCalcEnabled() && !IsVMAPDisabledForPtr(mapId, VMAP_DISABLE_LOS))
{
InstanceTreeMap::iterator instanceTree = iInstanceMapTrees.find(mapId);
if (instanceTree != iInstanceMapTrees.end())
@@ -187,7 +188,7 @@ namespace VMAP
float VMapManager2::getHeight(unsigned int mapId, float x, float y, float z, float maxSearchDist)
{
- if (isHeightCalcEnabled() && !DisableMgr::IsDisabledFor(DISABLE_TYPE_VMAP, mapId, NULL, VMAP_DISABLE_HEIGHT))
+ if (isHeightCalcEnabled() && !IsVMAPDisabledForPtr(mapId, VMAP_DISABLE_HEIGHT))
{
InstanceTreeMap::iterator instanceTree = iInstanceMapTrees.find(mapId);
if (instanceTree != iInstanceMapTrees.end())
@@ -206,7 +207,7 @@ namespace VMAP
bool VMapManager2::getAreaInfo(unsigned int mapId, float x, float y, float& z, uint32& flags, int32& adtId, int32& rootId, int32& groupId) const
{
- if (!DisableMgr::IsDisabledFor(DISABLE_TYPE_VMAP, mapId, NULL, VMAP_DISABLE_AREAFLAG))
+ if (!IsVMAPDisabledForPtr(mapId, VMAP_DISABLE_AREAFLAG))
{
InstanceTreeMap::const_iterator instanceTree = iInstanceMapTrees.find(mapId);
if (instanceTree != iInstanceMapTrees.end())
@@ -224,7 +225,7 @@ namespace VMAP
bool VMapManager2::GetLiquidLevel(uint32 mapId, float x, float y, float z, uint8 reqLiquidType, float& level, float& floor, uint32& type) const
{
- if (!DisableMgr::IsDisabledFor(DISABLE_TYPE_VMAP, mapId, NULL, VMAP_DISABLE_LIQUIDSTATUS))
+ if (!IsVMAPDisabledForPtr(mapId, VMAP_DISABLE_LIQUIDSTATUS))
{
InstanceTreeMap::const_iterator instanceTree = iInstanceMapTrees.find(mapId);
if (instanceTree != iInstanceMapTrees.end())
@@ -236,7 +237,7 @@ namespace VMAP
floor = info.ground_Z;
ASSERT(floor < std::numeric_limits<float>::max());
type = info.hitModel->GetLiquidType(); // entry from LiquidType.dbc
- if (reqLiquidType && !(GetLiquidFlags(type) & reqLiquidType))
+ if (reqLiquidType && !(GetLiquidFlagsPtr(type) & reqLiquidType))
return false;
if (info.hitInstance->GetLiquidLevel(pos, info, level))
return true;
diff --git a/src/server/collision/Management/VMapManager2.h b/src/server/collision/Management/VMapManager2.h
index 04292e7d8e4..9c419270b5a 100644
--- a/src/server/collision/Management/VMapManager2.h
+++ b/src/server/collision/Management/VMapManager2.h
@@ -66,6 +66,14 @@ namespace VMAP
typedef std::unordered_map<uint32, StaticMapTree*> InstanceTreeMap;
typedef std::unordered_map<std::string, ManagedModel> ModelFileMap;
+ enum DisableTypes
+ {
+ VMAP_DISABLE_AREAFLAG = 0x1,
+ VMAP_DISABLE_HEIGHT = 0x2,
+ VMAP_DISABLE_LOS = 0x4,
+ VMAP_DISABLE_LIQUIDSTATUS = 0x8
+ };
+
class VMapManager2 : public IVMapManager
{
protected:
@@ -78,6 +86,9 @@ namespace VMAP
bool _loadMap(uint32 mapId, const std::string& basePath, uint32 tileX, uint32 tileY);
/* void _unloadMap(uint32 pMapId, uint32 x, uint32 y); */
+ static uint32 GetLiquidFlagsDummy(uint32) { return 0; }
+ static bool IsVMAPDisabledForDummy(uint32 /*entry*/, uint8 /*flags*/) { return false; }
+
public:
// public for debug
G3D::Vector3 convertPositionToInternalRep(float x, float y, float z) const;
@@ -114,6 +125,12 @@ namespace VMAP
virtual bool existsMap(const char* basePath, unsigned int mapId, int x, int y) override;
public:
void getInstanceMapTree(InstanceTreeMap &instanceMapTree);
+
+ typedef uint32(*GetLiquidFlagsFn)(uint32 liquidType);
+ GetLiquidFlagsFn GetLiquidFlagsPtr;
+
+ typedef bool(*IsVMAPDisabledForFn)(uint32 entry, uint8 flags);
+ IsVMAPDisabledForFn IsVMAPDisabledForPtr;
};
}
diff --git a/src/server/game/AI/SmartScripts/SmartScript.cpp b/src/server/game/AI/SmartScripts/SmartScript.cpp
index fb3bbd17a69..ccfeb61206f 100644
--- a/src/server/game/AI/SmartScripts/SmartScript.cpp
+++ b/src/server/game/AI/SmartScripts/SmartScript.cpp
@@ -83,13 +83,13 @@ void SmartScript::ProcessEventsFor(SMART_EVENT e, Unit* unit, uint32 var0, uint3
{
for (SmartAIEventList::iterator i = mEvents.begin(); i != mEvents.end(); ++i)
{
- SMART_EVENT eventType = SMART_EVENT((*i).GetEventType());
+ SMART_EVENT eventType = SMART_EVENT(i->GetEventType());
if (eventType == SMART_EVENT_LINK)//special handling
continue;
- if (eventType == e/* && (!(*i).event.event_phase_mask || IsInPhase((*i).event.event_phase_mask)) && !((*i).event.event_flags & SMART_EVENT_FLAG_NOT_REPEATABLE && (*i).runOnce)*/)
+ if (eventType == e /*&& (!i->event.event_phase_mask || IsInPhase(i->event.event_phase_mask)) && !(i->event.event_flags & SMART_EVENT_FLAG_NOT_REPEATABLE && i->runOnce)*/)
{
- ConditionList conds = sConditionMgr->GetConditionsForSmartEvent((*i).entryOrGuid, (*i).event_id, (*i).source_type);
+ ConditionList conds = sConditionMgr->GetConditionsForSmartEvent(i->entryOrGuid, i->event_id, i->source_type);
ConditionSourceInfo info = ConditionSourceInfo(unit, GetBaseObject());
if (sConditionMgr->IsObjectMeetToConditions(info, conds))
@@ -167,7 +167,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
{
if (IsCreature(*itr))
- sCreatureTextMgr->SendChat((*itr)->ToCreature(), uint8(e.action.talk.textGroupID), IsPlayer(GetLastInvoker())? GetLastInvoker() : 0);
+ sCreatureTextMgr->SendChat((*itr)->ToCreature(), uint8(e.action.talk.textGroupID), IsPlayer(GetLastInvoker()) ? GetLastInvoker() : 0);
else if (IsPlayer(*itr) && me)
{
Unit* templastInvoker = GetLastInvoker();
@@ -2262,8 +2262,8 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
if (e.link && e.link != e.event_id)
{
- SmartScriptHolder linked = FindLinkedEvent(e.link);
- if (linked.GetActionType() && linked.GetEventType() == SMART_EVENT_LINK)
+ SmartScriptHolder& linked = SmartAIMgr::FindLinkedEvent(mEvents, e.link);
+ if (linked)
ProcessEvent(linked, unit, var0, var1, bvar, spell, gob);
else
TC_LOG_ERROR("sql.sql", "SmartScript::ProcessAction: Entry %d SourceType %u, Event %u, Link Event %u not found or invalid, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.link);
@@ -2468,10 +2468,10 @@ ObjectList* SmartScript::GetTargets(SmartScriptHolder const& e, Unit* invoker /*
if (!IsCreature(*itr))
continue;
- if (me && me == *itr)
+ if (me && me->GetGUID() == (*itr)->GetGUID())
continue;
- if (((e.target.unitRange.creature && (*itr)->ToCreature()->GetEntry() == e.target.unitRange.creature) || !e.target.unitRange.creature) && baseObject->IsInRange(*itr, (float)e.target.unitRange.minDist, (float)e.target.unitRange.maxDist))
+ if ((!e.target.unitRange.creature || (*itr)->ToCreature()->GetEntry() == e.target.unitRange.creature) && baseObject->IsInRange(*itr, float(e.target.unitRange.minDist), float(e.target.unitRange.maxDist)))
l->push_back(*itr);
}
@@ -2487,10 +2487,10 @@ ObjectList* SmartScript::GetTargets(SmartScriptHolder const& e, Unit* invoker /*
if (!IsCreature(*itr))
continue;
- if (me && me == *itr)
+ if (me && me->GetGUID() == (*itr)->GetGUID())
continue;
- if ((e.target.unitDistance.creature && (*itr)->ToCreature()->GetEntry() == e.target.unitDistance.creature) || !e.target.unitDistance.creature)
+ if (!e.target.unitDistance.creature || (*itr)->ToCreature()->GetEntry() == e.target.unitDistance.creature)
l->push_back(*itr);
}
@@ -2506,10 +2506,10 @@ ObjectList* SmartScript::GetTargets(SmartScriptHolder const& e, Unit* invoker /*
if (!IsGameObject(*itr))
continue;
- if (go && go == *itr)
+ if (go && go->GetGUID() == (*itr)->GetGUID())
continue;
- if ((e.target.goDistance.entry && (*itr)->ToGameObject()->GetEntry() == e.target.goDistance.entry) || !e.target.goDistance.entry)
+ if (!e.target.goDistance.entry || (*itr)->ToGameObject()->GetEntry() == e.target.goDistance.entry)
l->push_back(*itr);
}
@@ -2525,10 +2525,10 @@ ObjectList* SmartScript::GetTargets(SmartScriptHolder const& e, Unit* invoker /*
if (!IsGameObject(*itr))
continue;
- if (go && go == *itr)
+ if (go && go->GetGUID() == (*itr)->GetGUID())
continue;
- if (((e.target.goRange.entry && IsGameObject(*itr) && (*itr)->ToGameObject()->GetEntry() == e.target.goRange.entry) || !e.target.goRange.entry) && baseObject->IsInRange((*itr), (float)e.target.goRange.minDist, (float)e.target.goRange.maxDist))
+ if ((!e.target.goRange.entry && (*itr)->ToGameObject()->GetEntry() == e.target.goRange.entry) && baseObject->IsInRange(*itr, float(e.target.goRange.minDist), float(e.target.goRange.maxDist)))
l->push_back(*itr);
}
@@ -2537,32 +2537,28 @@ ObjectList* SmartScript::GetTargets(SmartScriptHolder const& e, Unit* invoker /*
}
case SMART_TARGET_CREATURE_GUID:
{
- Creature* target = NULL;
if (!scriptTrigger && !baseObject)
{
TC_LOG_ERROR("sql.sql", "SMART_TARGET_CREATURE_GUID can not be used without invoker");
break;
}
- target = FindCreatureNear(scriptTrigger ? scriptTrigger : baseObject, e.target.unitGUID.dbGuid);
-
- if (target && (!e.target.unitGUID.entry || target->GetEntry() == e.target.unitGUID.entry))
- l->push_back(target);
+ if (Creature* target = FindCreatureNear(scriptTrigger ? scriptTrigger : baseObject, e.target.unitGUID.dbGuid))
+ if (!e.target.unitGUID.entry || target->GetEntry() == e.target.unitGUID.entry)
+ l->push_back(target);
break;
}
case SMART_TARGET_GAMEOBJECT_GUID:
{
- GameObject* target = NULL;
if (!scriptTrigger && !baseObject)
{
TC_LOG_ERROR("sql.sql", "SMART_TARGET_GAMEOBJECT_GUID can not be used without invoker");
break;
}
- target = FindGameObjectNear(scriptTrigger ? scriptTrigger : baseObject, e.target.goGUID.dbGuid);
-
- if (target && (!e.target.goGUID.entry || target->GetEntry() == e.target.goGUID.entry))
- l->push_back(target);
+ if (GameObject* target = FindGameObjectNear(scriptTrigger ? scriptTrigger : baseObject, e.target.goGUID.dbGuid))
+ if (!e.target.goGUID.entry || target->GetEntry() == e.target.goGUID.entry)
+ l->push_back(target);
break;
}
case SMART_TARGET_PLAYER_RANGE:
@@ -2601,26 +2597,21 @@ ObjectList* SmartScript::GetTargets(SmartScriptHolder const& e, Unit* invoker /*
}
case SMART_TARGET_CLOSEST_CREATURE:
{
- Creature* target = GetClosestCreatureWithEntry(baseObject, e.target.closest.entry, (float)(e.target.closest.dist ? e.target.closest.dist : 100), !e.target.closest.dead);
- if (target)
+ if (Creature* target = GetClosestCreatureWithEntry(baseObject, e.target.closest.entry, float(e.target.closest.dist ? e.target.closest.dist : 100), !e.target.closest.dead))
l->push_back(target);
break;
}
case SMART_TARGET_CLOSEST_GAMEOBJECT:
{
- GameObject* target = GetClosestGameObjectWithEntry(baseObject, e.target.closest.entry, (float)(e.target.closest.dist ? e.target.closest.dist : 100));
- if (target)
+ if (GameObject* target = GetClosestGameObjectWithEntry(baseObject, e.target.closest.entry, float(e.target.closest.dist ? e.target.closest.dist : 100)))
l->push_back(target);
break;
}
case SMART_TARGET_CLOSEST_PLAYER:
{
if (me)
- {
- Player* target = me->SelectNearestPlayer((float)e.target.playerDistance.dist);
- if (target)
+ if (Player* target = me->SelectNearestPlayer(float(e.target.playerDistance.dist)))
l->push_back(target);
- }
break;
}
case SMART_TARGET_OWNER_OR_SUMMONER:
@@ -2653,7 +2644,6 @@ ObjectList* SmartScript::GetTargets(SmartScriptHolder const& e, Unit* invoker /*
if (me)
if (Unit* target = me->SelectNearestTarget(e.target.closestAttackable.maxDist, e.target.closestAttackable.playerOnly != 0))
l->push_back(target);
-
break;
}
case SMART_TARGET_CLOSEST_FRIENDLY:
@@ -2661,7 +2651,6 @@ ObjectList* SmartScript::GetTargets(SmartScriptHolder const& e, Unit* invoker /*
if (me)
if (Unit* target = DoFindClosestFriendlyInRange(e.target.closestFriendly.maxDist, e.target.closestFriendly.playerOnly != 0))
l->push_back(target);
-
break;
}
case SMART_TARGET_POSITION:
diff --git a/src/server/game/AI/SmartScripts/SmartScript.h b/src/server/game/AI/SmartScripts/SmartScript.h
index 02bc1a2b487..b59b62c5697 100644
--- a/src/server/game/AI/SmartScripts/SmartScript.h
+++ b/src/server/game/AI/SmartScripts/SmartScript.h
@@ -257,21 +257,6 @@ class SmartScript
}
}
}
- SmartScriptHolder FindLinkedEvent(uint32 link)
- {
- if (!mEvents.empty())
- {
- for (SmartAIEventList::iterator i = mEvents.begin(); i != mEvents.end(); ++i)
- {
- if (i->event_id == link)
- {
- return (*i);
- }
- }
- }
- SmartScriptHolder s;
- return s;
- }
};
#endif
diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp
index 2a7fd1369e2..0b2fdfc6bee 100644
--- a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp
+++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp
@@ -91,7 +91,6 @@ void SmartWaypointMgr::LoadFromDB()
while (result->NextRow());
TC_LOG_INFO("server.loading", ">> Loaded %u SmartAI waypoint paths (total %u waypoints) in %u ms", count, total, GetMSTimeDiffToNow(oldMSTime));
-
}
SmartWaypointMgr::~SmartWaypointMgr()
@@ -192,23 +191,23 @@ void SmartAIMgr::LoadSmartAIFromDB()
}
else
{
- CreatureData const* creature = sObjectMgr->GetCreatureData(uint32(abs(temp.entryOrGuid)));
+ CreatureData const* creature = sObjectMgr->GetCreatureData(uint32(std::abs(temp.entryOrGuid)));
if (!creature)
{
- TC_LOG_ERROR("sql.sql", "SmartAIMgr::LoadSmartAIFromDB: Creature guid (%u) does not exist, skipped loading.", uint32(abs(temp.entryOrGuid)));
+ TC_LOG_ERROR("sql.sql", "SmartAIMgr::LoadSmartAIFromDB: Creature guid (%u) does not exist, skipped loading.", uint32(std::abs(temp.entryOrGuid)));
continue;
}
CreatureTemplate const* creatureInfo = sObjectMgr->GetCreatureTemplate(creature->id);
if (!creatureInfo)
{
- TC_LOG_ERROR("sql.sql", "SmartAIMgr::LoadSmartAIFromDB: Creature entry (%u) does not exist, skipped loading.", uint32(temp.entryOrGuid));
+ TC_LOG_ERROR("sql.sql", "SmartAIMgr::LoadSmartAIFromDB: Creature entry (%u) guid (%u) does not exist, skipped loading.", creature->id, uint32(std::abs(temp.entryOrGuid)));
continue;
}
if (creatureInfo->AIName != "SmartAI")
{
- TC_LOG_ERROR("sql.sql", "SmartAIMgr::LoadSmartAIFromDB: Creature entry (%u) is not using SmartAI, skipped loading.", uint32(temp.entryOrGuid));
+ TC_LOG_ERROR("sql.sql", "SmartAIMgr::LoadSmartAIFromDB: Creature entry (%u) guid (%u) is not using SmartAI, skipped loading.", creature->id, uint32(std::abs(temp.entryOrGuid)));
continue;
}
}
@@ -263,26 +262,29 @@ void SmartAIMgr::LoadSmartAIFromDB()
}
while (result->NextRow());
- // TO-DO: Find better way
- for (uint8 i = 0; i < SMART_SCRIPT_TYPE_MAX; i++)
+ // Post Loading Validation
+ for (uint8 i = 0; i < SMART_SCRIPT_TYPE_MAX; ++i)
{
- for (auto itr = mEventMap[i].begin(); itr != mEventMap[i].end(); ++itr)
+ for (SmartAIEventMap::iterator itr = mEventMap[i].begin(); itr != mEventMap[i].end(); ++itr)
{
- for (auto e : mEventMap[i][itr->first])
+ for (SmartScriptHolder const& e : itr->second)
{
- bool found = false;
- if (e.link && e.link != e.event_id)
+ if (e.link)
{
- for (auto linked : mEventMap[i][itr->first])
+ if (!FindLinkedEvent(itr->second, e.link))
{
- if (linked.event_id == e.link)
- if (linked.GetActionType() && linked.GetEventType() == SMART_EVENT_LINK)
- found = true;
+ TC_LOG_ERROR("sql.sql", "SmartAIMgr::LoadSmartAIFromDB: Entry %d SourceType %u, Event %u, Link Event %u not found or invalid.",
+ e.entryOrGuid, e.GetScriptType(), e.event_id, e.link);
}
+ }
- if (!found)
- TC_LOG_ERROR("sql.sql", "SmartAIMgr::LoadSmartAIFromDB: Entry %d SourceType %u, Event %u, Link Event %u not found or invalid",
- e.entryOrGuid, e.GetScriptType(), e.event_id, e.link);
+ if (e.GetEventType() == SMART_EVENT_LINK)
+ {
+ if (!FindLinkedSourceEvent(itr->second, e.event_id))
+ {
+ TC_LOG_ERROR("sql.sql", "SmartAIMgr::LoadSmartAIFromDB: Entry %d SourceType %u, Event %u, Link Source Event not found or invalid. Event will never trigger.",
+ e.entryOrGuid, e.GetScriptType(), e.event_id);
+ }
}
}
}
@@ -295,8 +297,13 @@ void SmartAIMgr::LoadSmartAIFromDB()
bool SmartAIMgr::IsTargetValid(SmartScriptHolder const& e)
{
+ if (std::abs(e.target.o) > 2 * float(M_PI))
+ TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry %d SourceType %u Event %u Action %u has abs(`target.o` = %f) > 2*PI (orientation is expressed in radians)",
+ e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), e.target.o);
+
if (e.GetActionType() == SMART_ACTION_INSTALL_AI_TEMPLATE)
return true; // AI template has special handling
+
switch (e.GetTargetType())
{
case SMART_TARGET_CREATURE_DISTANCE:
@@ -375,27 +382,38 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e)
TC_LOG_ERROR("sql.sql", "SmartAIMgr: EntryOrGuid %d using event(%u) has invalid event type (%u), skipped.", e.entryOrGuid, e.event_id, e.GetEventType());
return false;
}
+
// in SMART_SCRIPT_TYPE_TIMED_ACTIONLIST all event types are overriden by core
if (e.GetScriptType() != SMART_SCRIPT_TYPE_TIMED_ACTIONLIST && !(SmartAIEventMask[e.event.type][1] & SmartAITypeMask[e.GetScriptType()][1]))
{
TC_LOG_ERROR("sql.sql", "SmartAIMgr: EntryOrGuid %d, event type %u can not be used for Script type %u", e.entryOrGuid, e.GetEventType(), e.GetScriptType());
return false;
}
+
if (e.action.type <= 0 || e.action.type >= SMART_ACTION_END)
{
TC_LOG_ERROR("sql.sql", "SmartAIMgr: EntryOrGuid %d using event(%u) has invalid action type (%u), skipped.", e.entryOrGuid, e.event_id, e.GetActionType());
return false;
}
+
if (e.event.event_phase_mask > SMART_EVENT_PHASE_ALL)
{
TC_LOG_ERROR("sql.sql", "SmartAIMgr: EntryOrGuid %d using event(%u) has invalid phase mask (%u), skipped.", e.entryOrGuid, e.event_id, e.event.event_phase_mask);
return false;
}
+
if (e.event.event_flags > SMART_EVENT_FLAGS_ALL)
{
TC_LOG_ERROR("sql.sql", "SmartAIMgr: EntryOrGuid %d using event(%u) has invalid event flags (%u), skipped.", e.entryOrGuid, e.event_id, e.event.event_flags);
return false;
}
+
+ if (e.link && e.link == e.event_id)
+ {
+ TC_LOG_ERROR("sql.sql", "SmartAIMgr: EntryOrGuid %d SourceType %u, Event %u, Event is linking self (infinite loop), skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id);
+ return false;
+ }
+
if (e.GetScriptType() == SMART_SCRIPT_TYPE_TIMED_ACTIONLIST)
{
e.event.type = SMART_EVENT_UPDATE_OOC;//force default OOC, can change when calling the script!
@@ -407,8 +425,7 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e)
}
else
{
- uint32 type = e.event.type;
- switch (type)
+ switch (e.GetEventType())
{
case SMART_EVENT_UPDATE:
case SMART_EVENT_UPDATE_IC:
@@ -568,17 +585,9 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e)
break;
}
case SMART_EVENT_TEXT_OVER:
- //if (e.event.textOver.textGroupID && !IsTextValid(e, e.event.textOver.textGroupID)) return false;// 0 is a valid text group!
- break;
- case SMART_EVENT_LINK:
- {
- if (e.link && e.link == e.event_id)
- {
- TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry %d SourceType %u, Event %u, Link Event is linking self (infinite loop), skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id);
+ if (!IsTextValid(e, e.event.textOver.textGroupID))
return false;
- }
break;
- }
case SMART_EVENT_DUMMY_EFFECT:
{
if (!IsSpellValid(e, e.event.dummy.spell))
@@ -686,6 +695,7 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e)
return false;
}
break;
+ case SMART_EVENT_LINK:
case SMART_EVENT_GO_STATE_CHANGED:
case SMART_EVENT_GO_EVENT_INFORM:
case SMART_EVENT_TIMED_EVENT_TRIGGERED:
@@ -729,14 +739,10 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e)
switch (e.GetActionType())
{
case SMART_ACTION_TALK:
- {
- if (e.GetScriptType() == SMART_SCRIPT_TYPE_CREATURE)
- {
- if (!IsTextValid(e, e.action.talk.textGroupID))
- return false;
- }
+ case SMART_ACTION_SIMPLE_TALK:
+ if (!IsTextValid(e, e.action.talk.textGroupID))
+ return false;
break;
- }
case SMART_ACTION_SET_FACTION:
if (e.action.faction.factionID && !sFactionTemplateStore.LookupEntry(e.action.faction.factionID))
{
@@ -816,7 +822,7 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e)
if (!IsSpellValid(e, e.action.cast.spell))
return false;
- SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(e.action.cast.spell);
+ SpellInfo const* spellInfo = sSpellMgr->EnsureSpellInfo(e.action.cast.spell);
for (uint32 j = 0; j < MAX_SPELL_EFFECTS; ++j)
{
if (spellInfo->Effects[j].IsEffect(SPELL_EFFECT_KILL_CREDIT) || spellInfo->Effects[j].IsEffect(SPELL_EFFECT_KILL_CREDIT2))
@@ -979,10 +985,10 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e)
if (!NotNULL(e, e.action.item.count))
return false;
- CacheSpellContainerBounds sBounds = GetCreditItemSpellContainerBounds(e.action.item.entry);
+ CacheSpellContainerBounds sBounds = GetCreateItemSpellContainerBounds(e.action.item.entry);
for (CacheSpellContainer::const_iterator itr = sBounds.first; itr != sBounds.second; ++itr)
TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry %d SourceType %u Event %u Action %u Create Item: There is a create item spell for item %u (SpellId: %u effect: %u)",
- e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), e.action.item.entry, itr->second.first, itr->second.second);
+ e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), e.action.item.entry, itr->second.first, itr->second.second);
break;
}
case SMART_ACTION_TELEPORT:
@@ -1183,7 +1189,6 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e)
case SMART_ACTION_SET_NPC_FLAG:
case SMART_ACTION_ADD_NPC_FLAG:
case SMART_ACTION_REMOVE_NPC_FLAG:
- case SMART_ACTION_SIMPLE_TALK:
case SMART_ACTION_CROSS_CAST:
case SMART_ACTION_CALL_RANDOM_TIMED_ACTIONLIST:
case SMART_ACTION_RANDOM_MOVE:
@@ -1214,32 +1219,47 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e)
return true;
}
-bool SmartAIMgr::IsTextValid(SmartScriptHolder const& e, uint32 id) // unused
+bool SmartAIMgr::IsTextValid(SmartScriptHolder const& e, uint32 id)
{
- bool error = false;
+ if (e.GetScriptType() != SMART_SCRIPT_TYPE_CREATURE)
+ return true;
+
uint32 entry = 0;
- if (e.entryOrGuid >= 0)
- entry = uint32(e.entryOrGuid);
+ if (e.GetEventType() == SMART_EVENT_TEXT_OVER)
+ {
+ entry = e.event.textOver.creatureEntry;
+ }
else
{
- entry = uint32(abs(e.entryOrGuid));
- CreatureData const* data = sObjectMgr->GetCreatureData(entry);
- if (!data)
+ switch (e.GetTargetType())
{
- TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry %d SourceType %u Event %u Action %u using non-existent Creature guid %d, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), entry);
- return false;
+ case SMART_TARGET_CREATURE_DISTANCE:
+ case SMART_TARGET_CREATURE_RANGE:
+ case SMART_TARGET_CLOSEST_CREATURE:
+ return true; // ignore
+ default:
+ if (e.entryOrGuid < 0)
+ {
+ entry = uint32(std::abs(e.entryOrGuid));
+ CreatureData const* data = sObjectMgr->GetCreatureData(entry);
+ if (!data)
+ {
+ TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry %d SourceType %u Event %u Action %u using non-existent Creature guid %d, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), entry);
+ return false;
+ }
+ else
+ entry = data->id;
+ }
+ else
+ entry = uint32(e.entryOrGuid);
+ break;
}
- else
- entry = data->id;
}
if (!entry || !sCreatureTextMgr->TextExist(entry, uint8(id)))
- error = true;
-
- if (error)
{
- TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry %d SourceType %u Event %u Action %u using non-existent Text id %d, skipped.", e.entryOrGuid, e.GetScriptType(), e.source_type, e.GetActionType(), id);
+ TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry %d SourceType %u Event %u Action %u using non-existent Text id %d, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), id);
return false;
}
@@ -1299,7 +1319,7 @@ CacheSpellContainerBounds SmartAIMgr::GetKillCreditSpellContainerBounds(uint32 k
return KillCreditSpellStore.equal_range(killCredit);
}
-CacheSpellContainerBounds SmartAIMgr::GetCreditItemSpellContainerBounds(uint32 itemId) const
+CacheSpellContainerBounds SmartAIMgr::GetCreateItemSpellContainerBounds(uint32 itemId) const
{
return CreateItemSpellStore.equal_range(itemId);
}
diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.h b/src/server/game/AI/SmartScripts/SmartScriptMgr.h
index bdd1dfc6ae0..a567a4be35e 100644
--- a/src/server/game/AI/SmartScripts/SmartScriptMgr.h
+++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.h
@@ -1355,6 +1355,8 @@ struct SmartScriptHolder
bool active;
bool runOnce;
bool enableTimed;
+
+ operator bool() const { return entryOrGuid != 0; }
};
typedef std::unordered_map<uint32, WayPoint*> WPPath;
@@ -1477,6 +1479,30 @@ class SmartAIMgr
}
}
+ static SmartScriptHolder& FindLinkedSourceEvent(SmartAIEventList& list, uint32 eventId)
+ {
+ SmartAIEventList::iterator itr = std::find_if(list.begin(), list.end(),
+ [eventId](SmartScriptHolder& source) { return source.link == eventId; });
+
+ if (itr != list.end())
+ return *itr;
+
+ static SmartScriptHolder SmartScriptHolderDummy;
+ return SmartScriptHolderDummy;
+ }
+
+ static SmartScriptHolder& FindLinkedEvent(SmartAIEventList& list, uint32 link)
+ {
+ SmartAIEventList::iterator itr = std::find_if(list.begin(), list.end(),
+ [link](SmartScriptHolder& linked) { return linked.event_id == link && linked.GetEventType() == SMART_EVENT_LINK; });
+
+ if (itr != list.end())
+ return *itr;
+
+ static SmartScriptHolder SmartScriptHolderDummy;
+ return SmartScriptHolderDummy;
+ }
+
private:
//event stores
SmartAIEventMap mEventMap[SMART_SCRIPT_TYPE_MAX];
@@ -1484,16 +1510,6 @@ class SmartAIMgr
bool IsEventValid(SmartScriptHolder& e);
bool IsTargetValid(SmartScriptHolder const& e);
- /*inline bool IsTargetValid(SmartScriptHolder e, int32 target)
- {
- if (target < SMART_TARGET_NONE || target >= SMART_TARGET_END)
- {
- TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry %d SourceType %u Event %u Action %u uses invalid Target type %d, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), target);
- return false;
- }
- return true;
- }*/
-
bool IsMinMaxValid(SmartScriptHolder const& e, uint32 min, uint32 max)
{
if (max < min)
@@ -1623,7 +1639,7 @@ class SmartAIMgr
CacheSpellContainerBounds GetSummonCreatureSpellContainerBounds(uint32 creatureEntry) const;
CacheSpellContainerBounds GetSummonGameObjectSpellContainerBounds(uint32 gameObjectEntry) const;
CacheSpellContainerBounds GetKillCreditSpellContainerBounds(uint32 killCredit) const;
- CacheSpellContainerBounds GetCreditItemSpellContainerBounds(uint32 itemId) const;
+ CacheSpellContainerBounds GetCreateItemSpellContainerBounds(uint32 itemId) const;
CacheSpellContainer SummonCreatureSpellStore;
CacheSpellContainer SummonGameObjectSpellStore;
diff --git a/src/server/game/Accounts/AccountMgr.cpp b/src/server/game/Accounts/AccountMgr.cpp
index 682df18b2d1..4abcf35fe57 100644
--- a/src/server/game/Accounts/AccountMgr.cpp
+++ b/src/server/game/Accounts/AccountMgr.cpp
@@ -84,7 +84,7 @@ AccountOpResult AccountMgr::DeleteAccount(uint32 accountId)
ObjectGuid guid(HIGHGUID_PLAYER, (*result)[0].GetUInt32());
// Kick if player is online
- if (Player* p = ObjectAccessor::FindPlayer(guid))
+ if (Player* p = ObjectAccessor::FindConnectedPlayer(guid))
{
WorldSession* s = p->GetSession();
s->KickPlayer(); // mark session to remove at next session list update
diff --git a/src/server/game/AuctionHouse/AuctionHouseMgr.cpp b/src/server/game/AuctionHouse/AuctionHouseMgr.cpp
index 79512e57fe3..9390ec80208 100644
--- a/src/server/game/AuctionHouse/AuctionHouseMgr.cpp
+++ b/src/server/game/AuctionHouse/AuctionHouseMgr.cpp
@@ -93,7 +93,7 @@ void AuctionHouseMgr::SendAuctionWonMail(AuctionEntry* auction, SQLTransaction&
uint32 bidderAccId = 0;
ObjectGuid bidderGuid(HIGHGUID_PLAYER, auction->bidder);
- Player* bidder = ObjectAccessor::FindPlayer(bidderGuid);
+ Player* bidder = ObjectAccessor::FindConnectedPlayer(bidderGuid);
// data for gm.log
std::string bidderName;
bool logGmTrade = false;
@@ -107,7 +107,7 @@ void AuctionHouseMgr::SendAuctionWonMail(AuctionEntry* auction, SQLTransaction&
else
{
bidderAccId = sObjectMgr->GetPlayerAccountIdByGUID(bidderGuid);
- logGmTrade = AccountMgr::HasPermission(bidderAccId, rbac::RBAC_PERM_LOG_GM_TRADE, realmID);
+ logGmTrade = AccountMgr::HasPermission(bidderAccId, rbac::RBAC_PERM_LOG_GM_TRADE, realmHandle.Index);
if (logGmTrade && !sObjectMgr->GetPlayerNameByGUID(bidderGuid, bidderName))
bidderName = sObjectMgr->GetTrinityStringForDBCLocale(LANG_UNKNOWN);
@@ -157,7 +157,7 @@ void AuctionHouseMgr::SendAuctionWonMail(AuctionEntry* auction, SQLTransaction&
void AuctionHouseMgr::SendAuctionSalePendingMail(AuctionEntry* auction, SQLTransaction& trans)
{
ObjectGuid owner_guid(HIGHGUID_PLAYER, auction->owner);
- Player* owner = ObjectAccessor::FindPlayer(owner_guid);
+ Player* owner = ObjectAccessor::FindConnectedPlayer(owner_guid);
uint32 owner_accId = sObjectMgr->GetPlayerAccountIdByGUID(owner_guid);
// owner exist (online or offline)
if (owner || owner_accId)
@@ -169,7 +169,7 @@ void AuctionHouseMgr::SendAuctionSalePendingMail(AuctionEntry* auction, SQLTrans
void AuctionHouseMgr::SendAuctionSuccessfulMail(AuctionEntry* auction, SQLTransaction& trans)
{
ObjectGuid owner_guid(HIGHGUID_PLAYER, auction->owner);
- Player* owner = ObjectAccessor::FindPlayer(owner_guid);
+ Player* owner = ObjectAccessor::FindConnectedPlayer(owner_guid);
uint32 owner_accId = sObjectMgr->GetPlayerAccountIdByGUID(owner_guid);
// owner exist
if (owner || owner_accId)
@@ -200,7 +200,7 @@ void AuctionHouseMgr::SendAuctionExpiredMail(AuctionEntry* auction, SQLTransacti
return;
ObjectGuid owner_guid(HIGHGUID_PLAYER, auction->owner);
- Player* owner = ObjectAccessor::FindPlayer(owner_guid);
+ Player* owner = ObjectAccessor::FindConnectedPlayer(owner_guid);
uint32 owner_accId = sObjectMgr->GetPlayerAccountIdByGUID(owner_guid);
// owner exist
if (owner || owner_accId)
@@ -223,7 +223,7 @@ void AuctionHouseMgr::SendAuctionExpiredMail(AuctionEntry* auction, SQLTransacti
void AuctionHouseMgr::SendAuctionOutbiddedMail(AuctionEntry* auction, uint32 newPrice, Player* newBidder, SQLTransaction& trans)
{
ObjectGuid oldBidder_guid(HIGHGUID_PLAYER, auction->bidder);
- Player* oldBidder = ObjectAccessor::FindPlayer(oldBidder_guid);
+ Player* oldBidder = ObjectAccessor::FindConnectedPlayer(oldBidder_guid);
uint32 oldBidder_accId = 0;
if (!oldBidder)
@@ -245,7 +245,7 @@ void AuctionHouseMgr::SendAuctionOutbiddedMail(AuctionEntry* auction, uint32 new
void AuctionHouseMgr::SendAuctionCancelledToBidderMail(AuctionEntry* auction, SQLTransaction& trans, Item* item)
{
ObjectGuid bidder_guid = ObjectGuid(HIGHGUID_PLAYER, auction->bidder);
- Player* bidder = ObjectAccessor::FindPlayer(bidder_guid);
+ Player* bidder = ObjectAccessor::FindConnectedPlayer(bidder_guid);
uint32 bidder_accId = 0;
if (!bidder)
diff --git a/src/server/game/Battlefield/Battlefield.cpp b/src/server/game/Battlefield/Battlefield.cpp
index ab90fca0115..3dcc126f872 100644
--- a/src/server/game/Battlefield/Battlefield.cpp
+++ b/src/server/game/Battlefield/Battlefield.cpp
@@ -422,7 +422,7 @@ void Battlefield::BroadcastPacketToQueue(WorldPacket& data) const
{
for (uint8 team = 0; team < BG_TEAMS_COUNT; ++team)
for (GuidSet::const_iterator itr = m_PlayersInQueue[team].begin(); itr != m_PlayersInQueue[team].end(); ++itr)
- if (Player* player = ObjectAccessor::FindPlayer(*itr))
+ if (Player* player = ObjectAccessor::FindConnectedPlayer(*itr))
player->SendDirectMessage(&data);
}
diff --git a/src/server/game/Battlefield/Zones/BattlefieldWG.cpp b/src/server/game/Battlefield/Zones/BattlefieldWG.cpp
index 4c5994f6b3a..326adb66c72 100644
--- a/src/server/game/Battlefield/Zones/BattlefieldWG.cpp
+++ b/src/server/game/Battlefield/Zones/BattlefieldWG.cpp
@@ -253,7 +253,7 @@ void BattlefieldWG::OnBattleStart()
for (GuidSet::const_iterator itr = m_players[team].begin(); itr != m_players[team].end(); ++itr)
{
// Kick player in orb room, TODO: offline player ?
- if (Player* player = sObjectAccessor->FindPlayer(*itr))
+ if (Player* player = ObjectAccessor::FindPlayer(*itr))
{
float x, y, z;
player->GetPosition(x, y, z);
@@ -356,7 +356,7 @@ void BattlefieldWG::OnBattleEnd(bool endByTimer)
for (GuidSet::const_iterator itr = m_PlayersInWar[GetDefenderTeam()].begin(); itr != m_PlayersInWar[GetDefenderTeam()].end(); ++itr)
{
- if (Player* player = sObjectAccessor->FindPlayer(*itr))
+ if (Player* player = ObjectAccessor::FindPlayer(*itr))
{
player->CastSpell(player, SPELL_ESSENCE_OF_WINTERGRASP, true);
player->CastSpell(player, SPELL_VICTORY_REWARD, true);
@@ -369,13 +369,13 @@ void BattlefieldWG::OnBattleEnd(bool endByTimer)
}
for (GuidSet::const_iterator itr = m_PlayersInWar[GetAttackerTeam()].begin(); itr != m_PlayersInWar[GetAttackerTeam()].end(); ++itr)
- if (Player* player = sObjectAccessor->FindPlayer(*itr))
+ if (Player* player = ObjectAccessor::FindPlayer(*itr))
player->CastSpell(player, SPELL_DEFEAT_REWARD, true);
for (uint8 team = 0; team < 2; ++team)
{
for (GuidSet::const_iterator itr = m_PlayersInWar[team].begin(); itr != m_PlayersInWar[team].end(); ++itr)
- if (Player* player = sObjectAccessor->FindPlayer(*itr))
+ if (Player* player = ObjectAccessor::FindPlayer(*itr))
RemoveAurasFromPlayer(player);
m_PlayersInWar[team].clear();
@@ -394,7 +394,7 @@ void BattlefieldWG::OnBattleEnd(bool endByTimer)
{
for (GuidSet::const_iterator itr = m_players[team].begin(); itr != m_players[team].end(); ++itr)
{
- if (Player* player = sObjectAccessor->FindPlayer(*itr))
+ if (Player* player = ObjectAccessor::FindPlayer(*itr))
{
player->RemoveAurasDueToSpell(m_DefenderTeam == TEAM_ALLIANCE ? SPELL_HORDE_CONTROL_PHASE_SHIFT : SPELL_ALLIANCE_CONTROL_PHASE_SHIFT, player->GetGUID());
player->AddAura(m_DefenderTeam == TEAM_HORDE ? SPELL_HORDE_CONTROL_PHASE_SHIFT : SPELL_ALLIANCE_CONTROL_PHASE_SHIFT, player);
@@ -620,7 +620,7 @@ void BattlefieldWG::HandleKill(Player* killer, Unit* victim)
if (victim->GetTypeId() == TYPEID_PLAYER)
{
for (GuidSet::const_iterator itr = m_PlayersInWar[killerTeam].begin(); itr != m_PlayersInWar[killerTeam].end(); ++itr)
- if (Player* player = sObjectAccessor->FindPlayer(*itr))
+ if (Player* player = ObjectAccessor::FindPlayer(*itr))
if (player->GetDistance2d(killer) < 40)
PromotePlayer(player);
return;
@@ -635,7 +635,7 @@ void BattlefieldWG::HandleKill(Player* killer, Unit* victim)
{
again = true;
for (GuidSet::const_iterator iter = m_PlayersInWar[killerTeam].begin(); iter != m_PlayersInWar[killerTeam].end(); ++iter)
- if (Player* player = sObjectAccessor->FindPlayer(*iter))
+ if (Player* player = ObjectAccessor::FindPlayer(*iter))
if (player->GetDistance2d(killer) < 40.0f)
PromotePlayer(player);
}
@@ -847,7 +847,7 @@ void BattlefieldWG::SendInitWorldStatesToAll()
{
for (uint8 team = 0; team < 2; team++)
for (GuidSet::iterator itr = m_players[team].begin(); itr != m_players[team].end(); ++itr)
- if (Player* player = sObjectAccessor->FindPlayer(*itr))
+ if (Player* player = ObjectAccessor::FindPlayer(*itr))
SendInitWorldStatesTo(player);
}
@@ -858,7 +858,7 @@ void BattlefieldWG::BrokenWallOrTower(TeamId /*team*/)
{
for (GuidSet::const_iterator itr = m_PlayersInWar[GetAttackerTeam()].begin(); itr != m_PlayersInWar[GetAttackerTeam()].end(); ++itr)
{
- if (Player* player = sObjectAccessor->FindPlayer(*itr))
+ if (Player* player = ObjectAccessor::FindPlayer(*itr))
IncrementQuest(player, WGQuest[player->GetTeamId()][2], true);
}
}*/
@@ -876,12 +876,12 @@ void BattlefieldWG::UpdatedDestroyedTowerCount(TeamId team)
// Remove buff stack on attackers
for (GuidSet::const_iterator itr = m_PlayersInWar[GetAttackerTeam()].begin(); itr != m_PlayersInWar[GetAttackerTeam()].end(); ++itr)
- if (Player* player = sObjectAccessor->FindPlayer(*itr))
+ if (Player* player = ObjectAccessor::FindPlayer(*itr))
player->RemoveAuraFromStack(SPELL_TOWER_CONTROL);
// Add buff stack to defenders
for (GuidSet::const_iterator itr = m_PlayersInWar[GetDefenderTeam()].begin(); itr != m_PlayersInWar[GetDefenderTeam()].end(); ++itr)
- if (Player* player = sObjectAccessor->FindPlayer(*itr))
+ if (Player* player = ObjectAccessor::FindPlayer(*itr))
{
player->CastSpell(player, SPELL_TOWER_CONTROL, true);
DoCompleteOrIncrementAchievement(ACHIEVEMENTS_WG_TOWER_DESTROY, player);
@@ -986,7 +986,7 @@ void BattlefieldWG::UpdateTenacity()
if (team != TEAM_NEUTRAL)
{
for (GuidSet::const_iterator itr = m_players[team].begin(); itr != m_players[team].end(); ++itr)
- if (Player* player = sObjectAccessor->FindPlayer(*itr))
+ if (Player* player = ObjectAccessor::FindPlayer(*itr))
if (player->getLevel() >= m_MinLevel)
player->RemoveAurasDueToSpell(SPELL_TENACITY);
@@ -1014,7 +1014,7 @@ void BattlefieldWG::UpdateTenacity()
buff_honor = 0;
for (GuidSet::const_iterator itr = m_PlayersInWar[team].begin(); itr != m_PlayersInWar[team].end(); ++itr)
- if (Player* player = sObjectAccessor->FindPlayer(*itr))
+ if (Player* player = ObjectAccessor::FindPlayer(*itr))
player->SetAuraStack(SPELL_TENACITY, player, newStack);
for (GuidSet::const_iterator itr = m_vehicles[team].begin(); itr != m_vehicles[team].end(); ++itr)
@@ -1024,7 +1024,7 @@ void BattlefieldWG::UpdateTenacity()
if (buff_honor != 0)
{
for (GuidSet::const_iterator itr = m_PlayersInWar[team].begin(); itr != m_PlayersInWar[team].end(); ++itr)
- if (Player* player = sObjectAccessor->FindPlayer(*itr))
+ if (Player* player = ObjectAccessor::FindPlayer(*itr))
player->CastSpell(player, buff_honor, true);
for (GuidSet::const_iterator itr = m_vehicles[team].begin(); itr != m_vehicles[team].end(); ++itr)
if (Creature* creature = GetCreature(*itr))
diff --git a/src/server/game/Battlegrounds/Arena.cpp b/src/server/game/Battlegrounds/Arena.cpp
index 39fff2529b9..b75a71f32b7 100644
--- a/src/server/game/Battlegrounds/Arena.cpp
+++ b/src/server/game/Battlegrounds/Arena.cpp
@@ -180,7 +180,7 @@ void Arena::EndBattleground(uint32 winner)
if (sWorld->getBoolConfig(CONFIG_ARENA_LOG_EXTENDED_INFO))
for (auto const& score : PlayerScores)
- if (Player* player = ObjectAccessor::FindPlayer(ObjectGuid(HIGHGUID_PLAYER, score.first)))
+ if (Player* player = ObjectAccessor::FindConnectedPlayer(ObjectGuid(HIGHGUID_PLAYER, score.first)))
{
TC_LOG_DEBUG("bg.arena", "Statistics match Type: %u for %s (GUID: %u, Team: %d, IP: %s): %s",
GetArenaType(), player->GetName().c_str(), score.first, player->GetArenaTeamId(GetArenaType() == 5 ? 2 : GetArenaType() == 3),
diff --git a/src/server/game/Battlegrounds/ArenaTeam.cpp b/src/server/game/Battlegrounds/ArenaTeam.cpp
index c26238cdc9c..8a0b0d04df6 100644
--- a/src/server/game/Battlegrounds/ArenaTeam.cpp
+++ b/src/server/game/Battlegrounds/ArenaTeam.cpp
@@ -120,7 +120,7 @@ bool ArenaTeam::AddMember(ObjectGuid playerGuid)
// Check if player is already in a similar arena team
if ((player && player->GetArenaTeamId(GetSlot())) || Player::GetArenaTeamIdFromDB(playerGuid, GetType()) != 0)
{
- TC_LOG_DEBUG("bg.arena", "Arena: Player %s (guid: %u) already has an arena team of type %u", playerName.c_str(), playerGuid.GetCounter(), GetType());
+ TC_LOG_DEBUG("bg.arena", "Arena: %s %s already has an arena team of type %u", playerGuid.ToString().c_str(), playerName.c_str(), GetType());
return false;
}
@@ -179,7 +179,7 @@ bool ArenaTeam::AddMember(ObjectGuid playerGuid)
player->SetArenaTeamInfoField(GetSlot(), ARENA_TEAM_MEMBER, 1);
}
- TC_LOG_INFO("bg.arena", "Player: %s [GUID: %u] joined arena team type: %u [Id: %u, Name: %s].", playerName.c_str(), playerGuid.GetCounter(), GetType(), GetId(), GetName().c_str());
+ TC_LOG_INFO("bg.arena", "Player: %s [%s] joined arena team type: %u [Id: %u, Name: %s].", playerName.c_str(), playerGuid.ToString().c_str(), GetType(), GetId(), GetName().c_str());
return true;
}
@@ -245,7 +245,7 @@ bool ArenaTeam::LoadMembersFromDB(QueryResult result)
// Delete member if character information is missing
if (newMember.Name.empty())
{
- TC_LOG_ERROR("sql.sql", "ArenaTeam %u has member with empty name - probably player %u doesn't exist, deleting him from memberlist!", arenaTeamId, newMember.Guid.GetCounter());
+ TC_LOG_ERROR("sql.sql", "ArenaTeam %u has member with empty name - probably %s doesn't exist, deleting him from memberlist!", arenaTeamId, newMember.Guid.ToString().c_str());
DelMember(newMember.Guid, true);
continue;
}
@@ -408,7 +408,7 @@ void ArenaTeam::Roster(WorldSession* session)
for (MemberList::const_iterator itr = Members.begin(); itr != Members.end(); ++itr)
{
- player = ObjectAccessor::FindPlayer(itr->Guid);
+ player = ObjectAccessor::FindConnectedPlayer(itr->Guid);
data << uint64(itr->Guid); // guid
data << uint8((player ? 1 : 0)); // online flag
@@ -465,7 +465,7 @@ void ArenaTeam::NotifyStatsChanged()
// This is called after a rated match ended
// Updates arena team stats for every member of the team (not only the ones who participated!)
for (MemberList::const_iterator itr = Members.begin(); itr != Members.end(); ++itr)
- if (Player* player = ObjectAccessor::FindPlayer(itr->Guid))
+ if (Player* player = ObjectAccessor::FindConnectedPlayer(itr->Guid))
SendStats(player->GetSession());
}
@@ -512,7 +512,7 @@ void ArenaTeamMember::ModifyMatchmakerRating(int32 mod, uint32 /*slot*/)
void ArenaTeam::BroadcastPacket(WorldPacket* packet)
{
for (MemberList::const_iterator itr = Members.begin(); itr != Members.end(); ++itr)
- if (Player* player = ObjectAccessor::FindPlayer(itr->Guid))
+ if (Player* player = ObjectAccessor::FindConnectedPlayer(itr->Guid))
player->GetSession()->SendPacket(packet);
}
@@ -611,7 +611,7 @@ uint32 ArenaTeam::GetAverageMMR(Group* group) const
for (MemberList::const_iterator itr = Members.begin(); itr != Members.end(); ++itr)
{
// Skip if player is not online
- if (!ObjectAccessor::FindPlayer(itr->Guid))
+ if (!ObjectAccessor::FindConnectedPlayer(itr->Guid))
continue;
// Skip if player is not a member of group
@@ -699,7 +699,7 @@ void ArenaTeam::FinishGame(int32 mod)
// Check if rating related achivements are met
for (MemberList::iterator itr = Members.begin(); itr != Members.end(); ++itr)
- if (Player* member = ObjectAccessor::FindPlayer(itr->Guid))
+ if (Player* member = ObjectAccessor::FindConnectedPlayer(itr->Guid))
member->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_TEAM_RATING, Stats.Rating, Type);
}
diff --git a/src/server/game/Battlegrounds/Battleground.cpp b/src/server/game/Battlegrounds/Battleground.cpp
index b1189e6c03e..52843b97a51 100644
--- a/src/server/game/Battlegrounds/Battleground.cpp
+++ b/src/server/game/Battlegrounds/Battleground.cpp
@@ -598,10 +598,11 @@ Player* Battleground::_GetPlayer(ObjectGuid guid, bool offlineRemove, char const
Player* player = NULL;
if (!offlineRemove)
{
+ // should this be ObjectAccessor::FindConnectedPlayer() to return players teleporting ?
player = ObjectAccessor::FindPlayer(guid);
if (!player)
- TC_LOG_ERROR("bg.battleground", "Battleground::%s: player (GUID: %u) not found for BG (map: %u, instance id: %u)!",
- context, guid.GetCounter(), m_MapId, m_InstanceID);
+ TC_LOG_ERROR("bg.battleground", "Battleground::%s: player (%s) not found for BG (map: %u, instance id: %u)!",
+ context, guid.ToString().c_str(), m_MapId, m_InstanceID);
}
return player;
}
@@ -1478,8 +1479,8 @@ void Battleground::DoorClose(uint32 type)
}
}
else
- TC_LOG_ERROR("bg.battleground", "Battleground::DoorClose: door gameobject (type: %u, GUID: %u) not found for BG (map: %u, instance id: %u)!",
- type, BgObjects[type].GetCounter(), m_MapId, m_InstanceID);
+ TC_LOG_ERROR("bg.battleground", "Battleground::DoorClose: door gameobject (type: %u, %s) not found for BG (map: %u, instance id: %u)!",
+ type, BgObjects[type].ToString().c_str(), m_MapId, m_InstanceID);
}
void Battleground::DoorOpen(uint32 type)
@@ -1490,8 +1491,8 @@ void Battleground::DoorOpen(uint32 type)
obj->SetGoState(GO_STATE_ACTIVE);
}
else
- TC_LOG_ERROR("bg.battleground", "Battleground::DoorOpen: door gameobject (type: %u, GUID: %u) not found for BG (map: %u, instance id: %u)!",
- type, BgObjects[type].GetCounter(), m_MapId, m_InstanceID);
+ TC_LOG_ERROR("bg.battleground", "Battleground::DoorOpen: door gameobject (type: %u, %s) not found for BG (map: %u, instance id: %u)!",
+ type, BgObjects[type].ToString().c_str(), m_MapId, m_InstanceID);
}
GameObject* Battleground::GetBGObject(uint32 type, bool logError)
@@ -1500,11 +1501,11 @@ GameObject* Battleground::GetBGObject(uint32 type, bool logError)
if (!obj)
{
if (logError)
- TC_LOG_ERROR("bg.battleground", "Battleground::GetBGObject: gameobject (type: %u, GUID: %u) not found for BG (map: %u, instance id: %u)!",
- type, BgObjects[type].GetCounter(), m_MapId, m_InstanceID);
+ TC_LOG_ERROR("bg.battleground", "Battleground::GetBGObject: gameobject (type: %u, %s) not found for BG (map: %u, instance id: %u)!",
+ type, BgObjects[type].ToString().c_str(), m_MapId, m_InstanceID);
else
- TC_LOG_INFO("bg.battleground", "Battleground::GetBGObject: gameobject (type: %u, GUID: %u) not found for BG (map: %u, instance id: %u)!",
- type, BgObjects[type].GetCounter(), m_MapId, m_InstanceID);
+ TC_LOG_INFO("bg.battleground", "Battleground::GetBGObject: gameobject (type: %u, %s) not found for BG (map: %u, instance id: %u)!",
+ type, BgObjects[type].ToString().c_str(), m_MapId, m_InstanceID);
}
return obj;
}
@@ -1515,11 +1516,11 @@ Creature* Battleground::GetBGCreature(uint32 type, bool logError)
if (!creature)
{
if (logError)
- TC_LOG_ERROR("bg.battleground", "Battleground::GetBGCreature: creature (type: %u, GUID: %u) not found for BG (map: %u, instance id: %u)!",
- type, BgCreatures[type].GetCounter(), m_MapId, m_InstanceID);
+ TC_LOG_ERROR("bg.battleground", "Battleground::GetBGCreature: creature (type: %u, %s) not found for BG (map: %u, instance id: %u)!",
+ type, BgCreatures[type].ToString().c_str(), m_MapId, m_InstanceID);
else
- TC_LOG_INFO("bg.battleground", "Battleground::GetBGCreature: creature (type: %u, GUID: %u) not found for BG (map: %u, instance id: %u)!",
- type, BgCreatures[type].GetCounter(), m_MapId, m_InstanceID);
+ TC_LOG_INFO("bg.battleground", "Battleground::GetBGCreature: creature (type: %u, %s) not found for BG (map: %u, instance id: %u)!",
+ type, BgCreatures[type].ToString().c_str(), m_MapId, m_InstanceID);
}
return creature;
}
@@ -1600,8 +1601,8 @@ bool Battleground::DelCreature(uint32 type)
return true;
}
- TC_LOG_ERROR("bg.battleground", "Battleground::DelCreature: creature (type: %u, GUID: %u) not found for BG (map: %u, instance id: %u)!",
- type, BgCreatures[type].GetCounter(), m_MapId, m_InstanceID);
+ TC_LOG_ERROR("bg.battleground", "Battleground::DelCreature: creature (type: %u, %s) not found for BG (map: %u, instance id: %u)!",
+ type, BgCreatures[type].ToString().c_str(), m_MapId, m_InstanceID);
BgCreatures[type].Clear();
return false;
}
@@ -1618,8 +1619,8 @@ bool Battleground::DelObject(uint32 type)
BgObjects[type].Clear();
return true;
}
- TC_LOG_ERROR("bg.battleground", "Battleground::DelObject: gameobject (type: %u, GUID: %u) not found for BG (map: %u, instance id: %u)!",
- type, BgObjects[type].GetCounter(), m_MapId, m_InstanceID);
+ TC_LOG_ERROR("bg.battleground", "Battleground::DelObject: gameobject (type: %u, %s) not found for BG (map: %u, instance id: %u)!",
+ type, BgObjects[type].ToString().c_str(), m_MapId, m_InstanceID);
BgObjects[type].Clear();
return false;
}
@@ -1734,8 +1735,8 @@ void Battleground::HandleTriggerBuff(ObjectGuid go_guid)
index--;
if (index < 0)
{
- TC_LOG_ERROR("bg.battleground", "Battleground::HandleTriggerBuff: cannot find buff gameobject (GUID: %u, entry: %u, type: %u) in internal data for BG (map: %u, instance id: %u)!",
- go_guid.GetCounter(), obj->GetEntry(), obj->GetGoType(), m_MapId, m_InstanceID);
+ TC_LOG_ERROR("bg.battleground", "Battleground::HandleTriggerBuff: cannot find buff gameobject (%s, entry: %u, type: %u) in internal data for BG (map: %u, instance id: %u)!",
+ go_guid.ToString().c_str(), obj->GetEntry(), obj->GetGoType(), m_MapId, m_InstanceID);
return;
}
@@ -1858,8 +1859,8 @@ int32 Battleground::GetObjectType(ObjectGuid guid)
for (uint32 i = 0; i < BgObjects.size(); ++i)
if (BgObjects[i] == guid)
return i;
- TC_LOG_ERROR("bg.battleground", "Battleground::GetObjectType: player used gameobject (GUID: %u) which is not in internal data for BG (map: %u, instance id: %u), cheating?",
- guid.GetCounter(), m_MapId, m_InstanceID);
+ TC_LOG_ERROR("bg.battleground", "Battleground::GetObjectType: player used gameobject (%s) which is not in internal data for BG (map: %u, instance id: %u), cheating?",
+ guid.ToString().c_str(), m_MapId, m_InstanceID);
return -1;
}
diff --git a/src/server/game/Battlegrounds/BattlegroundQueue.cpp b/src/server/game/Battlegrounds/BattlegroundQueue.cpp
index 375c896fd39..8bc37e023e8 100644
--- a/src/server/game/Battlegrounds/BattlegroundQueue.cpp
+++ b/src/server/game/Battlegrounds/BattlegroundQueue.cpp
@@ -293,7 +293,7 @@ void BattlegroundQueue::RemovePlayer(ObjectGuid guid, bool decreaseInvitedCount)
std::string playerName = "Unknown";
if (Player* player = ObjectAccessor::FindPlayer(guid))
playerName = player->GetName();
- TC_LOG_ERROR("bg.battleground", "BattlegroundQueue: couldn't find player %s (GUID: %u)", playerName.c_str(), guid.GetCounter());
+ TC_LOG_ERROR("bg.battleground", "BattlegroundQueue: couldn't find player %s (%s)", playerName.c_str(), guid.ToString().c_str());
return;
}
@@ -328,10 +328,10 @@ void BattlegroundQueue::RemovePlayer(ObjectGuid guid, bool decreaseInvitedCount)
//player can't be in queue without group, but just in case
if (bracket_id == -1)
{
- TC_LOG_ERROR("bg.battleground", "BattlegroundQueue: ERROR Cannot find groupinfo for player GUID: %u", guid.GetCounter());
+ TC_LOG_ERROR("bg.battleground", "BattlegroundQueue: ERROR Cannot find groupinfo for %s", guid.ToString().c_str());
return;
}
- TC_LOG_DEBUG("bg.battleground", "BattlegroundQueue: Removing player GUID %u, from bracket_id %u", guid.GetCounter(), (uint32)bracket_id);
+ TC_LOG_DEBUG("bg.battleground", "BattlegroundQueue: Removing %s, from bracket_id %u", guid.ToString().c_str(), (uint32)bracket_id);
// ALL variables are correctly set
// We can ignore leveling up in queue - it should not cause crash
@@ -361,8 +361,8 @@ void BattlegroundQueue::RemovePlayer(ObjectGuid guid, bool decreaseInvitedCount)
{
if (ArenaTeam* at = sArenaTeamMgr->GetArenaTeamById(group->ArenaTeamId))
{
- TC_LOG_DEBUG("bg.battleground", "UPDATING memberLost's personal arena rating for %u by opponents rating: %u", guid.GetCounter(), group->OpponentsTeamRating);
- if (Player* player = ObjectAccessor::FindPlayer(guid))
+ TC_LOG_DEBUG("bg.battleground", "UPDATING memberLost's personal arena rating for %s by opponents rating: %u", guid.ToString().c_str(), group->OpponentsTeamRating);
+ if (Player* player = ObjectAccessor::FindConnectedPlayer(guid))
at->MemberLost(player, group->OpponentsMatchmakerRating);
else
at->OfflineMemberLost(guid, group->OpponentsMatchmakerRating);
@@ -385,7 +385,7 @@ void BattlegroundQueue::RemovePlayer(ObjectGuid guid, bool decreaseInvitedCount)
{
// remove next player, this is recursive
// first send removal information
- if (Player* plr2 = ObjectAccessor::FindPlayer(group->Players.begin()->first))
+ if (Player* plr2 = ObjectAccessor::FindConnectedPlayer(group->Players.begin()->first))
{
Battleground* bg = sBattlegroundMgr->GetBattlegroundTemplate(group->BgTypeId);
BattlegroundQueueTypeId bgQueueTypeId = BattlegroundMgr::BGQueueTypeId(group->BgTypeId, group->ArenaType);
@@ -450,7 +450,7 @@ bool BattlegroundQueue::InviteGroupToBG(GroupQueueInfo* ginfo, Battleground* bg,
for (std::map<ObjectGuid, PlayerQueueInfo*>::iterator itr = ginfo->Players.begin(); itr != ginfo->Players.end(); ++itr)
{
// get the player
- Player* player = ObjectAccessor::FindPlayer(itr->first);
+ Player* player = ObjectAccessor::FindConnectedPlayer(itr->first);
// if offline, skip him, this should not happen - player is removed from queue when he logs out
if (!player)
continue;
@@ -981,7 +981,7 @@ void BattlegroundQueue::BattlegroundQueueUpdate(uint32 /*diff*/, BattlegroundTyp
bool BGQueueInviteEvent::Execute(uint64 /*e_time*/, uint32 /*p_time*/)
{
- Player* player = ObjectAccessor::FindPlayer(m_PlayerGuid);
+ Player* player = ObjectAccessor::FindConnectedPlayer(m_PlayerGuid);
// player logged off (we should do nothing, he is correctly removed from queue in another procedure)
if (!player)
return true;
@@ -1024,7 +1024,7 @@ void BGQueueInviteEvent::Abort(uint64 /*e_time*/)
*/
bool BGQueueRemoveEvent::Execute(uint64 /*e_time*/, uint32 /*p_time*/)
{
- Player* player = ObjectAccessor::FindPlayer(m_PlayerGuid);
+ Player* player = ObjectAccessor::FindConnectedPlayer(m_PlayerGuid);
if (!player)
// player logged off (we should do nothing, he is correctly removed from queue in another procedure)
return true;
diff --git a/src/server/game/CMakeLists.txt b/src/server/game/CMakeLists.txt
index 0d1b460500e..27b3ea2c381 100644
--- a/src/server/game/CMakeLists.txt
+++ b/src/server/game/CMakeLists.txt
@@ -111,6 +111,7 @@ include_directories(
${CMAKE_SOURCE_DIR}/dep/g3dlite/include
${CMAKE_SOURCE_DIR}/dep/SFMT
${CMAKE_SOURCE_DIR}/dep/zlib
+ ${CMAKE_SOURCE_DIR}/dep/zmqpp
${CMAKE_SOURCE_DIR}/src/server/collision
${CMAKE_SOURCE_DIR}/src/server/collision/Management
${CMAKE_SOURCE_DIR}/src/server/collision/Models
@@ -129,6 +130,7 @@ include_directories(
${CMAKE_SOURCE_DIR}/src/server/shared/Packets
${CMAKE_SOURCE_DIR}/src/server/shared/Threading
${CMAKE_SOURCE_DIR}/src/server/shared/Utilities
+ ${CMAKE_SOURCE_DIR}/src/server/ipc
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/Accounts
${CMAKE_CURRENT_SOURCE_DIR}/Achievements
@@ -205,6 +207,7 @@ include_directories(
${MYSQL_INCLUDE_DIR}
${OPENSSL_INCLUDE_DIR}
${VALGRIND_INCLUDE_DIR}
+ ${ZMQ_INCLUDE_DIR}
)
add_library(game STATIC
diff --git a/src/server/game/Calendar/CalendarMgr.cpp b/src/server/game/Calendar/CalendarMgr.cpp
index 2e62e8514a0..5270e42d0b1 100644
--- a/src/server/game/Calendar/CalendarMgr.cpp
+++ b/src/server/game/Calendar/CalendarMgr.cpp
@@ -350,7 +350,7 @@ CalendarEventStore CalendarMgr::GetPlayerEvents(ObjectGuid guid)
if (CalendarEvent* event = GetEvent(itr->first)) // NULL check added as attempt to fix #11512
events.insert(event);
- if (Player* player = ObjectAccessor::FindPlayer(guid))
+ if (Player* player = ObjectAccessor::FindConnectedPlayer(guid))
for (CalendarEventStore::const_iterator itr = _events.begin(); itr != _events.end(); ++itr)
if ((*itr)->GetGuildId() == player->GetGuildId())
events.insert(*itr);
@@ -424,7 +424,7 @@ void CalendarMgr::SendCalendarEventInvite(CalendarInvite const& invite)
bool hasStatusTime = statusTime != 946684800; // 01/01/2000 00:00:00
ObjectGuid invitee = invite.GetInviteeGUID();
- Player* player = ObjectAccessor::FindPlayer(invitee);
+ Player* player = ObjectAccessor::FindConnectedPlayer(invitee);
uint8 level = player ? player->getLevel() : Player::GetLevelFromDB(invitee);
@@ -441,7 +441,7 @@ void CalendarMgr::SendCalendarEventInvite(CalendarInvite const& invite)
if (!calendarEvent) // Pre-invite
{
- if (Player* playerSender = ObjectAccessor::FindPlayer(invite.GetSenderGUID()))
+ if (Player* playerSender = ObjectAccessor::FindConnectedPlayer(invite.GetSenderGUID()))
playerSender->SendDirectMessage(&data);
}
else
@@ -542,13 +542,13 @@ void CalendarMgr::SendCalendarEventInviteAlert(CalendarEvent const& calendarEven
guild->BroadcastPacket(&data);
}
else
- if (Player* player = ObjectAccessor::FindPlayer(invite.GetInviteeGUID()))
+ if (Player* player = ObjectAccessor::FindConnectedPlayer(invite.GetInviteeGUID()))
player->SendDirectMessage(&data);
}
void CalendarMgr::SendCalendarEvent(ObjectGuid guid, CalendarEvent const& calendarEvent, CalendarSendEventType sendType)
{
- Player* player = ObjectAccessor::FindPlayer(guid);
+ Player* player = ObjectAccessor::FindConnectedPlayer(guid);
if (!player)
return;
@@ -596,7 +596,7 @@ void CalendarMgr::SendCalendarEvent(ObjectGuid guid, CalendarEvent const& calend
void CalendarMgr::SendCalendarEventInviteRemoveAlert(ObjectGuid guid, CalendarEvent const& calendarEvent, CalendarInviteStatus status)
{
- if (Player* player = ObjectAccessor::FindPlayer(guid))
+ if (Player* player = ObjectAccessor::FindConnectedPlayer(guid))
{
WorldPacket data(SMSG_CALENDAR_EVENT_INVITE_REMOVED_ALERT, 8 + 4 + 4 + 1);
data << uint64(calendarEvent.GetEventId());
@@ -610,7 +610,7 @@ void CalendarMgr::SendCalendarEventInviteRemoveAlert(ObjectGuid guid, CalendarEv
void CalendarMgr::SendCalendarClearPendingAction(ObjectGuid guid)
{
- if (Player* player = ObjectAccessor::FindPlayer(guid))
+ if (Player* player = ObjectAccessor::FindConnectedPlayer(guid))
{
WorldPacket data(SMSG_CALENDAR_CLEAR_PENDING_ACTION, 0);
player->SendDirectMessage(&data);
@@ -619,7 +619,7 @@ void CalendarMgr::SendCalendarClearPendingAction(ObjectGuid guid)
void CalendarMgr::SendCalendarCommandResult(ObjectGuid guid, CalendarError err, char const* param /*= NULL*/)
{
- if (Player* player = ObjectAccessor::FindPlayer(guid))
+ if (Player* player = ObjectAccessor::FindConnectedPlayer(guid))
{
WorldPacket data(SMSG_CALENDAR_COMMAND_RESULT, 0);
data << uint32(0);
@@ -652,7 +652,7 @@ void CalendarMgr::SendPacketToAllEventRelatives(WorldPacket& packet, CalendarEve
// Send packet to all invitees if event is non-guild, in other case only to non-guild invitees (packet was broadcasted for them)
CalendarInviteStore invites = _invites[calendarEvent.GetEventId()];
for (CalendarInviteStore::iterator itr = invites.begin(); itr != invites.end(); ++itr)
- if (Player* player = ObjectAccessor::FindPlayer((*itr)->GetInviteeGUID()))
+ if (Player* player = ObjectAccessor::FindConnectedPlayer((*itr)->GetInviteeGUID()))
if (!calendarEvent.IsGuildEvent() || (calendarEvent.IsGuildEvent() && player->GetGuildId() != calendarEvent.GetGuildId()))
player->SendDirectMessage(&packet);
}
diff --git a/src/server/game/Chat/Channels/Channel.cpp b/src/server/game/Chat/Channels/Channel.cpp
index 654ce8da2b9..6d984ab2e66 100644
--- a/src/server/game/Chat/Channels/Channel.cpp
+++ b/src/server/game/Chat/Channels/Channel.cpp
@@ -296,7 +296,7 @@ void Channel::KickOrBan(Player const* player, std::string const& badname, bool b
return;
}
- Player* bad = sObjectAccessor->FindPlayerByName(badname);
+ Player* bad = ObjectAccessor::FindConnectedPlayerByName(badname);
ObjectGuid victim = bad ? bad->GetGUID() : ObjectGuid::Empty;
if (!victim || !IsOn(victim))
{
@@ -366,7 +366,7 @@ void Channel::UnBan(Player const* player, std::string const& badname)
return;
}
- Player* bad = sObjectAccessor->FindPlayerByName(badname);
+ Player* bad = ObjectAccessor::FindConnectedPlayerByName(badname);
ObjectGuid victim = bad ? bad->GetGUID() : ObjectGuid::Empty;
if (!victim || !IsBanned(victim))
@@ -439,7 +439,7 @@ void Channel::SetMode(Player const* player, std::string const& p2n, bool mod, bo
if (guid == _ownerGUID && std::string(p2n) == player->GetName() && mod)
return;
- Player* newp = sObjectAccessor->FindPlayerByName(p2n);
+ Player* newp = ObjectAccessor::FindConnectedPlayerByName(p2n);
ObjectGuid victim = newp ? newp->GetGUID() : ObjectGuid::Empty;
if (!victim || !IsOn(victim) ||
@@ -487,7 +487,7 @@ void Channel::SetOwner(Player const* player, std::string const& newname)
return;
}
- Player* newp = sObjectAccessor->FindPlayerByName(newname);
+ Player* newp = ObjectAccessor::FindConnectedPlayerByName(newname);
ObjectGuid victim = newp ? newp->GetGUID() : ObjectGuid::Empty;
if (!victim || !IsOn(victim) ||
@@ -543,7 +543,7 @@ void Channel::List(Player const* player)
uint32 count = 0;
for (PlayerContainer::const_iterator i = playersStore.begin(); i != playersStore.end(); ++i)
{
- Player* member = ObjectAccessor::FindPlayer(i->first);
+ Player* member = ObjectAccessor::FindConnectedPlayer(i->first);
// PLAYER can't see MODERATOR, GAME MASTER, ADMINISTRATOR characters
// MODERATOR, GAME MASTER, ADMINISTRATOR can see all
@@ -621,7 +621,7 @@ void Channel::Say(ObjectGuid guid, std::string const& what, uint32 lang)
}
WorldPacket data;
- if (Player* player = ObjectAccessor::FindPlayer(guid))
+ if (Player* player = ObjectAccessor::FindConnectedPlayer(guid))
ChatHandler::BuildChatPacket(data, CHAT_MSG_CHANNEL, Language(lang), player, player, what, 0, _name);
else
ChatHandler::BuildChatPacket(data, CHAT_MSG_CHANNEL, Language(lang), guid, guid, what, 0, "", "", 0, false, _name);
@@ -641,7 +641,7 @@ void Channel::Invite(Player const* player, std::string const& newname)
return;
}
- Player* newp = sObjectAccessor->FindPlayerByName(newname);
+ Player* newp = ObjectAccessor::FindConnectedPlayerByName(newname);
if (!newp || !newp->isGMVisible())
{
WorldPacket data;
@@ -723,7 +723,7 @@ void Channel::SetOwner(ObjectGuid guid, bool exclaim)
void Channel::SendToAll(WorldPacket* data, ObjectGuid guid)
{
for (PlayerContainer::const_iterator i = playersStore.begin(); i != playersStore.end(); ++i)
- if (Player* player = ObjectAccessor::FindPlayer(i->first))
+ if (Player* player = ObjectAccessor::FindConnectedPlayer(i->first))
if (!guid || !player->GetSocial()->HasIgnore(guid.GetCounter()))
player->GetSession()->SendPacket(data);
}
@@ -732,13 +732,13 @@ void Channel::SendToAllButOne(WorldPacket* data, ObjectGuid who)
{
for (PlayerContainer::const_iterator i = playersStore.begin(); i != playersStore.end(); ++i)
if (i->first != who)
- if (Player* player = ObjectAccessor::FindPlayer(i->first))
+ if (Player* player = ObjectAccessor::FindConnectedPlayer(i->first))
player->GetSession()->SendPacket(data);
}
void Channel::SendToOne(WorldPacket* data, ObjectGuid who)
{
- if (Player* player = ObjectAccessor::FindPlayer(who))
+ if (Player* player = ObjectAccessor::FindConnectedPlayer(who))
player->GetSession()->SendPacket(data);
}
diff --git a/src/server/game/Chat/Chat.cpp b/src/server/game/Chat/Chat.cpp
index ace13989efb..501f73c460f 100644
--- a/src/server/game/Chat/Chat.cpp
+++ b/src/server/game/Chat/Chat.cpp
@@ -160,7 +160,7 @@ bool ChatHandler::HasLowerSecurityAccount(WorldSession* target, uint32 target_ac
if (target)
target_sec = target->GetSecurity();
else if (target_account)
- target_sec = AccountMgr::GetSecurity(target_account, realmID);
+ target_sec = AccountMgr::GetSecurity(target_account, realmHandle.Index);
else
return true; // caller must report error for (target == NULL && target_account == 0)
@@ -765,7 +765,7 @@ Player* ChatHandler::getSelectedPlayer()
if (!selected)
return m_session->GetPlayer();
- return ObjectAccessor::FindPlayer(selected);
+ return ObjectAccessor::FindConnectedPlayer(selected);
}
Unit* ChatHandler::getSelectedUnit()
@@ -810,7 +810,7 @@ Player* ChatHandler::getSelectedPlayerOrSelf()
return m_session->GetPlayer();
// first try with selected target
- Player* targetPlayer = ObjectAccessor::FindPlayer(selected);
+ Player* targetPlayer = ObjectAccessor::FindConnectedPlayer(selected);
// if the target is not a player, then return self
if (!targetPlayer)
targetPlayer = m_session->GetPlayer();
@@ -1090,7 +1090,7 @@ ObjectGuid ChatHandler::extractGuidFromLink(char* text)
if (!normalizePlayerName(name))
return ObjectGuid::Empty;
- if (Player* player = sObjectAccessor->FindPlayerByName(name))
+ if (Player* player = ObjectAccessor::FindPlayerByName(name))
return player->GetGUID();
if (ObjectGuid guid = sObjectMgr->GetPlayerGUIDByName(name))
@@ -1148,7 +1148,7 @@ bool ChatHandler::extractPlayerTarget(char* args, Player** player, ObjectGuid* p
return false;
}
- Player* pl = sObjectAccessor->FindPlayerByName(name);
+ Player* pl = ObjectAccessor::FindPlayerByName(name);
// if allowed player pointer
if (player)
@@ -1312,7 +1312,7 @@ bool ChatHandler::GetPlayerGroupAndGUIDByName(const char* cname, Player*& player
return false;
}
- player = sObjectAccessor->FindPlayerByName(name);
+ player = ObjectAccessor::FindPlayerByName(name);
if (offline)
guid = sObjectMgr->GetPlayerGUIDByName(name.c_str());
}
diff --git a/src/server/game/Conditions/DisableMgr.cpp b/src/server/game/Conditions/DisableMgr.cpp
index 3f325be1e83..eb50545b510 100644
--- a/src/server/game/Conditions/DisableMgr.cpp
+++ b/src/server/game/Conditions/DisableMgr.cpp
@@ -21,8 +21,8 @@
#include "ObjectMgr.h"
#include "OutdoorPvP.h"
#include "SpellMgr.h"
-#include "VMapManager2.h"
#include "Player.h"
+#include "World.h"
namespace DisableMgr
{
@@ -193,28 +193,28 @@ void LoadDisables()
switch (mapEntry->map_type)
{
case MAP_COMMON:
- if (flags & VMAP_DISABLE_AREAFLAG)
+ if (flags & VMAP::VMAP_DISABLE_AREAFLAG)
TC_LOG_INFO("misc", "Areaflag disabled for world map %u.", entry);
- if (flags & VMAP_DISABLE_LIQUIDSTATUS)
+ if (flags & VMAP::VMAP_DISABLE_LIQUIDSTATUS)
TC_LOG_INFO("misc", "Liquid status disabled for world map %u.", entry);
break;
case MAP_INSTANCE:
case MAP_RAID:
- if (flags & VMAP_DISABLE_HEIGHT)
+ if (flags & VMAP::VMAP_DISABLE_HEIGHT)
TC_LOG_INFO("misc", "Height disabled for instance map %u.", entry);
- if (flags & VMAP_DISABLE_LOS)
+ if (flags & VMAP::VMAP_DISABLE_LOS)
TC_LOG_INFO("misc", "LoS disabled for instance map %u.", entry);
break;
case MAP_BATTLEGROUND:
- if (flags & VMAP_DISABLE_HEIGHT)
+ if (flags & VMAP::VMAP_DISABLE_HEIGHT)
TC_LOG_INFO("misc", "Height disabled for battleground map %u.", entry);
- if (flags & VMAP_DISABLE_LOS)
+ if (flags & VMAP::VMAP_DISABLE_LOS)
TC_LOG_INFO("misc", "LoS disabled for battleground map %u.", entry);
break;
case MAP_ARENA:
- if (flags & VMAP_DISABLE_HEIGHT)
+ if (flags & VMAP::VMAP_DISABLE_HEIGHT)
TC_LOG_INFO("misc", "Height disabled for arena map %u.", entry);
- if (flags & VMAP_DISABLE_LOS)
+ if (flags & VMAP::VMAP_DISABLE_LOS)
TC_LOG_INFO("misc", "LoS disabled for arena map %u.", entry);
break;
default:
@@ -387,4 +387,15 @@ bool IsDisabledFor(DisableType type, uint32 entry, Unit const* unit, uint8 flags
return false;
}
+bool IsVMAPDisabledFor(uint32 entry, uint8 flags)
+{
+ return IsDisabledFor(DISABLE_TYPE_VMAP, entry, NULL, flags);
+}
+
+bool IsPathfindingEnabled(uint32 mapId)
+{
+ return sWorld->getBoolConfig(CONFIG_ENABLE_MMAPS)
+ && !IsDisabledFor(DISABLE_TYPE_MMAP, mapId, NULL, MMAP_DISABLE_PATHFINDING);
+}
+
} // Namespace
diff --git a/src/server/game/Conditions/DisableMgr.h b/src/server/game/Conditions/DisableMgr.h
index 0930da78547..f6c65abe90a 100644
--- a/src/server/game/Conditions/DisableMgr.h
+++ b/src/server/game/Conditions/DisableMgr.h
@@ -19,6 +19,7 @@
#ifndef TRINITY_DISABLEMGR_H
#define TRINITY_DISABLEMGR_H
+#include "VMapManager2.h"
#include "Define.h"
class Unit;
@@ -49,14 +50,6 @@ enum SpellDisableTypes
SPELL_DISABLE_LOS)
};
-enum VmapDisableTypes
-{
- VMAP_DISABLE_AREAFLAG = 0x1,
- VMAP_DISABLE_HEIGHT = 0x2,
- VMAP_DISABLE_LOS = 0x4,
- VMAP_DISABLE_LIQUIDSTATUS = 0x8
-};
-
enum MMapDisableTypes
{
MMAP_DISABLE_PATHFINDING = 0x0
@@ -67,6 +60,8 @@ namespace DisableMgr
void LoadDisables();
bool IsDisabledFor(DisableType type, uint32 entry, Unit const* unit, uint8 flags = 0);
void CheckQuestDisables();
+ bool IsVMAPDisabledFor(uint32 entry, uint8 flags);
+ bool IsPathfindingEnabled(uint32 mapId);
}
#endif //TRINITY_DISABLEMGR_H
diff --git a/src/server/game/DungeonFinding/LFGMgr.cpp b/src/server/game/DungeonFinding/LFGMgr.cpp
index 4bed997bced..3946d7b543f 100644
--- a/src/server/game/DungeonFinding/LFGMgr.cpp
+++ b/src/server/game/DungeonFinding/LFGMgr.cpp
@@ -490,8 +490,8 @@ void LFGMgr::JoinLfg(Player* player, uint8 roles, LfgDungeonSet& dungeons, const
// Can't join. Send result
if (joinData.result != LFG_JOIN_OK)
{
- TC_LOG_DEBUG("lfg.join", "%u joining with %u members. Result: %u, Dungeons: %s",
- guid.GetCounter(), grp ? grp->GetMembersCount() : 1, joinData.result, ConcatenateDungeons(dungeons).c_str());
+ TC_LOG_DEBUG("lfg.join", "%s joining with %u members. Result: %u, Dungeons: %s",
+ guid.ToString().c_str(), grp ? grp->GetMembersCount() : 1, joinData.result, ConcatenateDungeons(dungeons).c_str());
if (!dungeons.empty()) // Only should show lockmap when have no dungeons available
joinData.lockmap.clear();
@@ -503,7 +503,7 @@ void LFGMgr::JoinLfg(Player* player, uint8 roles, LfgDungeonSet& dungeons, const
if (isRaid)
{
- TC_LOG_DEBUG("lfg.join", "%u trying to join raid browser and it's disabled.", guid.GetCounter());
+ TC_LOG_DEBUG("lfg.join", "%s trying to join raid browser and it's disabled.", guid.ToString().c_str());
return;
}
@@ -569,7 +569,7 @@ void LFGMgr::JoinLfg(Player* player, uint8 roles, LfgDungeonSet& dungeons, const
debugNames.append(player->GetName());
}
- TC_LOG_DEBUG("lfg.join", "%u joined (%s), Members: %s. Dungeons (%u): %s", guid.GetCounter(),
+ TC_LOG_DEBUG("lfg.join", "%s joined (%s), Members: %s. Dungeons (%u): %s", guid.ToString().c_str(),
grp ? "group" : "player", debugNames.c_str(), uint32(dungeons.size()), ConcatenateDungeons(dungeons).c_str());
}
@@ -583,7 +583,7 @@ void LFGMgr::LeaveLfg(ObjectGuid guid)
{
ObjectGuid gguid = guid.IsGroup() ? guid : GetGroup(guid);
- TC_LOG_DEBUG("lfg.leave", "%u left (%s)", guid.GetCounter(), guid == gguid ? "group" : "player");
+ TC_LOG_DEBUG("lfg.leave", "%s left (%s)", guid.ToString().c_str(), guid == gguid ? "group" : "player");
LfgState state = GetState(guid);
switch (state)
@@ -772,10 +772,9 @@ void LFGMgr::GetCompatibleDungeons(LfgDungeonSet& dungeons, GuidSet const& playe
Check if a group can be formed with the given group roles
@param[in] groles Map of roles to check
- @param[in] removeLeaderFlag Determines if we have to remove leader flag (only used first call, Default = true)
@return True if roles are compatible
*/
-bool LFGMgr::CheckGroupRoles(LfgRolesMap& groles, bool removeLeaderFlag /*= true*/)
+bool LFGMgr::CheckGroupRoles(LfgRolesMap& groles)
{
if (groles.empty())
return false;
@@ -784,21 +783,18 @@ bool LFGMgr::CheckGroupRoles(LfgRolesMap& groles, bool removeLeaderFlag /*= true
uint8 tank = 0;
uint8 healer = 0;
- if (removeLeaderFlag)
- for (LfgRolesMap::iterator it = groles.begin(); it != groles.end(); ++it)
- it->second &= ~PLAYER_ROLE_LEADER;
-
for (LfgRolesMap::iterator it = groles.begin(); it != groles.end(); ++it)
{
- if (it->second == PLAYER_ROLE_NONE)
+ uint8 role = it->second & ~PLAYER_ROLE_LEADER;
+ if (role == PLAYER_ROLE_NONE)
return false;
- if (it->second & PLAYER_ROLE_DAMAGE)
+ if (role & PLAYER_ROLE_DAMAGE)
{
- if (it->second != PLAYER_ROLE_DAMAGE)
+ if (role != PLAYER_ROLE_DAMAGE)
{
it->second -= PLAYER_ROLE_DAMAGE;
- if (CheckGroupRoles(groles, false))
+ if (CheckGroupRoles(groles))
return true;
it->second += PLAYER_ROLE_DAMAGE;
}
@@ -808,12 +804,12 @@ bool LFGMgr::CheckGroupRoles(LfgRolesMap& groles, bool removeLeaderFlag /*= true
damage++;
}
- if (it->second & PLAYER_ROLE_HEALER)
+ if (role & PLAYER_ROLE_HEALER)
{
- if (it->second != PLAYER_ROLE_HEALER)
+ if (role != PLAYER_ROLE_HEALER)
{
it->second -= PLAYER_ROLE_HEALER;
- if (CheckGroupRoles(groles, false))
+ if (CheckGroupRoles(groles))
return true;
it->second += PLAYER_ROLE_HEALER;
}
@@ -823,12 +819,12 @@ bool LFGMgr::CheckGroupRoles(LfgRolesMap& groles, bool removeLeaderFlag /*= true
healer++;
}
- if (it->second & PLAYER_ROLE_TANK)
+ if (role & PLAYER_ROLE_TANK)
{
- if (it->second != PLAYER_ROLE_TANK)
+ if (role != PLAYER_ROLE_TANK)
{
it->second -= PLAYER_ROLE_TANK;
- if (CheckGroupRoles(groles, false))
+ if (CheckGroupRoles(groles))
return true;
it->second += PLAYER_ROLE_TANK;
}
@@ -945,7 +941,7 @@ void LFGMgr::UpdateProposal(uint32 proposalId, ObjectGuid guid, bool accept)
LfgProposalPlayer& player = itProposalPlayer->second;
player.accept = LfgAnswer(accept);
- TC_LOG_DEBUG("lfg.proposal.update", "Player %u, Proposal %u, Selection: %u", guid.GetCounter(), proposalId, accept);
+ TC_LOG_DEBUG("lfg.proposal.update", "%s, Proposal %u, Selection: %u", guid.ToString().c_str(), proposalId, accept);
if (!accept)
{
RemoveProposal(itProposal, LFG_UPDATETYPE_PROPOSAL_DECLINED);
@@ -1073,12 +1069,12 @@ void LFGMgr::RemoveProposal(LfgProposalContainer::iterator itProposal, LfgUpdate
if (it->second.accept == LFG_ANSWER_DENY)
{
updateData.updateType = type;
- TC_LOG_DEBUG("lfg.proposal.remove", "%u didn't accept. Removing from queue and compatible cache", guid.GetCounter());
+ TC_LOG_DEBUG("lfg.proposal.remove", "%s didn't accept. Removing from queue and compatible cache", guid.ToString().c_str());
}
else
{
updateData.updateType = LFG_UPDATETYPE_REMOVED_FROM_QUEUE;
- TC_LOG_DEBUG("lfg.proposal.remove", "%u in same group that someone that didn't accept. Removing from queue and compatible cache", guid.GetCounter());
+ TC_LOG_DEBUG("lfg.proposal.remove", "%s in same group that someone that didn't accept. Removing from queue and compatible cache", guid.ToString().c_str());
}
RestoreState(guid, "Proposal Fail (didn't accepted or in group with someone that didn't accept");
@@ -1092,7 +1088,7 @@ void LFGMgr::RemoveProposal(LfgProposalContainer::iterator itProposal, LfgUpdate
}
else
{
- TC_LOG_DEBUG("lfg.proposal.remove", "Readding %u to queue.", guid.GetCounter());
+ TC_LOG_DEBUG("lfg.proposal.remove", "Readding %s to queue.", guid.ToString().c_str());
SetState(guid, LFG_STATE_QUEUED);
if (gguid != guid)
{
@@ -1325,13 +1321,13 @@ void LFGMgr::FinishDungeon(ObjectGuid gguid, const uint32 dungeonId)
uint32 gDungeonId = GetDungeon(gguid);
if (gDungeonId != dungeonId)
{
- TC_LOG_DEBUG("lfg.dungeon.finish", "Group %u finished dungeon %u but queued for %u", gguid.GetCounter(), dungeonId, gDungeonId);
+ TC_LOG_DEBUG("lfg.dungeon.finish", "Group %s finished dungeon %u but queued for %u", gguid.ToString().c_str(), dungeonId, gDungeonId);
return;
}
if (GetState(gguid) == LFG_STATE_FINISHED_DUNGEON) // Shouldn't happen. Do not reward multiple times
{
- TC_LOG_DEBUG("lfg.dungeon.finish", "Group: %u already rewarded", gguid.GetCounter());
+ TC_LOG_DEBUG("lfg.dungeon.finish", "Group: %s already rewarded", gguid.ToString().c_str());
return;
}
@@ -1343,7 +1339,7 @@ void LFGMgr::FinishDungeon(ObjectGuid gguid, const uint32 dungeonId)
ObjectGuid guid = (*it);
if (GetState(guid) == LFG_STATE_FINISHED_DUNGEON)
{
- TC_LOG_DEBUG("lfg.dungeon.finish", "Group: %u, Player: %u already rewarded", gguid.GetCounter(), guid.GetCounter());
+ TC_LOG_DEBUG("lfg.dungeon.finish", "Group: %s, Player: %s already rewarded", gguid.ToString().c_str(), guid.ToString().c_str());
continue;
}
@@ -1359,14 +1355,14 @@ void LFGMgr::FinishDungeon(ObjectGuid gguid, const uint32 dungeonId)
if (!dungeon || (dungeon->type != LFG_TYPE_RANDOM && !dungeon->seasonal))
{
- TC_LOG_DEBUG("lfg.dungeon.finish", "Group: %u, Player: %u dungeon %u is not random or seasonal", gguid.GetCounter(), guid.GetCounter(), rDungeonId);
+ TC_LOG_DEBUG("lfg.dungeon.finish", "Group: %s, Player: %s dungeon %u is not random or seasonal", gguid.ToString().c_str(), guid.ToString().c_str(), rDungeonId);
continue;
}
Player* player = ObjectAccessor::FindPlayer(guid);
- if (!player || !player->IsInWorld())
+ if (!player)
{
- TC_LOG_DEBUG("lfg.dungeon.finish", "Group: %u, Player: %u not found in world", gguid.GetCounter(), guid.GetCounter());
+ TC_LOG_DEBUG("lfg.dungeon.finish", "Group: %s, Player: %s not found in world", gguid.ToString().c_str(), guid.ToString().c_str());
continue;
}
@@ -1375,7 +1371,7 @@ void LFGMgr::FinishDungeon(ObjectGuid gguid, const uint32 dungeonId)
if (player->GetMapId() != mapId)
{
- TC_LOG_DEBUG("lfg.dungeon.finish", "Group: %u, Player: %u is in map %u and should be in %u to get reward", gguid.GetCounter(), guid.GetCounter(), player->GetMapId(), mapId);
+ TC_LOG_DEBUG("lfg.dungeon.finish", "Group: %s, Player: %s is in map %u and should be in %u to get reward", gguid.ToString().c_str(), guid.ToString().c_str(), player->GetMapId(), mapId);
continue;
}
@@ -1406,7 +1402,7 @@ void LFGMgr::FinishDungeon(ObjectGuid gguid, const uint32 dungeonId)
}
// Give rewards
- TC_LOG_DEBUG("lfg.dungeon.finish", "Group: %u, Player: %u done dungeon %u, %s previously done.", gguid.GetCounter(), guid.GetCounter(), GetDungeon(gguid), done? " " : " not");
+ TC_LOG_DEBUG("lfg.dungeon.finish", "Group: %s, Player: %s done dungeon %u, %s previously done.", gguid.ToString().c_str(), guid.ToString().c_str(), GetDungeon(gguid), done ? " " : " not");
LfgPlayerRewardData data = LfgPlayerRewardData(dungeon->Entry(), GetDungeon(gguid, false), done, quest);
player->GetSession()->SendLfgPlayerReward(data);
}
@@ -1472,12 +1468,12 @@ LfgState LFGMgr::GetState(ObjectGuid guid)
if (guid.IsGroup())
{
state = GroupsStore[guid].GetState();
- TC_LOG_TRACE("lfg.data.group.state.get", "Group: %u, State: %u", guid.GetCounter(), state);
+ TC_LOG_TRACE("lfg.data.group.state.get", "Group: %s, State: %u", guid.ToString().c_str(), state);
}
else
{
state = PlayersStore[guid].GetState();
- TC_LOG_TRACE("lfg.data.player.state.get", "Player: %u, State: %u", guid.GetCounter(), state);
+ TC_LOG_TRACE("lfg.data.player.state.get", "Player: %s, State: %u", guid.ToString().c_str(), state);
}
return state;
@@ -1489,12 +1485,12 @@ LfgState LFGMgr::GetOldState(ObjectGuid guid)
if (guid.IsGroup())
{
state = GroupsStore[guid].GetOldState();
- TC_LOG_TRACE("lfg.data.group.oldstate.get", "Group: %u, Old state: %u", guid.GetCounter(), state);
+ TC_LOG_TRACE("lfg.data.group.oldstate.get", "Group: %s, Old state: %u", guid.ToString().c_str(), state);
}
else
{
state = PlayersStore[guid].GetOldState();
- TC_LOG_TRACE("lfg.data.player.oldstate.get", "Player: %u, Old state: %u", guid.GetCounter(), state);
+ TC_LOG_TRACE("lfg.data.player.oldstate.get", "Player: %s, Old state: %u", guid.ToString().c_str(), state);
}
return state;
@@ -1503,7 +1499,7 @@ LfgState LFGMgr::GetOldState(ObjectGuid guid)
uint32 LFGMgr::GetDungeon(ObjectGuid guid, bool asId /*= true */)
{
uint32 dungeon = GroupsStore[guid].GetDungeon(asId);
- TC_LOG_TRACE("lfg.data.group.dungeon.get", "Group: %u, asId: %u, Dungeon: %u", guid.GetCounter(), asId, dungeon);
+ TC_LOG_TRACE("lfg.data.group.dungeon.get", "Group: %s, asId: %u, Dungeon: %u", guid.ToString().c_str(), asId, dungeon);
return dungeon;
}
@@ -1515,7 +1511,7 @@ uint32 LFGMgr::GetDungeonMapId(ObjectGuid guid)
if (LFGDungeonData const* dungeon = GetLFGDungeon(dungeonId))
mapId = dungeon->map;
- TC_LOG_TRACE("lfg.data.group.dungeon.map", "Group: %u, MapId: %u (DungeonId: %u)", guid.GetCounter(), mapId, dungeonId);
+ TC_LOG_TRACE("lfg.data.group.dungeon.map", "Group: %s, MapId: %u (DungeonId: %u)", guid.ToString().c_str(), mapId, dungeonId);
return mapId;
}
@@ -1523,30 +1519,30 @@ uint32 LFGMgr::GetDungeonMapId(ObjectGuid guid)
uint8 LFGMgr::GetRoles(ObjectGuid guid)
{
uint8 roles = PlayersStore[guid].GetRoles();
- TC_LOG_TRACE("lfg.data.player.role.get", "Player: %u, Role: %u", guid.GetCounter(), roles);
+ TC_LOG_TRACE("lfg.data.player.role.get", "Player: %s, Role: %u", guid.ToString().c_str(), roles);
return roles;
}
const std::string& LFGMgr::GetComment(ObjectGuid guid)
{
- TC_LOG_TRACE("lfg.data.player.comment.get", "Player: %u, Comment: %s", guid.GetCounter(), PlayersStore[guid].GetComment().c_str());
+ TC_LOG_TRACE("lfg.data.player.comment.get", "Player: %s, Comment: %s", guid.ToString().c_str(), PlayersStore[guid].GetComment().c_str());
return PlayersStore[guid].GetComment();
}
LfgDungeonSet const& LFGMgr::GetSelectedDungeons(ObjectGuid guid)
{
- TC_LOG_TRACE("lfg.data.player.dungeons.selected.get", "Player: %u, Selected Dungeons: %s", guid.GetCounter(), ConcatenateDungeons(PlayersStore[guid].GetSelectedDungeons()).c_str());
+ TC_LOG_TRACE("lfg.data.player.dungeons.selected.get", "Player: %s, Selected Dungeons: %s", guid.ToString().c_str(), ConcatenateDungeons(PlayersStore[guid].GetSelectedDungeons()).c_str());
return PlayersStore[guid].GetSelectedDungeons();
}
LfgLockMap const LFGMgr::GetLockedDungeons(ObjectGuid guid)
{
- TC_LOG_TRACE("lfg.data.player.dungeons.locked.get", "Player: %u, LockedDungeons.", guid.GetCounter());
+ TC_LOG_TRACE("lfg.data.player.dungeons.locked.get", "Player: %s, LockedDungeons.", guid.ToString().c_str());
LfgLockMap lock;
Player* player = ObjectAccessor::FindPlayer(guid);
if (!player)
{
- TC_LOG_WARN("lfg.data.player.dungeons.locked.get", "Player: %u not ingame while retrieving his LockedDungeons.", guid.GetCounter());
+ TC_LOG_WARN("lfg.data.player.dungeons.locked.get", "Player: %s not ingame while retrieving his LockedDungeons.", guid.ToString().c_str());
return lock;
}
@@ -1612,7 +1608,7 @@ LfgLockMap const LFGMgr::GetLockedDungeons(ObjectGuid guid)
uint8 LFGMgr::GetKicksLeft(ObjectGuid guid)
{
uint8 kicks = GroupsStore[guid].GetKicksLeft();
- TC_LOG_TRACE("lfg.data.group.kickleft.get", "Group: %u, Kicks left: %u", guid.GetCounter(), kicks);
+ TC_LOG_TRACE("lfg.data.group.kickleft.get", "Group: %s, Kicks left: %u", guid.ToString().c_str(), kicks);
return kicks;
}
@@ -1621,8 +1617,8 @@ void LFGMgr::RestoreState(ObjectGuid guid, char const* debugMsg)
if (guid.IsGroup())
{
LfgGroupData& data = GroupsStore[guid];
- TC_LOG_TRACE("lfg.data.group.state.restore", "Group: %u (%s), State: %s, Old state: %s",
- guid.GetCounter(), debugMsg, GetStateString(data.GetState()).c_str(),
+ TC_LOG_TRACE("lfg.data.group.state.restore", "Group: %s (%s), State: %s, Old state: %s",
+ guid.ToString().c_str(), debugMsg, GetStateString(data.GetState()).c_str(),
GetStateString(data.GetOldState()).c_str());
data.RestoreState();
@@ -1630,8 +1626,8 @@ void LFGMgr::RestoreState(ObjectGuid guid, char const* debugMsg)
else
{
LfgPlayerData& data = PlayersStore[guid];
- TC_LOG_TRACE("lfg.data.player.state.restore", "Player: %u (%s), State: %s, Old state: %s",
- guid.GetCounter(), debugMsg, GetStateString(data.GetState()).c_str(),
+ TC_LOG_TRACE("lfg.data.player.state.restore", "Player: %s (%s), State: %s, Old state: %s",
+ guid.ToString().c_str(), debugMsg, GetStateString(data.GetState()).c_str(),
GetStateString(data.GetOldState()).c_str());
data.RestoreState();
@@ -1643,8 +1639,8 @@ void LFGMgr::SetState(ObjectGuid guid, LfgState state)
if (guid.IsGroup())
{
LfgGroupData& data = GroupsStore[guid];
- TC_LOG_TRACE("lfg.data.group.state.set", "Group: %u, New state: %s, Previous: %s, Old state: %s",
- guid.GetCounter(), GetStateString(state).c_str(), GetStateString(data.GetState()).c_str(),
+ TC_LOG_TRACE("lfg.data.group.state.set", "Group: %s, New state: %s, Previous: %s, Old state: %s",
+ guid.ToString().c_str(), GetStateString(state).c_str(), GetStateString(data.GetState()).c_str(),
GetStateString(data.GetOldState()).c_str());
data.SetState(state);
@@ -1652,8 +1648,8 @@ void LFGMgr::SetState(ObjectGuid guid, LfgState state)
else
{
LfgPlayerData& data = PlayersStore[guid];
- TC_LOG_TRACE("lfg.data.player.state.set", "Player: %u, New state: %s, Previous: %s, OldState: %s",
- guid.GetCounter(), GetStateString(state).c_str(), GetStateString(data.GetState()).c_str(),
+ TC_LOG_TRACE("lfg.data.player.state.set", "Player: %s, New state: %s, Previous: %s, OldState: %s",
+ guid.ToString().c_str(), GetStateString(state).c_str(), GetStateString(data.GetState()).c_str(),
GetStateString(data.GetOldState()).c_str());
data.SetState(state);
@@ -1662,37 +1658,37 @@ void LFGMgr::SetState(ObjectGuid guid, LfgState state)
void LFGMgr::SetDungeon(ObjectGuid guid, uint32 dungeon)
{
- TC_LOG_TRACE("lfg.data.group.dungeon.set", "Group: %u, Dungeon: %u", guid.GetCounter(), dungeon);
+ TC_LOG_TRACE("lfg.data.group.dungeon.set", "Group: %s, Dungeon: %u", guid.ToString().c_str(), dungeon);
GroupsStore[guid].SetDungeon(dungeon);
}
void LFGMgr::SetRoles(ObjectGuid guid, uint8 roles)
{
- TC_LOG_TRACE("lfg.data.player.role.set", "Player: %u, Roles: %u", guid.GetCounter(), roles);
+ TC_LOG_TRACE("lfg.data.player.role.set", "Player: %s, Roles: %u", guid.ToString().c_str(), roles);
PlayersStore[guid].SetRoles(roles);
}
void LFGMgr::SetComment(ObjectGuid guid, std::string const& comment)
{
- TC_LOG_TRACE("lfg.data.player.comment.set", "Player: %u, Comment: %s", guid.GetCounter(), comment.c_str());
+ TC_LOG_TRACE("lfg.data.player.comment.set", "Player: %s, Comment: %s", guid.ToString().c_str(), comment.c_str());
PlayersStore[guid].SetComment(comment);
}
void LFGMgr::SetSelectedDungeons(ObjectGuid guid, LfgDungeonSet const& dungeons)
{
- TC_LOG_TRACE("lfg.data.player.dungeon.selected.set", "Player: %u, Dungeons: %s", guid.GetCounter(), ConcatenateDungeons(dungeons).c_str());
+ TC_LOG_TRACE("lfg.data.player.dungeon.selected.set", "Player: %s, Dungeons: %s", guid.ToString().c_str(), ConcatenateDungeons(dungeons).c_str());
PlayersStore[guid].SetSelectedDungeons(dungeons);
}
void LFGMgr::DecreaseKicksLeft(ObjectGuid guid)
{
GroupsStore[guid].DecreaseKicksLeft();
- TC_LOG_TRACE("lfg.data.group.kicksleft.decrease", "Group: %u, Kicks: %u", guid.GetCounter(), GroupsStore[guid].GetKicksLeft());
+ TC_LOG_TRACE("lfg.data.group.kicksleft.decrease", "Group: %s, Kicks: %u", guid.ToString().c_str(), GroupsStore[guid].GetKicksLeft());
}
void LFGMgr::RemovePlayerData(ObjectGuid guid)
{
- TC_LOG_TRACE("lfg.data.player.remove", "Player: %u", guid.GetCounter());
+ TC_LOG_TRACE("lfg.data.player.remove", "Player: %s", guid.ToString().c_str());
LfgPlayerDataContainer::iterator it = PlayersStore.find(guid);
if (it != PlayersStore.end())
PlayersStore.erase(it);
@@ -1700,7 +1696,7 @@ void LFGMgr::RemovePlayerData(ObjectGuid guid)
void LFGMgr::RemoveGroupData(ObjectGuid guid)
{
- TC_LOG_TRACE("lfg.data.group.remove", "Group: %u", guid.GetCounter());
+ TC_LOG_TRACE("lfg.data.group.remove", "Group: %s", guid.ToString().c_str());
LfgGroupDataContainer::iterator it = GroupsStore.find(guid);
if (it == GroupsStore.end())
return;
@@ -1723,7 +1719,7 @@ void LFGMgr::RemoveGroupData(ObjectGuid guid)
uint8 LFGMgr::GetTeam(ObjectGuid guid)
{
uint8 team = PlayersStore[guid].GetTeam();
- TC_LOG_TRACE("lfg.data.player.team.get", "Player: %u, Team: %u", guid.GetCounter(), team);
+ TC_LOG_TRACE("lfg.data.player.team.get", "Player: %s, Team: %u", guid.ToString().c_str(), team);
return team;
}
@@ -1777,50 +1773,50 @@ ObjectGuid LFGMgr::GetLeader(ObjectGuid guid)
bool LFGMgr::HasIgnore(ObjectGuid guid1, ObjectGuid guid2)
{
- Player* plr1 = ObjectAccessor::FindPlayer(guid1);
- Player* plr2 = ObjectAccessor::FindPlayer(guid2);
+ Player* plr1 = ObjectAccessor::FindConnectedPlayer(guid1);
+ Player* plr2 = ObjectAccessor::FindConnectedPlayer(guid2);
return plr1 && plr2 && (plr1->GetSocial()->HasIgnore(guid2.GetCounter()) || plr2->GetSocial()->HasIgnore(guid1.GetCounter()));
}
void LFGMgr::SendLfgRoleChosen(ObjectGuid guid, ObjectGuid pguid, uint8 roles)
{
- if (Player* player = ObjectAccessor::FindPlayer(guid))
+ if (Player* player = ObjectAccessor::FindConnectedPlayer(guid))
player->GetSession()->SendLfgRoleChosen(pguid, roles);
}
void LFGMgr::SendLfgRoleCheckUpdate(ObjectGuid guid, LfgRoleCheck const& roleCheck)
{
- if (Player* player = ObjectAccessor::FindPlayer(guid))
+ if (Player* player = ObjectAccessor::FindConnectedPlayer(guid))
player->GetSession()->SendLfgRoleCheckUpdate(roleCheck);
}
void LFGMgr::SendLfgUpdateStatus(ObjectGuid guid, LfgUpdateData const& data, bool party)
{
- if (Player* player = ObjectAccessor::FindPlayer(guid))
+ if (Player* player = ObjectAccessor::FindConnectedPlayer(guid))
player->GetSession()->SendLfgUpdateStatus(data, party);
}
void LFGMgr::SendLfgJoinResult(ObjectGuid guid, LfgJoinResultData const& data)
{
- if (Player* player = ObjectAccessor::FindPlayer(guid))
+ if (Player* player = ObjectAccessor::FindConnectedPlayer(guid))
player->GetSession()->SendLfgJoinResult(data);
}
void LFGMgr::SendLfgBootProposalUpdate(ObjectGuid guid, LfgPlayerBoot const& boot)
{
- if (Player* player = ObjectAccessor::FindPlayer(guid))
+ if (Player* player = ObjectAccessor::FindConnectedPlayer(guid))
player->GetSession()->SendLfgBootProposalUpdate(boot);
}
void LFGMgr::SendLfgUpdateProposal(ObjectGuid guid, LfgProposal const& proposal)
{
- if (Player* player = ObjectAccessor::FindPlayer(guid))
+ if (Player* player = ObjectAccessor::FindConnectedPlayer(guid))
player->GetSession()->SendLfgUpdateProposal(proposal);
}
void LFGMgr::SendLfgQueueStatus(ObjectGuid guid, LfgQueueStatusData const& data)
{
- if (Player* player = ObjectAccessor::FindPlayer(guid))
+ if (Player* player = ObjectAccessor::FindConnectedPlayer(guid))
player->GetSession()->SendLfgQueueStatus(data);
}
diff --git a/src/server/game/DungeonFinding/LFGMgr.h b/src/server/game/DungeonFinding/LFGMgr.h
index 343705a58ab..9f990131a71 100644
--- a/src/server/game/DungeonFinding/LFGMgr.h
+++ b/src/server/game/DungeonFinding/LFGMgr.h
@@ -421,7 +421,7 @@ class LFGMgr
/// Gets queue join time
time_t GetQueueJoinTime(ObjectGuid guid);
/// Checks if given roles match, modifies given roles map with new roles
- static bool CheckGroupRoles(LfgRolesMap &groles, bool removeLeaderFlag = true);
+ static bool CheckGroupRoles(LfgRolesMap &groles);
/// Checks if given players are ignoring each other
static bool HasIgnore(ObjectGuid guid1, ObjectGuid guid2);
/// Sends queue status to player
diff --git a/src/server/game/DungeonFinding/LFGScripts.cpp b/src/server/game/DungeonFinding/LFGScripts.cpp
index bac1949d894..f9c059feea9 100644
--- a/src/server/game/DungeonFinding/LFGScripts.cpp
+++ b/src/server/game/DungeonFinding/LFGScripts.cpp
@@ -60,8 +60,8 @@ void LFGPlayerScript::OnLogin(Player* player, bool /*loginFirst*/)
ObjectGuid gguid2 = group->GetGUID();
if (gguid != gguid2)
{
- TC_LOG_ERROR("lfg", "%s on group %u but LFG has group %u saved... Fixing.",
- player->GetSession()->GetPlayerInfo().c_str(), gguid2.GetCounter(), gguid.GetCounter());
+ TC_LOG_ERROR("lfg", "%s on group %s but LFG has group %s saved... Fixing.",
+ player->GetSession()->GetPlayerInfo().c_str(), gguid2.ToString().c_str(), gguid.ToString().c_str());
sLFGMgr->SetupGroupMember(guid, group->GetGUID());
}
}
@@ -184,7 +184,7 @@ void LFGGroupScript::OnRemoveMember(Group* group, ObjectGuid guid, RemoveMethod
}
if (isLFG && state != LFG_STATE_FINISHED_DUNGEON) // Need more players to finish the dungeon
- if (Player* leader = ObjectAccessor::FindPlayer(sLFGMgr->GetLeader(gguid)))
+ if (Player* leader = ObjectAccessor::FindConnectedPlayer(sLFGMgr->GetLeader(gguid)))
leader->GetSession()->SendLfgOfferContinue(sLFGMgr->GetDungeon(gguid, false));
}
diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp
index 7a0ee24aeca..8f75cd34f28 100644
--- a/src/server/game/Entities/Creature/Creature.cpp
+++ b/src/server/game/Entities/Creature/Creature.cpp
@@ -875,7 +875,7 @@ Player* Creature::GetLootRecipient() const
{
if (!m_lootRecipient)
return NULL;
- return ObjectAccessor::FindPlayer(m_lootRecipient);
+ return ObjectAccessor::FindConnectedPlayer(m_lootRecipient);
}
Group* Creature::GetLootRecipientGroup() const
@@ -1887,6 +1887,9 @@ void Creature::CallForHelp(float radius)
bool Creature::CanAssistTo(const Unit* u, const Unit* enemy, bool checkfaction /*= true*/) const
{
+ if (IsInEvadeMode())
+ return false;
+
// is it true?
if (!HasReactState(REACT_AGGRESSIVE))
return false;
@@ -2416,16 +2419,6 @@ std::string const & Creature::GetNameForLocaleIdx(LocaleConstant loc_idx) const
return GetName();
}
-//Do not if this works or not, moving creature to another map is very dangerous
-void Creature::FarTeleportTo(Map* map, float X, float Y, float Z, float O)
-{
- CleanupBeforeRemoveFromMap(false);
- GetMap()->RemoveFromMap(this, false);
- Relocate(X, Y, Z, O);
- SetMap(map);
- GetMap()->AddToMap(this);
-}
-
uint32 Creature::GetPetAutoSpellOnPos(uint8 pos) const
{
if (pos >= MAX_SPELL_CHARM || m_charmInfo->GetCharmSpell(pos)->GetType() != ACT_ENABLED)
diff --git a/src/server/game/Entities/Creature/Creature.h b/src/server/game/Entities/Creature/Creature.h
index b7c86aebfdf..c147c3e3f27 100644
--- a/src/server/game/Entities/Creature/Creature.h
+++ b/src/server/game/Entities/Creature/Creature.h
@@ -669,8 +669,6 @@ class Creature : public Unit, public GridObject<Creature>, public MapObject
float m_SightDistance, m_CombatDistance;
- void FarTeleportTo(Map* map, float X, float Y, float Z, float O);
-
bool m_isTempWorldObject; //true when possessed
// Handling caster facing during spellcast
diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp
index 334cd5ce905..46c9c80851b 100644
--- a/src/server/game/Entities/GameObject/GameObject.cpp
+++ b/src/server/game/Entities/GameObject/GameObject.cpp
@@ -2185,7 +2185,7 @@ Player* GameObject::GetLootRecipient() const
{
if (!m_lootRecipient)
return NULL;
- return ObjectAccessor::FindPlayer(m_lootRecipient);
+ return ObjectAccessor::FindConnectedPlayer(m_lootRecipient);
}
Group* GameObject::GetLootRecipientGroup() const
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index 0b7f358a1d3..14ca3a645d7 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -151,7 +151,7 @@ uint32 const MasterySpells[MAX_CLASSES] =
87491, // Druid
};
-uint64 const MAX_MONEY_AMOUNT = static_cast<uint64>(std::numeric_limits<int64>::max());
+uint64 const MAX_MONEY_AMOUNT = 9999999999ULL;
// == PlayerTaxi ================================================
@@ -4834,11 +4834,8 @@ void Player::DeleteFromDB(ObjectGuid playerguid, uint32 accountId, bool updateRe
{
if (Player* pFriend = ObjectAccessor::FindPlayer(ObjectGuid(HIGHGUID_PLAYER, 0, (*resultFriends)[0].GetUInt32())))
{
- if (pFriend->IsInWorld())
- {
- pFriend->GetSocial()->RemoveFromSocialList(guid, false);
- sSocialMgr->SendFriendStatus(pFriend, FRIEND_REMOVED, guid, false);
- }
+ pFriend->GetSocial()->RemoveFromSocialList(guid, false);
+ sSocialMgr->SendFriendStatus(pFriend, FRIEND_REMOVED, guid, false);
}
} while (resultFriends->NextRow());
}
@@ -21403,7 +21400,7 @@ void Player::RemovePetitionsAndSigns(ObjectGuid guid, uint32 type)
ObjectGuid petitionguid = ObjectGuid(HIGHGUID_ITEM, fields[1].GetUInt32());
// send update if charter owner in game
- Player* owner = ObjectAccessor::FindPlayer(ownerguid);
+ Player* owner = ObjectAccessor::FindConnectedPlayer(ownerguid);
if (owner)
owner->GetSession()->SendPetitionQueryOpcode(petitionguid);
} while (result->NextRow());
diff --git a/src/server/game/Entities/Player/SocialMgr.cpp b/src/server/game/Entities/Player/SocialMgr.cpp
index af076b8a5fb..c4b0165d4bc 100644
--- a/src/server/game/Entities/Player/SocialMgr.cpp
+++ b/src/server/game/Entities/Player/SocialMgr.cpp
@@ -295,7 +295,7 @@ void SocialMgr::BroadcastToFriendListers(Player* player, WorldPacket* packet)
if (itr2 != itr->second.m_playerSocialMap.end() && (itr2->second.Flags & SOCIAL_FLAG_FRIEND))
{
Player* target = ObjectAccessor::FindPlayer(ObjectGuid(HIGHGUID_PLAYER, 0, itr->first));
- if (!target || !target->IsInWorld())
+ if (!target)
continue;
WorldSession* session = target->GetSession();
diff --git a/src/server/game/Entities/Transport/Transport.cpp b/src/server/game/Entities/Transport/Transport.cpp
index 983e2e7c4b3..f237c1aa71a 100644
--- a/src/server/game/Entities/Transport/Transport.cpp
+++ b/src/server/game/Entities/Transport/Transport.cpp
@@ -618,19 +618,6 @@ bool Transport::TeleportTransport(uint32 newMapid, float x, float y, float z, fl
switch (obj->GetTypeId())
{
- case TYPEID_UNIT:
- if (!obj->ToUnit()->GetOwnerGUID().IsPlayer()) // pets should be teleported with player
- obj->ToCreature()->FarTeleportTo(newMap, destX, destY, destZ, destO);
- break;
- case TYPEID_GAMEOBJECT:
- {
- GameObject* go = obj->ToGameObject();
- go->GetMap()->RemoveFromMap(go, false);
- go->Relocate(destX, destY, destZ, destO);
- go->SetMap(newMap);
- newMap->AddToMap(go);
- break;
- }
case TYPEID_PLAYER:
if (!obj->ToPlayer()->TeleportTo(newMapid, destX, destY, destZ, destO, TELE_TO_NOT_LEAVE_TRANSPORT))
RemovePassenger(obj);
@@ -639,6 +626,7 @@ bool Transport::TeleportTransport(uint32 newMapid, float x, float y, float z, fl
obj->AddObjectToRemoveList();
break;
default:
+ RemovePassenger(obj);
break;
}
}
diff --git a/src/server/game/Globals/ObjectAccessor.cpp b/src/server/game/Globals/ObjectAccessor.cpp
index 16dabe4fcad..65b7d19aee3 100644
--- a/src/server/game/Globals/ObjectAccessor.cpp
+++ b/src/server/game/Globals/ObjectAccessor.cpp
@@ -212,6 +212,11 @@ Player* ObjectAccessor::FindPlayer(ObjectGuid guid)
return GetObjectInWorld(guid, (Player*)NULL);
}
+Player* ObjectAccessor::FindConnectedPlayer(ObjectGuid guid)
+{
+ return HashMapHolder<Player>::Find(guid);
+}
+
Unit* ObjectAccessor::FindUnit(ObjectGuid guid)
{
return GetObjectInWorld(guid, (Unit*)NULL);
@@ -237,6 +242,24 @@ Player* ObjectAccessor::FindPlayerByName(std::string const& name)
return NULL;
}
+Player* ObjectAccessor::FindConnectedPlayerByName(std::string const& name)
+{
+ boost::shared_lock<boost::shared_mutex> lock(*HashMapHolder<Player>::GetLock());
+
+ std::string nameStr = name;
+ std::transform(nameStr.begin(), nameStr.end(), nameStr.begin(), ::tolower);
+ HashMapHolder<Player>::MapType const& m = GetPlayers();
+ for (HashMapHolder<Player>::MapType::const_iterator iter = m.begin(); iter != m.end(); ++iter)
+ {
+ std::string currentName = iter->second->GetName();
+ std::transform(currentName.begin(), currentName.end(), currentName.begin(), ::tolower);
+ if (nameStr.compare(currentName) == 0)
+ return iter->second;
+ }
+
+ return NULL;
+}
+
void ObjectAccessor::SaveAllPlayers()
{
boost::shared_lock<boost::shared_mutex> lock(*HashMapHolder<Player>::GetLock());
diff --git a/src/server/game/Globals/ObjectAccessor.h b/src/server/game/Globals/ObjectAccessor.h
index a23932fb702..0b7f7d11f8d 100644
--- a/src/server/game/Globals/ObjectAccessor.h
+++ b/src/server/game/Globals/ObjectAccessor.h
@@ -170,6 +170,10 @@ class ObjectAccessor
static Unit* FindUnit(ObjectGuid);
static Player* FindPlayerByName(std::string const& name);
+ // this returns Player even if he is not in world, for example teleporting
+ static Player* FindConnectedPlayer(ObjectGuid);
+ static Player* FindConnectedPlayerByName(std::string const& name);
+
// when using this, you must use the hashmapholder's lock
static HashMapHolder<Player>::MapType const& GetPlayers()
{
diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp
index b5cabd70d3c..6ceee339d70 100644
--- a/src/server/game/Globals/ObjectMgr.cpp
+++ b/src/server/game/Globals/ObjectMgr.cpp
@@ -1782,6 +1782,21 @@ void ObjectMgr::LoadCreatures()
data.phaseGroup = 0;
}
+ if (sWorld->getBoolConfig(CONFIG_CALCULATE_CREATURE_ZONE_AREA_DATA))
+ {
+ uint32 zoneId = 0;
+ uint32 areaId = 0;
+ sMapMgr->GetZoneAndAreaId(zoneId, areaId, data.mapid, data.posX, data.posY, data.posZ);
+
+ PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_UPD_CREATURE_ZONE_AREA_DATA);
+
+ stmt->setUInt32(0, zoneId);
+ stmt->setUInt32(1, areaId);
+ stmt->setUInt64(2, guid);
+
+ WorldDatabase.Execute(stmt);
+ }
+
// Add to grid if not managed by the game event or pool system
if (gameEvent == 0 && PoolId == 0)
AddCreatureToGrid(guid, &data);
@@ -2105,6 +2120,21 @@ void ObjectMgr::LoadGameobjects()
data.phaseMask = 1;
}
+ if (sWorld->getBoolConfig(CONFIG_CALCULATE_GAMEOBJECT_ZONE_AREA_DATA))
+ {
+ uint32 zoneId = 0;
+ uint32 areaId = 0;
+ sMapMgr->GetZoneAndAreaId(zoneId, areaId, data.mapid, data.posX, data.posY, data.posZ);
+
+ PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_UPD_GAMEOBJECT_ZONE_AREA_DATA);
+
+ stmt->setUInt32(0, zoneId);
+ stmt->setUInt32(1, areaId);
+ stmt->setUInt64(2, guid);
+
+ WorldDatabase.Execute(stmt);
+ }
+
if (gameEvent == 0 && PoolId == 0) // if not this is to be managed by GameEvent System or Pool system
AddGameobjectToGrid(guid, &data);
++count;
@@ -2165,7 +2195,7 @@ ObjectGuid ObjectMgr::GetPlayerGUIDByName(std::string const& name) const
bool ObjectMgr::GetPlayerNameByGUID(ObjectGuid guid, std::string& name) const
{
// prevent DB access for online player
- if (Player* player = ObjectAccessor::FindPlayer(guid))
+ if (Player* player = ObjectAccessor::FindConnectedPlayer(guid))
{
name = player->GetName();
return true;
@@ -2189,7 +2219,7 @@ bool ObjectMgr::GetPlayerNameByGUID(ObjectGuid guid, std::string& name) const
uint32 ObjectMgr::GetPlayerTeamByGUID(ObjectGuid guid) const
{
// prevent DB access for online player
- if (Player* player = ObjectAccessor::FindPlayer(guid))
+ if (Player* player = ObjectAccessor::FindConnectedPlayer(guid))
{
return Player::TeamForRace(player->getRace());
}
@@ -2212,7 +2242,7 @@ uint32 ObjectMgr::GetPlayerTeamByGUID(ObjectGuid guid) const
uint32 ObjectMgr::GetPlayerAccountIdByGUID(ObjectGuid guid) const
{
// prevent DB access for online player
- if (Player* player = ObjectAccessor::FindPlayer(guid))
+ if (Player* player = ObjectAccessor::FindConnectedPlayer(guid))
{
return player->GetSession()->GetAccountId();
}
@@ -5551,7 +5581,7 @@ void ObjectMgr::ReturnOrDeleteOldMails(bool serverUp)
Player* player = NULL;
if (serverUp)
- player = ObjectAccessor::FindPlayer(ObjectGuid(HIGHGUID_PLAYER, m->receiver));
+ player = ObjectAccessor::FindConnectedPlayer(ObjectGuid(HIGHGUID_PLAYER, m->receiver));
if (player && player->m_mailsLoaded)
{ // this code will run very improbably (the time is between 4 and 5 am, in game is online a player, who has old mail
diff --git a/src/server/game/Grids/Notifiers/GridNotifiers.cpp b/src/server/game/Grids/Notifiers/GridNotifiers.cpp
index d5b1022b351..111a5dba77f 100644
--- a/src/server/game/Grids/Notifiers/GridNotifiers.cpp
+++ b/src/server/game/Grids/Notifiers/GridNotifiers.cpp
@@ -73,7 +73,7 @@ void VisibleNotifier::SendToSelf()
if (it->IsPlayer())
{
Player* player = ObjectAccessor::FindPlayer(*it);
- if (player && player->IsInWorld() && !player->isNeedNotify(NOTIFY_VISIBILITY_CHANGED))
+ if (player && !player->isNeedNotify(NOTIFY_VISIBILITY_CHANGED))
player->UpdateVisibilityOf(&i_player);
}
}
diff --git a/src/server/game/Groups/Group.cpp b/src/server/game/Groups/Group.cpp
index 53c5139e20f..95d67f3cb8b 100644
--- a/src/server/game/Groups/Group.cpp
+++ b/src/server/game/Groups/Group.cpp
@@ -526,7 +526,7 @@ bool Group::RemoveMember(ObjectGuid guid, const RemoveMethod& method /*= GROUP_R
// remove member and change leader (if need) only if strong more 2 members _before_ member remove (BG/BF allow 1 member group)
if (GetMembersCount() > ((isBGGroup() || isLFGGroup() || isBFGroup()) ? 1u : 2u))
{
- Player* player = ObjectAccessor::FindPlayer(guid);
+ Player* player = ObjectAccessor::FindConnectedPlayer(guid);
if (player)
{
// Battleground group handling
@@ -610,7 +610,7 @@ bool Group::RemoveMember(ObjectGuid guid, const RemoveMethod& method /*= GROUP_R
{
for (member_witerator itr = m_memberSlots.begin(); itr != m_memberSlots.end(); ++itr)
{
- if (ObjectAccessor::FindPlayer(itr->guid))
+ if (ObjectAccessor::FindConnectedPlayer(itr->guid))
{
ChangeLeader(itr->guid);
break;
@@ -622,7 +622,7 @@ bool Group::RemoveMember(ObjectGuid guid, const RemoveMethod& method /*= GROUP_R
if (isLFGGroup() && GetMembersCount() == 1)
{
- Player* leader = ObjectAccessor::FindPlayer(GetLeaderGUID());
+ Player* leader = ObjectAccessor::FindConnectedPlayer(GetLeaderGUID());
uint32 mapId = sLFGMgr->GetDungeonMapId(GetGUID());
if (!mapId || !leader || (leader->IsAlive() && leader->GetMapId() != mapId))
{
@@ -651,7 +651,7 @@ void Group::ChangeLeader(ObjectGuid newLeaderGuid)
if (slot == m_memberSlots.end())
return;
- Player* newLeader = ObjectAccessor::FindPlayer(slot->guid);
+ Player* newLeader = ObjectAccessor::FindConnectedPlayer(slot->guid);
// Don't allow switching leader to offline players
if (!newLeader)
@@ -699,7 +699,7 @@ void Group::ChangeLeader(ObjectGuid newLeaderGuid)
CharacterDatabase.CommitTransaction(trans);
}
- if (Player* oldLeader = ObjectAccessor::FindPlayer(m_leaderGuid))
+ if (Player* oldLeader = ObjectAccessor::FindConnectedPlayer(m_leaderGuid))
oldLeader->RemoveFlag(PLAYER_FLAGS, PLAYER_FLAGS_GROUP_LEADER);
newLeader->SetFlag(PLAYER_FLAGS, PLAYER_FLAGS_GROUP_LEADER);
@@ -719,7 +719,7 @@ void Group::Disband(bool hideDestroy /* = false */)
Player* player;
for (member_citerator citr = m_memberSlots.begin(); citr != m_memberSlots.end(); ++citr)
{
- player = ObjectAccessor::FindPlayer(citr->guid);
+ player = ObjectAccessor::FindConnectedPlayer(citr->guid);
if (!player)
continue;
@@ -818,7 +818,7 @@ void Group::SendLootStartRoll(uint32 countDown, uint32 mapid, const Roll &r)
for (Roll::PlayerVote::const_iterator itr=r.playerVote.begin(); itr != r.playerVote.end(); ++itr)
{
- Player* p = ObjectAccessor::FindPlayer(itr->first);
+ Player* p = ObjectAccessor::FindConnectedPlayer(itr->first);
if (!p || !p->GetSession())
continue;
@@ -865,7 +865,7 @@ void Group::SendLootRoll(ObjectGuid sourceGuid, ObjectGuid targetGuid, uint8 rol
for (Roll::PlayerVote::const_iterator itr = roll.playerVote.begin(); itr != roll.playerVote.end(); ++itr)
{
- Player* p = ObjectAccessor::FindPlayer(itr->first);
+ Player* p = ObjectAccessor::FindConnectedPlayer(itr->first);
if (!p || !p->GetSession())
continue;
@@ -888,7 +888,7 @@ void Group::SendLootRollWon(ObjectGuid sourceGuid, ObjectGuid targetGuid, uint8
for (Roll::PlayerVote::const_iterator itr = roll.playerVote.begin(); itr != roll.playerVote.end(); ++itr)
{
- Player* p = ObjectAccessor::FindPlayer(itr->first);
+ Player* p = ObjectAccessor::FindConnectedPlayer(itr->first);
if (!p || !p->GetSession())
continue;
@@ -908,7 +908,7 @@ void Group::SendLootAllPassed(Roll const& roll)
for (Roll::PlayerVote::const_iterator itr = roll.playerVote.begin(); itr != roll.playerVote.end(); ++itr)
{
- Player* player = ObjectAccessor::FindPlayer(itr->first);
+ Player* player = ObjectAccessor::FindConnectedPlayer(itr->first);
if (!player || !player->GetSession())
continue;
@@ -1000,7 +1000,7 @@ void Group::GroupLoot(Loot* loot, WorldObject* pLootedObject)
{
for (Roll::PlayerVote::const_iterator itr=r->playerVote.begin(); itr != r->playerVote.end(); ++itr)
{
- Player* p = ObjectAccessor::FindPlayer(itr->first);
+ Player* p = ObjectAccessor::FindConnectedPlayer(itr->first);
if (!p || !p->GetSession())
continue;
@@ -1143,7 +1143,7 @@ void Group::NeedBeforeGreed(Loot* loot, WorldObject* lootedObject)
//Broadcast Pass and Send Rollstart
for (Roll::PlayerVote::const_iterator itr = r->playerVote.begin(); itr != r->playerVote.end(); ++itr)
{
- Player* p = ObjectAccessor::FindPlayer(itr->first);
+ Player* p = ObjectAccessor::FindConnectedPlayer(itr->first);
if (!p || !p->GetSession())
continue;
@@ -1206,7 +1206,7 @@ void Group::NeedBeforeGreed(Loot* loot, WorldObject* lootedObject)
//Broadcast Pass and Send Rollstart
for (Roll::PlayerVote::const_iterator itr = r->playerVote.begin(); itr != r->playerVote.end(); ++itr)
{
- Player* p = ObjectAccessor::FindPlayer(itr->first);
+ Player* p = ObjectAccessor::FindConnectedPlayer(itr->first);
if (!p || !p->GetSession())
continue;
@@ -1373,7 +1373,7 @@ void Group::CountTheRoll(Rolls::iterator rollI)
}
}
SendLootRollWon(ObjectGuid::Empty, maxguid, maxresul, ROLL_NEED, *roll);
- player = ObjectAccessor::FindPlayer(maxguid);
+ player = ObjectAccessor::FindConnectedPlayer(maxguid);
if (player && player->GetSession())
{
@@ -1422,7 +1422,7 @@ void Group::CountTheRoll(Rolls::iterator rollI)
}
}
SendLootRollWon(ObjectGuid::Empty, maxguid, maxresul, rollvote, *roll);
- player = ObjectAccessor::FindPlayer(maxguid);
+ player = ObjectAccessor::FindConnectedPlayer(maxguid);
if (player && player->GetSession())
{
@@ -1539,7 +1539,7 @@ void Group::SendUpdate()
void Group::SendUpdateToPlayer(ObjectGuid playerGUID, MemberSlot* slot)
{
- Player* player = ObjectAccessor::FindPlayer(playerGUID);
+ Player* player = ObjectAccessor::FindConnectedPlayer(playerGUID);
if (!player || !player->GetSession() || player->GetGroup() != this)
return;
@@ -1575,7 +1575,7 @@ void Group::SendUpdateToPlayer(ObjectGuid playerGUID, MemberSlot* slot)
if (slot->guid == citr->guid)
continue;
- Player* member = ObjectAccessor::FindPlayer(citr->guid);
+ Player* member = ObjectAccessor::FindConnectedPlayer(citr->guid);
uint8 onlineState = (member && !member->GetSession()->PlayerLogout()) ? MEMBER_STATUS_ONLINE : MEMBER_STATUS_OFFLINE;
onlineState = onlineState | ((isBGGroup() || isBFGroup()) ? MEMBER_STATUS_PVP : 0);
@@ -1667,7 +1667,7 @@ void Group::OfflineReadyCheck()
{
for (member_citerator citr = m_memberSlots.begin(); citr != m_memberSlots.end(); ++citr)
{
- Player* player = ObjectAccessor::FindPlayer(citr->guid);
+ Player* player = ObjectAccessor::FindConnectedPlayer(citr->guid);
if (!player || !player->GetSession())
{
WorldPacket data(MSG_RAID_READY_CHECK_CONFIRM, 9);
@@ -1750,7 +1750,7 @@ void Group::ChangeMembersGroup(ObjectGuid guid, uint8 group)
}
// In case the moved player is online, update the player object with the new sub group references
- if (Player* player = ObjectAccessor::FindPlayer(guid))
+ if (Player* player = ObjectAccessor::FindConnectedPlayer(guid))
{
if (player->GetGroup() == this)
player->GetGroupRef().setSubGroup(group);
@@ -2175,7 +2175,7 @@ void Group::BroadcastGroupUpdate(void)
for (member_citerator citr = m_memberSlots.begin(); citr != m_memberSlots.end(); ++citr)
{
Player* pp = ObjectAccessor::FindPlayer(citr->guid);
- if (pp && pp->IsInWorld())
+ if (pp)
{
pp->ForceValuesUpdateAtIndex(UNIT_FIELD_BYTES_2);
pp->ForceValuesUpdateAtIndex(UNIT_FIELD_FACTIONTEMPLATE);
diff --git a/src/server/game/Guilds/Guild.cpp b/src/server/game/Guilds/Guild.cpp
index 3f346a0b8c7..b7f3f2c2f79 100644
--- a/src/server/game/Guilds/Guild.cpp
+++ b/src/server/game/Guilds/Guild.cpp
@@ -1760,7 +1760,7 @@ void Guild::HandleBuyBankTab(WorldSession* session, uint8 tabId)
void Guild::HandleInviteMember(WorldSession* session, std::string const& name)
{
- Player* pInvitee = sObjectAccessor->FindPlayerByName(name);
+ Player* pInvitee = ObjectAccessor::FindPlayerByName(name);
if (!pInvitee)
{
SendCommandResult(session, GUILD_COMMAND_INVITE, ERR_GUILD_PLAYER_NOT_FOUND_S, name);
@@ -2616,7 +2616,7 @@ void Guild::BroadcastToGuild(WorldSession* session, bool officerOnly, std::strin
WorldPacket data;
ChatHandler::BuildChatPacket(data, officerOnly ? CHAT_MSG_OFFICER : CHAT_MSG_GUILD, Language(language), session->GetPlayer(), NULL, msg);
for (Members::const_iterator itr = m_members.begin(); itr != m_members.end(); ++itr)
- if (Player* player = itr->second->FindPlayer())
+ if (Player* player = itr->second->FindConnectedPlayer())
if (player->GetSession() && _HasRankRight(player, officerOnly ? GR_RIGHT_OFFCHATLISTEN : GR_RIGHT_GCHATLISTEN) &&
!player->GetSocial()->HasIgnore(session->GetPlayer()->GetGUIDLow()))
player->GetSession()->SendPacket(&data);
@@ -2642,7 +2642,7 @@ void Guild::BroadcastPacketToRank(WorldPacket* packet, uint8 rankId) const
{
for (Members::const_iterator itr = m_members.begin(); itr != m_members.end(); ++itr)
if (itr->second->IsRank(rankId))
- if (Player* player = itr->second->FindPlayer())
+ if (Player* player = itr->second->FindConnectedPlayer())
player->GetSession()->SendPacket(packet);
}
@@ -2697,7 +2697,7 @@ void Guild::MassInviteToEvent(WorldSession* session, uint32 minLevel, uint32 max
// Members handling
bool Guild::AddMember(ObjectGuid guid, uint8 rankId)
{
- Player* player = ObjectAccessor::FindPlayer(guid);
+ Player* player = ObjectAccessor::FindConnectedPlayer(guid);
// Player cannot be in guild
if (player)
{
@@ -2777,7 +2777,7 @@ bool Guild::AddMember(ObjectGuid guid, uint8 rankId)
void Guild::DeleteMember(ObjectGuid guid, bool isDisbanding, bool isKicked, bool canDeleteGuild)
{
uint32 lowguid = guid.GetCounter();
- Player* player = ObjectAccessor::FindPlayer(guid);
+ Player* player = ObjectAccessor::FindConnectedPlayer(guid);
// Guild master can be deleted when loading guild and guid doesn't exist in characters table
// or when he is removed from guild by gm command
diff --git a/src/server/game/Guilds/Guild.h b/src/server/game/Guilds/Guild.h
index 5448180e0ae..4160edf5250 100644
--- a/src/server/game/Guilds/Guild.h
+++ b/src/server/game/Guilds/Guild.h
@@ -413,6 +413,7 @@ private:
void ResetValues(bool weekly = false);
inline Player* FindPlayer() const { return ObjectAccessor::FindPlayer(m_guid); }
+ inline Player* FindConnectedPlayer() const { return ObjectAccessor::FindConnectedPlayer(m_guid); }
private:
uint32 m_guildId;
@@ -855,7 +856,7 @@ public:
void BroadcastWorker(Do& _do, Player* except = NULL)
{
for (Members::iterator itr = m_members.begin(); itr != m_members.end(); ++itr)
- if (Player* player = itr->second->FindPlayer())
+ if (Player* player = itr->second->FindConnectedPlayer())
if (player != except)
_do(player);
}
diff --git a/src/server/game/Handlers/ArenaTeamHandler.cpp b/src/server/game/Handlers/ArenaTeamHandler.cpp
index d9303d0295a..0f40650691f 100644
--- a/src/server/game/Handlers/ArenaTeamHandler.cpp
+++ b/src/server/game/Handlers/ArenaTeamHandler.cpp
@@ -147,7 +147,7 @@ void WorldSession::HandleArenaTeamInviteOpcode(WorldPacket& recvData)
if (!normalizePlayerName(invitedName))
return;
- player = sObjectAccessor->FindPlayerByName(invitedName);
+ player = ObjectAccessor::FindPlayerByName(invitedName);
}
if (!player)
diff --git a/src/server/game/Handlers/CalendarHandler.cpp b/src/server/game/Handlers/CalendarHandler.cpp
index 954b4483f62..4d3b7dd024e 100644
--- a/src/server/game/Handlers/CalendarHandler.cpp
+++ b/src/server/game/Handlers/CalendarHandler.cpp
@@ -436,7 +436,7 @@ void WorldSession::HandleCalendarEventInvite(WorldPacket& recvData)
recvData >> eventId >> inviteId >> name >> isPreInvite >> isGuildEvent;
- if (Player* player = sObjectAccessor->FindPlayerByName(name.c_str()))
+ if (Player* player = ObjectAccessor::FindConnectedPlayerByName(name))
{
// Invitee is online
inviteeGuid = player->GetGUID();
diff --git a/src/server/game/Handlers/CharacterHandler.cpp b/src/server/game/Handlers/CharacterHandler.cpp
index feefaec83ab..bef7aada6e9 100644
--- a/src/server/game/Handlers/CharacterHandler.cpp
+++ b/src/server/game/Handlers/CharacterHandler.cpp
@@ -47,6 +47,7 @@
#include "World.h"
#include "WorldPacket.h"
#include "WorldSession.h"
+#include "BattlenetServerManager.h"
class LoginQueryHolder : public SQLQueryHolder
{
@@ -689,13 +690,13 @@ void WorldSession::HandleCharCreateCallback(PreparedQueryResult result, Characte
PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_DEL_REALM_CHARACTERS_BY_REALM);
stmt->setUInt32(0, GetAccountId());
- stmt->setUInt32(1, realmID);
+ stmt->setUInt32(1, realmHandle.Index);
trans->Append(stmt);
stmt = LoginDatabase.GetPreparedStatement(LOGIN_INS_REALM_CHARACTERS);
stmt->setUInt32(0, createInfo->CharCount);
stmt->setUInt32(1, GetAccountId());
- stmt->setUInt32(2, realmID);
+ stmt->setUInt32(2, realmHandle.Index);
trans->Append(stmt);
LoginDatabase.CommitTransaction(trans);
@@ -784,7 +785,7 @@ void WorldSession::HandleCharDeleteOpcode(WorldPacket& recvData)
{
std::string dump;
if (PlayerDumpWriter().GetDump(guid.GetCounter(), dump))
- sLog->outCharDump(dump.c_str(), accountId, guid.GetCounter(), name.c_str());
+ sLog->outCharDump(dump.c_str(), accountId, guid.GetRawValue(), name.c_str());
}
sGuildFinderMgr->RemoveAllMembershipRequestsFromPlayer(guid);
@@ -1139,6 +1140,8 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder* holder)
sScriptMgr->OnPlayerLogin(pCurrChar, firstLogin);
+ sBattlenetServer.SendChangeToonOnlineState(GetBattlenetAccountId(), GetAccountId(), _player->GetGUID(), _player->GetName(), true);
+
delete holder;
}
diff --git a/src/server/game/Handlers/ChatHandler.cpp b/src/server/game/Handlers/ChatHandler.cpp
index a65c03b25a1..73600ba7c60 100644
--- a/src/server/game/Handlers/ChatHandler.cpp
+++ b/src/server/game/Handlers/ChatHandler.cpp
@@ -326,7 +326,7 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData)
break;
}
- Player* receiver = sObjectAccessor->FindPlayerByName(to);
+ Player* receiver = ObjectAccessor::FindConnectedPlayerByName(to);
if (!receiver || (lang != LANG_ADDON && !receiver->isAcceptWhispers() && receiver->GetSession()->HasPermission(rbac::RBAC_PERM_CAN_FILTER_WHISPERS) && !receiver->IsInWhisperWhiteList(sender->GetGUID())))
{
SendPlayerNotFoundNotice(to);
@@ -803,7 +803,7 @@ void WorldSession::HandleChatIgnoredOpcode(WorldPacket& recvData)
recvData.ReadByteSeq(guid[7]);
recvData.ReadByteSeq(guid[2]);
- Player* player = ObjectAccessor::FindPlayer(guid);
+ Player* player = ObjectAccessor::FindConnectedPlayer(guid);
if (!player || !player->GetSession())
return;
diff --git a/src/server/game/Handlers/GroupHandler.cpp b/src/server/game/Handlers/GroupHandler.cpp
index 149d309f995..10a16dc6b48 100644
--- a/src/server/game/Handlers/GroupHandler.cpp
+++ b/src/server/game/Handlers/GroupHandler.cpp
@@ -106,7 +106,7 @@ void WorldSession::HandleGroupInviteOpcode(WorldPacket& recvData)
return;
}
- Player* player = sObjectAccessor->FindPlayerByName(memberName);
+ Player* player = ObjectAccessor::FindPlayerByName(memberName);
// no player
if (!player)
@@ -384,7 +384,7 @@ void WorldSession::HandleGroupInviteResponseOpcode(WorldPacket& recvData)
else
{
// Remember leader if online (group pointer will be invalid if group gets disbanded)
- Player* leader = ObjectAccessor::FindPlayer(group->GetLeaderGUID());
+ Player* leader = ObjectAccessor::FindConnectedPlayer(group->GetLeaderGUID());
// uninvite, group can be deleted
GetPlayer()->UninviteFromGroup();
@@ -500,7 +500,7 @@ void WorldSession::HandleGroupSetLeaderOpcode(WorldPacket& recvData)
ObjectGuid guid;
recvData >> guid;
- Player* player = ObjectAccessor::FindPlayer(guid);
+ Player* player = ObjectAccessor::FindConnectedPlayer(guid);
Group* group = GetPlayer()->GetGroup();
if (!group || !player)
@@ -755,7 +755,7 @@ void WorldSession::HandleRaidTargetUpdateOpcode(WorldPacket& recvData)
if (guid.IsPlayer())
{
- Player* target = ObjectAccessor::FindPlayer(guid);
+ Player* target = ObjectAccessor::FindConnectedPlayer(guid);
if (!target || target->IsHostileTo(GetPlayer()))
return;
@@ -831,7 +831,7 @@ void WorldSession::HandleGroupChangeSubGroupOpcode(WorldPacket& recvData)
if (!group->HasFreeSlotSubGroup(groupNr))
return;
- Player* movedPlayer = sObjectAccessor->FindPlayerByName(name);
+ Player* movedPlayer = ObjectAccessor::FindConnectedPlayerByName(name);
ObjectGuid guid;
if (movedPlayer)
@@ -1200,7 +1200,7 @@ void WorldSession::HandleRequestPartyMemberStatsOpcode(WorldPacket& recvData)
ObjectGuid Guid;
recvData >> Guid;
- Player* player = HashMapHolder<Player>::Find(Guid);
+ Player* player = ObjectAccessor::FindConnectedPlayer(Guid);
if (!player)
{
WorldPacket data(SMSG_PARTY_MEMBER_STATS_FULL, 3+4+2);
diff --git a/src/server/game/Handlers/LFGHandler.cpp b/src/server/game/Handlers/LFGHandler.cpp
index ea8f86e2adf..654a92f5c4e 100644
--- a/src/server/game/Handlers/LFGHandler.cpp
+++ b/src/server/game/Handlers/LFGHandler.cpp
@@ -230,8 +230,8 @@ void WorldSession::HandleLfgSetRolesOpcode(WorldPacket& recvData)
return;
}
ObjectGuid gguid = group->GetGUID();
- TC_LOG_DEBUG("lfg", "CMSG_LFG_SET_ROLES: Group %u, Player %s, Roles: %u",
- gguid.GetCounter(), GetPlayerInfo().c_str(), roles);
+ TC_LOG_DEBUG("lfg", "CMSG_LFG_SET_ROLES: Group %s, Player %s, Roles: %u",
+ gguid.ToString().c_str(), GetPlayerInfo().c_str(), roles);
sLFGMgr->UpdateRoleCheck(gguid, guid, roles);
}
@@ -497,8 +497,8 @@ void WorldSession::SendLfgUpdateStatus(lfg::LfgUpdateData const& updateData, boo
void WorldSession::SendLfgRoleChosen(ObjectGuid guid, uint8 roles)
{
- TC_LOG_DEBUG("lfg", "SMSG_LFG_ROLE_CHOSEN %s guid: %u roles: %u",
- GetPlayerInfo().c_str(), guid.GetCounter(), roles);
+ TC_LOG_DEBUG("lfg", "SMSG_LFG_ROLE_CHOSEN %s guid: %s roles: %u",
+ GetPlayerInfo().c_str(), guid.ToString().c_str(), roles);
WorldPacket data(SMSG_LFG_ROLE_CHOSEN, 8 + 1 + 4);
data << uint64(guid); // Guid
@@ -531,7 +531,7 @@ void WorldSession::SendLfgRoleCheckUpdate(lfg::LfgRoleCheck const& roleCheck)
// Leader info MUST be sent 1st :S
ObjectGuid guid = roleCheck.leader;
uint8 roles = roleCheck.roles.find(guid)->second;
- Player* player = ObjectAccessor::FindPlayer(guid);
+ Player* player = ObjectAccessor::FindConnectedPlayer(guid);
data << uint64(guid); // Guid
data << uint8(roles > 0); // Ready
data << uint32(roles); // Roles
@@ -544,7 +544,7 @@ void WorldSession::SendLfgRoleCheckUpdate(lfg::LfgRoleCheck const& roleCheck)
guid = it->first;
roles = it->second;
- player = ObjectAccessor::FindPlayer(guid);
+ player = ObjectAccessor::FindConnectedPlayer(guid);
data << uint64(guid); // Guid
data << uint8(roles > 0); // Ready
data << uint32(roles); // Roles
@@ -709,10 +709,10 @@ void WorldSession::SendLfgBootProposalUpdate(lfg::LfgPlayerBoot const& boot)
}
}
TC_LOG_DEBUG("lfg", "SMSG_LFG_BOOT_PROPOSAL_UPDATE %s inProgress: %u - "
- "didVote: %u - agree: %u - victim: %u votes: %u - agrees: %u - left: %u - "
+ "didVote: %u - agree: %u - victim: %s votes: %u - agrees: %u - left: %u - "
"needed: %u - reason %s",
GetPlayerInfo().c_str(), uint8(boot.inProgress), uint8(playerVote != lfg::LFG_ANSWER_PENDING),
- uint8(playerVote == lfg::LFG_ANSWER_AGREE), boot.victim.GetCounter(), votesNum, agreeNum,
+ uint8(playerVote == lfg::LFG_ANSWER_AGREE), boot.victim.ToString().c_str(), votesNum, agreeNum,
secsleft, lfg::LFG_GROUP_KICK_VOTES_NEEDED, boot.reason.c_str());
WorldPacket data(SMSG_LFG_BOOT_PROPOSAL_UPDATE, 1 + 1 + 1 + 1 + 8 + 4 + 4 + 4 + 4 + boot.reason.length());
data << uint8(boot.inProgress); // Vote in progress
diff --git a/src/server/game/Handlers/MailHandler.cpp b/src/server/game/Handlers/MailHandler.cpp
index adf70223db9..e2f9f36163e 100644
--- a/src/server/game/Handlers/MailHandler.cpp
+++ b/src/server/game/Handlers/MailHandler.cpp
@@ -194,7 +194,7 @@ void WorldSession::HandleSendMail(WorldPacket& recvData)
return;
}
- Player* receiver = ObjectAccessor::FindPlayer(receiverGuid);
+ Player* receiver = ObjectAccessor::FindConnectedPlayer(receiverGuid);
uint32 receiverTeam = 0;
uint8 mailsCount = 0; //do not allow to send to one player more than 100 mails
@@ -554,7 +554,7 @@ void WorldSession::HandleMailTakeItem(WorldPacket& recvData)
if (m->COD > 0) //if there is COD, take COD money from player and send them to sender by mail
{
ObjectGuid sender_guid(HIGHGUID_PLAYER, m->sender);
- Player* receiver = ObjectAccessor::FindPlayer(sender_guid);
+ Player* receiver = ObjectAccessor::FindConnectedPlayer(sender_guid);
uint32 sender_accId = 0;
diff --git a/src/server/game/Handlers/MiscHandler.cpp b/src/server/game/Handlers/MiscHandler.cpp
index 279b06e2cef..a149d066a05 100644
--- a/src/server/game/Handlers/MiscHandler.cpp
+++ b/src/server/game/Handlers/MiscHandler.cpp
@@ -258,7 +258,7 @@ void WorldSession::HandleWhoOpcode(WorldPacket& recvData)
boost::shared_lock<boost::shared_mutex> lock(*HashMapHolder<Player>::GetLock());
- HashMapHolder<Player>::MapType const& m = sObjectAccessor->GetPlayers();
+ HashMapHolder<Player>::MapType const& m = ObjectAccessor::GetPlayers();
for (HashMapHolder<Player>::MapType::const_iterator itr = m.begin(); itr != m.end(); ++itr)
{
Player* target = itr->second;
@@ -415,7 +415,8 @@ void WorldSession::HandleLogoutRequestOpcode(WorldPacket& /*recvData*/)
// not set flags if player can't free move to prevent lost state at logout cancel
if (GetPlayer()->CanFreeMove())
{
- GetPlayer()->SetStandState(UNIT_STAND_STATE_SIT);
+ if (GetPlayer()->getStandState() == UNIT_STAND_STATE_STAND)
+ GetPlayer()->SetStandState(UNIT_STAND_STATE_SIT);
GetPlayer()->SetRooted(true);
GetPlayer()->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED);
}
@@ -608,7 +609,7 @@ void WorldSession::HandleAddFriendOpcodeCallBack(PreparedQueryResult result, std
team = Player::TeamForRace(fields[1].GetUInt8());
friendAccountId = fields[2].GetUInt32();
- if (HasPermission(rbac::RBAC_PERM_ALLOW_GM_FRIEND) || AccountMgr::IsPlayerAccount(AccountMgr::GetSecurity(friendAccountId, realmID)))
+ if (HasPermission(rbac::RBAC_PERM_ALLOW_GM_FRIEND) || AccountMgr::IsPlayerAccount(AccountMgr::GetSecurity(friendAccountId, realmHandle.Index)))
{
if (friendGuid)
{
@@ -621,7 +622,7 @@ void WorldSession::HandleAddFriendOpcodeCallBack(PreparedQueryResult result, std
else
{
Player* pFriend = ObjectAccessor::FindPlayer(friendGuid);
- if (pFriend && pFriend->IsInWorld() && pFriend->IsVisibleGloballyFor(GetPlayer()))
+ if (pFriend && pFriend->IsVisibleGloballyFor(GetPlayer()))
friendResult = FRIEND_ADDED_ONLINE;
else
friendResult = FRIEND_ADDED_OFFLINE;
@@ -1374,7 +1375,7 @@ void WorldSession::HandleWhoisOpcode(WorldPacket& recvData)
return;
}
- Player* player = sObjectAccessor->FindPlayerByName(charname);
+ Player* player = ObjectAccessor::FindConnectedPlayerByName(charname);
if (!player)
{
diff --git a/src/server/game/Handlers/PetitionsHandler.cpp b/src/server/game/Handlers/PetitionsHandler.cpp
index d3d32745c5e..a8df52344a0 100644
--- a/src/server/game/Handlers/PetitionsHandler.cpp
+++ b/src/server/game/Handlers/PetitionsHandler.cpp
@@ -263,7 +263,7 @@ void WorldSession::HandlePetitionShowSignOpcode(WorldPacket& recvData)
if (!result)
{
- TC_LOG_DEBUG("entities.player.items", "Petition %u is not found for player %u %s", petitionguid.GetCounter(), GetPlayer()->GetGUIDLow(), GetPlayer()->GetName().c_str());
+ TC_LOG_DEBUG("entities.player.items", "Petition %s is not found for player %u %s", petitionguid.ToString().c_str(), GetPlayer()->GetGUIDLow(), GetPlayer()->GetName().c_str());
return;
}
Field* fields = result->Fetch();
@@ -581,7 +581,7 @@ void WorldSession::HandlePetitionSignOpcode(WorldPacket& recvData)
// item->SetUInt32Value(ITEM_FIELD_ENCHANTMENT_1_1+1, signs);
// update for owner if online
- if (Player* owner = ObjectAccessor::FindPlayer(ownerGuid))
+ if (Player* owner = ObjectAccessor::FindConnectedPlayer(ownerGuid))
owner->GetSession()->SendPacket(&data);
}
@@ -605,7 +605,7 @@ void WorldSession::HandlePetitionDeclineOpcode(WorldPacket& recvData)
Field* fields = result->Fetch();
ObjectGuid ownerguid(HIGHGUID_PLAYER, 0, fields[0].GetUInt32());
- Player* owner = ObjectAccessor::FindPlayer(ownerguid);
+ Player* owner = ObjectAccessor::FindConnectedPlayer(ownerguid);
if (owner) // petition owner online
{
WorldPacket data(MSG_PETITION_DECLINE, 8);
@@ -626,7 +626,7 @@ void WorldSession::HandleOfferPetitionOpcode(WorldPacket& recvData)
recvData >> petitionguid; // petition guid
recvData >> plguid; // player guid
- player = ObjectAccessor::FindPlayer(plguid);
+ player = ObjectAccessor::FindConnectedPlayer(plguid);
if (!player)
return;
diff --git a/src/server/game/Handlers/QueryHandler.cpp b/src/server/game/Handlers/QueryHandler.cpp
index 1418cd8a2d8..84f117a0000 100644
--- a/src/server/game/Handlers/QueryHandler.cpp
+++ b/src/server/game/Handlers/QueryHandler.cpp
@@ -33,7 +33,7 @@
void WorldSession::SendNameQueryOpcode(ObjectGuid guid)
{
- Player* player = ObjectAccessor::FindPlayer(guid);
+ Player* player = ObjectAccessor::FindConnectedPlayer(guid);
CharacterNameData const* nameData = sWorld->GetCharacterNameData(guid);
WorldPacket data(SMSG_NAME_QUERY_RESPONSE, (8+1+1+1+1+1+10));
diff --git a/src/server/game/Instances/InstanceSaveMgr.cpp b/src/server/game/Instances/InstanceSaveMgr.cpp
index 9f565c8d58d..f739c0f35dd 100644
--- a/src/server/game/Instances/InstanceSaveMgr.cpp
+++ b/src/server/game/Instances/InstanceSaveMgr.cpp
@@ -385,7 +385,7 @@ void InstanceSaveManager::LoadResetTimes()
if (oldresettime != newresettime)
CharacterDatabase.DirectPExecute("UPDATE instance_reset SET resettime = '%u' WHERE mapid = '%u' AND difficulty = '%u'", uint32(newresettime), mapid, difficulty);
- SetResetTimeFor(mapid, difficulty, newresettime);
+ InitializeResetTimeFor(mapid, difficulty, newresettime);
} while (result->NextRow());
}
@@ -422,7 +422,7 @@ void InstanceSaveManager::LoadResetTimes()
CharacterDatabase.DirectPExecute("UPDATE instance_reset SET resettime = '" UI64FMTD "' WHERE mapid = '%u' AND difficulty= '%u'", (uint64)t, mapid, difficulty);
}
- SetResetTimeFor(mapid, difficulty, t);
+ InitializeResetTimeFor(mapid, difficulty, t);
// schedule the global reset/warning
uint8 type;
diff --git a/src/server/game/Instances/InstanceSaveMgr.h b/src/server/game/Instances/InstanceSaveMgr.h
index 72d180c2373..b2c86d5152b 100644
--- a/src/server/game/Instances/InstanceSaveMgr.h
+++ b/src/server/game/Instances/InstanceSaveMgr.h
@@ -191,11 +191,20 @@ class InstanceSaveManager
return itr != m_resetTimeByMapDifficulty.end() ? itr->second : 0;
}
- void SetResetTimeFor(uint32 mapid, Difficulty d, time_t t)
+ // Use this on startup when initializing reset times
+ void InitializeResetTimeFor(uint32 mapid, Difficulty d, time_t t)
{
m_resetTimeByMapDifficulty[MAKE_PAIR32(mapid, d)] = t;
}
+ // Use this only when updating existing reset times
+ void SetResetTimeFor(uint32 mapid, Difficulty d, time_t t)
+ {
+ ResetTimeByMapDifficultyMap::iterator itr = m_resetTimeByMapDifficulty.find(MAKE_PAIR32(mapid, d));
+ ASSERT(itr != m_resetTimeByMapDifficulty.end());
+ itr->second = t;
+ }
+
ResetTimeByMapDifficultyMap const& GetResetTimeMap() const
{
return m_resetTimeByMapDifficulty;
diff --git a/src/server/game/Loot/LootMgr.cpp b/src/server/game/Loot/LootMgr.cpp
index 4a30b4f4b97..35b62bd24c3 100644
--- a/src/server/game/Loot/LootMgr.cpp
+++ b/src/server/game/Loot/LootMgr.cpp
@@ -272,9 +272,14 @@ void LootStore::ReportUnusedIds(LootIdSet const& lootIdSet) const
TC_LOG_ERROR("sql.sql", "Table '%s' Entry %d isn't %s and not referenced from loot, and thus useless.", GetName(), *itr, GetEntryName());
}
-void LootStore::ReportNonExistingId(uint32 id) const
+void LootStore::ReportNonExistingId(uint32 lootId) const
{
- TC_LOG_ERROR("sql.sql", "Table '%s' Entry %d (%s) does not exist but is used as loot id in DB.", GetName(), id, GetEntryName());
+ TC_LOG_ERROR("sql.sql", "Table '%s' Entry %d does not exist", GetName(), lootId);
+}
+
+void LootStore::ReportNonExistingId(uint32 lootId, const char* ownerType, uint32 ownerId) const
+{
+ TC_LOG_ERROR("sql.sql", "Table '%s' Entry %d does not exist but it is used by %s %d", GetName(), lootId, ownerType, ownerId);
}
//
@@ -1223,7 +1228,7 @@ void LootTemplate::LootGroup::CheckLootRefs(LootTemplateMap const& /*store*/, Lo
if (item->reference > 0)
{
if (!LootTemplates_Reference.GetLootFor(item->reference))
- LootTemplates_Reference.ReportNonExistingId(item->reference);
+ LootTemplates_Reference.ReportNonExistingId(item->reference, "Reference", item->itemid);
else if (ref_set)
ref_set->erase(item->reference);
}
@@ -1235,7 +1240,7 @@ void LootTemplate::LootGroup::CheckLootRefs(LootTemplateMap const& /*store*/, Lo
if (item->reference > 0)
{
if (!LootTemplates_Reference.GetLootFor(item->reference))
- LootTemplates_Reference.ReportNonExistingId(item->reference);
+ LootTemplates_Reference.ReportNonExistingId(item->reference, "Reference", item->itemid);
else if (ref_set)
ref_set->erase(item->reference);
}
@@ -1436,7 +1441,7 @@ void LootTemplate::CheckLootRefs(LootTemplateMap const& store, LootIdSet* ref_se
if (item->reference > 0)
{
if (!LootTemplates_Reference.GetLootFor(item->reference))
- LootTemplates_Reference.ReportNonExistingId(item->reference);
+ LootTemplates_Reference.ReportNonExistingId(item->reference, "Reference", item->itemid);
else if (ref_set)
ref_set->erase(item->reference);
}
@@ -1530,7 +1535,7 @@ void LoadLootTemplates_Creature()
if (uint32 lootid = itr->second.lootid)
{
if (lootIdSet.find(lootid) == lootIdSet.end())
- LootTemplates_Creature.ReportNonExistingId(lootid);
+ LootTemplates_Creature.ReportNonExistingId(lootid, "Creature", itr->second.Entry);
else
lootIdSetUsed.insert(lootid);
}
@@ -1622,7 +1627,7 @@ void LoadLootTemplates_Gameobject()
if (uint32 lootid = itr->second.GetLootId())
{
if (lootIdSet.find(lootid) == lootIdSet.end())
- LootTemplates_Gameobject.ReportNonExistingId(lootid);
+ LootTemplates_Gameobject.ReportNonExistingId(lootid, "Gameobject", itr->second.entry);
else
lootIdSetUsed.insert(lootid);
}
@@ -1709,7 +1714,7 @@ void LoadLootTemplates_Pickpocketing()
if (uint32 lootid = itr->second.pickpocketLootId)
{
if (lootIdSet.find(lootid) == lootIdSet.end())
- LootTemplates_Pickpocketing.ReportNonExistingId(lootid);
+ LootTemplates_Pickpocketing.ReportNonExistingId(lootid, "Creature", itr->second.Entry);
else
lootIdSetUsed.insert(lootid);
}
@@ -1796,7 +1801,7 @@ void LoadLootTemplates_Skinning()
if (uint32 lootid = itr->second.SkinLootId)
{
if (lootIdSet.find(lootid) == lootIdSet.end())
- LootTemplates_Skinning.ReportNonExistingId(lootid);
+ LootTemplates_Skinning.ReportNonExistingId(lootid, "Creature", itr->second.Entry);
else
lootIdSetUsed.insert(lootid);
}
@@ -1840,7 +1845,7 @@ void LoadLootTemplates_Spell()
// ignore 61756 (Northrend Inscription Research (FAST QA VERSION) for example
if (!(spellInfo->Attributes & SPELL_ATTR0_NOT_SHAPESHIFT) || (spellInfo->Attributes & SPELL_ATTR0_TRADESPELL))
{
- LootTemplates_Spell.ReportNonExistingId(spell_id);
+ LootTemplates_Spell.ReportNonExistingId(spell_id, "Spell", spellInfo->Id);
}
}
else
diff --git a/src/server/game/Loot/LootMgr.h b/src/server/game/Loot/LootMgr.h
index 1685996fd03..52632393ca1 100644
--- a/src/server/game/Loot/LootMgr.h
+++ b/src/server/game/Loot/LootMgr.h
@@ -216,7 +216,8 @@ class LootStore
uint32 LoadAndCollectLootIds(LootIdSet& ids_set);
void CheckLootRefs(LootIdSet* ref_set = NULL) const; // check existence reference and remove it from ref_set
void ReportUnusedIds(LootIdSet const& ids_set) const;
- void ReportNonExistingId(uint32 id) const;
+ void ReportNonExistingId(uint32 lootId) const;
+ void ReportNonExistingId(uint32 lootId, const char* ownerType, uint32 ownerId) const;
bool HaveLootFor(uint32 loot_id) const { return m_LootTemplates.find(loot_id) != m_LootTemplates.end(); }
bool HaveQuestLootFor(uint32 loot_id) const;
diff --git a/src/server/game/Mails/Mail.cpp b/src/server/game/Mails/Mail.cpp
index 2459e468c25..820a54b9760 100644
--- a/src/server/game/Mails/Mail.cpp
+++ b/src/server/game/Mails/Mail.cpp
@@ -131,7 +131,7 @@ void MailDraft::deleteIncludedItems(SQLTransaction& trans, bool inDB /*= false*/
void MailDraft::SendReturnToSender(uint32 sender_acc, uint32 sender_guid, uint32 receiver_guid, SQLTransaction& trans)
{
ObjectGuid receiverGuid(HIGHGUID_PLAYER, receiver_guid);
- Player* receiver = ObjectAccessor::FindPlayer(receiverGuid);
+ Player* receiver = ObjectAccessor::FindConnectedPlayer(receiverGuid);
uint32 rc_account = 0;
if (!receiver)
diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp
index ab50d16d8f5..f5f9546b7b2 100644
--- a/src/server/game/Maps/Map.cpp
+++ b/src/server/game/Maps/Map.cpp
@@ -20,6 +20,7 @@
#include "Battleground.h"
#include "MMapFactory.h"
#include "CellImpl.h"
+#include "DisableMgr.h"
#include "DynamicTree.h"
#include "GridNotifiers.h"
#include "GridNotifiersImpl.h"
@@ -119,7 +120,7 @@ bool Map::ExistVMap(uint32 mapid, int gx, int gy)
void Map::LoadMMap(int gx, int gy)
{
- if (!MMAP::MMapFactory::IsPathfindingEnabled(GetId()))
+ if (!DisableMgr::IsPathfindingEnabled(GetId()))
return;
bool mmapLoadResult = MMAP::MMapFactory::createOrGetMMapManager()->loadMap((sWorld->GetDataPath() + "mmaps").c_str(), GetId(), gx, gy);
@@ -1585,7 +1586,7 @@ GridMap::~GridMap()
unloadData();
}
-bool GridMap::loadData(char* filename)
+bool GridMap::loadData(const char* filename)
{
// Unload old data if exist
unloadData();
@@ -2967,7 +2968,7 @@ bool InstanceMap::AddPlayerToMap(Player* player)
InstanceGroupBind* groupBind = group->GetBoundInstance(this);
if (playerBind && playerBind->save != mapSave)
{
- TC_LOG_ERROR("maps", "InstanceMap::Add: player %s(%d) is being put into instance %s %d, %d, %d, %d, %d, %d but he is in group %d and is bound to instance %d, %d, %d, %d, %d, %d!", player->GetName().c_str(), player->GetGUIDLow(), GetMapName(), mapSave->GetMapId(), mapSave->GetInstanceId(), mapSave->GetDifficulty(), mapSave->GetPlayerCount(), mapSave->GetGroupCount(), mapSave->CanReset(), group->GetLeaderGUID().GetCounter(), playerBind->save->GetMapId(), playerBind->save->GetInstanceId(), playerBind->save->GetDifficulty(), playerBind->save->GetPlayerCount(), playerBind->save->GetGroupCount(), playerBind->save->CanReset());
+ TC_LOG_ERROR("maps", "InstanceMap::Add: player %s(%d) is being put into instance %s %d, %d, %d, %d, %d, %d but he is in group %s and is bound to instance %d, %d, %d, %d, %d, %d!", player->GetName().c_str(), player->GetGUIDLow(), GetMapName(), mapSave->GetMapId(), mapSave->GetInstanceId(), mapSave->GetDifficulty(), mapSave->GetPlayerCount(), mapSave->GetGroupCount(), mapSave->CanReset(), group->GetLeaderGUID().ToString().c_str(), playerBind->save->GetMapId(), playerBind->save->GetInstanceId(), playerBind->save->GetDifficulty(), playerBind->save->GetPlayerCount(), playerBind->save->GetGroupCount(), playerBind->save->CanReset());
if (groupBind)
TC_LOG_ERROR("maps", "InstanceMap::Add: the group is bound to the instance %s %d, %d, %d, %d, %d, %d", GetMapName(), groupBind->save->GetMapId(), groupBind->save->GetInstanceId(), groupBind->save->GetDifficulty(), groupBind->save->GetPlayerCount(), groupBind->save->GetGroupCount(), groupBind->save->CanReset());
//ASSERT(false);
@@ -2981,7 +2982,7 @@ bool InstanceMap::AddPlayerToMap(Player* player)
// cannot jump to a different instance without resetting it
if (groupBind->save != mapSave)
{
- TC_LOG_ERROR("maps", "InstanceMap::Add: player %s(%d) is being put into instance %d, %d, %d but he is in group %d which is bound to instance %d, %d, %d!", player->GetName().c_str(), player->GetGUIDLow(), mapSave->GetMapId(), mapSave->GetInstanceId(), mapSave->GetDifficulty(), group->GetLeaderGUID().GetCounter(), groupBind->save->GetMapId(), groupBind->save->GetInstanceId(), groupBind->save->GetDifficulty());
+ TC_LOG_ERROR("maps", "InstanceMap::Add: player %s(%d) is being put into instance %d, %d, %d but he is in group %s which is bound to instance %d, %d, %d!", player->GetName().c_str(), player->GetGUIDLow(), mapSave->GetMapId(), mapSave->GetInstanceId(), mapSave->GetDifficulty(), group->GetLeaderGUID().ToString().c_str(), groupBind->save->GetMapId(), groupBind->save->GetInstanceId(), groupBind->save->GetDifficulty());
TC_LOG_ERROR("maps", "MapSave players: %d, group count: %d", mapSave->GetPlayerCount(), mapSave->GetGroupCount());
if (groupBind->save)
TC_LOG_ERROR("maps", "GroupBind save players: %d, group count: %d", groupBind->save->GetPlayerCount(), groupBind->save->GetGroupCount());
diff --git a/src/server/game/Maps/Map.h b/src/server/game/Maps/Map.h
index c0b50b078d8..cf10f48f82e 100644
--- a/src/server/game/Maps/Map.h
+++ b/src/server/game/Maps/Map.h
@@ -200,7 +200,7 @@ class GridMap
public:
GridMap();
~GridMap();
- bool loadData(char* filaname);
+ bool loadData(const char* filename);
void unloadData();
uint16 getArea(float x, float y) const;
diff --git a/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.cpp
index dbe8c8b0329..2e859a7a56f 100644
--- a/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.cpp
+++ b/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.cpp
@@ -99,7 +99,12 @@ void RandomMovementGenerator<Creature>::_setRandomLocation(Creature* creature)
if (is_air_ok)
i_nextMoveTime.Reset(0);
else
- i_nextMoveTime.Reset(urand(500, 10000));
+ {
+ if (roll_chance_i(50))
+ i_nextMoveTime.Reset(urand(5000, 10000));
+ else
+ i_nextMoveTime.Reset(urand(50, 400));
+ }
creature->AddUnitState(UNIT_STATE_ROAMING_MOVE);
diff --git a/src/server/game/Movement/PathGenerator.cpp b/src/server/game/Movement/PathGenerator.cpp
index 2ef465f6775..523cfb7ea2f 100644
--- a/src/server/game/Movement/PathGenerator.cpp
+++ b/src/server/game/Movement/PathGenerator.cpp
@@ -23,7 +23,7 @@
#include "MMapFactory.h"
#include "MMapManager.h"
#include "Log.h"
-
+#include "DisableMgr.h"
#include "DetourCommon.h"
#include "DetourNavMeshQuery.h"
@@ -39,7 +39,7 @@ PathGenerator::PathGenerator(const Unit* owner) :
TC_LOG_DEBUG("maps", "++ PathGenerator::PathGenerator for %u \n", _sourceUnit->GetGUIDLow());
uint32 mapId = _sourceUnit->GetMapId();
- if (MMAP::MMapFactory::IsPathfindingEnabled(mapId))
+ if (DisableMgr::IsPathfindingEnabled(mapId))
{
MMAP::MMapManager* mmap = MMAP::MMapFactory::createOrGetMMapManager();
_navMesh = mmap->GetNavMesh(mapId);
diff --git a/src/server/game/Server/BattlenetServerManager.cpp b/src/server/game/Server/BattlenetServerManager.cpp
new file mode 100644
index 00000000000..b267926c6ff
--- /dev/null
+++ b/src/server/game/Server/BattlenetServerManager.cpp
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "Config.h"
+#include "World.h"
+#include "ZmqContext.h"
+#include "BattlenetServerManager.h"
+
+void Battlenet::ServerManager::InitializeConnection()
+{
+ std::string bnetserverAddress = sConfigMgr->GetStringDefault("BnetServer.Address", "127.0.0.1");
+ int32 bnetserverPort = sConfigMgr->GetIntDefault("BnetServer.Port", 1118);
+ _socket = new ZmqMux("inproc://bnetmgr", "tcp://" + bnetserverAddress + ":" + std::to_string(bnetserverPort));
+ _socket->Start();
+}
+
+void Battlenet::ServerManager::CloseConnection()
+{
+ _socket->End();
+ delete _socket;
+ _socket = nullptr;
+}
+
+Battlenet::Header Battlenet::ServerManager::CreateHeader(BnetCommands command)
+{
+ Header header;
+ header.Ipc.Channel = IPC_CHANNEL_BNET;
+ header.Ipc.Command = command;
+ header.Realm = realmHandle;
+ return header;
+}
+
+void Battlenet::ServerManager::SendChangeToonOnlineState(uint32 battlenetAccountId, uint32 gameAccountId, ObjectGuid guid, std::string const& name, bool online)
+{
+ // Do nothing for Grunt login
+ if (!battlenetAccountId)
+ return;
+
+ Header header = CreateHeader(BNET_CHANGE_TOON_ONLINE_STATE);
+ ToonHandle toon;
+ toon.AccountId = battlenetAccountId;
+ toon.GameAccountId = gameAccountId;
+ toon.Guid = guid;
+ toon.Name = name;
+
+ zmqpp::message msg;
+ msg << header;
+ msg << toon;
+ msg << online;
+
+ _socket->Send(&msg);
+}
diff --git a/src/server/game/Server/BattlenetServerManager.h b/src/server/game/Server/BattlenetServerManager.h
new file mode 100644
index 00000000000..fe103a1c981
--- /dev/null
+++ b/src/server/game/Server/BattlenetServerManager.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef BattlenetMgr_h__
+#define BattlenetMgr_h__
+
+#include "ZmqMux.h"
+#include "Commands.h"
+
+namespace zmqpp
+{
+ class socket;
+}
+
+namespace Battlenet
+{
+ class ServerManager
+ {
+ ServerManager() : _socket(nullptr) { }
+
+ public:
+ void InitializeConnection();
+ void CloseConnection();
+
+ static ServerManager& Instance()
+ {
+ static ServerManager instance;
+ return instance;
+ }
+
+ void SendChangeToonOnlineState(uint32 battlenetAccountId, uint32 gameAccountId, ObjectGuid guid, std::string const& name, bool online);
+
+ private:
+ static Header CreateHeader(BnetCommands command);
+ ZmqMux* _socket;
+ };
+}
+
+#define sBattlenetServer Battlenet::ServerManager::Instance()
+
+#endif // BattlenetMgr_h__
diff --git a/src/server/game/Server/WorldSession.cpp b/src/server/game/Server/WorldSession.cpp
index 428e0582867..0fd46f0d20b 100644
--- a/src/server/game/Server/WorldSession.cpp
+++ b/src/server/game/Server/WorldSession.cpp
@@ -47,6 +47,7 @@
#include "Transport.h"
#include "WardenWin.h"
#include "WardenMac.h"
+#include "BattlenetServerManager.h"
namespace {
@@ -56,8 +57,7 @@ std::string const DefaultPlayerName = "<none>";
bool MapSessionFilter::Process(WorldPacket* packet)
{
- Opcodes opcode = DropHighBytes(packet->GetOpcode());
- OpcodeHandler const* opHandle = opcodeTable[opcode];
+ OpcodeHandler const* opHandle = opcodeTable[packet->GetOpcode()];
//let's check if our opcode can be really processed in Map::Update()
if (opHandle->ProcessingPlace == PROCESS_INPLACE)
@@ -79,8 +79,7 @@ bool MapSessionFilter::Process(WorldPacket* packet)
//OR packet handler is not thread-safe!
bool WorldSessionFilter::Process(WorldPacket* packet)
{
- Opcodes opcode = DropHighBytes(packet->GetOpcode());
- OpcodeHandler const* opHandle = opcodeTable[opcode];
+ OpcodeHandler const* opHandle = opcodeTable[packet->GetOpcode()];
//check if packet handler is supposed to be safe
if (opHandle->ProcessingPlace == PROCESS_INPLACE)
return true;
@@ -584,6 +583,9 @@ void WorldSession::LogoutPlayer(bool save)
_player->CleanupsBeforeDelete();
TC_LOG_INFO("entities.player.character", "Account: %d (IP: %s) Logout Character:[%s] (GUID: %u) Level: %d",
GetAccountId(), GetRemoteAddress().c_str(), _player->GetName().c_str(), _player->GetGUIDLow(), _player->getLevel());
+
+ sBattlenetServer.SendChangeToonOnlineState(GetBattlenetAccountId(), GetAccountId(), _player->GetGUID(), _player->GetName(), false);
+
if (Map* _map = _player->FindMap())
_map->RemovePlayerFromMap(_player, true);
@@ -1145,11 +1147,11 @@ void WorldSession::LoadPermissions()
AccountMgr::GetName(id, name);
uint8 secLevel = GetSecurity();
- _RBACData = new rbac::RBACData(id, name, realmID, secLevel);
+ _RBACData = new rbac::RBACData(id, name, realmHandle.Index, secLevel);
_RBACData->LoadFromDB();
TC_LOG_DEBUG("rbac", "WorldSession::LoadPermissions [AccountId: %u, Name: %s, realmId: %d, secLevel: %u]",
- id, name.c_str(), realmID, secLevel);
+ id, name.c_str(), realmHandle.Index, secLevel);
}
rbac::RBACData* WorldSession::GetRBACData()
@@ -1164,7 +1166,7 @@ bool WorldSession::HasPermission(uint32 permission)
bool hasPermission = _RBACData->HasPermission(permission);
TC_LOG_DEBUG("rbac", "WorldSession::HasPermission [AccountId: %u, Name: %s, realmId: %d]",
- _RBACData->GetId(), _RBACData->GetName().c_str(), realmID);
+ _RBACData->GetId(), _RBACData->GetName().c_str(), realmHandle.Index);
return hasPermission;
}
@@ -1172,7 +1174,7 @@ bool WorldSession::HasPermission(uint32 permission)
void WorldSession::InvalidateRBACData()
{
TC_LOG_DEBUG("rbac", "WorldSession::Invalidaterbac::RBACData [AccountId: %u, Name: %s, realmId: %d]",
- _RBACData->GetId(), _RBACData->GetName().c_str(), realmID);
+ _RBACData->GetId(), _RBACData->GetName().c_str(), realmHandle.Index);
delete _RBACData;
_RBACData = NULL;
}
diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h
index 4ec407f5254..02a185b0b63 100644
--- a/src/server/game/Server/WorldSession.h
+++ b/src/server/game/Server/WorldSession.h
@@ -144,7 +144,6 @@ public:
virtual bool Process(WorldPacket* /*packet*/) { return true; }
virtual bool ProcessLogout() const { return true; }
- static Opcodes DropHighBytes(Opcodes opcode) { return Opcodes(opcode & 0xFFFF); }
protected:
WorldSession* const m_pSession;
diff --git a/src/server/game/Server/WorldSocket.cpp b/src/server/game/Server/WorldSocket.cpp
index f37354f7e65..7933ddfeb4d 100644
--- a/src/server/game/Server/WorldSocket.cpp
+++ b/src/server/game/Server/WorldSocket.cpp
@@ -162,7 +162,7 @@ bool WorldSocket::ReadDataHandler()
{
ClientPktHeader* header = reinterpret_cast<ClientPktHeader*>(_headerBuffer.GetReadPointer());
- Opcodes opcode = PacketFilter::DropHighBytes(Opcodes(header->cmd));
+ Opcodes opcode = Opcodes(header->cmd);
std::string opcodeName = GetOpcodeNameForLogging(opcode);
@@ -213,6 +213,20 @@ bool WorldSocket::ReadDataHandler()
return false;
}
+ // prevent invalid memory access/crash with custom opcodes
+ if (opcode >= NUM_OPCODE_HANDLERS)
+ {
+ CloseSocket();
+ return false;
+ }
+
+ OpcodeHandler const* handler = opcodeTable[opcode];
+ if (!handler)
+ {
+ TC_LOG_ERROR("network.opcode", "No defined handler for opcode %s sent by %s", GetOpcodeNameForLogging(packet.GetOpcode()).c_str(), _worldSession->GetPlayerInfo().c_str());
+ return true;
+ }
+
// Our Idle timer will reset on any non PING opcodes.
// Catches people idling on the login screen and any lingering ingame connections.
_worldSession->ResetTimeOutTime();
@@ -392,7 +406,7 @@ void WorldSocket::HandleAuthSession(WorldPacket& recvPacket)
return;
}
- if (realmIndex != realmID)
+ if (realmIndex != realmHandle.Index)
{
SendAuthResponseError(REALM_LIST_REALM_NOT_FOUND);
TC_LOG_ERROR("network", "WorldSocket::HandleAuthSession: Sent Auth Response (bad realm).");
@@ -471,7 +485,7 @@ void WorldSocket::HandleAuthSession(WorldPacket& recvPacket)
stmt = LoginDatabase.GetPreparedStatement(LOGIN_GET_GMLEVEL_BY_REALMID);
stmt->setUInt32(0, id);
- stmt->setInt32(1, int32(realmID));
+ stmt->setInt32(1, int32(realmHandle.Index));
result = LoginDatabase.Query(stmt);
diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp
index 108f23bcc6a..3d0955f5d97 100644
--- a/src/server/game/Spells/Spell.cpp
+++ b/src/server/game/Spells/Spell.cpp
@@ -4383,7 +4383,10 @@ void Spell::TakeAmmo()
if (!pItem || pItem->IsBroken() || pItem->GetTemplate()->SubClass == ITEM_SUBCLASS_WEAPON_WAND)
return;
- if (pItem->GetTemplate()->InventoryType == INVTYPE_THROWN)
+ if ((pItem->GetTemplate()->InventoryType == INVTYPE_THROWN ||
+ pItem->GetTemplate()->InventoryType == INVTYPE_RANGED ||
+ pItem->GetTemplate()->InventoryType == INVTYPE_RANGEDRIGHT)
+ && roll_chance_f(sWorld->getRate(RATE_DURABILITY_LOSS_DAMAGE)))
{
if (pItem->GetMaxStackCount() == 1)
{
diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp
index d5ddf62b441..46fac6340a8 100644
--- a/src/server/game/Spells/SpellMgr.cpp
+++ b/src/server/game/Spells/SpellMgr.cpp
@@ -2385,6 +2385,14 @@ void SpellMgr::LoadSpellLinked()
TC_LOG_ERROR("sql.sql", "Spell %u listed in `spell_linked_spell` does not exist", abs(trigger));
continue;
}
+
+ if (effect >= 0)
+ for (uint8 j = 0; j < MAX_SPELL_EFFECTS; ++j)
+ {
+ if (spellInfo->Effects[j].CalcValue() == abs(effect))
+ TC_LOG_ERROR("sql.sql", "Spell %u Effect: %u listed in `spell_linked_spell` has same bp%u like effect (possible hack)", abs(trigger), abs(effect), j);
+ }
+
spellInfo = GetSpellInfo(abs(effect));
if (!spellInfo)
{
@@ -3330,7 +3338,7 @@ void SpellMgr::LoadSpellInfoCorrections()
break;
case 51798: // Brewfest - Relay Race - Intro - Quest Complete
case 47134: // Quest Complete
- //! HACK: This spell break quest complete for alliance and on retail not used °_O
+ //! HACK: This spell break quest complete for alliance and on retail not used °_O
spellInfo->Effects[EFFECT_0].Effect = 0;
break;
// ULDUAR SPELLS
diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp
index 3a183ec50bc..d3d06d0ee8a 100644
--- a/src/server/game/World/World.cpp
+++ b/src/server/game/World/World.cpp
@@ -1303,6 +1303,9 @@ void World::LoadConfigSettings(bool reload)
// AHBot
m_int_configs[CONFIG_AHBOT_UPDATE_INTERVAL] = sConfigMgr->GetIntDefault("AuctionHouseBot.Update.Interval", 20);
+ m_bool_configs[CONFIG_CALCULATE_CREATURE_ZONE_AREA_DATA] = sConfigMgr->GetBoolDefault("Calculate.Creature.Zone.Area.Data", false);
+ m_bool_configs[CONFIG_CALCULATE_GAMEOBJECT_ZONE_AREA_DATA] = sConfigMgr->GetBoolDefault("Calculate.Gameoject.Zone.Area.Data", false);
+
// call ScriptMgr if we're reloading the configuration
if (reload)
sScriptMgr->OnConfigLoad(reload);
@@ -1322,6 +1325,13 @@ void World::SetInitialWorldSettings()
///- Initialize detour memory management
dtAllocSetCustom(dtCustomAlloc, dtCustomFree);
+ ///- Initialize VMapManager function pointers (to untangle game/collision circular deps)
+ if (VMAP::VMapManager2* vmmgr2 = dynamic_cast<VMAP::VMapManager2*>(VMAP::VMapFactory::createOrGetVMapManager()))
+ {
+ vmmgr2->GetLiquidFlagsPtr = &GetLiquidFlags;
+ vmmgr2->IsVMAPDisabledForPtr = &DisableMgr::IsVMAPDisabledFor;
+ }
+
///- Initialize config settings
LoadConfigSettings();
@@ -1365,7 +1375,7 @@ void World::SetInitialWorldSettings()
uint32 server_type = IsFFAPvPRealm() ? uint32(REALM_TYPE_PVP) : getIntConfig(CONFIG_GAME_TYPE);
uint32 realm_zone = getIntConfig(CONFIG_REALM_ZONE);
- LoginDatabase.PExecute("UPDATE realmlist SET icon = %u, timezone = %u WHERE id = '%d'", server_type, realm_zone, realmID); // One-time query
+ LoginDatabase.PExecute("UPDATE realmlist SET icon = %u, timezone = %u WHERE id = '%d'", server_type, realm_zone, realmHandle.Index); // One-time query
///- Remove the bones (they should not exist in DB though) and old corpses after a restart
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_OLD_CORPSES);
@@ -1787,7 +1797,7 @@ void World::SetInitialWorldSettings()
m_startTime = m_gameTime;
LoginDatabase.PExecute("INSERT INTO uptime (realmid, starttime, uptime, revision) VALUES(%u, %u, 0, '%s')",
- realmID, uint32(m_startTime), _FULLVERSION); // One-time query
+ realmHandle.Index, uint32(m_startTime), _FULLVERSION); // One-time query
m_timers[WUPDATE_WEATHERS].SetInterval(1*IN_MILLISECONDS);
m_timers[WUPDATE_AUCTIONS].SetInterval(MINUTE*IN_MILLISECONDS);
@@ -2069,7 +2079,7 @@ void World::Update(uint32 diff)
stmt->setUInt32(0, tmpDiff);
stmt->setUInt16(1, uint16(maxOnlinePlayers));
- stmt->setUInt32(2, realmID);
+ stmt->setUInt32(2, realmHandle.Index);
stmt->setUInt32(3, uint32(m_startTime));
LoginDatabase.Execute(stmt);
@@ -2489,7 +2499,7 @@ bool World::RemoveBanAccount(BanMode mode, std::string const& nameOrIP)
/// Ban an account or ban an IP address, duration will be parsed using TimeStringToSecs if it is positive, otherwise permban
BanReturn World::BanCharacter(std::string const& name, std::string const& duration, std::string const& reason, std::string const& author)
{
- Player* pBanned = sObjectAccessor->FindPlayerByName(name);
+ Player* pBanned = ObjectAccessor::FindConnectedPlayerByName(name);
uint32 guid = 0;
uint32 duration_secs = TimeStringToSecs(duration);
@@ -2530,7 +2540,7 @@ BanReturn World::BanCharacter(std::string const& name, std::string const& durati
/// Remove a ban from a character
bool World::RemoveBanCharacter(std::string const& name)
{
- Player* pBanned = sObjectAccessor->FindPlayerByName(name);
+ Player* pBanned = ObjectAccessor::FindConnectedPlayerByName(name);
uint32 guid = 0;
/// Pick a player to ban if not online
@@ -2799,13 +2809,13 @@ void World::_UpdateRealmCharCount(PreparedQueryResult resultCharCount)
PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_DEL_REALM_CHARACTERS_BY_REALM);
stmt->setUInt32(0, accountId);
- stmt->setUInt32(1, realmID);
+ stmt->setUInt32(1, realmHandle.Index);
LoginDatabase.Execute(stmt);
stmt = LoginDatabase.GetPreparedStatement(LOGIN_INS_REALM_CHARACTERS);
stmt->setUInt8(0, charCount);
stmt->setUInt32(1, accountId);
- stmt->setUInt32(2, realmID);
+ stmt->setUInt32(2, realmHandle.Index);
LoginDatabase.Execute(stmt);
}
}
@@ -2974,7 +2984,7 @@ void World::ResetCurrencyWeekCap()
void World::LoadDBAllowedSecurityLevel()
{
PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_REALMLIST_SECURITY_LEVEL);
- stmt->setInt32(0, int32(realmID));
+ stmt->setInt32(0, int32(realmHandle.Index));
PreparedQueryResult result = LoginDatabase.Query(stmt);
if (result)
diff --git a/src/server/game/World/World.h b/src/server/game/World/World.h
index 3bbc4e48eea..2c74e3929fe 100644
--- a/src/server/game/World/World.h
+++ b/src/server/game/World/World.h
@@ -24,6 +24,7 @@
#define __WORLD_H
#include "Common.h"
+#include "Commands.h"
#include "ObjectGuid.h"
#include "Timer.h"
#include "SharedDefines.h"
@@ -166,6 +167,8 @@ enum WorldBoolConfigs
CONFIG_INSTANCES_RESET_ANNOUNCE,
CONFIG_IP_BASED_ACTION_LOGGING,
CONFIG_ALLOW_TRACK_BOTH_RESOURCES,
+ CONFIG_CALCULATE_CREATURE_ZONE_AREA_DATA,
+ CONFIG_CALCULATE_GAMEOBJECT_ZONE_AREA_DATA,
BOOL_CONFIG_VALUE_COUNT
};
@@ -877,7 +880,7 @@ class World
std::deque<std::future<PreparedQueryResult>> m_realmCharCallbacks;
};
-extern uint32 realmID;
+extern Battlenet::RealmHandle realmHandle;
#define sWorld World::instance()
#endif
diff --git a/src/server/ipc/CMakeLists.txt b/src/server/ipc/CMakeLists.txt
new file mode 100644
index 00000000000..93a5d630dfe
--- /dev/null
+++ b/src/server/ipc/CMakeLists.txt
@@ -0,0 +1,24 @@
+# Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
+#
+# This file is free software; as a special exception the author gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+file(GLOB_RECURSE sources_ipc *.cpp *.h)
+
+set(ipc_SRCS
+ ${sources_ipc}
+)
+
+include_directories(
+ ${CMAKE_BINARY_DIR}
+ ${CMAKE_SOURCE_DIR}/dep/zmqpp
+ ${CMAKE_SOURCE_DIR}/src/server/shared/
+ ${ZMQ_INCLUDE_DIR}
+)
+
+add_library(ipc STATIC ${ipc_SRCS})
diff --git a/src/server/ipc/Commands.cpp b/src/server/ipc/Commands.cpp
new file mode 100644
index 00000000000..8e494fc34b9
--- /dev/null
+++ b/src/server/ipc/Commands.cpp
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "Commands.h"
+#include <zmqpp/message.hpp>
+
+zmqpp::message& operator>>(zmqpp::message& msg, IPCHeader& header)
+{
+ msg >> header.Channel;
+ msg >> header.Command;
+ return msg;
+}
+
+zmqpp::message& operator>>(zmqpp::message& msg, Battlenet::RealmHandle& realm)
+{
+ msg >> realm.Region;
+ msg >> realm.Battlegroup;
+ msg >> realm.Index;
+ return msg;
+}
+
+zmqpp::message& operator>>(zmqpp::message& msg, Battlenet::Header& header)
+{
+ msg >> header.Ipc;
+ msg >> header.Realm;
+ return msg;
+}
+
+zmqpp::message& operator>>(zmqpp::message& msg, Battlenet::ToonHandle& toonHandle)
+{
+ msg >> toonHandle.AccountId;
+ msg >> toonHandle.GameAccountId;
+ msg >> toonHandle.Guid;
+ msg >> toonHandle.Name;
+ return msg;
+}
+
+zmqpp::message& operator<<(zmqpp::message& msg, IPCHeader& header)
+{
+ msg << header.Channel;
+ msg << header.Command;
+ return msg;
+}
+
+zmqpp::message& operator<<(zmqpp::message& msg, Battlenet::RealmHandle& realm)
+{
+ msg << realm.Region;
+ msg << realm.Battlegroup;
+ msg << realm.Index;
+ return msg;
+}
+
+zmqpp::message& operator<<(zmqpp::message& msg, Battlenet::Header& header)
+{
+ msg << header.Ipc;
+ msg << header.Realm;
+ return msg;
+}
+
+zmqpp::message& operator<<(zmqpp::message& msg, Battlenet::ToonHandle& toonHandle)
+{
+ msg << toonHandle.AccountId;
+ msg << toonHandle.GameAccountId;
+ msg << toonHandle.Guid;
+ msg << toonHandle.Name;
+ return msg;
+}
diff --git a/src/server/ipc/Commands.h b/src/server/ipc/Commands.h
new file mode 100644
index 00000000000..05309a45022
--- /dev/null
+++ b/src/server/ipc/Commands.h
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _COMMANDS_H
+#define _COMMANDS_H
+
+#include "Define.h"
+#include <string>
+
+enum Channels
+{
+ IPC_CHANNEL_BNET,
+
+ MAX_IPC_CHANNELS,
+};
+
+enum BnetCommands
+{
+ BNET_CHANGE_TOON_ONLINE_STATE,
+
+ IPC_BNET_MAX_COMMAND
+};
+
+struct IPCHeader
+{
+ uint8 Channel;
+ uint8 Command;
+};
+
+namespace Battlenet
+{
+ struct RealmHandle
+ {
+ uint8 Region;
+ uint8 Battlegroup;
+ uint32 Index;
+ };
+
+ struct Header
+ {
+ IPCHeader Ipc;
+ RealmHandle Realm;
+ };
+
+ struct ToonHandle
+ {
+ uint32 AccountId;
+ uint32 GameAccountId;
+ uint64 Guid;
+ std::string Name;
+ };
+}
+
+namespace zmqpp
+{
+ class message;
+}
+
+zmqpp::message& operator>>(zmqpp::message& msg, IPCHeader& header);
+zmqpp::message& operator>>(zmqpp::message& msg, Battlenet::RealmHandle& realm);
+zmqpp::message& operator>>(zmqpp::message& msg, Battlenet::Header& header);
+zmqpp::message& operator>>(zmqpp::message& msg, Battlenet::ToonHandle& toonHandle);
+
+zmqpp::message& operator<<(zmqpp::message& msg, IPCHeader& header);
+zmqpp::message& operator<<(zmqpp::message& msg, Battlenet::RealmHandle& realm);
+zmqpp::message& operator<<(zmqpp::message& msg, Battlenet::Header& header);
+zmqpp::message& operator<<(zmqpp::message& msg, Battlenet::ToonHandle& toonHandle);
+
+#endif // _COMMANDS_H
diff --git a/src/server/ipc/ZMQTask.cpp b/src/server/ipc/ZMQTask.cpp
new file mode 100644
index 00000000000..0d25dc2babf
--- /dev/null
+++ b/src/server/ipc/ZMQTask.cpp
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "ZMQTask.h"
+#include "ZmqContext.h"
+#include <zmqpp/message.hpp>
+
+ZMQTask::ZMQTask()
+{
+ _poller = new zmqpp::poller();
+}
+
+ZMQTask::~ZMQTask()
+{
+ delete _poller;
+ _poller = NULL;
+ delete _inproc;
+ delete _thread;
+}
+
+void ZMQTask::Start()
+{
+ _inproc = sIpcContext->CreateInprocSubscriber();
+ _poller->add(*_inproc);
+
+ HandleOpen();
+ _thread = new std::thread(&ZMQTask::Run, this);
+}
+
+void ZMQTask::End()
+{
+ _thread->join();
+ _inproc->close();
+ HandleClose();
+}
+
+bool ZMQTask::ProcessExit()
+{
+ if (_poller->events(*_inproc) == zmqpp::poller::poll_in)
+ {
+ int op1;
+ do
+ {
+ zmqpp::message msg;
+ if (!_inproc->receive(msg, true))
+ return false; //No more messages to read from sock. This shouldn't happen.
+
+ // strip 'internalmq.' from message
+ std::string cmd = msg.get(0).substr(11);
+ if (cmd == "kill")
+ return true;
+
+ _inproc->get(zmqpp::socket_option::events, op1);
+ } while (op1 & zmqpp::poller::poll_in);
+ }
+
+ return false;
+}
+
+void ZMQTask::Pipeline(zmqpp::socket* from, zmqpp::socket* to)
+{
+ /*
+ Push messages from socket to socket.
+ */
+ if (_poller->events(*from) == zmqpp::poller::poll_in)
+ {
+ int32 op1, op2;
+ do
+ {
+ zmqpp::message msg;
+ if (!from->receive(msg, true))
+ return; //No more messages to read from socket. This shouldn't happen.
+
+ to->send(msg);
+ from->get(zmqpp::socket_option::events, op1);
+ to->get(zmqpp::socket_option::events, op2);
+ } while(op1 & zmqpp::poller::poll_in && op2 & zmqpp::poller::poll_out);
+ }
+}
diff --git a/src/server/ipc/ZMQTask.h b/src/server/ipc/ZMQTask.h
new file mode 100644
index 00000000000..24251893aaa
--- /dev/null
+++ b/src/server/ipc/ZMQTask.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __ZMQTASK_H
+#define __ZMQTASK_H
+
+#include "Define.h"
+#include <thread>
+#include <zmqpp/poller.hpp>
+#include <zmqpp/socket.hpp>
+
+/*
+ This class serves as a base for all long running tasks
+ It is set up to terminate its running task upon receiving "kill" command
+*/
+class ZMQTask
+{
+public:
+ ZMQTask();
+ virtual ~ZMQTask();
+
+ void Start();
+ void End();
+ virtual void Run() = 0;
+
+protected:
+ virtual void HandleOpen() { }
+ virtual void HandleClose() { }
+ void Pipeline(zmqpp::socket* from, zmqpp::socket* to);
+ bool ProcessExit();
+
+ zmqpp::poller* _poller;
+
+ zmqpp::socket* _inproc;
+ std::thread* _thread;
+};
+
+#endif // __ZMQTASK_H
diff --git a/src/server/ipc/ZmqContext.cpp b/src/server/ipc/ZmqContext.cpp
new file mode 100644
index 00000000000..305e6b1d843
--- /dev/null
+++ b/src/server/ipc/ZmqContext.cpp
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "ZmqContext.h"
+
+ZmqContext::ZmqContext() : _inproc(nullptr)
+{
+}
+
+ZmqContext::~ZmqContext()
+{
+ delete _inproc;
+}
+
+zmqpp::socket* ZmqContext::CreateNewSocket(zmqpp::socket_type type)
+{
+ std::unique_lock<std::mutex> lock(_mutex);
+ return new zmqpp::socket(_context, type);
+}
+
+void ZmqContext::Initialize()
+{
+ _inproc = new zmqpp::socket(_context, zmqpp::socket_type::pub);
+ _inproc->bind("inproc://workers");
+}
+
+zmqpp::socket* ZmqContext::CreateInprocSubscriber()
+{
+ zmqpp::socket* sub = CreateNewSocket(zmqpp::socket_type::sub);
+ sub->connect("inproc://workers");
+ sub->subscribe("internalmq.");
+ return sub;
+}
+
+void ZmqContext::Close()
+{
+ _inproc->send("internalmq.kill");
+}
diff --git a/src/server/ipc/ZmqContext.h b/src/server/ipc/ZmqContext.h
new file mode 100644
index 00000000000..a6ad12b1b70
--- /dev/null
+++ b/src/server/ipc/ZmqContext.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __ZMQCONTEX_H
+#define __ZMQCONTEX_H
+
+#include <zmqpp/zmqpp.hpp>
+#include <mutex>
+
+/*
+ * We need to serialize access to zmq context otherwise stuff blows up.
+ */
+class ZmqContext
+{
+public:
+ ~ZmqContext();
+
+ static ZmqContext* Instance()
+ {
+ static ZmqContext instance;
+ return &instance;
+ }
+
+ zmqpp::socket* CreateNewSocket(zmqpp::socket_type);
+ void Initialize();
+ zmqpp::socket* CreateInprocSubscriber();
+ void Close();
+
+private:
+ ZmqContext();
+ ZmqContext(ZmqContext const&) = delete;
+ ZmqContext& operator=(ZmqContext const&) = delete;
+
+ zmqpp::context _context;
+ std::mutex _mutex;
+ zmqpp::socket* _inproc;
+};
+
+#define sIpcContext ZmqContext::Instance()
+
+#endif
diff --git a/src/server/ipc/ZmqListener.cpp b/src/server/ipc/ZmqListener.cpp
new file mode 100644
index 00000000000..98333305e58
--- /dev/null
+++ b/src/server/ipc/ZmqListener.cpp
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "ZmqListener.h"
+#include "ZmqContext.h"
+
+ZmqListener::ZmqListener(std::string const& from, std::string const& to)
+{
+ _from = sIpcContext->CreateNewSocket(zmqpp::socket_type::sub);
+ _to = sIpcContext->CreateNewSocket(zmqpp::socket_type::push);
+ _from->connect(from);
+ _to->bind(to);
+}
+
+ZmqListener::~ZmqListener()
+{
+ delete _from;
+ delete _to;
+}
+
+void ZmqListener::HandleOpen()
+{
+}
+
+void ZmqListener::HandleClose()
+{
+ _from->close();
+ _to->close();
+}
+
+void ZmqListener::Run()
+{
+ while (!ProcessExit())
+ {
+ _poller->poll();
+
+ while (_poller->events(*_from) & zmqpp::poller::poll_in &&
+ _poller->events(*_to) & zmqpp::poller::poll_out)
+ {
+ zmqpp::message msg;
+ _from->receive(msg);
+ _to->send(msg);
+ }
+ }
+}
+
+void ZmqListener::Subscribe(std::string const& keyword)
+{
+ _from->subscribe(keyword);
+}
+
+void ZmqListener::Unsubscribe(std::string const& keyword)
+{
+ _from->unsubscribe(keyword);
+}
diff --git a/src/server/authserver/Server/BattlenetSessionManager.cpp b/src/server/ipc/ZmqListener.h
index 91ba2b65094..8b79ba67f6d 100644
--- a/src/server/authserver/Server/BattlenetSessionManager.cpp
+++ b/src/server/ipc/ZmqListener.h
@@ -15,23 +15,37 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "BattlenetSessionManager.h"
+#ifndef __ZMQLISTENER_H
+#define __ZMQLISTENER_H
-bool Battlenet::SessionManager::StartNetwork(boost::asio::io_service& service, std::string const& bindIp, uint16 port)
+#include "ZMQTask.h"
+#include <zmqpp/zmqpp.hpp>
+
+class ZmqListener : public ZMQTask
{
- if (!BaseSocketMgr::StartNetwork(service, bindIp, port))
- return false;
+/*
+ * Read broadcasts from remote PUB socket, and forward them to
+ * another socket.
+ *
+ * from - client SUB socket
+ * to - listen PUSH socket
+ *
+ */
+public:
+ ZmqListener(std::string const& from, std::string const& to);
+ ~ZmqListener();
+ void Run() override;
- _acceptor->AsyncAcceptManaged(&OnSocketAccept);
- return true;
-}
+ void Subscribe(std::string const& keyword);
+ void Unsubscribe(std::string const& keyword);
-NetworkThread<Battlenet::Session>* Battlenet::SessionManager::CreateThreads() const
-{
- return new NetworkThread<Session>[GetNetworkThreadCount()];
-}
+protected:
+ void HandleOpen() override;
+ void HandleClose() override;
-void Battlenet::SessionManager::OnSocketAccept(tcp::socket&& sock)
-{
- sBattlenetSessionMgr.OnSocketOpen(std::forward<tcp::socket>(sock));
-}
+private:
+ zmqpp::socket* _from;
+ zmqpp::socket* _to;
+};
+
+#endif
diff --git a/src/server/ipc/ZmqMux.cpp b/src/server/ipc/ZmqMux.cpp
new file mode 100644
index 00000000000..4b5a4f48b05
--- /dev/null
+++ b/src/server/ipc/ZmqMux.cpp
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "ZmqMux.h"
+#include "ZmqContext.h"
+
+ZmqMux::ZmqMux(std::string from_uri, std::string to_uri):
+ _fromAddress(from_uri)
+{
+ printf("Opening muxer thread from %s to %s\n", from_uri.c_str(), to_uri.c_str());
+ _from = sIpcContext->CreateNewSocket(zmqpp::socket_type::pull);
+ _to = sIpcContext->CreateNewSocket(zmqpp::socket_type::push);
+
+ _from->bind(from_uri);
+ _to->connect(to_uri);
+}
+
+ZmqMux::~ZmqMux()
+{
+ delete _from;
+ delete _to;
+}
+
+void ZmqMux::HandleOpen()
+{
+ _poller->add(*_from);
+ _poller->add(*_to, zmqpp::poller::poll_out);
+}
+
+bool ZmqMux::Send(zmqpp::message* m, bool dont_block)
+{
+ if (_socket.get() == nullptr)
+ {
+ _socket.reset(sIpcContext->CreateNewSocket(zmqpp::socket_type::push));
+ _socket->connect(_fromAddress);
+ }
+
+ return _socket->send(*m, dont_block);
+}
+
+void ZmqMux::Run()
+{
+ for (;;)
+ {
+ if (!_poller->poll())
+ break;
+
+ if (ProcessExit())
+ break;
+
+ Pipeline(_from, _to);
+ }
+}
diff --git a/src/server/ipc/ZmqMux.h b/src/server/ipc/ZmqMux.h
new file mode 100644
index 00000000000..4b81f11daaf
--- /dev/null
+++ b/src/server/ipc/ZmqMux.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __ZMQMUX_H
+#define __ZMQMUX_H
+
+#include "ZMQTask.h"
+#include <string>
+#include <boost/thread/tss.hpp>
+
+/*
+ * Multiplexes zmq messages from many threads,
+ * and then passes them to another socket.
+ */
+class ZmqMux : public ZMQTask
+{
+public:
+ ZmqMux(std::string from, std::string to);
+ ~ZmqMux();
+ bool Send(zmqpp::message*, bool dont_block = false);
+ void Run() override;
+
+protected:
+ void HandleOpen() override;
+
+private:
+ boost::thread_specific_ptr<zmqpp::socket> _socket;
+ zmqpp::socket* _from;
+ zmqpp::socket* _to;
+ std::string const _fromAddress;
+};
+
+#endif
diff --git a/src/server/ipc/ZmqWorker.cpp b/src/server/ipc/ZmqWorker.cpp
new file mode 100644
index 00000000000..f205ea831b5
--- /dev/null
+++ b/src/server/ipc/ZmqWorker.cpp
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "ZmqWorker.h"
+#include "ZmqContext.h"
+
+ZmqWorker::ZmqWorker(std::string task_uri, std::string res_uri) :
+ _taskUri(task_uri), _resultsUri(res_uri)
+{
+}
+
+ZmqWorker::~ZmqWorker()
+{
+ delete _taskQueue;
+ delete _results;
+ delete _inproc;
+}
+
+void ZmqWorker::HandleOpen()
+{
+ _taskQueue = sIpcContext->CreateNewSocket(zmqpp::socket_type::pull);
+ _results = sIpcContext->CreateNewSocket(zmqpp::socket_type::push);
+
+ _taskQueue->connect(_taskUri);
+ _results->connect(_resultsUri);
+
+ _poller->add(*_taskQueue);
+}
+
+void ZmqWorker::HandleClose()
+{
+ _taskQueue->close();
+ _results->close();
+}
+
+void ZmqWorker::Run()
+{
+ while (!ProcessExit())
+ {
+ _poller->poll();
+ if (_poller->events(*_taskQueue) & zmqpp::poller::poll_in)
+ PerformWork();
+ }
+}
+
+void ZmqWorker::PerformWork()
+{
+ int32 op1;
+ do
+ {
+ zmqpp::message msg;
+ _taskQueue->receive(msg);
+ Dispatch(msg);
+ _taskQueue->get(zmqpp::socket_option::events, op1);
+ } while (op1 & zmqpp::poller::poll_in);
+}
diff --git a/src/server/ipc/ZmqWorker.h b/src/server/ipc/ZmqWorker.h
new file mode 100644
index 00000000000..b3e221e9129
--- /dev/null
+++ b/src/server/ipc/ZmqWorker.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __ZMQWORKER_H
+#define __ZMQWORKER_H
+
+#include "ZMQTask.h"
+#include <zmqpp/zmqpp.hpp>
+
+class ZmqWorker : public ZMQTask
+{
+public:
+ ZmqWorker(std::string task_uri, std::string res_uri);
+ ~ZmqWorker();
+ void Run() override;
+
+protected:
+ void HandleOpen() override;
+ void HandleClose() override;
+ zmqpp::socket* _results;
+
+private:
+ void PerformWork();
+ virtual void Dispatch(zmqpp::message const&) = 0;
+ zmqpp::socket* _taskQueue;
+ std::string _taskUri;
+ std::string _resultsUri;
+};
+
+#endif
diff --git a/src/server/scripts/CMakeLists.txt b/src/server/scripts/CMakeLists.txt
index e92c883eeff..eab6a36d02e 100644
--- a/src/server/scripts/CMakeLists.txt
+++ b/src/server/scripts/CMakeLists.txt
@@ -64,6 +64,7 @@ include_directories(
${CMAKE_SOURCE_DIR}/src/server/shared/Packets
${CMAKE_SOURCE_DIR}/src/server/shared/Threading
${CMAKE_SOURCE_DIR}/src/server/shared/Utilities
+ ${CMAKE_SOURCE_DIR}/src/server/ipc
${CMAKE_SOURCE_DIR}/src/server/collision
${CMAKE_SOURCE_DIR}/src/server/collision/Management
${CMAKE_SOURCE_DIR}/src/server/collision/Models
diff --git a/src/server/scripts/Commands/cs_ban.cpp b/src/server/scripts/Commands/cs_ban.cpp
index e11ee0008d2..370d03162d1 100644
--- a/src/server/scripts/Commands/cs_ban.cpp
+++ b/src/server/scripts/Commands/cs_ban.cpp
@@ -299,7 +299,7 @@ public:
if (!*args)
return false;
- Player* target = sObjectAccessor->FindPlayerByName(args);
+ Player* target = ObjectAccessor::FindPlayerByName(args);
uint32 targetGuid = 0;
std::string name(args);
diff --git a/src/server/scripts/Commands/cs_character.cpp b/src/server/scripts/Commands/cs_character.cpp
index 8254d08558a..c8961d4fad8 100644
--- a/src/server/scripts/Commands/cs_character.cpp
+++ b/src/server/scripts/Commands/cs_character.cpp
@@ -776,7 +776,7 @@ public:
ObjectGuid characterGuid;
uint32 accountId;
- Player* player = sObjectAccessor->FindPlayerByName(characterName);
+ Player* player = ObjectAccessor::FindPlayerByName(characterName);
if (player)
{
characterGuid = player->GetGUID();
diff --git a/src/server/scripts/Commands/cs_debug.cpp b/src/server/scripts/Commands/cs_debug.cpp
index 4b555fcf625..862b683597a 100644
--- a/src/server/scripts/Commands/cs_debug.cpp
+++ b/src/server/scripts/Commands/cs_debug.cpp
@@ -559,10 +559,10 @@ public:
for (uint8 j = 0; j < bag->GetBagSize(); ++j)
if (Item* item2 = bag->GetItemByPos(j))
if (item2->GetState() == state)
- handler->PSendSysMessage("bag: 255 slot: %d guid: %d owner: %d", item2->GetSlot(), item2->GetGUIDLow(), item2->GetOwnerGUID().GetCounter());
+ handler->PSendSysMessage("bag: 255 slot: %d %s owner: %s", item2->GetSlot(), item2->GetGUID().ToString().c_str(), item2->GetOwnerGUID().ToString().c_str());
}
else if (item->GetState() == state)
- handler->PSendSysMessage("bag: 255 slot: %d guid: %d owner: %d", item->GetSlot(), item->GetGUIDLow(), item->GetOwnerGUID().GetCounter());
+ handler->PSendSysMessage("bag: 255 slot: %d %s owner: %s", item->GetSlot(), item->GetGUID().ToString().c_str(), item->GetOwnerGUID().ToString().c_str());
}
}
}
@@ -624,14 +624,14 @@ public:
if (item->GetOwnerGUID() != player->GetGUID())
{
- handler->PSendSysMessage("The item with slot %d and itemguid %d does have non-matching owner guid (%d) and player guid (%d) !", item->GetSlot(), item->GetGUIDLow(), item->GetOwnerGUID().GetCounter(), player->GetGUIDLow());
+ handler->PSendSysMessage("The item with slot %d %s does have non-matching owner guid %s and %s!", item->GetSlot(), item->GetGUID().ToString().c_str(), item->GetOwnerGUID().ToString().c_str(), player->GetGUID().ToString().c_str());
error = true;
continue;
}
if (Bag* container = item->GetContainer())
{
- handler->PSendSysMessage("The item with slot %d and guid %d has a container (slot: %d, guid: %d) but shouldn't!", item->GetSlot(), item->GetGUIDLow(), container->GetSlot(), container->GetGUIDLow());
+ handler->PSendSysMessage("The item with slot %d %s has a container (slot: %d, %s) but shouldn't!", item->GetSlot(), item->GetGUID().ToString().c_str(), container->GetSlot(), container->GetGUID().ToString().c_str());
error = true;
continue;
}
@@ -684,7 +684,7 @@ public:
if (item2->GetOwnerGUID() != player->GetGUID())
{
- handler->PSendSysMessage("The item in bag %d at slot %d and with itemguid %d, the owner's guid (%d) and the player's guid (%d) don't match!", bag->GetSlot(), item2->GetSlot(), item2->GetGUIDLow(), item2->GetOwnerGUID().GetCounter(), player->GetGUIDLow());
+ handler->PSendSysMessage("The item in bag %d at slot %d and %s, the owner (%s) and the player (%s) don't match!", bag->GetSlot(), item2->GetSlot(), item2->GetGUID().ToString().c_str(), item2->GetOwnerGUID().ToString().c_str(), player->GetGUID().ToString().c_str());
error = true;
continue;
}
@@ -692,14 +692,14 @@ public:
Bag* container = item2->GetContainer();
if (!container)
{
- handler->PSendSysMessage("The item in bag %d at slot %d with guid %d has no container!", bag->GetSlot(), item2->GetSlot(), item2->GetGUIDLow());
+ handler->PSendSysMessage("The item in bag %d at slot %d %s has no container!", bag->GetSlot(), item2->GetSlot(), item2->GetGUID().ToString().c_str());
error = true;
continue;
}
if (container != bag)
{
- handler->PSendSysMessage("The item in bag %d at slot %d with guid %d has a different container(slot %d guid %d)!", bag->GetSlot(), item2->GetSlot(), item2->GetGUIDLow(), container->GetSlot(), container->GetGUIDLow());
+ handler->PSendSysMessage("The item in bag %d at slot %d %s has a different container(slot %d %s)!", bag->GetSlot(), item2->GetSlot(), item2->GetGUID().ToString().c_str(), container->GetSlot(), container->GetGUID().ToString().c_str());
error = true;
continue;
}
@@ -746,14 +746,14 @@ public:
if (item->GetOwnerGUID() != player->GetGUID())
{
- handler->PSendSysMessage("queue(%zu): For the item with guid %d, the owner's guid (%d) and the player's guid (%d) don't match!", i, item->GetGUIDLow(), item->GetOwnerGUID().GetCounter(), player->GetGUIDLow());
+ handler->PSendSysMessage("queue(%zu): For the item %s, the owner (%s) and the player (%s) don't match!", i, item->GetGUID().ToString().c_str(), item->GetOwnerGUID().ToString().c_str(), player->GetGUID().ToString().c_str());
error = true;
continue;
}
if (item->GetQueuePos() != i)
{
- handler->PSendSysMessage("queue(%zu): For the item with guid %d, the queuepos doesn't match it's position in the queue!", i, item->GetGUIDLow());
+ handler->PSendSysMessage("queue(%zu): For the item %s, the queuepos doesn't match it's position in the queue!", i, item->GetGUID().ToString().c_str());
error = true;
continue;
}
@@ -765,14 +765,14 @@ public:
if (test == NULL)
{
- handler->PSendSysMessage("queue(%zu): The bag(%d) and slot(%d) values for the item with guid %d are incorrect, the player doesn't have any item at that position!", i, item->GetBagSlot(), item->GetSlot(), item->GetGUIDLow());
+ handler->PSendSysMessage("queue(%zu): The bag(%d) and slot(%d) values for %s are incorrect, the player doesn't have any item at that position!", i, item->GetBagSlot(), item->GetSlot(), item->GetGUID().ToString().c_str());
error = true;
continue;
}
if (test != item)
{
- handler->PSendSysMessage("queue(%zu): The bag(%d) and slot(%d) values for the item with guid %d are incorrect, an item which guid is %d is there instead!", i, item->GetBagSlot(), item->GetSlot(), item->GetGUIDLow(), test->GetGUIDLow());
+ handler->PSendSysMessage("queue(%zu): The bag(%d) and slot(%d) values for the %s are incorrect, %s is there instead!", i, item->GetBagSlot(), item->GetSlot(), item->GetGUID().ToString().c_str(), test->GetGUID().ToString().c_str());
error = true;
continue;
}
diff --git a/src/server/scripts/Commands/cs_gm.cpp b/src/server/scripts/Commands/cs_gm.cpp
index 27ec4835ce6..24da9e37327 100644
--- a/src/server/scripts/Commands/cs_gm.cpp
+++ b/src/server/scripts/Commands/cs_gm.cpp
@@ -121,7 +121,7 @@ public:
bool footer = false;
boost::shared_lock<boost::shared_mutex> lock(*HashMapHolder<Player>::GetLock());
- HashMapHolder<Player>::MapType const& m = sObjectAccessor->GetPlayers();
+ HashMapHolder<Player>::MapType const& m = ObjectAccessor::GetPlayers();
for (HashMapHolder<Player>::MapType::const_iterator itr = m.begin(); itr != m.end(); ++itr)
{
AccountTypes itrSec = itr->second->GetSession()->GetSecurity();
@@ -163,7 +163,7 @@ public:
///- Get the accounts with GM Level >0
PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_GM_ACCOUNTS);
stmt->setUInt8(0, uint8(SEC_MODERATOR));
- stmt->setInt32(1, int32(realmID));
+ stmt->setInt32(1, int32(realmHandle.Index));
PreparedQueryResult result = LoginDatabase.Query(stmt);
if (result)
diff --git a/src/server/scripts/Commands/cs_group.cpp b/src/server/scripts/Commands/cs_group.cpp
index e39aca6f6a7..a558d977b85 100644
--- a/src/server/scripts/Commands/cs_group.cpp
+++ b/src/server/scripts/Commands/cs_group.cpp
@@ -343,7 +343,7 @@ public:
// Check if iterator is online. If is...
Player* p = ObjectAccessor::FindPlayer((*itr).guid);
- if (p && p->IsInWorld())
+ if (p)
{
// ... than, it prints information like "is online", where he is, etc...
onlineState = "online";
diff --git a/src/server/scripts/Commands/cs_message.cpp b/src/server/scripts/Commands/cs_message.cpp
index f2067e6c70b..715487eff99 100644
--- a/src/server/scripts/Commands/cs_message.cpp
+++ b/src/server/scripts/Commands/cs_message.cpp
@@ -211,7 +211,7 @@ public:
std::string name = strtok(NULL, " ");
if (normalizePlayerName(name))
{
- if (Player* player = sObjectAccessor->FindPlayerByName(name))
+ if (Player* player = ObjectAccessor::FindPlayerByName(name))
{
handler->GetSession()->GetPlayer()->RemoveFromWhisperWhiteList(player->GetGUID());
handler->PSendSysMessage(LANG_COMMAND_WHISPEROFFPLAYER, name.c_str());
diff --git a/src/server/scripts/Commands/cs_misc.cpp b/src/server/scripts/Commands/cs_misc.cpp
index 9277956262f..75dbf975857 100644
--- a/src/server/scripts/Commands/cs_misc.cpp
+++ b/src/server/scripts/Commands/cs_misc.cpp
@@ -35,6 +35,7 @@
#include "LFG.h"
#include "GroupMgr.h"
#include "MMapFactory.h"
+#include "DisableMgr.h"
class misc_commandscript : public CommandScript
{
@@ -185,7 +186,7 @@ public:
uint32 haveMap = Map::ExistMap(mapId, gridX, gridY) ? 1 : 0;
uint32 haveVMap = Map::ExistVMap(mapId, gridX, gridY) ? 1 : 0;
- uint32 haveMMap = (MMAP::MMapFactory::IsPathfindingEnabled(mapId) && MMAP::MMapFactory::createOrGetMMapManager()->GetNavMesh(handler->GetSession()->GetPlayer()->GetMapId())) ? 1 : 0;
+ uint32 haveMMap = (DisableMgr::IsPathfindingEnabled(mapId) && MMAP::MMapFactory::createOrGetMMapManager()->GetNavMesh(handler->GetSession()->GetPlayer()->GetMapId())) ? 1 : 0;
if (haveVMap)
{
@@ -1541,7 +1542,7 @@ public:
// Query the prepared statement for login data
stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_PINFO);
- stmt->setInt32(0, int32(realmID));
+ stmt->setInt32(0, int32(realmHandle.Index));
stmt->setUInt32(1, accId);
PreparedQueryResult result = LoginDatabase.Query(stmt);
@@ -2193,7 +2194,7 @@ public:
if (args && args[0] != '\0')
{
- target = sObjectAccessor->FindPlayerByName(args);
+ target = ObjectAccessor::FindPlayerByName(args);
if (!target)
{
handler->SendSysMessage(LANG_PLAYER_NOT_FOUND);
@@ -2281,7 +2282,7 @@ public:
// find the player
std::string name = arg1;
normalizePlayerName(name);
- player = sObjectAccessor->FindPlayerByName(name);
+ player = ObjectAccessor::FindPlayerByName(name);
// Check if we have duration set
if (arg2 && isNumeric(arg2))
{
@@ -2345,7 +2346,7 @@ public:
{
name = targetName;
normalizePlayerName(name);
- player = sObjectAccessor->FindPlayerByName(name);
+ player = ObjectAccessor::FindPlayerByName(name);
}
else // If no name was entered - use target
{
@@ -2421,7 +2422,7 @@ public:
int32 remaintime = fields[1].GetInt32();
// Save the frozen player to update remaining time in case of future .listfreeze uses
// before the frozen state expires
- if (Player* frozen = sObjectAccessor->FindPlayerByName(player))
+ if (Player* frozen = ObjectAccessor::FindPlayerByName(player))
frozen->SaveToDB();
// Notify the freeze duration
if (remaintime == -1) // Permanent duration
diff --git a/src/server/scripts/Commands/cs_mmaps.cpp b/src/server/scripts/Commands/cs_mmaps.cpp
index 969027139fc..a6a7fac3cb5 100644
--- a/src/server/scripts/Commands/cs_mmaps.cpp
+++ b/src/server/scripts/Commands/cs_mmaps.cpp
@@ -25,6 +25,7 @@
#include "ScriptMgr.h"
#include "Chat.h"
+#include "DisableMgr.h"
#include "ObjectMgr.h"
#include "Player.h"
#include "PointMovementGenerator.h"
@@ -209,7 +210,7 @@ public:
{
uint32 mapId = handler->GetSession()->GetPlayer()->GetMapId();
handler->PSendSysMessage("mmap stats:");
- handler->PSendSysMessage(" global mmap pathfinding is %sabled", MMAP::MMapFactory::IsPathfindingEnabled(mapId) ? "en" : "dis");
+ handler->PSendSysMessage(" global mmap pathfinding is %sabled", DisableMgr::IsPathfindingEnabled(mapId) ? "en" : "dis");
MMAP::MMapManager* manager = MMAP::MMapFactory::createOrGetMMapManager();
handler->PSendSysMessage(" %u maps loaded with %u tiles overall", manager->getLoadedMapsCount(), manager->getLoadedTilesCount());
diff --git a/src/server/scripts/Commands/cs_rbac.cpp b/src/server/scripts/Commands/cs_rbac.cpp
index 95ef5ab6984..ab960026d69 100644
--- a/src/server/scripts/Commands/cs_rbac.cpp
+++ b/src/server/scripts/Commands/cs_rbac.cpp
@@ -160,7 +160,7 @@ public:
if (!rdata)
{
- data->rbac = new rbac::RBACData(accountId, accountName, realmID, AccountMgr::GetSecurity(accountId, realmID));
+ data->rbac = new rbac::RBACData(accountId, accountName, realmHandle.Index, AccountMgr::GetSecurity(accountId, realmHandle.Index));
data->rbac->LoadFromDB();
data->needDelete = true;
}
diff --git a/src/server/scripts/Commands/cs_reset.cpp b/src/server/scripts/Commands/cs_reset.cpp
index faf87adc7b6..2823c2c8c5d 100644
--- a/src/server/scripts/Commands/cs_reset.cpp
+++ b/src/server/scripts/Commands/cs_reset.cpp
@@ -295,7 +295,7 @@ public:
CharacterDatabase.Execute(stmt);
boost::shared_lock<boost::shared_mutex> lock(*HashMapHolder<Player>::GetLock());
- HashMapHolder<Player>::MapType const& plist = sObjectAccessor->GetPlayers();
+ HashMapHolder<Player>::MapType const& plist = ObjectAccessor::GetPlayers();
for (HashMapHolder<Player>::MapType::const_iterator itr = plist.begin(); itr != plist.end(); ++itr)
itr->second->SetAtLoginFlag(atLogin);
diff --git a/src/server/scripts/Commands/cs_ticket.cpp b/src/server/scripts/Commands/cs_ticket.cpp
index 674658f41ff..a06bd95f6b6 100644
--- a/src/server/scripts/Commands/cs_ticket.cpp
+++ b/src/server/scripts/Commands/cs_ticket.cpp
@@ -98,7 +98,7 @@ public:
ObjectGuid targetGuid = sObjectMgr->GetPlayerGUIDByName(target);
uint32 accountId = sObjectMgr->GetPlayerAccountIdByGUID(targetGuid);
// Target must exist and have administrative rights
- if (!AccountMgr::HasPermission(accountId, rbac::RBAC_PERM_COMMANDS_BE_ASSIGNED_TICKET, realmID))
+ if (!AccountMgr::HasPermission(accountId, rbac::RBAC_PERM_COMMANDS_BE_ASSIGNED_TICKET, realmHandle.Index))
{
handler->SendSysMessage(LANG_COMMAND_TICKETASSIGNERROR_A);
return true;
@@ -122,7 +122,7 @@ public:
// Assign ticket
SQLTransaction trans = SQLTransaction(NULL);
- ticket->SetAssignedTo(targetGuid, AccountMgr::IsAdminAccount(AccountMgr::GetSecurity(accountId, realmID)));
+ ticket->SetAssignedTo(targetGuid, AccountMgr::IsAdminAccount(AccountMgr::GetSecurity(accountId, realmHandle.Index)));
ticket->SaveToDB(trans);
sTicketMgr->UpdateLastChange();
@@ -162,12 +162,9 @@ public:
// Inform player, who submitted this ticket, that it is closed
if (Player* submitter = ticket->GetPlayer())
{
- if (submitter->IsInWorld())
- {
- WorldPacket data(SMSG_GMTICKET_DELETETICKET, 4);
- data << uint32(GMTICKET_RESPONSE_TICKET_DELETED);
- submitter->GetSession()->SendPacket(&data);
- }
+ WorldPacket data(SMSG_GMTICKET_DELETETICKET, 4);
+ data << uint32(GMTICKET_RESPONSE_TICKET_DELETED);
+ submitter->GetSession()->SendPacket(&data);
}
return true;
}
@@ -232,8 +229,7 @@ public:
}
if (Player* player = ticket->GetPlayer())
- if (player->IsInWorld())
- ticket->SendResponse(player->GetSession());
+ ticket->SendResponse(player->GetSession());
SQLTransaction trans = SQLTransaction(NULL);
ticket->SetCompleted();
@@ -273,13 +269,10 @@ public:
if (Player* player = ticket->GetPlayer())
{
- if (player->IsInWorld())
- {
- // Force abandon ticket
- WorldPacket data(SMSG_GMTICKET_DELETETICKET, 4);
- data << uint32(GMTICKET_RESPONSE_TICKET_DELETED);
- player->GetSession()->SendPacket(&data);
- }
+ // Force abandon ticket
+ WorldPacket data(SMSG_GMTICKET_DELETETICKET, 4);
+ data << uint32(GMTICKET_RESPONSE_TICKET_DELETED);
+ player->GetSession()->SendPacket(&data);
}
return true;
@@ -301,8 +294,7 @@ public:
ticket->SetEscalatedStatus(TICKET_IN_ESCALATION_QUEUE);
if (Player* player = ticket->GetPlayer())
- if (player->IsInWorld())
- sTicketMgr->SendTicket(player->GetSession(), ticket);
+ sTicketMgr->SendTicket(player->GetSession(), ticket);
sTicketMgr->UpdateLastChange();
return true;
@@ -372,13 +364,13 @@ public:
// Get security level of player, whom this ticket is assigned to
uint32 security = SEC_PLAYER;
Player* assignedPlayer = ticket->GetAssignedPlayer();
- if (assignedPlayer && assignedPlayer->IsInWorld())
+ if (assignedPlayer)
security = assignedPlayer->GetSession()->GetSecurity();
else
{
ObjectGuid guid = ticket->GetAssignedToGUID();
uint32 accountId = sObjectMgr->GetPlayerAccountIdByGUID(guid);
- security = AccountMgr::GetSecurity(accountId, realmID);
+ security = AccountMgr::GetSecurity(accountId, realmHandle.Index);
}
// Check security
@@ -435,7 +427,7 @@ public:
// Detect target's GUID
ObjectGuid guid;
- if (Player* player = sObjectAccessor->FindPlayerByName(name))
+ if (Player* player = ObjectAccessor::FindPlayerByName(name))
guid = player->GetGUID();
else
guid = sObjectMgr->GetPlayerGUIDByName(name);
diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/instance_culling_of_stratholme.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/instance_culling_of_stratholme.cpp
index c25a061d622..cb3fa49216b 100644
--- a/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/instance_culling_of_stratholme.cpp
+++ b/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/instance_culling_of_stratholme.cpp
@@ -204,7 +204,7 @@ class instance_culling_of_stratholme : public InstanceMapScript
if (state == DONE)
{
if (GameObject* go = instance->GetGameObject(_malGanisChestGUID))
- go->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_INTERACT_COND);
+ go->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
instance->SummonCreature(NPC_CHROMIE_3, ChromieSummonPos[1]);
}
break;
diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_anubarak_trial.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_anubarak_trial.cpp
index d5bd2bcae7e..072dbd81fd8 100644
--- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_anubarak_trial.cpp
+++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_anubarak_trial.cpp
@@ -212,7 +212,6 @@ class boss_anubarak_trial : public CreatureScript
}
void MoveInLineOfSight(Unit* /*who*/) override
-
{
if (!_intro)
{
diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/instance_trial_of_the_crusader.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/instance_trial_of_the_crusader.cpp
index 79fb154d6e3..e3ad891fdc7 100644
--- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/instance_trial_of_the_crusader.cpp
+++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/instance_trial_of_the_crusader.cpp
@@ -68,15 +68,10 @@ class instance_trial_of_the_crusader : public InstanceMapScript
else
player->SendUpdateWorldState(UPDATE_STATE_UI_SHOW, 0);
- // make sure Anub'arak isnt missing and floor is destroyed after a crash
+ // make sure Anub'arak isnt missing
if (GetBossState(BOSS_LICH_KING) == DONE && TrialCounter && GetBossState(BOSS_ANUBARAK) != DONE)
- {
- if (Creature* anubArak = ObjectAccessor::GetCreature(*player, GetGuidData(NPC_ANUBARAK)))
- anubArak = player->SummonCreature(NPC_ANUBARAK, AnubarakLoc[0].GetPositionX(), AnubarakLoc[0].GetPositionY(), AnubarakLoc[0].GetPositionZ(), 3, TEMPSUMMON_CORPSE_TIMED_DESPAWN, DESPAWN_TIME);
-
- if (GameObject* floor = ObjectAccessor::GetGameObject(*player, GetGuidData(GO_ARGENT_COLISEUM_FLOOR)))
- floor->SetDestructibleState(GO_DESTRUCTIBLE_DAMAGED);
- }
+ if (!ObjectAccessor::GetCreature(*player, GetGuidData(NPC_ANUBARAK)))
+ player->SummonCreature(NPC_ANUBARAK, AnubarakLoc[0], TEMPSUMMON_CORPSE_TIMED_DESPAWN, DESPAWN_TIME);
}
void OpenDoor(ObjectGuid guid)
@@ -160,23 +155,15 @@ class instance_trial_of_the_crusader : public InstanceMapScript
switch (go->GetEntry())
{
case GO_CRUSADERS_CACHE_10:
- if (instance->GetSpawnMode() == RAID_DIFFICULTY_10MAN_NORMAL)
- CrusadersCacheGUID = go->GetGUID();
- break;
case GO_CRUSADERS_CACHE_25:
- if (instance->GetSpawnMode() == RAID_DIFFICULTY_25MAN_NORMAL)
- CrusadersCacheGUID = go->GetGUID();
- break;
case GO_CRUSADERS_CACHE_10_H:
- if (instance->GetSpawnMode() == RAID_DIFFICULTY_10MAN_HEROIC)
- CrusadersCacheGUID = go->GetGUID();
- break;
case GO_CRUSADERS_CACHE_25_H:
- if (instance->GetSpawnMode() == RAID_DIFFICULTY_25MAN_HEROIC)
- CrusadersCacheGUID = go->GetGUID();
+ CrusadersCacheGUID = go->GetGUID();
break;
case GO_ARGENT_COLISEUM_FLOOR:
FloorGUID = go->GetGUID();
+ if (GetBossState(BOSS_LICH_KING) == DONE)
+ go->SetDestructibleState(GO_DESTRUCTIBLE_DAMAGED);
break;
case GO_MAIN_GATE_DOOR:
MainGateDoorGUID = go->GetGUID();
diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/trial_of_the_crusader.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/trial_of_the_crusader.cpp
index d8ec322c57c..885017c24dd 100644
--- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/trial_of_the_crusader.cpp
+++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/trial_of_the_crusader.cpp
@@ -207,11 +207,8 @@ class npc_announcer_toc10 : public CreatureScript
creature->CastSpell(creature, SPELL_CORPSE_TELEPORT, false);
creature->CastSpell(creature, SPELL_DESTROY_FLOOR_KNOCKUP, false);
- Creature* anubArak = ObjectAccessor::GetCreature(*creature, instance->GetGuidData(NPC_ANUBARAK));
- if (!anubArak || !anubArak->IsAlive())
- anubArak = creature->SummonCreature(NPC_ANUBARAK, AnubarakLoc[0].GetPositionX(), AnubarakLoc[0].GetPositionY(), AnubarakLoc[0].GetPositionZ(), 3, TEMPSUMMON_CORPSE_TIMED_DESPAWN, DESPAWN_TIME);
-
- instance->SetBossState(BOSS_ANUBARAK, NOT_STARTED);
+ if (!ObjectAccessor::GetCreature(*creature, instance->GetGuidData(NPC_ANUBARAK)))
+ creature->SummonCreature(NPC_ANUBARAK, AnubarakLoc[0], TEMPSUMMON_CORPSE_TIMED_DESPAWN, DESPAWN_TIME);
if (creature->IsVisible())
creature->SetVisible(false);
@@ -319,19 +316,15 @@ class boss_lich_king_toc : public CreatureScript
case 5080:
{
if (GameObject* go = ObjectAccessor::GetGameObject(*me, _instance->GetGuidData(GO_ARGENT_COLISEUM_FLOOR)))
- {
- go->SetDisplayId(DISPLAYID_DESTROYED_FLOOR);
- go->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_DAMAGED | GO_FLAG_NODESPAWN);
- go->SetGoState(GO_STATE_ACTIVE);
- }
+ go->SetDestructibleState(GO_DESTRUCTIBLE_DAMAGED);
me->CastSpell(me, SPELL_CORPSE_TELEPORT, false);
me->CastSpell(me, SPELL_DESTROY_FLOOR_KNOCKUP, false);
_instance->SetBossState(BOSS_LICH_KING, DONE);
- Creature* temp = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(NPC_ANUBARAK));
- if (!temp || !temp->IsAlive())
- temp = me->SummonCreature(NPC_ANUBARAK, AnubarakLoc[0].GetPositionX(), AnubarakLoc[0].GetPositionY(), AnubarakLoc[0].GetPositionZ(), 3, TEMPSUMMON_CORPSE_TIMED_DESPAWN, DESPAWN_TIME);
+
+ if (!ObjectAccessor::GetCreature(*me, _instance->GetGuidData(NPC_ANUBARAK)))
+ me->SummonCreature(NPC_ANUBARAK, AnubarakLoc[0], TEMPSUMMON_CORPSE_TIMED_DESPAWN, DESPAWN_TIME);
_instance->SetData(TYPE_EVENT, 0);
diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/trial_of_the_crusader.h b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/trial_of_the_crusader.h
index cf08fb75228..e37148aa508 100644
--- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/trial_of_the_crusader.h
+++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/trial_of_the_crusader.h
@@ -42,9 +42,7 @@ enum SpellIds
enum MiscData
{
- DESPAWN_TIME = 1200000,
-
- DISPLAYID_DESTROYED_FLOOR = 9060
+ DESPAWN_TIME = 1200000
};
const Position ToCSpawnLoc[]=
@@ -133,7 +131,7 @@ const Position LichKingLoc[]=
const Position AnubarakLoc[]=
{
- {787.932556f, 133.289780f, 142.612152f, 0}, // 0 - Anub'arak start location
+ {783.9305f, 132.9722f, 142.6711f, 3.141593f}, // 0 - Anub'arak Spawn Location (sniffed)
{695.240051f, 137.834824f, 142.200000f, 0}, // 1 - Anub'arak move point location
{694.886353f, 102.484665f, 142.119614f, 0}, // 3 - Nerub Spawn
{694.500671f, 185.363968f, 142.117905f, 0}, // 5 - Nerub Spawn
@@ -232,13 +230,13 @@ enum CreatureIds
NPC_HORDE_WARLOCK = 34450,
NPC_HORDE_WARRIOR = 34453,
- NPC_LIGHTBANE = 34497,
- NPC_DARKBANE = 34496,
+ NPC_LIGHTBANE = 34497,
+ NPC_DARKBANE = 34496,
- NPC_DARK_ESSENCE = 34567,
- NPC_LIGHT_ESSENCE = 34568,
+ NPC_DARK_ESSENCE = 34567,
+ NPC_LIGHT_ESSENCE = 34568,
- NPC_ANUBARAK = 34564
+ NPC_ANUBARAK = 34564
};
enum GameObjectIds
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_rotface.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_rotface.cpp
index 5e55256ae59..d5c07fb6942 100644
--- a/src/server/scripts/Northrend/IcecrownCitadel/boss_rotface.cpp
+++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_rotface.cpp
@@ -178,6 +178,8 @@ class boss_rotface : public CreatureScript
if (summon->GetEntry() == NPC_VILE_GAS_STALKER)
if (Creature* professor = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_PROFESSOR_PUTRICIDE)))
professor->CastSpell(summon, SPELL_VILE_GAS_H, true);
+
+ summons.Summon(summon);
}
void UpdateAI(uint32 diff) override
diff --git a/src/server/scripts/Northrend/Ulduar/HallsOfStone/instance_halls_of_stone.cpp b/src/server/scripts/Northrend/Ulduar/HallsOfStone/instance_halls_of_stone.cpp
index d6c7b18eabd..880d032265a 100644
--- a/src/server/scripts/Northrend/Ulduar/HallsOfStone/instance_halls_of_stone.cpp
+++ b/src/server/scripts/Northrend/Ulduar/HallsOfStone/instance_halls_of_stone.cpp
@@ -91,7 +91,7 @@ class instance_halls_of_stone : public InstanceMapScript
case GO_TRIBUNAL_CHEST_HERO:
TribunalChestGUID = go->GetGUID();
if (GetBossState(DATA_BRANN_EVENT) == DONE)
- go->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_INTERACT_COND);
+ go->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
break;
case GO_TRIBUNAL_SKY_FLOOR:
TribunalSkyFloorGUID = go->GetGUID();
@@ -160,7 +160,7 @@ class instance_halls_of_stone : public InstanceMapScript
if (state == DONE)
{
if (GameObject* go = instance->GetGameObject(TribunalChestGUID))
- go->RemoveFlag(GAMEOBJECT_FLAGS,GO_FLAG_INTERACT_COND);
+ go->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
}
break;
default:
diff --git a/src/server/scripts/Outland/Auchindoun/SethekkHalls/boss_darkweaver_syth.cpp b/src/server/scripts/Outland/Auchindoun/SethekkHalls/boss_darkweaver_syth.cpp
index e6ffa3f8979..6ec69ee11af 100644
--- a/src/server/scripts/Outland/Auchindoun/SethekkHalls/boss_darkweaver_syth.cpp
+++ b/src/server/scripts/Outland/Auchindoun/SethekkHalls/boss_darkweaver_syth.cpp
@@ -72,7 +72,7 @@ public:
struct boss_darkweaver_sythAI : public BossAI
{
boss_darkweaver_sythAI(Creature* creature) : BossAI(creature, DATA_DARKWEAVER_SYTH)
- {
+ {
Initialize();
}
diff --git a/src/server/scripts/Outland/BlackTemple/boss_reliquary_of_souls.cpp b/src/server/scripts/Outland/BlackTemple/boss_reliquary_of_souls.cpp
index dd0e271a02d..23abf48233e 100644
--- a/src/server/scripts/Outland/BlackTemple/boss_reliquary_of_souls.cpp
+++ b/src/server/scripts/Outland/BlackTemple/boss_reliquary_of_souls.cpp
@@ -117,7 +117,7 @@ public:
void Reset() override
{
- ReliquaryGUID.Clear();
+ ReliquaryGUID.Clear();
}
void EnterCombat(Unit* /*who*/) override
diff --git a/src/server/scripts/World/go_scripts.cpp b/src/server/scripts/World/go_scripts.cpp
index 65cb2c2abce..752ea2feb1c 100644
--- a/src/server/scripts/World/go_scripts.cpp
+++ b/src/server/scripts/World/go_scripts.cpp
@@ -24,7 +24,6 @@ go_ethereum_stasis
go_sacred_fire_of_life
go_shrine_of_the_birds
go_southfury_moonstone
-go_field_repair_bot_74A
go_orb_of_command
go_resonite_cask
go_tablet_of_madness
@@ -94,24 +93,6 @@ public:
};
/*######
-## go_field_repair_bot_74A
-######*/
-
-class go_field_repair_bot_74A : public GameObjectScript
-{
-public:
- go_field_repair_bot_74A() : GameObjectScript("go_field_repair_bot_74A") { }
-
- bool OnGossipHello(Player* player, GameObject* /*go*/) override
- {
- if (player->HasSkill(SKILL_ENGINEERING) && player->GetBaseSkillValue(SKILL_ENGINEERING) >= 300 && !player->HasSpell(22704))
- player->CastSpell(player, 22864, false);
-
- return true;
- }
-};
-
-/*######
## go_gilded_brazier (Paladin First Trail quest (9678))
######*/
@@ -1213,7 +1194,6 @@ void AddSC_go_scripts()
{
new go_cat_figurine();
new go_barov_journal();
- new go_field_repair_bot_74A();
new go_gilded_brazier();
new go_orb_of_command();
new go_shrine_of_the_birds();
diff --git a/src/server/shared/Database/Implementation/WorldDatabase.cpp b/src/server/shared/Database/Implementation/WorldDatabase.cpp
index ecbd0e9244c..531d092d039 100644
--- a/src/server/shared/Database/Implementation/WorldDatabase.cpp
+++ b/src/server/shared/Database/Implementation/WorldDatabase.cpp
@@ -89,4 +89,6 @@ void WorldDatabaseConnection::DoPrepareStatements()
PrepareStatement(WORLD_INS_DISABLES, "INSERT INTO disables (entry, sourceType, flags, comment) VALUES (?, ?, ?, ?)", CONNECTION_ASYNC);
PrepareStatement(WORLD_SEL_DISABLES, "SELECT entry FROM disables WHERE entry = ? AND sourceType = ?", CONNECTION_SYNCH);
PrepareStatement(WORLD_DEL_DISABLES, "DELETE FROM disables WHERE entry = ? AND sourceType = ?", CONNECTION_ASYNC);
+ PrepareStatement(WORLD_UPD_CREATURE_ZONE_AREA_DATA, "UPDATE creature SET zoneId = ?, areaId = ? WHERE guid = ?", CONNECTION_ASYNC);
+ PrepareStatement(WORLD_UPD_GAMEOBJECT_ZONE_AREA_DATA, "UPDATE gameobject SET zoneId = ?, areaId = ? WHERE guid = ?", CONNECTION_ASYNC);
}
diff --git a/src/server/shared/Database/Implementation/WorldDatabase.h b/src/server/shared/Database/Implementation/WorldDatabase.h
index 8a5bd206021..a398b412c50 100644
--- a/src/server/shared/Database/Implementation/WorldDatabase.h
+++ b/src/server/shared/Database/Implementation/WorldDatabase.h
@@ -110,6 +110,8 @@ enum WorldDatabaseStatements
WORLD_SEL_DISABLES,
WORLD_INS_DISABLES,
WORLD_DEL_DISABLES,
+ WORLD_UPD_CREATURE_ZONE_AREA_DATA,
+ WORLD_UPD_GAMEOBJECT_ZONE_AREA_DATA,
MAX_WORLDDATABASE_STATEMENTS
};
diff --git a/src/server/shared/Logging/Log.cpp b/src/server/shared/Logging/Log.cpp
index a7b6b418cc4..3305b364f0f 100644
--- a/src/server/shared/Logging/Log.cpp
+++ b/src/server/shared/Logging/Log.cpp
@@ -334,7 +334,7 @@ bool Log::SetLogLevel(std::string const& name, const char* newLevelc, bool isLog
return true;
}
-void Log::outCharDump(char const* str, uint32 accountId, uint32 guid, char const* name)
+void Log::outCharDump(char const* str, uint32 accountId, uint64 guid, char const* name)
{
if (!str || !ShouldLog("entities.player.dump", LOG_LEVEL_INFO))
return;
diff --git a/src/server/shared/Logging/Log.h b/src/server/shared/Logging/Log.h
index 78e7e012bbe..e2d4baa5f0e 100644
--- a/src/server/shared/Logging/Log.h
+++ b/src/server/shared/Logging/Log.h
@@ -62,7 +62,7 @@ class Log
void outMessage(std::string const& f, LogLevel level, char const* str, ...) ATTR_PRINTF(4, 5);
void outCommand(uint32 account, const char * str, ...) ATTR_PRINTF(3, 4);
- void outCharDump(char const* str, uint32 account_id, uint32 guid, char const* name);
+ void outCharDump(char const* str, uint32 account_id, uint64 guid, char const* name);
void SetRealmId(uint32 id);
diff --git a/src/server/worldserver/CMakeLists.txt b/src/server/worldserver/CMakeLists.txt
index 0cdf5f13f79..65972e680ef 100644
--- a/src/server/worldserver/CMakeLists.txt
+++ b/src/server/worldserver/CMakeLists.txt
@@ -47,6 +47,7 @@ include_directories(
${CMAKE_SOURCE_DIR}/dep/gsoap
${CMAKE_SOURCE_DIR}/dep/sockets/include
${CMAKE_SOURCE_DIR}/dep/SFMT
+ ${CMAKE_SOURCE_DIR}/dep/zmqpp
${CMAKE_SOURCE_DIR}/src/server/collision
${CMAKE_SOURCE_DIR}/src/server/collision/Management
${CMAKE_SOURCE_DIR}/src/server/collision/Models
@@ -64,6 +65,7 @@ include_directories(
${CMAKE_SOURCE_DIR}/src/server/shared/Packets
${CMAKE_SOURCE_DIR}/src/server/shared/Threading
${CMAKE_SOURCE_DIR}/src/server/shared/Utilities
+ ${CMAKE_SOURCE_DIR}/src/server/ipc
${CMAKE_SOURCE_DIR}/src/server/game
${CMAKE_SOURCE_DIR}/src/server/game/Accounts
${CMAKE_SOURCE_DIR}/src/server/game/Achievements
@@ -141,6 +143,7 @@ include_directories(
${MYSQL_INCLUDE_DIR}
${OPENSSL_INCLUDE_DIR}
${VALGRIND_INCLUDE_DIR}
+ ${ZMQ_INCLUDE_DIR}
)
add_executable(worldserver
@@ -164,18 +167,21 @@ set_target_properties(worldserver PROPERTIES LINK_FLAGS "${worldserver_LINK_FLAG
target_link_libraries(worldserver
game
+ ipc
shared
scripts
collision
g3dlib
gsoap
Detour
+ zmqpp
${JEMALLOC_LIBRARY}
${READLINE_LIBRARY}
${TERMCAP_LIBRARY}
${MYSQL_LIBRARY}
${OPENSSL_LIBRARIES}
${ZLIB_LIBRARIES}
+ ${ZMQ_LIBRARY}
${CMAKE_THREAD_LIBS_INIT}
${Boost_LIBRARIES}
)
diff --git a/src/server/worldserver/Main.cpp b/src/server/worldserver/Main.cpp
index 6c93343b8de..c5127b8f3e2 100644
--- a/src/server/worldserver/Main.cpp
+++ b/src/server/worldserver/Main.cpp
@@ -20,13 +20,9 @@
/// @{
/// \file
-#include <openssl/opensslv.h>
-#include <openssl/crypto.h>
-#include <boost/asio/io_service.hpp>
-#include <boost/asio/deadline_timer.hpp>
-#include <boost/program_options.hpp>
-
#include "Common.h"
+#include "Commands.h"
+#include "ZmqContext.h"
#include "DatabaseEnv.h"
#include "AsyncAcceptor.h"
#include "RASession.h"
@@ -47,6 +43,12 @@
#include "SystemConfig.h"
#include "WorldSocket.h"
#include "WorldSocketMgr.h"
+#include "BattlenetServerManager.h"
+#include <openssl/opensslv.h>
+#include <openssl/crypto.h>
+#include <boost/asio/io_service.hpp>
+#include <boost/asio/deadline_timer.hpp>
+#include <boost/program_options.hpp>
using namespace boost::program_options;
@@ -79,7 +81,7 @@ uint32 _maxCoreStuckTimeInMs(0);
WorldDatabaseWorkerPool WorldDatabase; ///< Accessor to the world database
CharacterDatabaseWorkerPool CharacterDatabase; ///< Accessor to the character database
LoginDatabaseWorkerPool LoginDatabase; ///< Accessor to the realm/login database
-uint32 realmID; ///< Id of the realm
+Battlenet::RealmHandle realmHandle; ///< Id of the realm
void SignalHandler(const boost::system::error_code& error, int signalNumber);
void FreezeDetectorHandler(const boost::system::error_code& error);
@@ -188,7 +190,7 @@ extern int main(int argc, char** argv)
}
// Set server offline (not connectable)
- LoginDatabase.DirectPExecute("UPDATE realmlist SET flag = (flag & ~%u) | %u WHERE id = '%d'", REALM_FLAG_OFFLINE, REALM_FLAG_INVALID, realmID);
+ LoginDatabase.DirectPExecute("UPDATE realmlist SET flag = (flag & ~%u) | %u WHERE id = '%d'", REALM_FLAG_OFFLINE, REALM_FLAG_INVALID, realmHandle.Index);
// Initialize the World
sWorld->SetInitialWorldSettings();
@@ -223,7 +225,7 @@ extern int main(int argc, char** argv)
sWorldSocketMgr.StartNetwork(_ioService, worldListener, worldPort);
// Set server online (allow connecting now)
- LoginDatabase.DirectPExecute("UPDATE realmlist SET flag = flag & ~%u, population = 0 WHERE id = '%u'", REALM_FLAG_INVALID, realmID);
+ LoginDatabase.DirectPExecute("UPDATE realmlist SET flag = flag & ~%u, population = 0 WHERE id = '%u'", REALM_FLAG_INVALID, realmHandle.Index);
// Start the freeze check callback cycle in 5 seconds (cycle itself is 1 sec)
if (int coreStuckTime = sConfigMgr->GetIntDefault("MaxCoreStuckTime", 0))
@@ -234,6 +236,10 @@ extern int main(int argc, char** argv)
TC_LOG_INFO("server.worldserver", "Starting up anti-freeze thread (%u seconds max stuck time)...", coreStuckTime);
}
+ sIpcContext->Initialize();
+
+ sBattlenetServer.InitializeConnection();
+
TC_LOG_INFO("server.worldserver", "%s (worldserver-daemon) ready...", _FULLVERSION);
sScriptMgr->OnStartup();
@@ -245,6 +251,10 @@ extern int main(int argc, char** argv)
sScriptMgr->OnShutdown();
+ sIpcContext->Close();
+
+ sBattlenetServer.CloseConnection();
+
sWorld->KickAll(); // save and kick all players
sWorld->UpdateSessions(1); // real players unload required UpdateSessions call
@@ -260,7 +270,7 @@ extern int main(int argc, char** argv)
sOutdoorPvPMgr->Die();
// set server offline
- LoginDatabase.DirectPExecute("UPDATE realmlist SET flag = flag | %u WHERE id = '%d'", REALM_FLAG_OFFLINE, realmID);
+ LoginDatabase.DirectPExecute("UPDATE realmlist SET flag = flag | %u WHERE id = '%d'", REALM_FLAG_OFFLINE, realmHandle.Index);
// Clean up threads if any
if (soapThread != nullptr)
@@ -523,13 +533,24 @@ bool StartDB()
}
///- Get the realm Id from the configuration file
- realmID = sConfigMgr->GetIntDefault("RealmID", 0);
- if (!realmID)
+ realmHandle.Index = sConfigMgr->GetIntDefault("RealmID", 0);
+ if (!realmHandle.Index)
{
TC_LOG_ERROR("server.worldserver", "Realm ID not defined in configuration file");
return false;
}
- TC_LOG_INFO("server.worldserver", "Realm running as realm ID %d", realmID);
+
+ QueryResult realmIdQuery = LoginDatabase.PQuery("SELECT `Region`,`Battlegroup` FROM `realmlist` WHERE `id`=%u", realmHandle.Index);
+ if (!realmIdQuery)
+ {
+ TC_LOG_ERROR("server.worldserver", "Realm id %u not defined in realmlist table", realmHandle.Index);
+ return false;
+ }
+
+ realmHandle.Region = (*realmIdQuery)[0].GetUInt8();
+ realmHandle.Battlegroup = (*realmIdQuery)[1].GetUInt8();
+
+ TC_LOG_INFO("server.worldserver", "Realm running as realm ID %u region %u battlegroup %u", realmHandle.Index, uint32(realmHandle.Region), uint32(realmHandle.Battlegroup));
///- Clean the database before starting
ClearOnlineAccounts();
@@ -556,7 +577,7 @@ void StopDB()
void ClearOnlineAccounts()
{
// Reset online status for all accounts with characters on the current realm
- LoginDatabase.DirectPExecute("UPDATE account SET online = 0 WHERE online > 0 AND id IN (SELECT acctid FROM realmcharacters WHERE realmid = %d)", realmID);
+ LoginDatabase.DirectPExecute("UPDATE account SET online = 0 WHERE online > 0 AND id IN (SELECT acctid FROM realmcharacters WHERE realmid = %d)", realmHandle.Index);
// Reset online status for all characters
CharacterDatabase.DirectExecute("UPDATE characters SET online = 0 WHERE online <> 0");
diff --git a/src/server/worldserver/worldserver.conf.dist b/src/server/worldserver/worldserver.conf.dist
index d1a4c244ba2..57d97756d70 100644
--- a/src/server/worldserver/worldserver.conf.dist
+++ b/src/server/worldserver/worldserver.conf.dist
@@ -267,9 +267,9 @@ ChangeWeatherInterval = 600000
#
# PlayerSaveInterval
# Description: Time (in milliseconds) for player save interval.
-# Default: 900000 - (15 min)
+# Default: 90000 - (90 seconds)
-PlayerSaveInterval = 900000
+PlayerSaveInterval = 90000
#
# PlayerSave.Stats.MinLevel
@@ -289,7 +289,7 @@ PlayerSave.Stats.SaveOnlyOnLogout = 1
#
# mmap.enablePathFinding
-# Description: Enable/Disable pathfinding using mmaps - experimental.
+# Description: Enable/Disable pathfinding using mmaps - recommended.
# Default: 0 - (Disabled)
# 1 - (Enabled)
@@ -2004,9 +2004,9 @@ AutoBroadcast.Center = 0
#
# AutoBroadcast.Timer
# Description: Timer (in milliseconds) for auto broadcasts.
-# Default: 60000 - (60 seconds)
+# Default: 60000 - (10 minutes)
-AutoBroadcast.Timer = 60000
+AutoBroadcast.Timer = 600000
#
###################################################################################################
@@ -2620,6 +2620,20 @@ PlayerDump.DisallowOverwrite = 1
UI.ShowQuestLevelsInDialogs = 0
#
+# Calculate.Creature.Zone.Area.Data
+# Description: Calculate at loading creature zoneId / areaId and save in creature table (WARNING: SLOW WORLD SERVER STARTUP)
+# Default: 0 - (Do not show)
+
+Calculate.Creature.Zone.Area.Data = 0
+
+#
+# Calculate.Gameoject.Zone.Area.Data
+# Description: Calculate at loading gameobject zoneId / areaId and save in gameobject table (WARNING: SLOW WORLD SERVER STARTUP)
+# Default: 0 - (Do not show)
+
+Calculate.Gameoject.Zone.Area.Data = 0
+
+#
###################################################################################################
###################################################################################################
@@ -3275,6 +3289,8 @@ Currency.ConquestPointsArenaReward = 180
#
###################################################################################################
+
+###################################################################################################
# PACKET SPOOF PROTECTION SETTINGS
#
# These settings determine which action to take when harmful packet spoofing is detected.
@@ -3308,3 +3324,24 @@ PacketSpoof.BanDuration = 86400
#
###################################################################################################
+
+###################################################################################################
+# IPC SETTINGS
+#
+# BnetServer.Address
+# Description: Determines IP address of battle.net server to connect to.
+# Default: 127.0.0.1
+#
+
+BnetServer.Address = 127.0.0.1
+
+#
+# BnetServer.Port
+# Description: Determines port to use when connecting to battle.net server.
+# Default: 1118
+#
+
+BnetServer.Port = 1118
+
+#
+###################################################################################################
diff --git a/src/tools/mmaps_generator/MapBuilder.cpp b/src/tools/mmaps_generator/MapBuilder.cpp
index 885dd24d760..2f8b35fd52d 100644
--- a/src/tools/mmaps_generator/MapBuilder.cpp
+++ b/src/tools/mmaps_generator/MapBuilder.cpp
@@ -27,14 +27,6 @@
#include "DetourNavMesh.h"
#include "DetourCommon.h"
-#include "DisableMgr.h"
-
-uint32 GetLiquidFlags(uint32 /*liquidType*/) { return 0; }
-namespace DisableMgr
-{
- bool IsDisabledFor(DisableType /*type*/, uint32 /*entry*/, Unit const* /*unit*/, uint8 /*flags*/ /*= 0*/) { return false; }
-}
-
#define MMAP_MAGIC 0x4d4d4150 // 'MMAP'
#define MMAP_VERSION 5
diff --git a/src/tools/mmaps_generator/PathCommon.h b/src/tools/mmaps_generator/PathCommon.h
index 8285fef74f2..694e40dacde 100644
--- a/src/tools/mmaps_generator/PathCommon.h
+++ b/src/tools/mmaps_generator/PathCommon.h
@@ -62,7 +62,7 @@ namespace MMAP
if (*++filter == '\0') // wildcard at end of filter means all remaing chars match
return true;
- while (true)
+ for (;;)
{
if (*filter == *str)
break;