aboutsummaryrefslogtreecommitdiff
path: root/src/server
diff options
context:
space:
mode:
Diffstat (limited to 'src/server')
-rw-r--r--src/server/authserver/CMakeLists.txt4
-rw-r--r--src/server/authserver/Main.cpp288
-rw-r--r--src/server/authserver/PrecompiledHeaders/authPCH.h4
-rw-r--r--src/server/authserver/Realms/RealmList.cpp100
-rw-r--r--src/server/authserver/Realms/RealmList.h54
-rw-r--r--src/server/authserver/Server/AuthSession.cpp (renamed from src/server/authserver/Server/AuthSocket.cpp)770
-rw-r--r--src/server/authserver/Server/AuthSession.h84
-rw-r--r--src/server/authserver/Server/AuthSocket.h81
-rw-r--r--src/server/authserver/Server/RealmAcceptor.h72
-rw-r--r--src/server/authserver/Server/RealmSocket.cpp291
-rw-r--r--src/server/authserver/Server/RealmSocket.h80
-rw-r--r--src/server/collision/BoundingIntervalHierarchy.h4
-rw-r--r--src/server/collision/CMakeLists.txt1
-rw-r--r--src/server/collision/Management/VMapManager2.cpp6
-rw-r--r--src/server/collision/Management/VMapManager2.h6
-rw-r--r--src/server/collision/Maps/MapTree.cpp2
-rw-r--r--src/server/collision/Models/ModelInstance.cpp4
-rw-r--r--src/server/collision/VMapDefinitions.h1
-rw-r--r--src/server/game/AI/CoreAI/UnitAI.cpp4
-rw-r--r--src/server/game/AI/CreatureAI.cpp6
-rw-r--r--src/server/game/AI/CreatureAIFactory.h2
-rw-r--r--src/server/game/AI/CreatureAISelector.cpp6
-rw-r--r--src/server/game/AI/ScriptedAI/ScriptedEscortAI.h2
-rw-r--r--src/server/game/AI/ScriptedAI/ScriptedFollowerAI.h2
-rw-r--r--src/server/game/AI/SmartScripts/SmartScript.cpp38
-rw-r--r--src/server/game/AI/SmartScripts/SmartScript.h2
-rw-r--r--src/server/game/AI/SmartScripts/SmartScriptMgr.h28
-rw-r--r--src/server/game/Accounts/AccountMgr.h11
-rw-r--r--src/server/game/Achievements/AchievementMgr.cpp15
-rw-r--r--src/server/game/Achievements/AchievementMgr.h10
-rw-r--r--src/server/game/AuctionHouse/AuctionHouseMgr.h11
-rw-r--r--src/server/game/Battlefield/BattlefieldMgr.h17
-rw-r--r--src/server/game/Battlefield/Zones/BattlefieldWG.cpp2
-rw-r--r--src/server/game/Battlegrounds/Arena.cpp4
-rw-r--r--src/server/game/Battlegrounds/ArenaTeamMgr.h10
-rw-r--r--src/server/game/Battlegrounds/Battleground.h4
-rw-r--r--src/server/game/Battlegrounds/BattlegroundMgr.cpp6
-rw-r--r--src/server/game/Battlegrounds/BattlegroundMgr.h11
-rw-r--r--src/server/game/Battlegrounds/BattlegroundQueue.cpp1
-rw-r--r--src/server/game/Battlegrounds/Zones/BattlegroundRV.cpp2
-rw-r--r--src/server/game/CMakeLists.txt1
-rw-r--r--src/server/game/Calendar/CalendarMgr.h15
-rw-r--r--src/server/game/Chat/Channels/Channel.h14
-rw-r--r--src/server/game/Chat/Channels/ChannelMgr.cpp6
-rw-r--r--src/server/game/Chat/Channels/ChannelMgr.h14
-rw-r--r--src/server/game/Combat/UnitEvents.h2
-rw-r--r--src/server/game/Conditions/ConditionMgr.cpp12
-rw-r--r--src/server/game/Conditions/ConditionMgr.h12
-rw-r--r--src/server/game/Conditions/DisableMgr.cpp12
-rw-r--r--src/server/game/DataStores/DBCStructure.h10
-rw-r--r--src/server/game/DungeonFinding/LFGMgr.cpp2
-rw-r--r--src/server/game/DungeonFinding/LFGMgr.h13
-rw-r--r--src/server/game/Entities/Creature/Creature.cpp2
-rw-r--r--src/server/game/Entities/Creature/Creature.h14
-rw-r--r--src/server/game/Entities/Creature/CreatureGroups.h13
-rw-r--r--src/server/game/Entities/GameObject/GameObject.h26
-rw-r--r--src/server/game/Entities/Item/Item.cpp4
-rw-r--r--src/server/game/Entities/Item/ItemPrototype.h2
-rw-r--r--src/server/game/Entities/Object/Object.h12
-rw-r--r--src/server/game/Entities/Pet/Pet.cpp2
-rw-r--r--src/server/game/Entities/Player/Player.cpp8
-rw-r--r--src/server/game/Entities/Player/Player.h12
-rw-r--r--src/server/game/Entities/Player/SocialMgr.cpp2
-rw-r--r--src/server/game/Entities/Player/SocialMgr.h11
-rw-r--r--src/server/game/Entities/Unit/Unit.cpp10
-rw-r--r--src/server/game/Entities/Unit/Unit.h14
-rw-r--r--src/server/game/Entities/Vehicle/VehicleDefines.h2
-rw-r--r--src/server/game/Events/GameEventMgr.cpp16
-rw-r--r--src/server/game/Events/GameEventMgr.h11
-rw-r--r--src/server/game/Globals/ObjectAccessor.cpp23
-rw-r--r--src/server/game/Globals/ObjectAccessor.h53
-rw-r--r--src/server/game/Globals/ObjectMgr.cpp4
-rw-r--r--src/server/game/Globals/ObjectMgr.h12
-rw-r--r--src/server/game/Groups/Group.cpp6
-rw-r--r--src/server/game/Groups/GroupMgr.cpp2
-rw-r--r--src/server/game/Groups/GroupMgr.h9
-rw-r--r--src/server/game/Guilds/Guild.cpp2
-rw-r--r--src/server/game/Guilds/GuildMgr.h10
-rw-r--r--src/server/game/Handlers/AddonHandler.cpp4
-rw-r--r--src/server/game/Handlers/AddonHandler.h19
-rw-r--r--src/server/game/Handlers/CharacterHandler.cpp8
-rw-r--r--src/server/game/Handlers/GroupHandler.cpp2
-rw-r--r--src/server/game/Handlers/GuildHandler.cpp2
-rw-r--r--src/server/game/Handlers/MiscHandler.cpp3
-rw-r--r--src/server/game/Handlers/NPCHandler.cpp4
-rw-r--r--src/server/game/Handlers/PetHandler.cpp6
-rw-r--r--src/server/game/Instances/InstanceSaveMgr.h28
-rw-r--r--src/server/game/Maps/Map.cpp14
-rw-r--r--src/server/game/Maps/Map.h6
-rw-r--r--src/server/game/Maps/MapInstanced.cpp4
-rw-r--r--src/server/game/Maps/MapManager.cpp10
-rw-r--r--src/server/game/Maps/MapManager.h16
-rw-r--r--src/server/game/Maps/MapUpdater.cpp104
-rw-r--r--src/server/game/Maps/MapUpdater.h48
-rw-r--r--src/server/game/Maps/TransportMgr.h10
-rwxr-xr-xsrc/server/game/Movement/MovementGenerator.h2
-rw-r--r--src/server/game/Movement/PathGenerator.cpp4
-rw-r--r--src/server/game/Movement/Spline/MoveSplineFlag.h4
-rw-r--r--src/server/game/Movement/Waypoints/WaypointManager.h13
-rw-r--r--src/server/game/OutdoorPvP/OutdoorPvPMgr.h11
-rw-r--r--src/server/game/Pools/PoolMgr.h11
-rw-r--r--src/server/game/PrecompiledHeaders/gamePCH.h3
-rw-r--r--src/server/game/Quests/QuestDef.cpp4
-rw-r--r--src/server/game/Quests/QuestDef.h10
-rw-r--r--src/server/game/Reputation/ReputationMgr.cpp2
-rw-r--r--src/server/game/Scripting/MapScripts.cpp2
-rw-r--r--src/server/game/Scripting/ScriptMgr.cpp16
-rw-r--r--src/server/game/Scripting/ScriptMgr.h37
-rw-r--r--src/server/game/Scripting/ScriptSystem.h11
-rw-r--r--src/server/game/Server/Protocol/PacketLog.h11
-rw-r--r--src/server/game/Server/Protocol/ServerPktHeader.h59
-rw-r--r--src/server/game/Server/WorldSession.cpp48
-rw-r--r--src/server/game/Server/WorldSession.h15
-rw-r--r--src/server/game/Server/WorldSocket.cpp977
-rw-r--r--src/server/game/Server/WorldSocket.h258
-rw-r--r--src/server/game/Server/WorldSocketAcceptor.h67
-rw-r--r--src/server/game/Server/WorldSocketMgr.cpp360
-rw-r--r--src/server/game/Server/WorldSocketMgr.h74
-rw-r--r--src/server/game/Spells/Auras/SpellAuras.cpp2
-rw-r--r--src/server/game/Spells/Auras/SpellAuras.h6
-rw-r--r--src/server/game/Spells/Spell.cpp12
-rw-r--r--src/server/game/Spells/Spell.h6
-rw-r--r--src/server/game/Spells/SpellEffects.cpp2
-rw-r--r--src/server/game/Spells/SpellInfo.cpp14
-rw-r--r--src/server/game/Spells/SpellMgr.h12
-rw-r--r--src/server/game/Spells/SpellScript.cpp2
-rw-r--r--src/server/game/Spells/SpellScript.h4
-rw-r--r--src/server/game/Texts/CreatureTextMgr.h14
-rw-r--r--src/server/game/Tickets/TicketMgr.h13
-rw-r--r--src/server/game/Tools/CharacterDatabaseCleaner.cpp6
-rw-r--r--src/server/game/Warden/WardenCheckMgr.cpp2
-rw-r--r--src/server/game/Warden/WardenCheckMgr.h18
-rw-r--r--src/server/game/Warden/WardenWin.cpp4
-rw-r--r--src/server/game/Weather/Weather.cpp2
-rw-r--r--src/server/game/Weather/WeatherMgr.cpp3
-rw-r--r--src/server/game/World/World.cpp44
-rw-r--r--src/server/game/World/World.h28
-rw-r--r--src/server/scripts/CMakeLists.txt1
-rw-r--r--src/server/scripts/Commands/cs_ban.cpp12
-rw-r--r--src/server/scripts/Commands/cs_debug.cpp28
-rw-r--r--src/server/scripts/Commands/cs_gm.cpp2
-rw-r--r--src/server/scripts/Commands/cs_lfg.cpp2
-rw-r--r--src/server/scripts/Commands/cs_misc.cpp3
-rw-r--r--src/server/scripts/Commands/cs_mmaps.cpp4
-rw-r--r--src/server/scripts/Commands/cs_reset.cpp2
-rw-r--r--src/server/scripts/EasternKingdoms/MagistersTerrace/instance_magisters_terrace.cpp4
-rw-r--r--src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kiljaeden.cpp2
-rw-r--r--src/server/scripts/Northrend/ChamberOfAspects/ObsidianSanctum/obsidian_sanctum.cpp2
-rw-r--r--src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/boss_grand_champions.cpp2
-rw-r--r--src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.cpp2
-rw-r--r--src/server/scripts/Northrend/Gundrak/boss_drakkari_colossus.cpp2
-rw-r--r--src/server/scripts/Northrend/Gundrak/boss_slad_ran.cpp2
-rw-r--r--src/server/scripts/Northrend/IcecrownCitadel/boss_icecrown_gunship_battle.cpp9
-rw-r--r--src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp2
-rw-r--r--src/server/scripts/Northrend/Naxxramas/boss_gothik.cpp2
-rw-r--r--src/server/scripts/Northrend/Ulduar/Ulduar/boss_flame_leviathan.cpp2
-rw-r--r--src/server/scripts/Northrend/Ulduar/Ulduar/boss_ignis.cpp2
-rw-r--r--src/server/scripts/Northrend/Ulduar/Ulduar/boss_razorscale.cpp2
-rw-r--r--src/server/scripts/Northrend/Ulduar/Ulduar/boss_xt002.cpp2
-rw-r--r--src/server/scripts/Northrend/Ulduar/Ulduar/boss_yogg_saron.cpp2
-rw-r--r--src/server/scripts/Northrend/Ulduar/Ulduar/instance_ulduar.cpp2
-rw-r--r--src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/boss_ingvar_the_plunderer.cpp2
-rw-r--r--src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/boss_keleseth.cpp2
-rw-r--r--src/server/scripts/Northrend/zone_storm_peaks.cpp2
-rw-r--r--src/server/scripts/OutdoorPvP/OutdoorPvPNA.cpp108
-rw-r--r--src/server/scripts/OutdoorPvP/OutdoorPvPTF.cpp12
-rw-r--r--src/server/scripts/OutdoorPvP/OutdoorPvPZM.cpp36
-rw-r--r--src/server/scripts/Outland/BlackTemple/illidari_council.cpp2
-rw-r--r--src/server/scripts/Outland/zone_blades_edge_mountains.cpp2
-rw-r--r--src/server/scripts/Spells/spell_dk.cpp2
-rw-r--r--src/server/scripts/Spells/spell_generic.cpp2
-rw-r--r--src/server/scripts/Spells/spell_hunter.cpp2
-rw-r--r--src/server/scripts/Spells/spell_item.cpp2
-rw-r--r--src/server/scripts/Spells/spell_mage.cpp2
-rw-r--r--src/server/scripts/Spells/spell_paladin.cpp2
-rw-r--r--src/server/scripts/Spells/spell_priest.cpp4
-rw-r--r--src/server/scripts/Spells/spell_quest.cpp5
-rw-r--r--src/server/scripts/Spells/spell_rogue.cpp4
-rw-r--r--src/server/scripts/Spells/spell_warrior.cpp2
-rw-r--r--src/server/shared/AutoPtr.h53
-rw-r--r--src/server/shared/CMakeLists.txt8
-rw-r--r--src/server/shared/Common.h32
-rw-r--r--src/server/shared/Configuration/Config.cpp133
-rw-r--r--src/server/shared/Configuration/Config.h45
-rw-r--r--src/server/shared/Cryptography/ARC4.h2
-rw-r--r--src/server/shared/Cryptography/BigNumber.cpp8
-rw-r--r--src/server/shared/Cryptography/BigNumber.h4
-rw-r--r--src/server/shared/Cryptography/OpenSSLCrypto.cpp21
-rw-r--r--src/server/shared/Database/AdhocStatement.cpp20
-rw-r--r--src/server/shared/Database/AdhocStatement.h14
-rw-r--r--src/server/shared/Database/DatabaseWorker.cpp46
-rw-r--r--src/server/shared/Database/DatabaseWorker.h24
-rw-r--r--src/server/shared/Database/DatabaseWorkerPool.h43
-rw-r--r--src/server/shared/Database/Implementation/CharacterDatabase.h2
-rw-r--r--src/server/shared/Database/Implementation/LoginDatabase.h2
-rw-r--r--src/server/shared/Database/Implementation/WorldDatabase.h2
-rw-r--r--src/server/shared/Database/MySQLConnection.cpp11
-rw-r--r--src/server/shared/Database/MySQLConnection.h13
-rw-r--r--src/server/shared/Database/MySQLThreading.h27
-rw-r--r--src/server/shared/Database/PreparedStatement.cpp22
-rw-r--r--src/server/shared/Database/PreparedStatement.h11
-rw-r--r--src/server/shared/Database/QueryHolder.cpp5
-rw-r--r--src/server/shared/Database/QueryHolder.h15
-rw-r--r--src/server/shared/Database/QueryResult.cpp23
-rw-r--r--src/server/shared/Database/QueryResult.h8
-rw-r--r--src/server/shared/Database/SQLOperation.h7
-rw-r--r--src/server/shared/Database/Transaction.h2
-rw-r--r--src/server/shared/Debugging/Errors.cpp11
-rw-r--r--src/server/shared/Debugging/Errors.h16
-rw-r--r--src/server/shared/Debugging/WheatyExceptionReport.cpp2
-rw-r--r--src/server/shared/Define.h42
-rw-r--r--src/server/shared/Dynamic/FactoryHolder.h6
-rw-r--r--src/server/shared/Dynamic/ObjectRegistry.h12
-rw-r--r--src/server/shared/Logging/Appender.cpp3
-rw-r--r--src/server/shared/Logging/Appender.h4
-rw-r--r--src/server/shared/Logging/AppenderConsole.cpp6
-rw-r--r--src/server/shared/Logging/AppenderConsole.h2
-rw-r--r--src/server/shared/Logging/AppenderFile.cpp2
-rw-r--r--src/server/shared/Logging/AppenderFile.h4
-rw-r--r--src/server/shared/Logging/Log.cpp25
-rw-r--r--src/server/shared/Logging/Log.h26
-rw-r--r--src/server/shared/Logging/LogWorker.cpp50
-rw-r--r--src/server/shared/Logging/LogWorker.h47
-rw-r--r--src/server/shared/Networking/AsyncAcceptor.h65
-rw-r--r--src/server/shared/Packets/ByteBuffer.cpp1
-rw-r--r--src/server/shared/Packets/ByteBuffer.h4
-rw-r--r--src/server/shared/Threading/Callback.h43
-rw-r--r--src/server/shared/Threading/DelayExecutor.cpp109
-rw-r--r--src/server/shared/Threading/DelayExecutor.h37
-rw-r--r--src/server/shared/Threading/LockedQueue.h240
-rw-r--r--src/server/shared/Threading/ProcessPriority.h100
-rw-r--r--src/server/shared/Threading/ProducerConsumerQueue.h111
-rw-r--r--src/server/shared/Threading/Threading.cpp235
-rw-r--r--src/server/shared/Threading/Threading.h108
-rw-r--r--src/server/shared/Utilities/ServiceWin32.cpp6
-rw-r--r--src/server/shared/Utilities/SignalHandler.h41
-rw-r--r--src/server/shared/Utilities/Timer.h248
-rw-r--r--src/server/shared/Utilities/Util.cpp55
-rw-r--r--src/server/shared/Utilities/Util.h9
-rw-r--r--src/server/worldserver/CMakeLists.txt7
-rw-r--r--src/server/worldserver/CommandLine/CliRunnable.cpp2
-rw-r--r--src/server/worldserver/CommandLine/CliRunnable.h7
-rw-r--r--src/server/worldserver/Main.cpp571
-rw-r--r--src/server/worldserver/Master.cpp508
-rw-r--r--src/server/worldserver/Master.h45
-rw-r--r--src/server/worldserver/PrecompiledHeaders/worldPCH.h2
-rw-r--r--src/server/worldserver/RemoteAccess/RARunnable.cpp84
-rw-r--r--src/server/worldserver/RemoteAccess/RARunnable.h43
-rw-r--r--src/server/worldserver/RemoteAccess/RASession.cpp222
-rw-r--r--src/server/worldserver/RemoteAccess/RASession.h63
-rw-r--r--src/server/worldserver/RemoteAccess/RASocket.cpp424
-rw-r--r--src/server/worldserver/RemoteAccess/RASocket.h64
-rw-r--r--src/server/worldserver/TCSoap/TCSoap.cpp44
-rw-r--r--src/server/worldserver/TCSoap/TCSoap.h33
-rw-r--r--src/server/worldserver/WorldThread/WorldRunnable.cpp98
-rw-r--r--src/server/worldserver/WorldThread/WorldRunnable.h35
-rw-r--r--src/server/worldserver/worldserver.conf.dist30
257 files changed, 3464 insertions, 6301 deletions
diff --git a/src/server/authserver/CMakeLists.txt b/src/server/authserver/CMakeLists.txt
index 4391ac0450a..d6f0515a8e1 100644
--- a/src/server/authserver/CMakeLists.txt
+++ b/src/server/authserver/CMakeLists.txt
@@ -50,13 +50,13 @@ include_directories(
${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_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/Authentication
${CMAKE_CURRENT_SOURCE_DIR}/Realms
${CMAKE_CURRENT_SOURCE_DIR}/Server
- ${ACE_INCLUDE_DIR}
${MYSQL_INCLUDE_DIR}
${OPENSSL_INCLUDE_DIR}
)
@@ -79,7 +79,7 @@ target_link_libraries(authserver
${MYSQL_LIBRARY}
${OPENSSL_LIBRARIES}
${CMAKE_THREAD_LIBS_INIT}
- ${ACE_LIBRARY}
+ ${Boost_LIBRARIES}
)
if( WIN32 )
diff --git a/src/server/authserver/Main.cpp b/src/server/authserver/Main.cpp
index 2daf01c2fc8..732ed58a19c 100644
--- a/src/server/authserver/Main.cpp
+++ b/src/server/authserver/Main.cpp
@@ -24,28 +24,26 @@
* authentication server
*/
-#include <ace/Dev_Poll_Reactor.h>
-#include <ace/TP_Reactor.h>
-#include <ace/ACE.h>
-#include <ace/Sig_Handler.h>
+#include <cstdlib>
+#include <boost/date_time/posix_time/posix_time.hpp>
+#include <boost/program_options.hpp>
+#include <iostream>
#include <openssl/opensslv.h>
#include <openssl/crypto.h>
+#include "AsyncAcceptor.h"
+#include "AuthSession.h"
#include "Common.h"
-#include "Database/DatabaseEnv.h"
#include "Configuration/Config.h"
+#include "Database/DatabaseEnv.h"
#include "Log.h"
+#include "ProcessPriority.h"
+#include "RealmList.h"
#include "SystemConfig.h"
#include "Util.h"
-#include "SignalHandler.h"
-#include "RealmList.h"
-#include "RealmAcceptor.h"
-#ifdef __linux__
-#include <sched.h>
-#include <sys/resource.h>
-#define PROCESS_HIGH_PRIORITY -15 // [-20, 19], default is 0
-#endif
+using boost::asio::ip::tcp;
+using namespace boost::program_options;
#ifndef _TRINITY_REALM_CONFIG
# define _TRINITY_REALM_CONFIG "authserver.conf"
@@ -53,77 +51,35 @@
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);
-bool stopEvent = false; // Setting it to true stops the server
-
-LoginDatabaseWorkerPool LoginDatabase; // Accessor to the authserver database
+boost::asio::io_service _ioService;
+boost::asio::deadline_timer _dbPingTimer(_ioService);
+uint32 _dbPingInterval;
+LoginDatabaseWorkerPool LoginDatabase;
-/// Handle authserver's termination signals
-class AuthServerSignalHandler : public Trinity::SignalHandler
+int main(int argc, char** argv)
{
-public:
- virtual void HandleSignal(int sigNum)
- {
- switch (sigNum)
- {
- case SIGINT:
- case SIGTERM:
- stopEvent = true;
- break;
- }
- }
-};
-
-/// Print out the usage string for this program on the console.
-void usage(const char* prog)
-{
- TC_LOG_INFO("server.authserver", "Usage: \n %s [<options>]\n"
- " -c config_file use config_file as configuration file\n\r",
- prog);
-}
-
-/// Launch the auth server
-extern int main(int argc, char** argv)
-{
- // Command line parsing to get the configuration file name
- char const* configFile = _TRINITY_REALM_CONFIG;
- int count = 1;
- while (count < argc)
- {
- if (strcmp(argv[count], "-c") == 0)
- {
- if (++count >= argc)
- {
- printf("Runtime-Error: -c option requires an input argument\n");
- usage(argv[0]);
- return 1;
- }
- else
- configFile = argv[count];
- }
- ++count;
- }
+ std::string configFile = _TRINITY_REALM_CONFIG;
+ auto vm = GetConsoleArguments(argc, argv, configFile);
+ // exit if help is enabled
+ if (vm.count("help"))
+ return 0;
if (!sConfigMgr->LoadInitial(configFile))
{
- printf("Invalid or missing configuration file : %s\n", configFile);
+ printf("Invalid or missing configuration file : %s\n", configFile.c_str());
printf("Verify that the file exists and has \'[authserver]\' written in the top of the file!\n");
return 1;
}
TC_LOG_INFO("server.authserver", "%s (authserver)", _FULLVERSION);
TC_LOG_INFO("server.authserver", "<Ctrl-C> to stop.\n");
- TC_LOG_INFO("server.authserver", "Using configuration file %s.", configFile);
-
- TC_LOG_INFO("server.authserver", "%s (Library: %s)", OPENSSL_VERSION_TEXT, SSLeay_version(SSLEAY_VERSION));
-
-#if defined (ACE_HAS_EVENT_POLL) || defined (ACE_HAS_DEV_POLL)
- ACE_Reactor::instance(new ACE_Reactor(new ACE_Dev_Poll_Reactor(ACE::max_handles(), 1), 1), true);
-#else
- ACE_Reactor::instance(new ACE_Reactor(new ACE_TP_Reactor(), true), true);
-#endif
-
- TC_LOG_DEBUG("server.authserver", "Max allowed open files is %d", ACE::max_handles());
+ TC_LOG_INFO("server.authserver", "Using configuration file %s.", configFile.c_str());
+ TC_LOG_INFO("server.worldserver", "Using SSL version: %s (library: %s)", OPENSSL_VERSION_TEXT, SSLeay_version(SSLEAY_VERSION));
+ TC_LOG_INFO("server.worldserver", "Using Boost version: %i.%i.%i", BOOST_VERSION / 100000, BOOST_VERSION / 100 % 1000, BOOST_VERSION % 100);
// authserver PID file creation
std::string pidFile = sConfigMgr->GetStringDefault("PidFile", "");
@@ -143,139 +99,42 @@ extern int main(int argc, char** argv)
return 1;
// Get the list of realms for the server
- sRealmList->Initialize(sConfigMgr->GetIntDefault("RealmsStateUpdateDelay", 20));
- if (sRealmList->size() == 0)
+ sRealmList.Initialize(_ioService, sConfigMgr->GetIntDefault("RealmsStateUpdateDelay", 20));
+
+ if (sRealmList.size() == 0)
{
TC_LOG_ERROR("server.authserver", "No valid realms specified.");
return 1;
}
- // Launch the listening network socket
- RealmAcceptor<AuthSocket> acceptor;
- RealmAcceptor<Battlenet::Socket> bnetacceptor;
-
- int32 rmport = sConfigMgr->GetIntDefault("RealmServerPort", 3724);
- if (rmport < 0 || rmport > 0xFFFF)
+ // Start the listening port (acceptor) for auth connections
+ int32 port = sConfigMgr->GetIntDefault("RealmServerPort", 3724);
+ if (port < 0 || port > 0xFFFF)
{
TC_LOG_ERROR("server.authserver", "Specified port out of allowed range (1-65535)");
return 1;
}
- std::string bind_ip = sConfigMgr->GetStringDefault("BindIP", "0.0.0.0");
-
- ACE_INET_Addr bind_addr(uint16(rmport), bind_ip.c_str());
-
- if (acceptor.open(bind_addr, ACE_Reactor::instance(), ACE_NONBLOCK) == -1)
- {
- TC_LOG_ERROR("server.authserver", "Auth server can not bind to %s:%d", bind_ip.c_str(), rmport);
- return 1;
- }
-
- bind_addr.set_port_number(1119);
- if (bnetacceptor.open(bind_addr, ACE_Reactor::instance(), ACE_NONBLOCK) == -1)
- {
- TC_LOG_ERROR("server.authserver", "Auth server can not bind to %s:%d", bind_ip.c_str(), 1119);
- return 1;
- }
-
- // Initialize the signal handlers
- AuthServerSignalHandler SignalINT, SignalTERM;
+ std::string bindIp = sConfigMgr->GetStringDefault("BindIP", "0.0.0.0");
+ AsyncAcceptor<AuthSession> authServer(_ioService, bindIp, port);
+ AsyncAcceptor<Battlenet::Socket> bnetServer(_ioService, bindIp, 1119);
- // Register authservers's signal handlers
- ACE_Sig_Handler Handler;
- Handler.register_handler(SIGINT, &SignalINT);
- Handler.register_handler(SIGTERM, &SignalTERM);
+ // Set signal handlers
+ boost::asio::signal_set signals(_ioService, SIGINT, SIGTERM);
+ signals.async_wait(SignalHandler);
-#if defined(_WIN32) || defined(__linux__)
-
- ///- Handle affinity for multiple processors and process priority
- uint32 affinity = sConfigMgr->GetIntDefault("UseProcessors", 0);
- bool highPriority = sConfigMgr->GetBoolDefault("ProcessPriority", false);
-
-#ifdef _WIN32 // Windows
-
- HANDLE hProcess = GetCurrentProcess();
- if (affinity > 0)
- {
- ULONG_PTR appAff;
- ULONG_PTR sysAff;
-
- if (GetProcessAffinityMask(hProcess, &appAff, &sysAff))
- {
- // remove non accessible processors
- ULONG_PTR currentAffinity = affinity & appAff;
-
- if (!currentAffinity)
- TC_LOG_ERROR("server.authserver", "Processors marked in UseProcessors bitmask (hex) %x are not accessible for the authserver. Accessible processors bitmask (hex): %x", affinity, appAff);
- else if (SetProcessAffinityMask(hProcess, currentAffinity))
- TC_LOG_INFO("server.authserver", "Using processors (bitmask, hex): %x", currentAffinity);
- else
- TC_LOG_ERROR("server.authserver", "Can't set used processors (hex): %x", currentAffinity);
- }
- }
-
- if (highPriority)
- {
- if (SetPriorityClass(hProcess, HIGH_PRIORITY_CLASS))
- TC_LOG_INFO("server.authserver", "authserver process priority class set to HIGH");
- else
- TC_LOG_ERROR("server.authserver", "Can't set authserver process priority class.");
- }
+ // Set process priority according to configuration settings
+ SetProcessPriority("server.authserver");
-#else // Linux
-
- if (affinity > 0)
- {
- cpu_set_t mask;
- CPU_ZERO(&mask);
-
- for (unsigned int i = 0; i < sizeof(affinity) * 8; ++i)
- if (affinity & (1 << i))
- CPU_SET(i, &mask);
-
- if (sched_setaffinity(0, sizeof(mask), &mask))
- TC_LOG_ERROR("server.authserver", "Can't set used processors (hex): %x, error: %s", affinity, strerror(errno));
- else
- {
- CPU_ZERO(&mask);
- sched_getaffinity(0, sizeof(mask), &mask);
- TC_LOG_INFO("server.authserver", "Using processors (bitmask, hex): %lx", *(__cpu_mask*)(&mask));
- }
- }
-
- if (highPriority)
- {
- if (setpriority(PRIO_PROCESS, 0, PROCESS_HIGH_PRIORITY))
- TC_LOG_ERROR("server.authserver", "Can't set authserver process priority class, error: %s", strerror(errno));
- else
- TC_LOG_INFO("server.authserver", "authserver process priority class set to %i", getpriority(PRIO_PROCESS, 0));
- }
-
-#endif
-#endif
+ // 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);
sBattlenetMgr->Load();
- // maximum counter for next ping
- uint32 numLoops = (sConfigMgr->GetIntDefault("MaxPingTime", 30) * (MINUTE * 1000000 / 100000));
- uint32 loopCounter = 0;
-
- // Wait for termination signal
- while (!stopEvent)
- {
- // dont move this outside the loop, the reactor will modify it
- ACE_Time_Value interval(0, 100000);
-
- if (ACE_Reactor::instance()->run_reactor_event_loop(interval) == -1)
- break;
-
- if ((++loopCounter) == numLoops)
- {
- loopCounter = 0;
- TC_LOG_INFO("server.authserver", "Ping MySQL to keep connection alive");
- LoginDatabase.KeepAlive();
- }
- }
+ // Start the io service worker loop
+ _ioService.run();
// Close the Database Pool and library
StopDB();
@@ -284,6 +143,7 @@ extern int main(int argc, char** argv)
return 0;
}
+
/// Initialize connection to the database
bool StartDB()
{
@@ -328,3 +188,53 @@ void StopDB()
LoginDatabase.Close();
MySQL::Library_End();
}
+
+void SignalHandler(const boost::system::error_code& error, int signalNumber)
+{
+ if (!error)
+ {
+ switch (signalNumber)
+ {
+ case SIGINT:
+ case SIGTERM:
+ _ioService.stop();
+ break;
+ }
+ }
+}
+
+void KeepDatabaseAliveHandler(const boost::system::error_code& error)
+{
+ if (!error)
+ {
+ TC_LOG_INFO("server.authserver", "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_REALM_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/authserver/PrecompiledHeaders/authPCH.h b/src/server/authserver/PrecompiledHeaders/authPCH.h
index 5fc3b0a3416..ef757a656d5 100644
--- a/src/server/authserver/PrecompiledHeaders/authPCH.h
+++ b/src/server/authserver/PrecompiledHeaders/authPCH.h
@@ -1,6 +1,6 @@
+#include "Common.h"
#include "Configuration/Config.h"
#include "Database/DatabaseEnv.h"
#include "Log.h"
#include "RealmList.h"
-#include "RealmSocket.h"
-#include "Common.h"
+#include "AuthSession.h"
diff --git a/src/server/authserver/Realms/RealmList.cpp b/src/server/authserver/Realms/RealmList.cpp
index 48b7a178c2d..181bee31185 100644
--- a/src/server/authserver/Realms/RealmList.cpp
+++ b/src/server/authserver/Realms/RealmList.cpp
@@ -16,12 +16,14 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+#include <boost/asio/ip/tcp.hpp>
#include "Common.h"
#include "RealmList.h"
#include "BattlenetManager.h"
#include "Database/DatabaseEnv.h"
#include "Util.h"
+namespace boost { namespace asio { namespace ip { class address; } } }
ACE_INET_Addr const& Realm::GetAddressForClient(ACE_INET_Addr const& clientAddr) const
{
// Attempt to send best address for client
@@ -42,16 +44,24 @@ RealmList::RealmList() : m_UpdateInterval(0), m_NextUpdateTime(time(NULL))
{
}
+RealmList::RealmList() : m_UpdateInterval(0), m_NextUpdateTime(time(NULL)), _resolver(nullptr) { }
+RealmList::~RealmList()
+{
+ delete _resolver;
+}
+
// Load the realm list from the database
-void RealmList::Initialize(uint32 updateInterval)
+void RealmList::Initialize(boost::asio::io_service& ioService, uint32 updateInterval)
{
+ _resolver = new boost::asio::ip::tcp::resolver(ioService);
m_UpdateInterval = updateInterval;
// Get the content of the realmlist table in the database
UpdateRealms(true);
}
-void RealmList::UpdateRealm(uint32 id, const std::string& name, ACE_INET_Addr const& address, ACE_INET_Addr const& localAddr, ACE_INET_Addr const& localSubmask, uint8 icon, RealmFlags flag, uint8 timezone, AccountTypes allowedSecurityLevel, float popu, uint32 build, uint8 region, uint8 battlegroup)
+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)
{
// Create new if not exist or update existed
Realm& realm = m_realms[name];
@@ -62,12 +72,14 @@ void RealmList::UpdateRealm(uint32 id, const std::string& name, ACE_INET_Addr co
realm.flag = flag;
realm.timezone = timezone;
realm.allowedSecurityLevel = allowedSecurityLevel;
- realm.populationLevel = popu;
+ 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;
@@ -100,30 +112,64 @@ void RealmList::UpdateRealms(bool init)
{
do
{
- Field* fields = result->Fetch();
- uint32 realmId = fields[0].GetUInt32();
- std::string name = fields[1].GetString();
- std::string externalAddress = fields[2].GetString();
- std::string localAddress = fields[3].GetString();
- std::string localSubmask = fields[4].GetString();
- 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 build = fields[11].GetUInt32();
- uint8 region = fields[12].GetUInt8();
- uint8 battlegroup = fields[13].GetUInt8();
-
- ACE_INET_Addr externalAddr(port, externalAddress.c_str(), AF_INET);
- ACE_INET_Addr localAddr(port, localAddress.c_str(), AF_INET);
- ACE_INET_Addr submask(0, localSubmask.c_str(), AF_INET);
-
- UpdateRealm(realmId, name, externalAddr, localAddr, submask, icon, flag, timezone, (allowedSecurityLevel <= SEC_ADMINISTRATOR ? AccountTypes(allowedSecurityLevel) : SEC_ADMINISTRATOR), pop, build, region, battlegroup);
-
- if (init)
- TC_LOG_INFO("server.authserver", "Added realm \"%s\" at %s:%u.", name.c_str(), m_realms[name].ExternalAddress.get_host_addr(), port);
+ try
+ {
+ boost::asio::ip::tcp::resolver::iterator end;
+
+ Field* fields = result->Fetch();
+ uint32 realmId = fields[0].GetUInt32();
+ std::string name = fields[1].GetString();
+ boost::asio::ip::tcp::resolver::query externalAddressQuery(fields[2].GetString(), "");
+ boost::asio::ip::tcp::resolver::iterator endPoint = _resolver->resolve(externalAddressQuery);
+ if (endPoint == end)
+ {
+ TC_LOG_ERROR("server.authserver", "Could not resolve address %s", fields[2].GetString().c_str());
+ return;
+ }
+
+ ip::address externalAddress = (*endPoint).endpoint().address();
+
+ boost::asio::ip::tcp::resolver::query localAddressQuery(fields[3].GetString(), "");
+ endPoint = _resolver->resolve(localAddressQuery);
+ if (endPoint == end)
+ {
+ TC_LOG_ERROR("server.authserver", "Could not resolve address %s", fields[3].GetString().c_str());
+ return;
+ }
+
+ ip::address localAddress = (*endPoint).endpoint().address();
+
+ boost::asio::ip::tcp::resolver::query localSubmaskQuery(fields[4].GetString(), "");
+ endPoint = _resolver->resolve(localSubmaskQuery);
+ if (endPoint == end)
+ {
+ TC_LOG_ERROR("server.authserver", "Could not resolve address %s", fields[4].GetString().c_str());
+ return;
+ }
+
+ 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 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);
+
+ 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);
+ }
+ catch (std::exception& ex)
+ {
+ TC_LOG_ERROR("server.authserver", "Realmlist::UpdateRealms has thrown an exception: %s", ex.what());
+ ASSERT(false);
+ }
}
while (result->NextRow());
}
diff --git a/src/server/authserver/Realms/RealmList.h b/src/server/authserver/Realms/RealmList.h
index c4a6b4eaa0b..7426d5b3f32 100644
--- a/src/server/authserver/Realms/RealmList.h
+++ b/src/server/authserver/Realms/RealmList.h
@@ -19,30 +19,33 @@
#ifndef _REALMLIST_H
#define _REALMLIST_H
-#include <ace/Singleton.h>
-#include <ace/Null_Mutex.h>
-#include <ace/INET_Addr.h>
+#include <boost/asio/ip/address.hpp>
+#include <boost/asio/ip/tcp.hpp>
+#include <boost/asio/io_service.hpp>
#include "Common.h"
+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
+ 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
};
// Storage object for a realm
struct Realm
{
- ACE_INET_Addr ExternalAddress;
- ACE_INET_Addr LocalAddress;
- ACE_INET_Addr LocalSubnetMask;
+ ip::address ExternalAddress;
+ ip::address LocalAddress;
+ ip::address LocalSubnetMask;
+ uint16 port;
std::string name;
uint8 icon;
RealmFlags flag;
@@ -68,10 +71,15 @@ class RealmList
public:
typedef std::map<std::string, Realm> RealmMap;
- RealmList();
- ~RealmList() { }
+ static RealmList& instance()
+ {
+ static RealmList *instance = new RealmList();
+ return *instance;
+ }
+
+ ~RealmList();
- void Initialize(uint32 updateInterval);
+ void Initialize(boost::asio::io_service& ioService, uint32 updateInterval);
void UpdateIfNeed();
@@ -83,13 +91,17 @@ public:
Realm const* GetRealm(Battlenet::RealmId const& id) const;
private:
- void UpdateRealms(bool init=false);
- void UpdateRealm(uint32 id, const std::string& name, ACE_INET_Addr const& address, ACE_INET_Addr const& localAddr, ACE_INET_Addr const& localSubmask, uint8 icon, RealmFlags flag, uint8 timezone, AccountTypes allowedSecurityLevel, float popu, uint32 build, uint8 region, uint8 battlegroup);
+ 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);
RealmMap m_realms;
uint32 m_UpdateInterval;
time_t m_NextUpdateTime;
+ boost::asio::ip::tcp::resolver* _resolver;
};
-#define sRealmList ACE_Singleton<RealmList, ACE_Null_Mutex>::instance()
+#define sRealmList RealmList::instance()
#endif
diff --git a/src/server/authserver/Server/AuthSocket.cpp b/src/server/authserver/Server/AuthSession.cpp
index f1cb3af3f51..b426b82e44d 100644
--- a/src/server/authserver/Server/AuthSocket.cpp
+++ b/src/server/authserver/Server/AuthSession.cpp
@@ -1,64 +1,57 @@
/*
- * 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 <algorithm>
-#include <openssl/md5.h>
-
-#include "Common.h"
-#include "Database/DatabaseEnv.h"
+* 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 <memory>
+#include <boost/lexical_cast.hpp>
+#include <boost/asio/write.hpp>
+#include <AuthSession.h>
+#include <Log.h>
#include "ByteBuffer.h"
-#include "Configuration/Config.h"
-#include "Log.h"
-#include "RealmList.h"
-#include "AuthSocket.h"
#include "AuthCodes.h"
-#include "TOTP.h"
+#include "Database/DatabaseEnv.h"
#include "SHA1.h"
#include "openssl/crypto.h"
+#include "Configuration/Config.h"
+#include "RealmList.h"
-#define ChunkSize 2048
+using boost::asio::ip::tcp;
enum eAuthCmd
{
- AUTH_LOGON_CHALLENGE = 0x00,
- AUTH_LOGON_PROOF = 0x01,
- AUTH_RECONNECT_CHALLENGE = 0x02,
- AUTH_RECONNECT_PROOF = 0x03,
- REALM_LIST = 0x10,
- XFER_INITIATE = 0x30,
- XFER_DATA = 0x31,
- XFER_ACCEPT = 0x32,
- XFER_RESUME = 0x33,
- XFER_CANCEL = 0x34
+ AUTH_LOGON_CHALLENGE = 0x00,
+ AUTH_LOGON_PROOF = 0x01,
+ AUTH_RECONNECT_CHALLENGE = 0x02,
+ AUTH_RECONNECT_PROOF = 0x03,
+ REALM_LIST = 0x10,
+ XFER_INITIATE = 0x30,
+ XFER_DATA = 0x31,
+ XFER_ACCEPT = 0x32,
+ XFER_RESUME = 0x33,
+ XFER_CANCEL = 0x34
};
enum eStatus
{
- STATUS_CONNECTED = 0,
+ STATUS_CONNECTED = 0,
STATUS_AUTHED
};
-// GCC have alternative #pragma pack(N) syntax and old gcc version not support pack(push, N), also any gcc version not support it at some paltform
-#if defined(__GNUC__)
-#pragma pack(1)
-#else
#pragma pack(push, 1)
-#endif
typedef struct AUTH_LOGON_CHALLENGE_C
{
@@ -86,7 +79,7 @@ typedef struct AUTH_LOGON_PROOF_C
uint8 M1[20];
uint8 crc_hash[20];
uint8 number_of_keys;
- uint8 securityFlags; // 0x00-0x04
+ uint8 securityFlags;
} sAuthLogonProof_C;
typedef struct AUTH_LOGON_PROOF_S
@@ -116,237 +109,110 @@ typedef struct AUTH_RECONNECT_PROOF_C
uint8 number_of_keys;
} sAuthReconnectProof_C;
-typedef struct XFER_INIT
-{
- uint8 cmd; // XFER_INITIATE
- uint8 fileNameLen; // strlen(fileName);
- uint8 fileName[5]; // fileName[fileNameLen]
- uint64 file_size; // file size (bytes)
- uint8 md5[MD5_DIGEST_LENGTH]; // MD5
-} XFER_INIT;
-
-typedef struct XFER_DATA
-{
- uint8 opcode;
- uint16 data_size;
- uint8 data[ChunkSize];
-} XFER_DATA_STRUCT;
+#pragma pack(pop)
+
typedef struct AuthHandler
{
eAuthCmd cmd;
uint32 status;
- bool (AuthSocket::*handler)(void);
+ size_t packetSize;
+ bool (AuthSession::*handler)();
} AuthHandler;
-// GCC have alternative #pragma pack() syntax and old gcc version not support pack(pop), also any gcc version not support it at some paltform
-#if defined(__GNUC__)
-#pragma pack()
-#else
-#pragma pack(pop)
-#endif
-
-// Launch a thread to transfer a patch to the client
-class PatcherRunnable: public ACE_Based::Runnable
-{
-public:
- PatcherRunnable(class AuthSocket*);
- void run();
-
-private:
- AuthSocket* mySocket;
-};
-
-typedef struct PATCH_INFO
-{
- uint8 md5[MD5_DIGEST_LENGTH];
-} PATCH_INFO;
-
-// Caches MD5 hash of client patches present on the server
-class Patcher
-{
-public:
- typedef std::map<std::string, PATCH_INFO*> Patches;
- ~Patcher();
- Patcher();
- Patches::const_iterator begin() const { return _patches.begin(); }
- Patches::const_iterator end() const { return _patches.end(); }
- void LoadPatchMD5(char*);
- bool GetHash(char * pat, uint8 mymd5[16]);
-
-private:
- void LoadPatchesInfo();
- Patches _patches;
-};
+#define BYTE_SIZE 32
+#define REALMLIST_SKIP_PACKETS 5
const AuthHandler table[] =
{
- { AUTH_LOGON_CHALLENGE, STATUS_CONNECTED, &AuthSocket::_HandleLogonChallenge },
- { AUTH_LOGON_PROOF, STATUS_CONNECTED, &AuthSocket::_HandleLogonProof },
- { AUTH_RECONNECT_CHALLENGE, STATUS_CONNECTED, &AuthSocket::_HandleReconnectChallenge},
- { AUTH_RECONNECT_PROOF, STATUS_CONNECTED, &AuthSocket::_HandleReconnectProof },
- { REALM_LIST, STATUS_AUTHED, &AuthSocket::_HandleRealmList },
- { XFER_ACCEPT, STATUS_CONNECTED, &AuthSocket::_HandleXferAccept },
- { XFER_RESUME, STATUS_CONNECTED, &AuthSocket::_HandleXferResume },
- { XFER_CANCEL, STATUS_CONNECTED, &AuthSocket::_HandleXferCancel }
+ { AUTH_LOGON_CHALLENGE, STATUS_CONNECTED, sizeof(AUTH_LOGON_CHALLENGE_C), &AuthSession::_HandleLogonChallenge },
+ { AUTH_LOGON_PROOF, STATUS_CONNECTED, sizeof(AUTH_LOGON_PROOF_C), &AuthSession::_HandleLogonProof },
+ { AUTH_RECONNECT_CHALLENGE, STATUS_CONNECTED, sizeof(AUTH_LOGON_CHALLENGE_C), &AuthSession::_HandleReconnectChallenge },
+ { AUTH_RECONNECT_PROOF, STATUS_CONNECTED, sizeof(AUTH_RECONNECT_PROOF_C), &AuthSession::_HandleReconnectProof },
+ { REALM_LIST, STATUS_AUTHED, REALMLIST_SKIP_PACKETS, &AuthSession::_HandleRealmList }
};
-#define AUTH_TOTAL_COMMANDS 8
-
-// Holds the MD5 hash of client patches present on the server
-Patcher PatchesCache;
-
-// Constructor - set the N and g values for SRP6
-AuthSocket::AuthSocket(RealmSocket& socket) :
- pPatch(NULL), socket_(socket), _authed(false), _build(0),
- _expversion(0), _accountSecurityLevel(SEC_PLAYER)
+void AuthSession::AsyncReadHeader()
{
- N.SetHexStr("894B645E89E1535BBDAD5B8B290650530801B18EBFBF5E8FAB3C82872A3E9BB7");
- g.SetDword(7);
-}
+ auto self(shared_from_this());
-// Close patch file descriptor before leaving
-AuthSocket::~AuthSocket(void) { }
+ _socket.async_read_some(boost::asio::buffer(_readBuffer, 1), [this, self](boost::system::error_code error, size_t transferedBytes)
+ {
+ if (!error && transferedBytes == 1)
+ {
+ for (const AuthHandler& entry : table)
+ {
+ if ((uint8)entry.cmd == _readBuffer[0] && (entry.status == STATUS_CONNECTED || (_isAuthenticated && entry.status == STATUS_AUTHED)))
+ {
+ // Handle dynamic size packet
+ if (_readBuffer[0] == AUTH_LOGON_CHALLENGE)
+ {
+ _socket.read_some(boost::asio::buffer(&_readBuffer[1], sizeof(uint8) + sizeof(uint16))); //error + size
-// Accept the connection
-void AuthSocket::OnAccept(void)
-{
- TC_LOG_DEBUG("server.authserver", "'%s:%d' Accepting connection", socket().getRemoteAddress().c_str(), socket().getRemotePort());
+ AsyncReadData(entry.handler, *reinterpret_cast<uint16*>(&_readBuffer[2]), sizeof(uint8) + sizeof(uint8) + sizeof(uint16)); // cmd + error + size
+ }
+ else
+ {
+ AsyncReadData(entry.handler, entry.packetSize, sizeof(uint8));
+ }
+ break;
+ }
+ }
+ }
+ else
+ {
+ _socket.close();
+ }
+ });
}
-void AuthSocket::OnClose(void)
+void AuthSession::AsyncReadData(bool (AuthSession::*handler)(), size_t dataSize, size_t bufferOffSet)
{
- TC_LOG_DEBUG("server.authserver", "AuthSocket::OnClose");
-}
+ auto self(shared_from_this());
-// Read the packet from the client
-void AuthSocket::OnRead()
-{
- #define MAX_AUTH_LOGON_CHALLENGES_IN_A_ROW 3
- uint32 challengesInARow = 0;
- uint8 _cmd;
- while (1)
+ _socket.async_read_some(boost::asio::buffer(&_readBuffer[bufferOffSet], dataSize), [handler, this, self](boost::system::error_code error, size_t transferedBytes)
{
- if (!socket().recv_soft((char *)&_cmd, 1))
- return;
-
- if (_cmd == AUTH_LOGON_CHALLENGE)
+ if (!error && transferedBytes > 0)
{
- ++challengesInARow;
- if (challengesInARow == MAX_AUTH_LOGON_CHALLENGES_IN_A_ROW)
+ if (!(*this.*handler)())
{
- TC_LOG_WARN("server.authserver", "Got %u AUTH_LOGON_CHALLENGE in a row from '%s', possible ongoing DoS", challengesInARow, socket().getRemoteAddress().c_str());
- socket().shutdown();
+ _socket.close();
return;
}
- }
-
- size_t i;
- // Circle through known commands and call the correct command handler
- for (i = 0; i < AUTH_TOTAL_COMMANDS; ++i)
- {
- if ((uint8)table[i].cmd == _cmd && (table[i].status == STATUS_CONNECTED || (_authed && table[i].status == STATUS_AUTHED)))
- {
- TC_LOG_DEBUG("server.authserver", "Got data for cmd %u recv length %u", (uint32)_cmd, (uint32)socket().recv_len());
-
- if (!(*this.*table[i].handler)())
- {
- TC_LOG_DEBUG("server.authserver", "Command handler failed for cmd %u recv length %u", (uint32)_cmd, (uint32)socket().recv_len());
- return;
- }
- break;
- }
+ AsyncReadHeader();
}
-
- // Report unknown packets in the error log
- if (i == AUTH_TOTAL_COMMANDS)
+ else
{
- TC_LOG_ERROR("server.authserver", "Got unknown packet from '%s'", socket().getRemoteAddress().c_str());
- socket().shutdown();
- return;
+ _socket.close();
}
- }
+ });
}
-// Make the SRP6 calculation from hash in dB
-void AuthSocket::_SetVSFields(const std::string& rI)
+void AuthSession::AsyncWrite(std::size_t length)
{
- s.SetRand(s_BYTE_SIZE * 8);
-
- BigNumber I;
- I.SetHexStr(rI.c_str());
-
- // In case of leading zeros in the rI hash, restore them
- uint8 mDigest[SHA_DIGEST_LENGTH];
- memset(mDigest, 0, SHA_DIGEST_LENGTH);
- if (I.GetNumBytes() <= SHA_DIGEST_LENGTH)
- memcpy(mDigest, I.AsByteArray().get(), I.GetNumBytes());
-
- std::reverse(mDigest, mDigest + SHA_DIGEST_LENGTH);
-
- SHA1Hash sha;
- sha.UpdateData(s.AsByteArray().get(), s.GetNumBytes());
- sha.UpdateData(mDigest, SHA_DIGEST_LENGTH);
- sha.Finalize();
- BigNumber x;
- x.SetBinary(sha.GetDigest(), sha.GetLength());
- v = g.ModExp(x, N);
-
- PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_VS);
- stmt->setString(0, v.AsHexStr());
- stmt->setString(1, s.AsHexStr());
- stmt->setString(2, _login);
- LoginDatabase.Execute(stmt);
+ boost::asio::async_write(_socket, boost::asio::buffer(_writeBuffer, length), [this](boost::system::error_code error, std::size_t /*length*/)
+ {
+ if (error)
+ {
+ _socket.close();
+ }
+ });
}
-// Logon Challenge command handler
-bool AuthSocket::_HandleLogonChallenge()
+bool AuthSession::_HandleLogonChallenge()
{
- TC_LOG_DEBUG("server.authserver", "Entering _HandleLogonChallenge");
- if (socket().recv_len() < sizeof(sAuthLogonChallenge_C))
- return false;
-
- // Read the first 4 bytes (header) to get the length of the remaining of the packet
- std::vector<uint8> buf;
- buf.resize(4);
-
- socket().recv((char *)&buf[0], 4);
+ sAuthLogonChallenge_C *challenge = (sAuthLogonChallenge_C*)&_readBuffer;
- EndianConvertPtr<uint16>(&buf[0]);
-
- uint16 remaining = ((sAuthLogonChallenge_C *)&buf[0])->size;
- TC_LOG_DEBUG("server.authserver", "[AuthChallenge] got header, body is %#04x bytes", remaining);
-
- if ((remaining < sizeof(sAuthLogonChallenge_C) - buf.size()) || (socket().recv_len() < remaining))
- return false;
-
- //No big fear of memory outage (size is int16, i.e. < 65536)
- buf.resize(remaining + buf.size() + 1);
- buf[buf.size() - 1] = 0;
- sAuthLogonChallenge_C *ch = (sAuthLogonChallenge_C*)&buf[0];
-
- // Read the remaining of the packet
- socket().recv((char *)&buf[4], remaining);
- TC_LOG_DEBUG("server.authserver", "[AuthChallenge] got full packet, %#04x bytes", ch->size);
- TC_LOG_DEBUG("server.authserver", "[AuthChallenge] name(%d): '%s'", ch->I_len, ch->I);
-
- // BigEndian code, nop in little endian case
- // size already converted
- EndianConvertPtr<uint32>(&ch->gamename[0]);
- EndianConvert(ch->build);
- EndianConvertPtr<uint32>(&ch->platform[0]);
- EndianConvertPtr<uint32>(&ch->os[0]);
- EndianConvertPtr<uint32>(&ch->country[0]);
- EndianConvert(ch->timezone_bias);
- EndianConvert(ch->ip);
+ //TC_LOG_DEBUG("server.authserver", "[AuthChallenge] got full packet, %#04x bytes", challenge->size);
+ TC_LOG_DEBUG("server.authserver", "[AuthChallenge] name(%d): '%s'", challenge->I_len, challenge->I);
ByteBuffer pkt;
- _login = (const char*)ch->I;
- _build = ch->build;
+ _login.assign((const char*)challenge->I, challenge->I_len);
+ _build = challenge->build;
_expversion = uint8(AuthHelper::IsPostBCAcceptedClientBuild(_build) ? POST_BC_EXP_FLAG : (AuthHelper::IsPreBCAcceptedClientBuild(_build) ? PRE_BC_EXP_FLAG : NO_VALID_EXP_FLAG));
- _os = (const char*)ch->os;
+ _os = (const char*)challenge->os;
if (_os.size() > 4)
return false;
@@ -360,14 +226,16 @@ bool AuthSocket::_HandleLogonChallenge()
// Verify that this IP is not in the ip_banned table
LoginDatabase.Execute(LoginDatabase.GetPreparedStatement(LOGIN_DEL_EXPIRED_IP_BANS));
- std::string const& ip_address = socket().getRemoteAddress();
+ std::string const& ipAddress = _socket.remote_endpoint().address().to_string();
+ unsigned short port = _socket.remote_endpoint().port();
+
PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_IP_BANNED);
- stmt->setString(0, ip_address);
+ stmt->setString(0, ipAddress);
PreparedQueryResult result = LoginDatabase.Query(stmt);
if (result)
{
pkt << uint8(WOW_FAIL_BANNED);
- TC_LOG_DEBUG("server.authserver", "'%s:%d' [AuthChallenge] Banned ip tries to login!", socket().getRemoteAddress().c_str(), socket().getRemotePort());
+ TC_LOG_DEBUG("server.authserver", "'%s:%d' [AuthChallenge] Banned ip tries to login!", ipAddress.c_str(), port);
}
else
{
@@ -386,9 +254,9 @@ bool AuthSocket::_HandleLogonChallenge()
if (fields[2].GetUInt8() == 1) // if ip is locked
{
TC_LOG_DEBUG("server.authserver", "[AuthChallenge] Account '%s' is locked to IP - '%s'", _login.c_str(), fields[4].GetCString());
- TC_LOG_DEBUG("server.authserver", "[AuthChallenge] Player address is '%s'", ip_address.c_str());
+ TC_LOG_DEBUG("server.authserver", "[AuthChallenge] Player address is '%s'", ipAddress.c_str());
- if (strcmp(fields[4].GetCString(), ip_address.c_str()) != 0)
+ if (strcmp(fields[4].GetCString(), ipAddress.c_str()) != 0)
{
TC_LOG_DEBUG("server.authserver", "[AuthChallenge] Account IP differs");
pkt << uint8(WOW_FAIL_LOCKED_ENFORCED);
@@ -405,7 +273,7 @@ bool AuthSocket::_HandleLogonChallenge()
TC_LOG_DEBUG("server.authserver", "[AuthChallenge] Account '%s' is not locked to country", _login.c_str());
else if (!accountCountry.empty())
{
- uint32 ip = inet_addr(ip_address.c_str());
+ uint32 ip = inet_addr(ipAddress.c_str());
EndianConvertReverse(ip);
stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_LOGON_COUNTRY);
@@ -413,7 +281,9 @@ bool AuthSocket::_HandleLogonChallenge()
if (PreparedQueryResult sessionCountryQuery = LoginDatabase.Query(stmt))
{
std::string loginCountry = (*sessionCountryQuery)[0].GetString();
- TC_LOG_DEBUG("server.authserver", "[AuthChallenge] Account '%s' is locked to country: '%s' Player country is '%s'", _login.c_str(), accountCountry.c_str(), loginCountry.c_str());
+ TC_LOG_DEBUG("server.authserver", "[AuthChallenge] Account '%s' is locked to country: '%s' Player country is '%s'", _login.c_str(),
+ accountCountry.c_str(), loginCountry.c_str());
+
if (loginCountry != accountCountry)
{
TC_LOG_DEBUG("server.authserver", "[AuthChallenge] Account country differs.");
@@ -442,12 +312,14 @@ bool AuthSocket::_HandleLogonChallenge()
if ((*banresult)[0].GetUInt32() == (*banresult)[1].GetUInt32())
{
pkt << uint8(WOW_FAIL_BANNED);
- TC_LOG_DEBUG("server.authserver", "'%s:%d' [AuthChallenge] Banned account %s tried to login!", socket().getRemoteAddress().c_str(), socket().getRemotePort(), _login.c_str ());
+ TC_LOG_DEBUG("server.authserver", "'%s:%d' [AuthChallenge] Banned account %s tried to login!", ipAddress.c_str(),
+ port, _login.c_str());
}
else
{
pkt << uint8(WOW_FAIL_SUSPENDED);
- TC_LOG_DEBUG("server.authserver", "'%s:%d' [AuthChallenge] Temporarily banned account %s tried to login!", socket().getRemoteAddress().c_str(), socket().getRemotePort(), _login.c_str ());
+ TC_LOG_DEBUG("server.authserver", "'%s:%d' [AuthChallenge] Temporarily banned account %s tried to login!",
+ ipAddress.c_str(), port, _login.c_str());
}
}
else
@@ -462,8 +334,8 @@ bool AuthSocket::_HandleLogonChallenge()
TC_LOG_DEBUG("network", "database authentication values: v='%s' s='%s'", databaseV.c_str(), databaseS.c_str());
// multiply with 2 since bytes are stored as hexstring
- if (databaseV.size() != s_BYTE_SIZE * 2 || databaseS.size() != s_BYTE_SIZE * 2)
- _SetVSFields(rI);
+ if (databaseV.size() != BYTE_SIZE * 2 || databaseS.size() != BYTE_SIZE * 2)
+ SetVSFields(rI);
else
{
s.SetHexStr(databaseS.c_str());
@@ -527,10 +399,12 @@ bool AuthSocket::_HandleLogonChallenge()
_localizationName.resize(4);
for (int i = 0; i < 4; ++i)
- _localizationName[i] = ch->country[4-i-1];
+ _localizationName[i] = challenge->country[4 - i - 1];
- TC_LOG_DEBUG("server.authserver", "'%s:%d' [AuthChallenge] account %s is using '%c%c%c%c' locale (%u)", socket().getRemoteAddress().c_str(), socket().getRemotePort(),
- _login.c_str (), ch->country[3], ch->country[2], ch->country[1], ch->country[0], GetLocaleByName(_localizationName)
+ TC_LOG_DEBUG("server.authserver", "'%s:%d' [AuthChallenge] account %s is using '%c%c%c%c' locale (%u)",
+ ipAddress.c_str(), port, _login.c_str(),
+ challenge->country[3], challenge->country[2], challenge->country[1], challenge->country[0],
+ GetLocaleByName(_localizationName)
);
}
}
@@ -539,39 +413,38 @@ bool AuthSocket::_HandleLogonChallenge()
pkt << uint8(WOW_FAIL_UNKNOWN_ACCOUNT);
}
- socket().send((char const*)pkt.contents(), pkt.size());
+ std::memcpy(_writeBuffer, (char const*)pkt.contents(), pkt.size());
+
+ AsyncWrite(pkt.size());
+
return true;
}
// Logon Proof command handler
-bool AuthSocket::_HandleLogonProof()
+bool AuthSession::_HandleLogonProof()
{
+
TC_LOG_DEBUG("server.authserver", "Entering _HandleLogonProof");
// Read the packet
- sAuthLogonProof_C lp;
-
- if (!socket().recv((char *)&lp, sizeof(sAuthLogonProof_C)))
- return false;
+ sAuthLogonProof_C *logonProof = (sAuthLogonProof_C*)&_readBuffer;
// If the client has no valid version
if (_expversion == NO_VALID_EXP_FLAG)
{
// Check if we have the appropriate patch on the disk
TC_LOG_DEBUG("network", "Client with invalid version, patching is not implemented");
- socket().shutdown();
- return true;
+ return false;
}
// Continue the SRP6 calculation based on data received from the client
BigNumber A;
- A.SetBinary(lp.A, 32);
+ A.SetBinary(logonProof->A, 32);
// SRP safeguard: abort if A == 0
if (A.isZero())
{
- socket().shutdown();
- return true;
+ return false;
}
SHA1Hash sha;
@@ -639,14 +512,14 @@ bool AuthSocket::_HandleLogonProof()
M.SetBinary(sha.GetDigest(), 20);
// Check if SRP6 results match (password is correct), else send an error
- if (!memcmp(M.AsByteArray().get(), lp.M1, 20))
+ if (!memcmp(M.AsByteArray().get(), logonProof->M1, 20))
{
- TC_LOG_DEBUG("server.authserver", "'%s:%d' User '%s' successfully authenticated", socket().getRemoteAddress().c_str(), socket().getRemotePort(), _login.c_str());
+ TC_LOG_DEBUG("server.authserver", "'%s:%d' User '%s' successfully authenticated", GetRemoteIpAddress().c_str(), GetRemotePort(), _login.c_str());
// Update the sessionkey, last_ip, last login time and reset number of failed logins in the account table for this account
PreparedStatement *stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_LOGONPROOF);
stmt->setString(0, K.AsHexStr());
- stmt->setString(1, socket().getRemoteAddress().c_str());
+ stmt->setString(1, GetRemoteIpAddress().c_str());
stmt->setUInt32(2, GetLocaleByName(_localizationName));
stmt->setString(3, _os);
stmt->setString(4, _login);
@@ -658,8 +531,11 @@ bool AuthSocket::_HandleLogonProof()
sha.Finalize();
// Check auth token
- if ((lp.securityFlags & 0x04) || !_tokenKey.empty())
+ if ((logonProof->securityFlags & 0x04) || !_tokenKey.empty())
{
+ // TODO To be fixed
+
+ /*
uint8 size;
socket().recv((char*)&size, 1);
char* token = new char[size + 1];
@@ -670,10 +546,10 @@ bool AuthSocket::_HandleLogonProof()
delete[] token;
if (validToken != incomingToken)
{
- char data[] = { AUTH_LOGON_PROOF, WOW_FAIL_UNKNOWN_ACCOUNT, 3, 0 };
- socket().send(data, sizeof(data));
- return false;
- }
+ char data[] = { AUTH_LOGON_PROOF, WOW_FAIL_UNKNOWN_ACCOUNT, 3, 0 };
+ socket().send(data, sizeof(data));
+ return false;
+ }*/
}
if (_expversion & POST_BC_EXP_FLAG) // 2.x and 3.x clients
@@ -685,7 +561,9 @@ bool AuthSocket::_HandleLogonProof()
proof.unk1 = GAMEACCOUNT_FLAG_PROPASS_LOCK;
proof.unk2 = 0x00; // SurveyId
proof.unk3 = 0x00;
- socket().send((char *)&proof, sizeof(proof));
+
+ std::memcpy(_writeBuffer, (char *)&proof, sizeof(proof));
+ AsyncWrite(sizeof(proof));
}
else
{
@@ -694,26 +572,31 @@ bool AuthSocket::_HandleLogonProof()
proof.cmd = AUTH_LOGON_PROOF;
proof.error = 0;
proof.unk2 = 0x00;
- socket().send((char *)&proof, sizeof(proof));
+
+ std::memcpy(_writeBuffer, (char *)&proof, sizeof(proof));
+ AsyncWrite(sizeof(proof));
}
- _authed = true;
+ _isAuthenticated = true;
}
else
{
char data[4] = { AUTH_LOGON_PROOF, WOW_FAIL_UNKNOWN_ACCOUNT, 3, 0 };
- socket().send(data, sizeof(data));
- TC_LOG_DEBUG("server.authserver", "'%s:%d' [AuthChallenge] account %s tried to login with invalid password!", socket().getRemoteAddress().c_str(), socket().getRemotePort(), _login.c_str());
+ std::memcpy(_writeBuffer, data, sizeof(data));
+ AsyncWrite(sizeof(data));
+
+ TC_LOG_DEBUG("server.authserver", "'%s:%d' [AuthChallenge] account %s tried to login with invalid password!",
+ GetRemoteIpAddress().c_str(), GetRemotePort(), _login.c_str());
uint32 MaxWrongPassCount = sConfigMgr->GetIntDefault("WrongPass.MaxCount", 0);
// We can not include the failed account login hook. However, this is a workaround to still log this.
- if (sConfigMgr->GetBoolDefault("Additional.IP.Based.Login.Logging", false))
+ if (sConfigMgr->GetBoolDefault("Wrong.Password.Login.Logging", false))
{
PreparedStatement* logstmt = LoginDatabase.GetPreparedStatement(LOGIN_INS_FALP_IP_LOGGING);
logstmt->setString(0, _login);
- logstmt->setString(1, socket().getRemoteAddress());
+ logstmt->setString(1, GetRemoteIpAddress());
logstmt->setString(2, "Logged on failed AccountLogin due wrong password");
LoginDatabase.Execute(logstmt);
@@ -747,17 +630,17 @@ bool AuthSocket::_HandleLogonProof()
LoginDatabase.Execute(stmt);
TC_LOG_DEBUG("server.authserver", "'%s:%d' [AuthChallenge] account %s got banned for '%u' seconds because it failed to authenticate '%u' times",
- socket().getRemoteAddress().c_str(), socket().getRemotePort(), _login.c_str(), WrongPassBanTime, failed_logins);
+ GetRemoteIpAddress().c_str(), GetRemotePort(), _login.c_str(), WrongPassBanTime, failed_logins);
}
else
{
stmt = LoginDatabase.GetPreparedStatement(LOGIN_INS_IP_AUTO_BANNED);
- stmt->setString(0, socket().getRemoteAddress());
+ stmt->setString(0, GetRemoteIpAddress());
stmt->setUInt32(1, WrongPassBanTime);
LoginDatabase.Execute(stmt);
- TC_LOG_DEBUG("server.authserver", "'%s:%d' [AuthChallenge] IP %s got banned for '%u' seconds because account %s failed to authenticate '%u' times",
- socket().getRemoteAddress().c_str(), socket().getRemotePort(), socket().getRemoteAddress().c_str(), WrongPassBanTime, _login.c_str(), failed_logins);
+ TC_LOG_DEBUG("server.authserver", "'%s:%d' [AuthChallenge] IP got banned for '%u' seconds because account %s failed to authenticate '%u' times",
+ GetRemoteIpAddress().c_str(), GetRemotePort(), WrongPassBanTime, _login.c_str(), failed_logins);
}
}
}
@@ -767,38 +650,15 @@ bool AuthSocket::_HandleLogonProof()
return true;
}
-// Reconnect Challenge command handler
-bool AuthSocket::_HandleReconnectChallenge()
+bool AuthSession::_HandleReconnectChallenge()
{
TC_LOG_DEBUG("server.authserver", "Entering _HandleReconnectChallenge");
- if (socket().recv_len() < sizeof(sAuthLogonChallenge_C))
- return false;
-
- // Read the first 4 bytes (header) to get the length of the remaining of the packet
- std::vector<uint8> buf;
- buf.resize(4);
-
- socket().recv((char *)&buf[0], 4);
-
- EndianConvertPtr<uint16>(&buf[0]);
-
- uint16 remaining = ((sAuthLogonChallenge_C *)&buf[0])->size;
- TC_LOG_DEBUG("server.authserver", "[ReconnectChallenge] got header, body is %#04x bytes", remaining);
-
- if ((remaining < sizeof(sAuthLogonChallenge_C) - buf.size()) || (socket().recv_len() < remaining))
- return false;
+ sAuthLogonChallenge_C *challenge = (sAuthLogonChallenge_C*)&_readBuffer;
- // No big fear of memory outage (size is int16, i.e. < 65536)
- buf.resize(remaining + buf.size() + 1);
- buf[buf.size() - 1] = 0;
- sAuthLogonChallenge_C *ch = (sAuthLogonChallenge_C*)&buf[0];
+ //TC_LOG_DEBUG("server.authserver", "[AuthChallenge] got full packet, %#04x bytes", challenge->size);
+ TC_LOG_DEBUG("server.authserver", "[AuthChallenge] name(%d): '%s'", challenge->I_len, challenge->I);
- // Read the remaining of the packet
- socket().recv((char *)&buf[4], remaining);
- TC_LOG_DEBUG("server.authserver", "[ReconnectChallenge] got full packet, %#04x bytes", ch->size);
- TC_LOG_DEBUG("server.authserver", "[ReconnectChallenge] name(%d): '%s'", ch->I_len, ch->I);
-
- _login = (const char*)ch->I;
+ _login.assign((const char*)challenge->I, challenge->I_len);
PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_SESSIONKEY);
stmt->setString(0, _login);
@@ -807,15 +667,15 @@ bool AuthSocket::_HandleReconnectChallenge()
// Stop if the account is not found
if (!result)
{
- TC_LOG_ERROR("server.authserver", "'%s:%d' [ERROR] user %s tried to login and we cannot find his session key in the database.", socket().getRemoteAddress().c_str(), socket().getRemotePort(), _login.c_str());
- socket().shutdown();
+ TC_LOG_ERROR("server.authserver", "'%s:%d' [ERROR] user %s tried to login and we cannot find his session key in the database.",
+ GetRemoteIpAddress().c_str(), GetRemotePort(), _login.c_str());
return false;
}
// Reinitialize build, expansion and the account securitylevel
- _build = ch->build;
+ _build = challenge->build;
_expversion = uint8(AuthHelper::IsPostBCAcceptedClientBuild(_build) ? POST_BC_EXP_FLAG : (AuthHelper::IsPreBCAcceptedClientBuild(_build) ? PRE_BC_EXP_FLAG : NO_VALID_EXP_FLAG));
- _os = (const char*)ch->os;
+ _os = (const char*)challenge->os;
if (_os.size() > 4)
return false;
@@ -827,7 +687,7 @@ bool AuthSocket::_HandleReconnectChallenge()
uint8 secLevel = fields[2].GetUInt8();
_accountSecurityLevel = secLevel <= SEC_ADMINISTRATOR ? AccountTypes(secLevel) : SEC_ADMINISTRATOR;
- K.SetHexStr ((*result)[0].GetCString());
+ K.SetHexStr((*result)[0].GetCString());
// Sending response
ByteBuffer pkt;
@@ -836,24 +696,22 @@ bool AuthSocket::_HandleReconnectChallenge()
_reconnectProof.SetRand(16 * 8);
pkt.append(_reconnectProof.AsByteArray(16).get(), 16); // 16 bytes random
pkt << uint64(0x00) << uint64(0x00); // 16 bytes zeros
- socket().send((char const*)pkt.contents(), pkt.size());
+
+ std::memcpy(_writeBuffer, (char const*)pkt.contents(), pkt.size());
+ AsyncWrite(pkt.size());
+
return true;
}
-
-// Reconnect Proof command handler
-bool AuthSocket::_HandleReconnectProof()
+bool AuthSession::_HandleReconnectProof()
{
TC_LOG_DEBUG("server.authserver", "Entering _HandleReconnectProof");
- // Read the packet
- sAuthReconnectProof_C lp;
- if (!socket().recv((char *)&lp, sizeof(sAuthReconnectProof_C)))
- return false;
+ sAuthReconnectProof_C *reconnectProof = (sAuthReconnectProof_C*)&_readBuffer;
if (_login.empty() || !_reconnectProof.GetNumBytes() || !K.GetNumBytes())
return false;
BigNumber t1;
- t1.SetBinary(lp.R1, 16);
+ t1.SetBinary(reconnectProof->R1, 16);
SHA1Hash sha;
sha.Initialize();
@@ -861,33 +719,64 @@ bool AuthSocket::_HandleReconnectProof()
sha.UpdateBigNumbers(&t1, &_reconnectProof, &K, NULL);
sha.Finalize();
- if (!memcmp(sha.GetDigest(), lp.R2, SHA_DIGEST_LENGTH))
+ if (!memcmp(sha.GetDigest(), reconnectProof->R2, SHA_DIGEST_LENGTH))
{
// Sending response
ByteBuffer pkt;
pkt << uint8(AUTH_RECONNECT_PROOF);
pkt << uint8(0x00);
pkt << uint16(0x00); // 2 bytes zeros
- socket().send((char const*)pkt.contents(), pkt.size());
- _authed = true;
+ std::memcpy(_writeBuffer, (char const*)pkt.contents(), pkt.size());
+ AsyncWrite(pkt.size());
+ _isAuthenticated = true;
return true;
}
else
{
- TC_LOG_ERROR("server.authserver", "'%s:%d' [ERROR] user %s tried to login, but session is invalid.", socket().getRemoteAddress().c_str(), socket().getRemotePort(), _login.c_str());
- socket().shutdown();
+ TC_LOG_ERROR("server.authserver", "'%s:%d' [ERROR] user %s tried to login, but session is invalid.", GetRemoteIpAddress().c_str(),
+ GetRemotePort(), _login.c_str());
return false;
}
}
-// Realm List command handler
-bool AuthSocket::_HandleRealmList()
+tcp::endpoint const GetAddressForClient(Realm const& realm, ip::address const& clientAddr)
{
- TC_LOG_DEBUG("server.authserver", "Entering _HandleRealmList");
- if (socket().recv_len() < 5)
- return false;
+ ip::address realmIp;
+
+ // Attempt to send best address for client
+ if (clientAddr.is_loopback())
+ {
+ // Try guessing if realm is also connected locally
+ if (realm.LocalAddress.is_loopback() || realm.ExternalAddress.is_loopback())
+ realmIp = clientAddr;
+ else
+ {
+ // Assume that user connecting from the machine that authserver is located on
+ // has all realms available in his local network
+ realmIp = realm.LocalAddress;
+ }
+ }
+ else
+ {
+ if (clientAddr.is_v4() &&
+ (clientAddr.to_v4().to_ulong() & realm.LocalSubnetMask.to_v4().to_ulong()) ==
+ (realm.LocalAddress.to_v4().to_ulong() & realm.LocalSubnetMask.to_v4().to_ulong()))
+ {
+ realmIp = realm.LocalAddress;
+ }
+ else
+ realmIp = realm.ExternalAddress;
+ }
+
+ tcp::endpoint endpoint(realmIp, realm.port);
- socket().recv_skip(5);
+ // Return external IP
+ return endpoint;
+}
+
+bool AuthSession::_HandleRealmList()
+{
+ TC_LOG_DEBUG("server.authserver", "Entering _HandleRealmList");
// Get the user id (else close the connection)
// No SQL injection (prepared statement)
@@ -896,8 +785,8 @@ bool AuthSocket::_HandleRealmList()
PreparedQueryResult result = LoginDatabase.Query(stmt);
if (!result)
{
- TC_LOG_ERROR("server.authserver", "'%s:%d' [ERROR] user %s tried to login but we cannot find him in the database.", socket().getRemoteAddress().c_str(), socket().getRemotePort(), _login.c_str());
- socket().shutdown();
+ TC_LOG_ERROR("server.authserver", "'%s:%d' [ERROR] user %s tried to login but we cannot find him in the database.", GetRemoteIpAddress().c_str(),
+ GetRemotePort(), _login.c_str());
return false;
}
@@ -905,16 +794,13 @@ bool AuthSocket::_HandleRealmList()
uint32 id = fields[0].GetUInt32();
// Update realm list if need
- sRealmList->UpdateIfNeed();
-
- ACE_INET_Addr clientAddr;
- socket().peer().get_remote_addr(clientAddr);
+ sRealmList.UpdateIfNeed();
// Circle through realms in the RealmList and construct the return packet (including # of user characters in each realm)
ByteBuffer pkt;
size_t RealmListSize = 0;
- for (RealmList::RealmMap::const_iterator i = sRealmList->begin(); i != sRealmList->end(); ++i)
+ for (RealmList::RealmMap::const_iterator i = sRealmList.begin(); i != sRealmList.end(); ++i)
{
const Realm &realm = i->second;
// don't work with realms which not compatible with the client
@@ -942,9 +828,6 @@ bool AuthSocket::_HandleRealmList()
name = ss.str();
}
- // We don't need the port number from which client connects with but the realm's port
- clientAddr.set_port_number(realm.ExternalAddress.get_port_number());
-
uint8 lock = (realm.allowedSecurityLevel > _accountSecurityLevel) ? 1 : 0;
uint8 AmountOfCharacters = 0;
@@ -960,7 +843,7 @@ bool AuthSocket::_HandleRealmList()
pkt << lock; // if 1, then realm locked
pkt << uint8(flag); // RealmFlags
pkt << name;
- pkt << GetAddressString(realm.GetAddressForClient(clientAddr));
+ pkt << boost::lexical_cast<std::string>(GetAddressForClient(realm, _socket.remote_endpoint().address()));
pkt << realm.populationLevel;
pkt << AmountOfCharacters;
pkt << realm.timezone; // realm category
@@ -1005,182 +888,47 @@ bool AuthSocket::_HandleRealmList()
hdr.append(RealmListSizeBuffer); // append RealmList's size buffer
hdr.append(pkt); // append realms in the realmlist
- socket().send((char const*)hdr.contents(), hdr.size());
+ std::memcpy(_writeBuffer, (char const*)hdr.contents(), hdr.size());
+ AsyncWrite(hdr.size());
return true;
}
-// Resume patch transfer
-bool AuthSocket::_HandleXferResume()
-{
- TC_LOG_DEBUG("server.authserver", "Entering _HandleXferResume");
- // Check packet length and patch existence
- if (socket().recv_len() < 9 || !pPatch) // FIXME: pPatch is never used
- {
- TC_LOG_ERROR("server.authserver", "Error while resuming patch transfer (wrong packet)");
- return false;
- }
-
- // Launch a PatcherRunnable thread starting at given patch file offset
- uint64 start;
- socket().recv_skip(1);
- socket().recv((char*)&start, sizeof(start));
- fseek(pPatch, long(start), 0);
-
- ACE_Based::Thread u(new PatcherRunnable(this));
- return true;
-}
-
-// Cancel patch transfer
-bool AuthSocket::_HandleXferCancel()
-{
- TC_LOG_DEBUG("server.authserver", "Entering _HandleXferCancel");
-
- // Close and delete the socket
- socket().recv_skip(1); //clear input buffer
- socket().shutdown();
-
- return true;
-}
-
-// Accept patch transfer
-bool AuthSocket::_HandleXferAccept()
-{
- TC_LOG_DEBUG("server.authserver", "Entering _HandleXferAccept");
-
- // Check packet length and patch existence
- if (!pPatch)
- {
- TC_LOG_ERROR("server.authserver", "Error while accepting patch transfer (wrong packet)");
- return false;
- }
-
- // Launch a PatcherRunnable thread, starting at the beginning of the patch file
- socket().recv_skip(1); // clear input buffer
- fseek(pPatch, 0, 0);
-
- ACE_Based::Thread u(new PatcherRunnable(this));
- return true;
-}
-
-PatcherRunnable::PatcherRunnable(class AuthSocket* as)
-{
- mySocket = as;
-}
-
-// Send content of patch file to the client
-void PatcherRunnable::run() { }
-
-// Preload MD5 hashes of existing patch files on server
-#ifndef _WIN32
-#include <dirent.h>
-#include <errno.h>
-void Patcher::LoadPatchesInfo()
-{
- DIR *dirp;
- struct dirent *dp;
- dirp = opendir("./patches/");
-
- if (!dirp)
- return;
-
- while (dirp)
- {
- errno = 0;
- if ((dp = readdir(dirp)) != NULL)
- {
- int l = strlen(dp->d_name);
-
- if (l < 8)
- continue;
-
- if (!memcmp(&dp->d_name[l - 4], ".mpq", 4))
- LoadPatchMD5(dp->d_name);
- }
- else
- {
- if (errno != 0)
- {
- closedir(dirp);
- return;
- }
- break;
- }
- }
-
- if (dirp)
- closedir(dirp);
-}
-#else
-void Patcher::LoadPatchesInfo()
-{
- WIN32_FIND_DATA fil;
- HANDLE hFil = FindFirstFile("./patches/*.mpq", &fil);
- if (hFil == INVALID_HANDLE_VALUE)
- return; // no patches were found
-
- do
- LoadPatchMD5(fil.cFileName);
- while (FindNextFile(hFil, &fil));
-}
-#endif
-
-// Calculate and store MD5 hash for a given patch file
-void Patcher::LoadPatchMD5(char *szFileName)
+// Make the SRP6 calculation from hash in dB
+void AuthSession::SetVSFields(const std::string& rI)
{
- // Try to open the patch file
- std::string path = "./patches/";
- path += szFileName;
- FILE* pPatch = fopen(path.c_str(), "rb");
- TC_LOG_DEBUG("network", "Loading patch info from %s\n", path.c_str());
+ s.SetRand(BYTE_SIZE * 8);
- if (!pPatch)
- {
- TC_LOG_ERROR("server.authserver", "Error loading patch %s\n", path.c_str());
- return;
- }
-
- // Calculate the MD5 hash
- MD5_CTX ctx;
- MD5_Init(&ctx);
- uint8* buf = new uint8[512 * 1024];
-
- while (!feof(pPatch))
- {
- size_t read = fread(buf, 1, 512 * 1024, pPatch);
- MD5_Update(&ctx, buf, read);
- }
+ BigNumber I;
+ I.SetHexStr(rI.c_str());
- delete [] buf;
- fclose(pPatch);
+ // In case of leading zeros in the rI hash, restore them
+ uint8 mDigest[SHA_DIGEST_LENGTH];
+ memset(mDigest, 0, SHA_DIGEST_LENGTH);
+ if (I.GetNumBytes() <= SHA_DIGEST_LENGTH)
+ memcpy(mDigest, I.AsByteArray().get(), I.GetNumBytes());
- // Store the result in the internal patch hash map
- _patches[path] = new PATCH_INFO;
- MD5_Final((uint8 *)&_patches[path]->md5, &ctx);
-}
+ std::reverse(mDigest, mDigest + SHA_DIGEST_LENGTH);
-// Get cached MD5 hash for a given patch file
-bool Patcher::GetHash(char * pat, uint8 mymd5[16])
-{
- for (Patches::iterator i = _patches.begin(); i != _patches.end(); ++i)
- if (!stricmp(pat, i->first.c_str()))
- {
- memcpy(mymd5, i->second->md5, 16);
- return true;
- }
+ SHA1Hash sha;
+ sha.UpdateData(s.AsByteArray().get(), s.GetNumBytes());
+ sha.UpdateData(mDigest, SHA_DIGEST_LENGTH);
+ sha.Finalize();
+ BigNumber x;
+ x.SetBinary(sha.GetDigest(), sha.GetLength());
+ v = g.ModExp(x, N);
- return false;
-}
+ // No SQL injection (username escaped)
+ char *v_hex, *s_hex;
+ v_hex = v.AsHexStr();
+ s_hex = s.AsHexStr();
-// Launch the patch hashing mechanism on object creation
-Patcher::Patcher()
-{
- LoadPatchesInfo();
-}
+ PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_VS);
+ stmt->setString(0, v_hex);
+ stmt->setString(1, s_hex);
+ stmt->setString(2, _login);
+ LoginDatabase.Execute(stmt);
-// Empty and delete the patch map on termination
-Patcher::~Patcher()
-{
- for (Patches::iterator i = _patches.begin(); i != _patches.end(); ++i)
- delete i->second;
+ OPENSSL_free(v_hex);
+ OPENSSL_free(s_hex);
}
diff --git a/src/server/authserver/Server/AuthSession.h b/src/server/authserver/Server/AuthSession.h
new file mode 100644
index 00000000000..4ae33f44cb3
--- /dev/null
+++ b/src/server/authserver/Server/AuthSession.h
@@ -0,0 +1,84 @@
+/*
+* 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 __AUTHSESSION_H__
+#define __AUTHSESSION_H__
+
+#include <memory>
+#include <boost/asio/ip/tcp.hpp>
+#include "Common.h"
+#include "BigNumber.h"
+
+using boost::asio::ip::tcp;
+
+const size_t bufferSize = 4096;
+
+#define BUFFER_SIZE 4096
+
+class AuthSession : public std::enable_shared_from_this < AuthSession >
+{
+public:
+ AuthSession(tcp::socket&& socket) : _socket(std::move(socket))
+ {
+ N.SetHexStr("894B645E89E1535BBDAD5B8B290650530801B18EBFBF5E8FAB3C82872A3E9BB7");
+ g.SetDword(7);
+ }
+
+ void Start()
+ {
+ AsyncReadHeader();
+ }
+
+ bool _HandleLogonChallenge();
+ bool _HandleLogonProof();
+ bool _HandleReconnectChallenge();
+ bool _HandleReconnectProof();
+ bool _HandleRealmList();
+
+ const std::string GetRemoteIpAddress() const { return _socket.remote_endpoint().address().to_string(); };
+ unsigned short GetRemotePort() const { return _socket.remote_endpoint().port(); }
+
+private:
+ void AsyncReadHeader();
+ void AsyncReadData(bool (AuthSession::*handler)(), size_t dataSize, size_t bufferOffset);
+ void AsyncWrite(size_t length);
+
+
+ void SetVSFields(const std::string& rI);
+
+ BigNumber N, s, g, v;
+ BigNumber b, B;
+ BigNumber K;
+ BigNumber _reconnectProof;
+
+ tcp::socket _socket;
+ char _readBuffer[BUFFER_SIZE];
+ char _writeBuffer[BUFFER_SIZE];
+
+ bool _isAuthenticated;
+ std::string _tokenKey;
+ std::string _login;
+ std::string _localizationName;
+ std::string _os;
+ uint16 _build;
+ uint8 _expversion;
+
+ AccountTypes _accountSecurityLevel;
+};
+
+#endif
diff --git a/src/server/authserver/Server/AuthSocket.h b/src/server/authserver/Server/AuthSocket.h
deleted file mode 100644
index e81944389ef..00000000000
--- a/src/server/authserver/Server/AuthSocket.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * 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 _AUTHSOCKET_H
-#define _AUTHSOCKET_H
-
-#include "Common.h"
-#include "BigNumber.h"
-#include "RealmSocket.h"
-
-class ACE_INET_Addr;
-struct Realm;
-
-// Handle login commands
-class AuthSocket: public RealmSocket::Session
-{
-public:
- const static int s_BYTE_SIZE = 32;
-
- AuthSocket(RealmSocket& socket);
- virtual ~AuthSocket(void);
-
- virtual void OnRead(void);
- virtual void OnAccept(void);
- virtual void OnClose(void);
-
- bool _HandleLogonChallenge();
- bool _HandleLogonProof();
- bool _HandleReconnectChallenge();
- bool _HandleReconnectProof();
- bool _HandleRealmList();
-
- //data transfer handle for patch
- bool _HandleXferResume();
- bool _HandleXferCancel();
- bool _HandleXferAccept();
-
- void _SetVSFields(const std::string& rI);
-
- FILE* pPatch;
- ACE_Thread_Mutex patcherLock;
-
-private:
- RealmSocket& socket_;
- RealmSocket& socket(void) { return socket_; }
-
- BigNumber N, s, g, v;
- BigNumber b, B;
- BigNumber K;
- BigNumber _reconnectProof;
-
- bool _authed;
-
- std::string _login;
- std::string _tokenKey;
-
- // Since GetLocaleByName() is _NOT_ bijective, we have to store the locale as a string. Otherwise we can't differ
- // between enUS and enGB, which is important for the patch system
- std::string _localizationName;
- std::string _os;
- uint16 _build;
- uint8 _expversion;
- AccountTypes _accountSecurityLevel;
-};
-
-#endif
diff --git a/src/server/authserver/Server/RealmAcceptor.h b/src/server/authserver/Server/RealmAcceptor.h
deleted file mode 100644
index 2089b0c7a22..00000000000
--- a/src/server/authserver/Server/RealmAcceptor.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
- * Copyright (C) 2005-2010 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 __REALMACCEPTOR_H__
-#define __REALMACCEPTOR_H__
-
-#include <ace/Acceptor.h>
-#include <ace/SOCK_Acceptor.h>
-
-#include "RealmSocket.h"
-#include "AuthSocket.h"
-#include "BattlenetSocket.h"
-
-template<class LoginType>
-class RealmAcceptor : public ACE_Acceptor<RealmSocket, ACE_SOCK_Acceptor>
-{
-public:
- RealmAcceptor(void) { }
- virtual ~RealmAcceptor(void)
- {
- if (reactor())
- reactor()->cancel_timer(this, 1);
- }
-
-protected:
- virtual int make_svc_handler(RealmSocket* &sh)
- {
- if (sh == 0)
- ACE_NEW_RETURN(sh, RealmSocket, -1);
-
- sh->reactor(reactor());
- sh->set_session(new LoginType(*sh));
- return 0;
- }
-
- virtual int handle_timeout(const ACE_Time_Value& /*current_time*/, const void* /*act = 0*/)
- {
- TC_LOG_DEBUG("server.authserver", "Resuming acceptor");
- reactor()->cancel_timer(this, 1);
- return reactor()->register_handler(this, ACE_Event_Handler::ACCEPT_MASK);
- }
-
- virtual int handle_accept_error(void)
- {
-#if defined(ENFILE) && defined(EMFILE)
- if (errno == ENFILE || errno == EMFILE)
- {
- TC_LOG_ERROR("server.authserver", "Out of file descriptors, suspending incoming connections for 10 seconds");
- reactor()->remove_handler(this, ACE_Event_Handler::ACCEPT_MASK | ACE_Event_Handler::DONT_CALL);
- reactor()->schedule_timer(this, NULL, ACE_Time_Value(10));
- }
-#endif
- return 0;
- }
-};
-
-#endif
diff --git a/src/server/authserver/Server/RealmSocket.cpp b/src/server/authserver/Server/RealmSocket.cpp
deleted file mode 100644
index 1013639cc50..00000000000
--- a/src/server/authserver/Server/RealmSocket.cpp
+++ /dev/null
@@ -1,291 +0,0 @@
-/*
- * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
- * Copyright (C) 2005-2010 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 <ace/OS_NS_string.h>
-#include <ace/INET_Addr.h>
-#include <ace/SString.h>
-
-#include "RealmSocket.h"
-#include "Log.h"
-
-RealmSocket::Session::Session(void) { }
-
-RealmSocket::Session::~Session(void) { }
-
-RealmSocket::RealmSocket(void) :
- input_buffer_(4096), session_(NULL),
- _remoteAddress(), _remotePort(0)
-{
- reference_counting_policy().value(ACE_Event_Handler::Reference_Counting_Policy::ENABLED);
-
- msg_queue()->high_water_mark(8 * 1024 * 1024);
- msg_queue()->low_water_mark(8 * 1024 * 1024);
-}
-
-RealmSocket::~RealmSocket(void)
-{
- if (msg_queue())
- msg_queue()->close();
-
- // delete RealmSocketObject must never be called from our code.
- closing_ = true;
-
- delete session_;
-
- peer().close();
-}
-
-int RealmSocket::open(void * arg)
-{
- ACE_INET_Addr addr;
-
- if (peer().get_remote_addr(addr) == -1)
- {
- TC_LOG_ERROR("server.authserver", "Error %s while opening realm socket!", ACE_OS::strerror(errno));
- return -1;
- }
-
- _remoteAddress = addr.get_host_addr();
- _remotePort = addr.get_port_number();
-
- // Register with ACE Reactor
- if (Base::open(arg) == -1)
- return -1;
-
- if (session_)
- session_->OnAccept();
-
- // reactor takes care of the socket from now on
- remove_reference();
-
- return 0;
-}
-
-int RealmSocket::close(u_long)
-{
- shutdown();
-
- closing_ = true;
-
- remove_reference();
-
- return 0;
-}
-
-const std::string& RealmSocket::getRemoteAddress(void) const
-{
- return _remoteAddress;
-}
-
-uint16 RealmSocket::getRemotePort(void) const
-{
- return _remotePort;
-}
-
-size_t RealmSocket::recv_len(void) const
-{
- return input_buffer_.length();
-}
-
-bool RealmSocket::recv_soft(char *buf, size_t len)
-{
- if (input_buffer_.length() < len)
- return false;
-
- ACE_OS::memcpy(buf, input_buffer_.rd_ptr(), len);
-
- return true;
-}
-
-bool RealmSocket::recv(char *buf, size_t len)
-{
- bool ret = recv_soft(buf, len);
-
- if (ret)
- recv_skip(len);
-
- return ret;
-}
-
-void RealmSocket::recv_skip(size_t len)
-{
- input_buffer_.rd_ptr(len);
-}
-
-ssize_t RealmSocket::noblk_send(ACE_Message_Block &message_block)
-{
- const size_t len = message_block.length();
-
- if (len == 0)
- return -1;
-
- // Try to send the message directly.
-#ifdef MSG_NOSIGNAL
- ssize_t n = peer().send(message_block.rd_ptr(), len, MSG_NOSIGNAL);
-#else
- ssize_t n = peer().send(message_block.rd_ptr(), len);
-#endif // MSG_NOSIGNAL
-
- if (n < 0)
- {
- if (errno == EWOULDBLOCK) // Blocking signal
- return 0;
- else // Error happened
- return -1;
- }
- else if (n == 0)
- {
- // Can this happen ?
- return -1;
- }
-
- // return bytes transmitted
- return n;
-}
-
-bool RealmSocket::send(const char *buf, size_t len)
-{
- if (buf == NULL || len == 0)
- return true;
-
- ACE_Data_Block db(len, ACE_Message_Block::MB_DATA, (const char*)buf, 0, 0, ACE_Message_Block::DONT_DELETE, 0);
- ACE_Message_Block message_block(&db, ACE_Message_Block::DONT_DELETE, 0);
-
- message_block.wr_ptr(len);
-
- if (msg_queue()->is_empty())
- {
- // Try to send it directly.
- ssize_t n = noblk_send(message_block);
-
- if (n < 0)
- return false;
-
- size_t un = size_t(n);
- if (un == len)
- return true;
-
- // fall down
- message_block.rd_ptr(un);
- }
-
- ACE_Message_Block* mb = message_block.clone();
-
- if (msg_queue()->enqueue_tail(mb, (ACE_Time_Value *)(&ACE_Time_Value::zero)) == -1)
- {
- mb->release();
- return false;
- }
-
- if (reactor()->schedule_wakeup(this, ACE_Event_Handler::WRITE_MASK) == -1)
- return false;
-
- return true;
-}
-
-int RealmSocket::handle_output(ACE_HANDLE)
-{
- if (closing_)
- return -1;
-
- ACE_Message_Block* mb = 0;
-
- if (msg_queue()->is_empty())
- {
- reactor()->cancel_wakeup(this, ACE_Event_Handler::WRITE_MASK);
- return 0;
- }
-
- if (msg_queue()->dequeue_head(mb, (ACE_Time_Value *)(&ACE_Time_Value::zero)) == -1)
- return -1;
-
- ssize_t n = noblk_send(*mb);
-
- if (n < 0)
- {
- mb->release();
- return -1;
- }
- else if (size_t(n) == mb->length())
- {
- mb->release();
- return 1;
- }
- else
- {
- mb->rd_ptr(n);
-
- if (msg_queue()->enqueue_head(mb, (ACE_Time_Value *) &ACE_Time_Value::zero) == -1)
- {
- mb->release();
- return -1;
- }
-
- return 0;
- }
-
- ACE_NOTREACHED(return -1);
-}
-
-int RealmSocket::handle_close(ACE_HANDLE h, ACE_Reactor_Mask)
-{
- // As opposed to WorldSocket::handle_close, we don't need locks here.
- closing_ = true;
-
- if (h == ACE_INVALID_HANDLE)
- peer().close_writer();
-
- if (session_)
- session_->OnClose();
-
- reactor()->remove_handler(this, ACE_Event_Handler::DONT_CALL | ACE_Event_Handler::ALL_EVENTS_MASK);
- return 0;
-}
-
-int RealmSocket::handle_input(ACE_HANDLE)
-{
- if (closing_)
- return -1;
-
- const ssize_t space = input_buffer_.space();
-
- ssize_t n = peer().recv(input_buffer_.wr_ptr(), space);
-
- if (n < 0)
- return errno == EWOULDBLOCK ? 0 : -1;
- else if (n == 0) // EOF
- return -1;
-
- input_buffer_.wr_ptr((size_t)n);
-
- if (session_ != NULL)
- {
- session_->OnRead();
- input_buffer_.crunch();
- }
-
- // return 1 in case there is more data to read from OS
- return n == space ? 1 : 0;
-}
-
-void RealmSocket::set_session(Session* session)
-{
- delete session_;
-
- session_ = session;
-}
diff --git a/src/server/authserver/Server/RealmSocket.h b/src/server/authserver/Server/RealmSocket.h
deleted file mode 100644
index c1190d638b3..00000000000
--- a/src/server/authserver/Server/RealmSocket.h
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
- * Copyright (C) 2005-2010 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 __REALMSOCKET_H__
-#define __REALMSOCKET_H__
-
-#include <ace/Synch_Traits.h>
-#include <ace/Svc_Handler.h>
-#include <ace/SOCK_Stream.h>
-#include <ace/Message_Block.h>
-#include <ace/Basic_Types.h>
-#include "Common.h"
-
-class RealmSocket : public ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_NULL_SYNCH>
-{
-private:
- typedef ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_NULL_SYNCH> Base;
-
-public:
- class Session
- {
- public:
- Session(void);
- virtual ~Session(void);
-
- virtual void OnRead(void) = 0;
- virtual void OnAccept(void) = 0;
- virtual void OnClose(void) = 0;
- };
-
- RealmSocket(void);
- virtual ~RealmSocket(void);
-
- size_t recv_len(void) const;
- bool recv_soft(char *buf, size_t len);
- bool recv(char *buf, size_t len);
- void recv_skip(size_t len);
-
- bool send(const char *buf, size_t len);
-
- const std::string& getRemoteAddress(void) const;
-
- uint16 getRemotePort(void) const;
-
- virtual int open(void *);
-
- virtual int close(u_long);
-
- virtual int handle_input(ACE_HANDLE = ACE_INVALID_HANDLE);
- virtual int handle_output(ACE_HANDLE = ACE_INVALID_HANDLE);
-
- virtual int handle_close(ACE_HANDLE = ACE_INVALID_HANDLE, ACE_Reactor_Mask = ACE_Event_Handler::ALL_EVENTS_MASK);
-
- void set_session(Session* session);
-
-private:
- ssize_t noblk_send(ACE_Message_Block &message_block);
-
- ACE_Message_Block input_buffer_;
- Session* session_;
- std::string _remoteAddress;
- uint16 _remotePort;
-};
-
-#endif /* __REALMSOCKET_H__ */
diff --git a/src/server/collision/BoundingIntervalHierarchy.h b/src/server/collision/BoundingIntervalHierarchy.h
index 4d38bfc18c4..491a299ca68 100644
--- a/src/server/collision/BoundingIntervalHierarchy.h
+++ b/src/server/collision/BoundingIntervalHierarchy.h
@@ -177,7 +177,7 @@ class BIH
{
uint32 tn = tree[node];
uint32 axis = (tn & (3 << 30)) >> 30;
- bool BVH2 = tn & (1 << 29);
+ bool BVH2 = (tn & (1 << 29)) != 0;
int offset = tn & ~(7 << 29);
if (!BVH2)
{
@@ -271,7 +271,7 @@ class BIH
{
uint32 tn = tree[node];
uint32 axis = (tn & (3 << 30)) >> 30;
- bool BVH2 = tn & (1 << 29);
+ bool BVH2 = (tn & (1 << 29)) != 0;
int offset = tn & ~(7 << 29);
if (!BVH2)
{
diff --git a/src/server/collision/CMakeLists.txt b/src/server/collision/CMakeLists.txt
index a2024bff7cb..378bd62a78a 100644
--- a/src/server/collision/CMakeLists.txt
+++ b/src/server/collision/CMakeLists.txt
@@ -75,7 +75,6 @@ include_directories(
${CMAKE_CURRENT_SOURCE_DIR}/Management
${CMAKE_CURRENT_SOURCE_DIR}/Maps
${CMAKE_CURRENT_SOURCE_DIR}/Models
- ${ACE_INCLUDE_DIR}
${MYSQL_INCLUDE_DIR}
)
diff --git a/src/server/collision/Management/VMapManager2.cpp b/src/server/collision/Management/VMapManager2.cpp
index 813a3c04288..1d267cbd2a5 100644
--- a/src/server/collision/Management/VMapManager2.cpp
+++ b/src/server/collision/Management/VMapManager2.cpp
@@ -25,8 +25,6 @@
#include "ModelInstance.h"
#include "WorldModel.h"
#include <G3D/Vector3.h>
-#include <ace/Null_Mutex.h>
-#include <ace/Singleton.h>
#include "DisableMgr.h"
#include "DBCStores.h"
#include "Log.h"
@@ -252,7 +250,7 @@ namespace VMAP
WorldModel* VMapManager2::acquireModelInstance(const std::string& basepath, const std::string& filename)
{
//! Critical section, thread safe access to iLoadedModelFiles
- TRINITY_GUARD(ACE_Thread_Mutex, LoadedModelFilesLock);
+ std::lock_guard<std::mutex> lock(LoadedModelFilesLock);
ModelFileMap::iterator model = iLoadedModelFiles.find(filename);
if (model == iLoadedModelFiles.end())
@@ -275,7 +273,7 @@ namespace VMAP
void VMapManager2::releaseModelInstance(const std::string &filename)
{
//! Critical section, thread safe access to iLoadedModelFiles
- TRINITY_GUARD(ACE_Thread_Mutex, LoadedModelFilesLock);
+ std::lock_guard<std::mutex> lock(LoadedModelFilesLock);
ModelFileMap::iterator model = iLoadedModelFiles.find(filename);
if (model == iLoadedModelFiles.end())
diff --git a/src/server/collision/Management/VMapManager2.h b/src/server/collision/Management/VMapManager2.h
index 711025e67c0..03de6951d5d 100644
--- a/src/server/collision/Management/VMapManager2.h
+++ b/src/server/collision/Management/VMapManager2.h
@@ -19,10 +19,10 @@
#ifndef _VMAPMANAGER2_H
#define _VMAPMANAGER2_H
+#include <mutex>
+#include <unordered_map>
#include "Define.h"
#include "IVMapManager.h"
-#include <unordered_map>
-#include <ace/Thread_Mutex.h>
//===========================================================
@@ -73,7 +73,7 @@ namespace VMAP
ModelFileMap iLoadedModelFiles;
InstanceTreeMap iInstanceMapTrees;
// Mutex for iLoadedModelFiles
- ACE_Thread_Mutex LoadedModelFilesLock;
+ std::mutex LoadedModelFilesLock;
bool _loadMap(uint32 mapId, const std::string& basePath, uint32 tileX, uint32 tileY);
/* void _unloadMap(uint32 pMapId, uint32 x, uint32 y); */
diff --git a/src/server/collision/Maps/MapTree.cpp b/src/server/collision/Maps/MapTree.cpp
index d592d795125..6b82e06aff7 100644
--- a/src/server/collision/Maps/MapTree.cpp
+++ b/src/server/collision/Maps/MapTree.cpp
@@ -295,7 +295,7 @@ namespace VMAP
success = readChunk(rf, chunk, "GOBJ", 4);
}
- iIsTiled = bool(tiled);
+ iIsTiled = tiled != '\0';
// global model spawns
// only non-tiled maps have them, and if so exactly one (so far at least...)
diff --git a/src/server/collision/Models/ModelInstance.cpp b/src/server/collision/Models/ModelInstance.cpp
index 3262c154965..475984c4fd3 100644
--- a/src/server/collision/Models/ModelInstance.cpp
+++ b/src/server/collision/Models/ModelInstance.cpp
@@ -167,7 +167,7 @@ namespace VMAP
check += fread(&spawn.iPos, sizeof(float), 3, rf);
check += fread(&spawn.iRot, sizeof(float), 3, rf);
check += fread(&spawn.iScale, sizeof(float), 1, rf);
- bool has_bound = (spawn.flags & MOD_HAS_BOUND);
+ bool has_bound = (spawn.flags & MOD_HAS_BOUND) != 0;
if (has_bound) // only WMOs have bound in MPQ, only available after computation
{
Vector3 bLow, bHigh;
@@ -206,7 +206,7 @@ namespace VMAP
check += fwrite(&spawn.iPos, sizeof(float), 3, wf);
check += fwrite(&spawn.iRot, sizeof(float), 3, wf);
check += fwrite(&spawn.iScale, sizeof(float), 1, wf);
- bool has_bound = (spawn.flags & MOD_HAS_BOUND);
+ bool has_bound = (spawn.flags & MOD_HAS_BOUND) != 0;
if (has_bound) // only WMOs have bound in MPQ, only available after computation
{
check += fwrite(&spawn.iBound.low(), sizeof(float), 3, wf);
diff --git a/src/server/collision/VMapDefinitions.h b/src/server/collision/VMapDefinitions.h
index 0bc74df51ec..8cd965ddffd 100644
--- a/src/server/collision/VMapDefinitions.h
+++ b/src/server/collision/VMapDefinitions.h
@@ -19,6 +19,7 @@
#ifndef _VMAPDEFINITIONS_H
#define _VMAPDEFINITIONS_H
#include <cstring>
+#include <cstdio>
#define LIQUID_TILE_SIZE (533.333f / 128.f)
diff --git a/src/server/game/AI/CoreAI/UnitAI.cpp b/src/server/game/AI/CoreAI/UnitAI.cpp
index cb32740e068..90bd3e8627a 100644
--- a/src/server/game/AI/CoreAI/UnitAI.cpp
+++ b/src/server/game/AI/CoreAI/UnitAI.cpp
@@ -141,7 +141,7 @@ void UnitAI::DoCast(uint32 spellId)
{
if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId))
{
- bool playerOnly = spellInfo->AttributesEx3 & SPELL_ATTR3_ONLY_TARGET_PLAYERS;
+ bool playerOnly = (spellInfo->AttributesEx3 & SPELL_ATTR3_ONLY_TARGET_PLAYERS) != 0;
target = SelectTarget(SELECT_TARGET_RANDOM, 0, spellInfo->GetMaxRange(false), playerOnly);
}
break;
@@ -156,7 +156,7 @@ void UnitAI::DoCast(uint32 spellId)
{
if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId))
{
- bool playerOnly = spellInfo->AttributesEx3 & SPELL_ATTR3_ONLY_TARGET_PLAYERS;
+ bool playerOnly = (spellInfo->AttributesEx3 & SPELL_ATTR3_ONLY_TARGET_PLAYERS) != 0;
float range = spellInfo->GetMaxRange(false);
DefaultTargetSelector targetSelector(me, range, playerOnly, -(int32)spellId);
diff --git a/src/server/game/AI/CreatureAI.cpp b/src/server/game/AI/CreatureAI.cpp
index ac9de00cd10..7a79bb722a0 100644
--- a/src/server/game/AI/CreatureAI.cpp
+++ b/src/server/game/AI/CreatureAI.cpp
@@ -204,7 +204,8 @@ bool CreatureAI::UpdateVictimWithGaze()
if (Unit* victim = me->SelectVictim())
AttackStart(victim);
- return me->GetVictim();
+
+ return me->GetVictim() != nullptr;
}
bool CreatureAI::UpdateVictim()
@@ -216,7 +217,8 @@ bool CreatureAI::UpdateVictim()
{
if (Unit* victim = me->SelectVictim())
AttackStart(victim);
- return me->GetVictim();
+
+ return me->GetVictim() != nullptr;
}
else if (me->getThreatManager().isThreatListEmpty())
{
diff --git a/src/server/game/AI/CreatureAIFactory.h b/src/server/game/AI/CreatureAIFactory.h
index fc2d009e673..f2854f1a9ce 100644
--- a/src/server/game/AI/CreatureAIFactory.h
+++ b/src/server/game/AI/CreatureAIFactory.h
@@ -49,7 +49,6 @@ CreatureAIFactory<REAL_AI>::Create(void* data) const
typedef FactoryHolder<CreatureAI> CreatureAICreator;
typedef FactoryHolder<CreatureAI>::FactoryHolderRegistry CreatureAIRegistry;
-typedef FactoryHolder<CreatureAI>::FactoryHolderRepository CreatureAIRepository;
//GO
struct SelectableGameObjectAI : public FactoryHolder<GameObjectAI>, public Permissible<GameObject>
@@ -77,5 +76,4 @@ GameObjectAIFactory<REAL_GO_AI>::Create(void* data) const
typedef FactoryHolder<GameObjectAI> GameObjectAICreator;
typedef FactoryHolder<GameObjectAI>::FactoryHolderRegistry GameObjectAIRegistry;
-typedef FactoryHolder<GameObjectAI>::FactoryHolderRepository GameObjectAIRepository;
#endif
diff --git a/src/server/game/AI/CreatureAISelector.cpp b/src/server/game/AI/CreatureAISelector.cpp
index 473af0d787e..afbd306c184 100644
--- a/src/server/game/AI/CreatureAISelector.cpp
+++ b/src/server/game/AI/CreatureAISelector.cpp
@@ -31,7 +31,7 @@ namespace FactorySelector
CreatureAI* selectAI(Creature* creature)
{
const CreatureAICreator* ai_factory = NULL;
- CreatureAIRegistry& ai_registry(*CreatureAIRepository::instance());
+ CreatureAIRegistry& ai_registry(*CreatureAIRegistry::instance());
if (creature->IsPet())
ai_factory = ai_registry.GetRegistryItem("PetAI");
@@ -101,7 +101,7 @@ namespace FactorySelector
MovementGenerator* selectMovementGenerator(Creature* creature)
{
- MovementGeneratorRegistry& mv_registry(*MovementGeneratorRepository::instance());
+ MovementGeneratorRegistry& mv_registry(*MovementGeneratorRegistry::instance());
ASSERT(creature->GetCreatureTemplate());
const MovementGeneratorCreator* mv_factory = mv_registry.GetRegistryItem(creature->GetDefaultMovementType());
@@ -130,7 +130,7 @@ namespace FactorySelector
GameObjectAI* SelectGameObjectAI(GameObject* go)
{
const GameObjectAICreator* ai_factory = NULL;
- GameObjectAIRegistry& ai_registry(*GameObjectAIRepository::instance());
+ GameObjectAIRegistry& ai_registry(*GameObjectAIRegistry::instance());
// scriptname in db
if (GameObjectAI* scriptedAI = sScriptMgr->GetGameObjectAI(go))
diff --git a/src/server/game/AI/ScriptedAI/ScriptedEscortAI.h b/src/server/game/AI/ScriptedAI/ScriptedEscortAI.h
index 4aa00d74e4e..177810bbbfd 100644
--- a/src/server/game/AI/ScriptedAI/ScriptedEscortAI.h
+++ b/src/server/game/AI/ScriptedAI/ScriptedEscortAI.h
@@ -93,7 +93,7 @@ struct npc_escortAI : public ScriptedAI
void SetRun(bool on = true);
void SetEscortPaused(bool on);
- bool HasEscortState(uint32 escortState) { return (m_uiEscortState & escortState); }
+ bool HasEscortState(uint32 escortState) { return (m_uiEscortState & escortState) != 0; }
virtual bool IsEscorted() { return (m_uiEscortState & STATE_ESCORT_ESCORTING); }
void SetMaxPlayerDistance(float newMax) { MaxPlayerDistance = newMax; }
diff --git a/src/server/game/AI/ScriptedAI/ScriptedFollowerAI.h b/src/server/game/AI/ScriptedAI/ScriptedFollowerAI.h
index df435fa5c9a..af7508441b9 100644
--- a/src/server/game/AI/ScriptedAI/ScriptedFollowerAI.h
+++ b/src/server/game/AI/ScriptedAI/ScriptedFollowerAI.h
@@ -60,7 +60,7 @@ class FollowerAI : public ScriptedAI
void SetFollowPaused(bool bPaused); //if special event require follow mode to hold/resume during the follow
void SetFollowComplete(bool bWithEndEvent = false);
- bool HasFollowState(uint32 uiFollowState) { return (m_uiFollowState & uiFollowState); }
+ bool HasFollowState(uint32 uiFollowState) { return (m_uiFollowState & uiFollowState) != 0; }
protected:
Player* GetLeaderForFollower();
diff --git a/src/server/game/AI/SmartScripts/SmartScript.cpp b/src/server/game/AI/SmartScripts/SmartScript.cpp
index 140bb5507b4..d4b41f529a9 100644
--- a/src/server/game/AI/SmartScripts/SmartScript.cpp
+++ b/src/server/game/AI/SmartScripts/SmartScript.cpp
@@ -522,10 +522,10 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
CAST_AI(SmartAI, me->AI())->SetCombatMove(_allowMove);
}
- me->CastSpell((*itr)->ToUnit(), e.action.cast.spell, (e.action.cast.flags & SMARTCAST_TRIGGERED));
+ me->CastSpell((*itr)->ToUnit(), e.action.cast.spell, (e.action.cast.flags & SMARTCAST_TRIGGERED) != 0);
}
else if (go)
- go->CastSpell((*itr)->ToUnit(), e.action.cast.spell, (e.action.cast.flags & SMARTCAST_TRIGGERED));
+ go->CastSpell((*itr)->ToUnit(), e.action.cast.spell, (e.action.cast.flags & SMARTCAST_TRIGGERED) != 0);
TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_CAST:: %s: %u casts spell %u on target %u with castflags %u",
GetLogNameForGuid(me ? me->GetGUID() : go->GetGUID()), me ? me->GetGUIDLow() : go->GetGUIDLow(), e.action.cast.spell, (*itr)->GetGUIDLow(), e.action.cast.flags);
@@ -557,7 +557,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
if (e.action.cast.flags & SMARTCAST_INTERRUPT_PREVIOUS)
tempLastInvoker->InterruptNonMeleeSpells(false);
- tempLastInvoker->CastSpell((*itr)->ToUnit(), e.action.cast.spell, (e.action.cast.flags & SMARTCAST_TRIGGERED));
+ tempLastInvoker->CastSpell((*itr)->ToUnit(), e.action.cast.spell, (e.action.cast.flags & SMARTCAST_TRIGGERED) != 0);
TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_INVOKER_CAST: Invoker %u casts spell %u on target %u with castflags %u",
tempLastInvoker->GetGUIDLow(), e.action.cast.spell, (*itr)->GetGUIDLow(), e.action.cast.flags);
}
@@ -707,7 +707,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
if (!IsSmart())
break;
- CAST_AI(SmartAI, me->AI())->SetAutoAttack(e.action.autoAttack.attack);
+ CAST_AI(SmartAI, me->AI())->SetAutoAttack(e.action.autoAttack.attack != 0);
TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_AUTO_ATTACK: Creature: %u bool on = %u",
me->GetGUIDLow(), e.action.autoAttack.attack);
break;
@@ -717,7 +717,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
if (!IsSmart())
break;
- bool move = e.action.combatMove.move;
+ bool move = e.action.combatMove.move != 0;
CAST_AI(SmartAI, me->AI())->SetCombatMove(move);
TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_ALLOW_COMBAT_MOVEMENT: Creature %u bool on = %u",
me->GetGUIDLow(), e.action.combatMove.move);
@@ -1149,13 +1149,13 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
case SMART_ACTION_SET_VISIBILITY:
{
if (me)
- me->SetVisible(e.action.visibility.state);
+ me->SetVisible(e.action.visibility.state != 0);
break;
}
case SMART_ACTION_SET_ACTIVE:
{
if (WorldObject* baseObj = GetBaseObject())
- baseObj->setActive(e.action.active.state);
+ baseObj->setActive(e.action.active.state != 0);
break;
}
@@ -1331,7 +1331,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
if (!IsSmart())
break;
- CAST_AI(SmartAI, me->AI())->SetFly(e.action.setFly.fly);
+ CAST_AI(SmartAI, me->AI())->SetFly(e.action.setFly.fly != 0);
break;
}
case SMART_ACTION_SET_RUN:
@@ -1339,7 +1339,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
if (!IsSmart())
break;
- CAST_AI(SmartAI, me->AI())->SetRun(e.action.setRun.run);
+ CAST_AI(SmartAI, me->AI())->SetRun(e.action.setRun.run != 0);
break;
}
case SMART_ACTION_SET_SWIM:
@@ -1347,7 +1347,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
if (!IsSmart())
break;
- CAST_AI(SmartAI, me->AI())->SetSwim(e.action.setSwim.swim);
+ CAST_AI(SmartAI, me->AI())->SetSwim(e.action.setSwim.swim != 0);
break;
}
case SMART_ACTION_WP_START:
@@ -1355,9 +1355,9 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
if (!IsSmart())
break;
- bool run = e.action.wpStart.run;
+ bool run = e.action.wpStart.run != 0;
uint32 entry = e.action.wpStart.pathID;
- bool repeat = e.action.wpStart.repeat;
+ bool repeat = e.action.wpStart.repeat != 0;
ObjectList* targets = GetTargets(e, unit);
StoreTargetList(targets, SMART_ESCORT_TARGETS);
me->SetReactState((ReactStates)e.action.wpStart.reactState);
@@ -1385,7 +1385,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
uint32 DespawnTime = e.action.wpStop.despawnTime;
uint32 quest = e.action.wpStop.quest;
- bool fail = e.action.wpStop.fail;
+ bool fail = e.action.wpStop.fail != 0;
CAST_AI(SmartAI, me->AI())->StopPath(DespawnTime, quest, fail);
break;
}
@@ -1739,7 +1739,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
interruptedSpell = true;
}
- unit->CastSpell((*it)->ToUnit(), e.action.cast.spell, (e.action.cast.flags & SMARTCAST_TRIGGERED));
+ unit->CastSpell((*it)->ToUnit(), e.action.cast.spell, (e.action.cast.flags & SMARTCAST_TRIGGERED) != 0);
}
else
TC_LOG_DEBUG("scripts.ai", "Spell %u not cast because it has flag SMARTCAST_AURA_NOT_PRESENT and the target (Guid: " UI64FMTD " Entry: %u Type: %u) already has the aura", e.action.cast.spell, (*it)->GetGUID(), (*it)->GetEntry(), uint32((*it)->GetTypeId()));
@@ -1909,7 +1909,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
if (IsUnit(*itr))
- (*itr)->ToUnit()->InterruptNonMeleeSpells(e.action.interruptSpellCasting.withDelayed, e.action.interruptSpellCasting.spell_id, e.action.interruptSpellCasting.withInstant);
+ (*itr)->ToUnit()->InterruptNonMeleeSpells(e.action.interruptSpellCasting.withDelayed != 0, e.action.interruptSpellCasting.spell_id, e.action.interruptSpellCasting.withInstant != 0);
delete targets;
break;
@@ -2100,7 +2100,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))
- (*itr)->ToCreature()->setRegeneratingHealth(e.action.setHealthRegen.regenHealth);
+ (*itr)->ToCreature()->setRegeneratingHealth(e.action.setHealthRegen.regenHealth != 0);
delete targets;
break;
@@ -2113,7 +2113,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))
- (*itr)->ToCreature()->SetControlled(e.action.setRoot.root, UNIT_STATE_ROOT);
+ (*itr)->ToCreature()->SetControlled(e.action.setRoot.root != 0, UNIT_STATE_ROOT);
delete targets;
break;
@@ -2622,7 +2622,7 @@ ObjectList* SmartScript::GetTargets(SmartScriptHolder const& e, Unit* invoker /*
case SMART_TARGET_CLOSEST_ENEMY:
{
if (me)
- if (Unit* target = me->SelectNearestTarget(e.target.closestAttackable.maxDist, e.target.closestAttackable.playerOnly))
+ if (Unit* target = me->SelectNearestTarget(e.target.closestAttackable.maxDist, e.target.closestAttackable.playerOnly != 0))
l->push_back(target);
break;
@@ -2630,7 +2630,7 @@ ObjectList* SmartScript::GetTargets(SmartScriptHolder const& e, Unit* invoker /*
case SMART_TARGET_CLOSEST_FRIENDLY:
{
if (me)
- if (Unit* target = DoFindClosestFriendlyInRange(e.target.closestFriendly.maxDist, e.target.closestFriendly.playerOnly))
+ if (Unit* target = DoFindClosestFriendlyInRange(e.target.closestFriendly.maxDist, e.target.closestFriendly.playerOnly != 0))
l->push_back(target);
break;
diff --git a/src/server/game/AI/SmartScripts/SmartScript.h b/src/server/game/AI/SmartScripts/SmartScript.h
index b83222dc263..0931756a026 100644
--- a/src/server/game/AI/SmartScripts/SmartScript.h
+++ b/src/server/game/AI/SmartScripts/SmartScript.h
@@ -216,7 +216,7 @@ class SmartScript
}
void DecPhase(int32 p = 1) { mEventPhase -= (mEventPhase < (uint32)p ? (uint32)p - mEventPhase : (uint32)p); }
- bool IsInPhase(uint32 p) const { return (1 << (mEventPhase - 1)) & p; }
+ bool IsInPhase(uint32 p) const { return ((1 << (mEventPhase - 1)) & p) != 0; }
void SetPhase(uint32 p = 0) { mEventPhase = p; }
SmartAIEventList mEvents;
diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.h b/src/server/game/AI/SmartScripts/SmartScriptMgr.h
index f57fae507d0..f3106ed726b 100644
--- a/src/server/game/AI/SmartScripts/SmartScriptMgr.h
+++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.h
@@ -1404,11 +1404,17 @@ typedef std::unordered_map<uint32, ObjectGuidList*> ObjectListMap;
class SmartWaypointMgr
{
- friend class ACE_Singleton<SmartWaypointMgr, ACE_Null_Mutex>;
- SmartWaypointMgr() { }
- public:
+ private:
+ SmartWaypointMgr() { }
~SmartWaypointMgr();
+ public:
+ static SmartWaypointMgr* instance()
+ {
+ static SmartWaypointMgr* instance = new SmartWaypointMgr();
+ return instance;
+ }
+
void LoadFromDB();
WPPath* GetPath(uint32 id)
@@ -1434,11 +1440,17 @@ typedef std::pair<CacheSpellContainer::const_iterator, CacheSpellContainer::cons
class SmartAIMgr
{
- friend class ACE_Singleton<SmartAIMgr, ACE_Null_Mutex>;
- SmartAIMgr() { }
- public:
+ private:
+ SmartAIMgr() { }
~SmartAIMgr() { }
+ public:
+ static SmartAIMgr* instance()
+ {
+ static SmartAIMgr* instance = new SmartAIMgr();
+ return instance;
+ }
+
void LoadSmartAIFromDB();
SmartAIEventList GetScript(int32 entry, SmartScriptType type)
@@ -1606,6 +1618,6 @@ class SmartAIMgr
CacheSpellContainer KillCreditSpellStore;
};
-#define sSmartScriptMgr ACE_Singleton<SmartAIMgr, ACE_Null_Mutex>::instance()
-#define sSmartWaypointMgr ACE_Singleton<SmartWaypointMgr, ACE_Null_Mutex>::instance()
+#define sSmartScriptMgr SmartAIMgr::instance()
+#define sSmartWaypointMgr SmartWaypointMgr::instance()
#endif
diff --git a/src/server/game/Accounts/AccountMgr.h b/src/server/game/Accounts/AccountMgr.h
index f39873f0ebf..47801f3ce19 100644
--- a/src/server/game/Accounts/AccountMgr.h
+++ b/src/server/game/Accounts/AccountMgr.h
@@ -20,7 +20,6 @@
#define _ACCMGR_H
#include "RBAC.h"
-#include <ace/Singleton.h>
enum class AccountOpResult : uint8
{
@@ -52,13 +51,17 @@ typedef std::map<uint8, rbac::RBACPermissionContainer> RBACDefaultPermissionsCon
class AccountMgr
{
- friend class ACE_Singleton<AccountMgr, ACE_Null_Mutex>;
-
private:
AccountMgr();
~AccountMgr();
public:
+ static AccountMgr* instance()
+ {
+ static AccountMgr* instance = new AccountMgr();
+ return instance;
+ }
+
AccountOpResult CreateAccount(std::string username, std::string password, std::string email = "");
static AccountOpResult DeleteAccount(uint32 accountId);
static AccountOpResult ChangeUsername(uint32 accountId, std::string newUsername, std::string newPassword);
@@ -95,5 +98,5 @@ class AccountMgr
rbac::RBACDefaultPermissionsContainer _defaultPermissions;
};
-#define sAccountMgr ACE_Singleton<AccountMgr, ACE_Null_Mutex>::instance()
+#define sAccountMgr AccountMgr::instance()
#endif
diff --git a/src/server/game/Achievements/AchievementMgr.cpp b/src/server/game/Achievements/AchievementMgr.cpp
index 09b0981c751..48724dfe53d 100644
--- a/src/server/game/Achievements/AchievementMgr.cpp
+++ b/src/server/game/Achievements/AchievementMgr.cpp
@@ -388,6 +388,21 @@ bool AchievementCriteriaData::Meets(uint32 criteria_id, Player const* source, Un
return false;
return pProto->ItemLevel >= equipped_item.item_level && pProto->Quality >= equipped_item.item_quality;
}
+ case ACHIEVEMENT_CRITERIA_DATA_TYPE_MAP_ID:
+ return source->GetMapId() == map_id.mapId;
+ case ACHIEVEMENT_CRITERIA_DATA_TYPE_NTH_BIRTHDAY:
+ {
+ time_t birthday_start = time_t(sWorld->getIntConfig(CONFIG_BIRTHDAY_TIME));
+ tm birthday_tm;
+ localtime_r(&birthday_start, &birthday_tm);
+
+ // exactly N birthday
+ birthday_tm.tm_year += birthday_login.nth_birthday;
+
+ time_t birthday = mktime(&birthday_tm);
+ time_t now = sWorld->GetGameTime();
+ return now <= birthday + DAY && now >= birthday;
+ }
case ACHIEVEMENT_CRITERIA_DATA_TYPE_S_KNOWN_TITLE:
{
if (CharTitlesEntry const* titleInfo = sCharTitlesStore.LookupEntry(known_title.title_id))
diff --git a/src/server/game/Achievements/AchievementMgr.h b/src/server/game/Achievements/AchievementMgr.h
index 2758c677c21..66c91ef728e 100644
--- a/src/server/game/Achievements/AchievementMgr.h
+++ b/src/server/game/Achievements/AchievementMgr.h
@@ -23,7 +23,6 @@
#include <string>
#include "Common.h"
-#include <ace/Singleton.h>
#include "DatabaseEnv.h"
#include "DBCEnums.h"
#include "DBCStores.h"
@@ -299,7 +298,6 @@ class AchievementMgr
class AchievementGlobalMgr
{
- friend class ACE_Singleton<AchievementGlobalMgr, ACE_Null_Mutex>;
AchievementGlobalMgr() { }
~AchievementGlobalMgr() { }
@@ -307,6 +305,12 @@ class AchievementGlobalMgr
static char const* GetCriteriaTypeString(AchievementCriteriaTypes type);
static char const* GetCriteriaTypeString(uint32 type);
+ static AchievementGlobalMgr* instance()
+ {
+ static AchievementGlobalMgr* instance = new AchievementGlobalMgr();
+ return instance;
+ }
+
AchievementCriteriaEntryList const& GetAchievementCriteriaByType(AchievementCriteriaTypes type, bool guild = false) const
{
return guild ? m_GuildAchievementCriteriasByType[type] : m_AchievementCriteriasByType[type];
@@ -405,6 +409,6 @@ class AchievementGlobalMgr
AchievementRewardLocales m_achievementRewardLocales;
};
-#define sAchievementMgr ACE_Singleton<AchievementGlobalMgr, ACE_Null_Mutex>::instance()
+#define sAchievementMgr AchievementGlobalMgr::instance()
#endif
diff --git a/src/server/game/AuctionHouse/AuctionHouseMgr.h b/src/server/game/AuctionHouse/AuctionHouseMgr.h
index 978e6869bac..3222d3bfa3c 100644
--- a/src/server/game/AuctionHouse/AuctionHouseMgr.h
+++ b/src/server/game/AuctionHouse/AuctionHouseMgr.h
@@ -19,8 +19,6 @@
#ifndef _AUCTION_HOUSE_MGR_H
#define _AUCTION_HOUSE_MGR_H
-#include <ace/Singleton.h>
-
#include "Common.h"
#include "DatabaseEnv.h"
#include "DBCStructure.h"
@@ -137,13 +135,16 @@ class AuctionHouseObject
class AuctionHouseMgr
{
- friend class ACE_Singleton<AuctionHouseMgr, ACE_Null_Mutex>;
-
private:
AuctionHouseMgr();
~AuctionHouseMgr();
public:
+ static AuctionHouseMgr* instance()
+ {
+ static AuctionHouseMgr* instance = new AuctionHouseMgr();
+ return instance;
+ }
typedef std::unordered_map<uint32, Item*> ItemMap;
@@ -193,6 +194,6 @@ class AuctionHouseMgr
ItemMap mAitems;
};
-#define sAuctionMgr ACE_Singleton<AuctionHouseMgr, ACE_Null_Mutex>::instance()
+#define sAuctionMgr AuctionHouseMgr::instance()
#endif
diff --git a/src/server/game/Battlefield/BattlefieldMgr.h b/src/server/game/Battlefield/BattlefieldMgr.h
index 225fa380870..a3aad126479 100644
--- a/src/server/game/Battlefield/BattlefieldMgr.h
+++ b/src/server/game/Battlefield/BattlefieldMgr.h
@@ -19,7 +19,6 @@
#define BATTLEFIELD_MGR_H_
#include "Battlefield.h"
-#include <ace/Singleton.h>
class Player;
class ZoneScript;
@@ -28,11 +27,12 @@ class ZoneScript;
class BattlefieldMgr
{
public:
- // ctor
- BattlefieldMgr();
- // dtor
- ~BattlefieldMgr();
-
+ static BattlefieldMgr* instance()
+ {
+ static BattlefieldMgr* instance = new BattlefieldMgr();
+ return instance;
+ }
+
// create battlefield events
void InitBattlefield();
@@ -53,6 +53,9 @@ class BattlefieldMgr
void Update(uint32 diff);
private:
+ BattlefieldMgr();
+ ~BattlefieldMgr();
+
typedef std::vector<Battlefield*> BattlefieldSet;
typedef std::map<uint32 /*zoneId*/, Battlefield*> BattlefieldMap;
// contains all initiated battlefield events
@@ -65,6 +68,6 @@ class BattlefieldMgr
uint32 _updateTimer;
};
-#define sBattlefieldMgr ACE_Singleton<BattlefieldMgr, ACE_Null_Mutex>::instance()
+#define sBattlefieldMgr BattlefieldMgr::instance()
#endif // BATTLEFIELD_MGR_H_
diff --git a/src/server/game/Battlefield/Zones/BattlefieldWG.cpp b/src/server/game/Battlefield/Zones/BattlefieldWG.cpp
index 3e603f4bb28..e05c918f501 100644
--- a/src/server/game/Battlefield/Zones/BattlefieldWG.cpp
+++ b/src/server/game/Battlefield/Zones/BattlefieldWG.cpp
@@ -84,7 +84,7 @@ bool BattlefieldWG::SetupBattlefield()
sWorld->setWorldState(ClockWorldState[0], uint64(m_NoWarBattleTime));
}
- m_isActive = bool(sWorld->getWorldState(BATTLEFIELD_WG_WORLD_STATE_ACTIVE));
+ m_isActive = sWorld->getWorldState(BATTLEFIELD_WG_WORLD_STATE_ACTIVE) != 0;
m_DefenderTeam = TeamId(sWorld->getWorldState(BATTLEFIELD_WG_WORLD_STATE_DEFENDER));
m_Timer = sWorld->getWorldState(ClockWorldState[0]);
diff --git a/src/server/game/Battlegrounds/Arena.cpp b/src/server/game/Battlegrounds/Arena.cpp
index 23d540adfb9..7a72afa2b12 100644
--- a/src/server/game/Battlegrounds/Arena.cpp
+++ b/src/server/game/Battlegrounds/Arena.cpp
@@ -110,7 +110,7 @@ void Arena::RemovePlayerAtLeave(uint64 guid, bool transport, bool sendPacket)
// left a rated match while the encounter was in progress, consider as loser
if (winnerArenaTeam && loserArenaTeam && winnerArenaTeam != loserArenaTeam)
{
- if (Player* player = _GetPlayer(itr->first, itr->second.OfflineRemoveTime, "Arena::RemovePlayerAtLeave"))
+ if (Player* player = _GetPlayer(itr->first, itr->second.OfflineRemoveTime != 0, "Arena::RemovePlayerAtLeave"))
loserArenaTeam->MemberLost(player, GetArenaMatchmakerRating(GetOtherTeam(team)));
else
loserArenaTeam->OfflineMemberLost(guid, GetArenaMatchmakerRating(GetOtherTeam(team)));
@@ -213,7 +213,7 @@ void Arena::EndBattleground(uint32 winner)
continue;
}
- Player* player = _GetPlayer(i.first, i.second.OfflineRemoveTime, "Arena::EndBattleground");
+ Player* player = _GetPlayer(i.first, i.second.OfflineRemoveTime != 0, "Arena::EndBattleground");
if (!player)
continue;
diff --git a/src/server/game/Battlegrounds/ArenaTeamMgr.h b/src/server/game/Battlegrounds/ArenaTeamMgr.h
index ca915e0db6f..17b9120c7f6 100644
--- a/src/server/game/Battlegrounds/ArenaTeamMgr.h
+++ b/src/server/game/Battlegrounds/ArenaTeamMgr.h
@@ -22,11 +22,17 @@
class ArenaTeamMgr
{
- friend class ACE_Singleton<ArenaTeamMgr, ACE_Null_Mutex>;
+private:
ArenaTeamMgr();
~ArenaTeamMgr();
public:
+ static ArenaTeamMgr* instance()
+ {
+ static ArenaTeamMgr* instance = new ArenaTeamMgr();
+ return instance;
+ }
+
typedef std::unordered_map<uint32, ArenaTeam*> ArenaTeamContainer;
ArenaTeam* GetArenaTeamById(uint32 arenaTeamId) const;
@@ -48,6 +54,6 @@ protected:
ArenaTeamContainer ArenaTeamStore;
};
-#define sArenaTeamMgr ACE_Singleton<ArenaTeamMgr, ACE_Null_Mutex>::instance()
+#define sArenaTeamMgr ArenaTeamMgr::instance()
#endif
diff --git a/src/server/game/Battlegrounds/Battleground.h b/src/server/game/Battlegrounds/Battleground.h
index a67be38be05..d04ff5171aa 100644
--- a/src/server/game/Battlegrounds/Battleground.h
+++ b/src/server/game/Battlegrounds/Battleground.h
@@ -481,8 +481,8 @@ class Battleground
void PlayerAddedToBGCheckIfBGIsRunning(Player* player);
Player* _GetPlayer(uint64 guid, bool offlineRemove, const char* context) const;
- Player* _GetPlayer(BattlegroundPlayerMap::iterator itr, const char* context) { return _GetPlayer(itr->first, itr->second.OfflineRemoveTime, context); }
- Player* _GetPlayer(BattlegroundPlayerMap::const_iterator itr, const char* context) const { return _GetPlayer(itr->first, itr->second.OfflineRemoveTime, context); }
+ Player* _GetPlayer(BattlegroundPlayerMap::iterator itr, const char* context) { return _GetPlayer(itr->first, itr->second.OfflineRemoveTime != 0, context); }
+ Player* _GetPlayer(BattlegroundPlayerMap::const_iterator itr, const char* context) const { return _GetPlayer(itr->first, itr->second.OfflineRemoveTime != 0, context); }
Player* _GetPlayerForTeam(uint32 teamId, BattlegroundPlayerMap::const_iterator itr, const char* context) const;
void _ProcessOfflineQueue();
diff --git a/src/server/game/Battlegrounds/BattlegroundMgr.cpp b/src/server/game/Battlegrounds/BattlegroundMgr.cpp
index 9a22052e17d..45111a80bc5 100644
--- a/src/server/game/Battlegrounds/BattlegroundMgr.cpp
+++ b/src/server/game/Battlegrounds/BattlegroundMgr.cpp
@@ -1077,12 +1077,8 @@ void BattlegroundMgr::ToggleArenaTesting()
void BattlegroundMgr::SetHolidayWeekends(uint32 mask)
{
for (uint32 bgtype = 1; bgtype < MAX_BATTLEGROUND_TYPE_ID; ++bgtype)
- {
if (Battleground* bg = GetBattlegroundTemplate(BattlegroundTypeId(bgtype)))
- {
- bg->SetHoliday(mask & (1 << bgtype));
- }
- }
+ bg->SetHoliday((mask & (1 << bgtype)) != 0);
}
void BattlegroundMgr::ScheduleQueueUpdate(uint32 arenaMatchmakerRating, uint8 arenaType, BattlegroundQueueTypeId bgQueueTypeId, BattlegroundTypeId bgTypeId, BattlegroundBracketId bracket_id)
diff --git a/src/server/game/Battlegrounds/BattlegroundMgr.h b/src/server/game/Battlegrounds/BattlegroundMgr.h
index fdef1b32993..ee7fd660851 100644
--- a/src/server/game/Battlegrounds/BattlegroundMgr.h
+++ b/src/server/game/Battlegrounds/BattlegroundMgr.h
@@ -23,7 +23,6 @@
#include "DBCEnums.h"
#include "Battleground.h"
#include "BattlegroundQueue.h"
-#include <ace/Singleton.h>
typedef std::map<uint32, Battleground*> BattlegroundContainer;
typedef std::set<uint32> BattlegroundClientIdsContainer;
@@ -57,13 +56,17 @@ struct BattlegroundTemplate
class BattlegroundMgr
{
- friend class ACE_Singleton<BattlegroundMgr, ACE_Null_Mutex>;
-
private:
BattlegroundMgr();
~BattlegroundMgr();
public:
+ static BattlegroundMgr* instance()
+ {
+ static BattlegroundMgr* instance = new BattlegroundMgr();
+ return instance;
+ }
+
void Update(uint32 diff);
/* Packet Building */
@@ -167,6 +170,6 @@ class BattlegroundMgr
BattlegroundMapTemplateContainer _battlegroundMapTemplates;
};
-#define sBattlegroundMgr ACE_Singleton<BattlegroundMgr, ACE_Null_Mutex>::instance()
+#define sBattlegroundMgr BattlegroundMgr::instance()
#endif // __BATTLEGROUNDMGR_H
diff --git a/src/server/game/Battlegrounds/BattlegroundQueue.cpp b/src/server/game/Battlegrounds/BattlegroundQueue.cpp
index 4b71f8f88b6..2b9713157c9 100644
--- a/src/server/game/Battlegrounds/BattlegroundQueue.cpp
+++ b/src/server/game/Battlegrounds/BattlegroundQueue.cpp
@@ -191,7 +191,6 @@ GroupQueueInfo* BattlegroundQueue::AddGroup(Player* leader, Group* grp, Battlegr
//add GroupInfo to m_QueuedGroups
{
- //ACE_Guard<ACE_Recursive_Thread_Mutex> guard(m_Lock);
m_QueuedGroups[bracketId][index].push_back(ginfo);
//announce to world, this code needs mutex
diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundRV.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundRV.cpp
index 9609009d610..284b05a8960 100644
--- a/src/server/game/Battlegrounds/Zones/BattlegroundRV.cpp
+++ b/src/server/game/Battlegrounds/Zones/BattlegroundRV.cpp
@@ -158,7 +158,7 @@ void BattlegroundRV::TogglePillarCollision()
{
if (i >= BG_RV_OBJECT_PILAR_COLLISION_1)
{
- GOState state = (bool(go->GetGOInfo()->door.startOpen) == _pillarCollision) ? GO_STATE_ACTIVE : GO_STATE_READY;
+ GOState state = ((go->GetGOInfo()->door.startOpen != 0) == _pillarCollision) ? GO_STATE_ACTIVE : GO_STATE_READY;
go->SetGoState(state);
}
diff --git a/src/server/game/CMakeLists.txt b/src/server/game/CMakeLists.txt
index 932b792c3bf..8e4ae9b5498 100644
--- a/src/server/game/CMakeLists.txt
+++ b/src/server/game/CMakeLists.txt
@@ -198,7 +198,6 @@ include_directories(
${CMAKE_CURRENT_SOURCE_DIR}/Weather
${CMAKE_CURRENT_SOURCE_DIR}/World
${CMAKE_SOURCE_DIR}/src/server/scripts/PrecompiledHeaders
- ${ACE_INCLUDE_DIR}
${MYSQL_INCLUDE_DIR}
${OPENSSL_INCLUDE_DIR}
)
diff --git a/src/server/game/Calendar/CalendarMgr.h b/src/server/game/Calendar/CalendarMgr.h
index eceeda62581..8d744988a76 100644
--- a/src/server/game/Calendar/CalendarMgr.h
+++ b/src/server/game/Calendar/CalendarMgr.h
@@ -18,7 +18,6 @@
#ifndef TRINITY_CALENDARMGR_H
#define TRINITY_CALENDARMGR_H
-#include <ace/Singleton.h>
#include "Common.h"
#include "DatabaseEnv.h"
#include "WorldPacket.h"
@@ -245,8 +244,8 @@ struct CalendarEvent
void SetTimeZoneTime(time_t timezoneTime) { _timezoneTime = timezoneTime; }
time_t GetTimeZoneTime() const { return _timezoneTime; }
- bool IsGuildEvent() const { return _flags & CALENDAR_FLAG_GUILD_EVENT; }
- bool IsGuildAnnouncement() const { return _flags & CALENDAR_FLAG_WITHOUT_INVITES; }
+ bool IsGuildEvent() const { return (_flags & CALENDAR_FLAG_GUILD_EVENT) != 0; }
+ bool IsGuildAnnouncement() const { return (_flags & CALENDAR_FLAG_WITHOUT_INVITES) != 0; }
std::string BuildCalendarMailSubject(uint64 remover) const;
std::string BuildCalendarMailBody() const;
@@ -269,8 +268,6 @@ typedef std::map<uint64 /* eventId */, CalendarInviteStore > CalendarEventInvite
class CalendarMgr
{
- friend class ACE_Singleton<CalendarMgr, ACE_Null_Mutex>;
-
private:
CalendarMgr();
~CalendarMgr();
@@ -284,6 +281,12 @@ class CalendarMgr
uint64 _maxInviteId;
public:
+ static CalendarMgr* instance()
+ {
+ static CalendarMgr* instance = new CalendarMgr();
+ return instance;
+ }
+
void LoadFromDB();
CalendarEvent* GetEvent(uint64 eventId) const;
@@ -330,6 +333,6 @@ class CalendarMgr
void SendPacketToAllEventRelatives(WorldPacket packet, CalendarEvent const& calendarEvent);
};
-#define sCalendarMgr ACE_Singleton<CalendarMgr, ACE_Null_Mutex>::instance()
+#define sCalendarMgr CalendarMgr::instance()
#endif
diff --git a/src/server/game/Chat/Channels/Channel.h b/src/server/game/Chat/Channels/Channel.h
index 115e340762e..877c1e826c9 100644
--- a/src/server/game/Chat/Channels/Channel.h
+++ b/src/server/game/Chat/Channels/Channel.h
@@ -125,21 +125,21 @@ class Channel
uint64 player;
uint8 flags;
- bool HasFlag(uint8 flag) const { return flags & flag; }
- void SetFlag(uint8 flag) { if (!HasFlag(flag)) flags |= flag; }
- bool IsOwner() const { return flags & MEMBER_FLAG_OWNER; }
+ bool HasFlag(uint8 flag) const { return (flags & flag) != 0; }
+ void SetFlag(uint8 flag) { flags |= flag; }
+ bool IsOwner() const { return (flags & MEMBER_FLAG_OWNER) != 0; }
void SetOwner(bool state)
{
if (state) flags |= MEMBER_FLAG_OWNER;
else flags &= ~MEMBER_FLAG_OWNER;
}
- bool IsModerator() const { return flags & MEMBER_FLAG_MODERATOR; }
+ bool IsModerator() const { return (flags & MEMBER_FLAG_MODERATOR) != 0; }
void SetModerator(bool state)
{
if (state) flags |= MEMBER_FLAG_MODERATOR;
else flags &= ~MEMBER_FLAG_MODERATOR;
}
- bool IsMuted() const { return flags & MEMBER_FLAG_MUTED; }
+ bool IsMuted() const { return (flags & MEMBER_FLAG_MUTED) != 0; }
void SetMuted(bool state)
{
if (state) flags |= MEMBER_FLAG_MUTED;
@@ -153,13 +153,13 @@ class Channel
uint32 GetChannelId() const { return _channelId; }
bool IsConstant() const { return _channelId != 0; }
bool IsAnnounce() const { return _announce; }
- bool IsLFG() const { return GetFlags() & CHANNEL_FLAG_LFG; }
+ bool IsLFG() const { return (GetFlags() & CHANNEL_FLAG_LFG) != 0; }
std::string const& GetPassword() const { return _password; }
void SetPassword(std::string const& npassword) { _password = npassword; }
void SetAnnounce(bool nannounce) { _announce = nannounce; }
uint32 GetNumPlayers() const { return playersStore.size(); }
uint8 GetFlags() const { return _flags; }
- bool HasFlag(uint8 flag) const { return _flags & flag; }
+ bool HasFlag(uint8 flag) const { return (_flags & flag) != 0; }
void JoinChannel(Player* player, std::string const& pass);
void LeaveChannel(Player* player, bool send = true);
diff --git a/src/server/game/Chat/Channels/ChannelMgr.cpp b/src/server/game/Chat/Channels/ChannelMgr.cpp
index 5926d67cbd5..366b0eee59f 100644
--- a/src/server/game/Chat/Channels/ChannelMgr.cpp
+++ b/src/server/game/Chat/Channels/ChannelMgr.cpp
@@ -30,13 +30,13 @@ ChannelMgr::~ChannelMgr()
ChannelMgr* ChannelMgr::forTeam(uint32 team)
{
if (sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_CHANNEL))
- return ACE_Singleton<AllianceChannelMgr, ACE_Null_Mutex>::instance(); // cross-faction
+ return AllianceChannelMgr::instance(); // cross-faction
if (team == ALLIANCE)
- return ACE_Singleton<AllianceChannelMgr, ACE_Null_Mutex>::instance();
+ return AllianceChannelMgr::instance();
if (team == HORDE)
- return ACE_Singleton<HordeChannelMgr, ACE_Null_Mutex>::instance();
+ return HordeChannelMgr::instance();
return NULL;
}
diff --git a/src/server/game/Chat/Channels/ChannelMgr.h b/src/server/game/Chat/Channels/ChannelMgr.h
index 603eb52f589..0fd5cdbfe24 100644
--- a/src/server/game/Chat/Channels/ChannelMgr.h
+++ b/src/server/game/Chat/Channels/ChannelMgr.h
@@ -20,7 +20,6 @@
#include "Common.h"
#include "Channel.h"
-#include <ace/Singleton.h>
#include <map>
#include <string>
@@ -31,12 +30,17 @@ class ChannelMgr
{
typedef std::map<std::wstring, Channel*> ChannelMap;
- public:
- ChannelMgr() : team(0)
- { }
-
+ protected:
+ ChannelMgr() : team(0) { }
~ChannelMgr();
+ public:
+ static ChannelMgr* instance()
+ {
+ static ChannelMgr* instance = new ChannelMgr();
+ return instance;
+ }
+
static ChannelMgr * forTeam(uint32 team);
void setTeam(uint32 newTeam) { team = newTeam; }
diff --git a/src/server/game/Combat/UnitEvents.h b/src/server/game/Combat/UnitEvents.h
index 50d4c3ad322..3377097a12e 100644
--- a/src/server/game/Combat/UnitEvents.h
+++ b/src/server/game/Combat/UnitEvents.h
@@ -74,7 +74,7 @@ class UnitBaseEvent
public:
UnitBaseEvent(uint32 pType) { iType = pType; }
uint32 getType() const { return iType; }
- bool matchesTypeMask(uint32 pMask) const { return iType & pMask; }
+ bool matchesTypeMask(uint32 pMask) const { return (iType & pMask) != 0; }
void setType(uint32 pType) { iType = pType; }
};
diff --git a/src/server/game/Conditions/ConditionMgr.cpp b/src/server/game/Conditions/ConditionMgr.cpp
index 0217363862e..04ceaefb0d5 100644
--- a/src/server/game/Conditions/ConditionMgr.cpp
+++ b/src/server/game/Conditions/ConditionMgr.cpp
@@ -78,7 +78,7 @@ bool Condition::Meets(ConditionSourceInfo& sourceInfo)
if (Player* player = object->ToPlayer())
{
if (FactionEntry const* faction = sFactionStore.LookupEntry(ConditionValue1))
- condMeets = (ConditionValue2 & (1 << player->GetReputationMgr().GetRank(faction)));
+ condMeets = (ConditionValue2 & (1 << player->GetReputationMgr().GetRank(faction))) != 0;
}
break;
}
@@ -97,13 +97,13 @@ bool Condition::Meets(ConditionSourceInfo& sourceInfo)
case CONDITION_CLASS:
{
if (Unit* unit = object->ToUnit())
- condMeets = unit->getClassMask() & ConditionValue1;
+ condMeets = (unit->getClassMask() & ConditionValue1) != 0;
break;
}
case CONDITION_RACE:
{
if (Unit* unit = object->ToUnit())
- condMeets = unit->getRaceMask() & ConditionValue1;
+ condMeets = (unit->getRaceMask() & ConditionValue1) != 0;
break;
}
case CONDITION_GENDER:
@@ -262,7 +262,7 @@ bool Condition::Meets(ConditionSourceInfo& sourceInfo)
Unit* toUnit = toObject->ToUnit();
Unit* unit = object->ToUnit();
if (toUnit && unit)
- condMeets = (1 << unit->GetReactionTo(toUnit)) & ConditionValue2;
+ condMeets = ((1 << unit->GetReactionTo(toUnit)) & ConditionValue2) != 0;
}
break;
}
@@ -308,7 +308,7 @@ bool Condition::Meets(ConditionSourceInfo& sourceInfo)
}
case CONDITION_SPAWNMASK:
{
- condMeets = ((1 << object->GetMap()->GetSpawnMode()) & ConditionValue1);
+ condMeets = ((1 << object->GetMap()->GetSpawnMode()) & ConditionValue1) != 0;
break;
}
case CONDITION_UNIT_STATE:
@@ -828,7 +828,7 @@ void ConditionMgr::LoadConditions(bool isReload)
cond->ConditionValue1 = fields[7].GetUInt32();
cond->ConditionValue2 = fields[8].GetUInt32();
cond->ConditionValue3 = fields[9].GetUInt32();
- cond->NegativeCondition = fields[10].GetUInt8();
+ cond->NegativeCondition = fields[10].GetBool();
cond->ErrorType = fields[11].GetUInt32();
cond->ErrorTextId = fields[12].GetUInt32();
cond->ScriptId = sObjectMgr->GetScriptId(fields[13].GetCString());
diff --git a/src/server/game/Conditions/ConditionMgr.h b/src/server/game/Conditions/ConditionMgr.h
index 35aa60772bd..f4130a3a619 100644
--- a/src/server/game/Conditions/ConditionMgr.h
+++ b/src/server/game/Conditions/ConditionMgr.h
@@ -21,7 +21,6 @@
#include "Define.h"
#include "Errors.h"
-#include <ace/Singleton.h>
#include <list>
#include <map>
@@ -224,13 +223,18 @@ typedef std::map<uint32, ConditionList> ConditionReferenceContainer;//only used
class ConditionMgr
{
- friend class ACE_Singleton<ConditionMgr, ACE_Null_Mutex>;
-
private:
ConditionMgr();
~ConditionMgr();
public:
+
+ static ConditionMgr* instance()
+ {
+ static ConditionMgr* instance = new ConditionMgr();
+ return instance;
+ }
+
void LoadConditions(bool isReload = false);
bool isConditionTypeValid(Condition* cond);
ConditionList GetConditionReferences(uint32 refId);
@@ -268,6 +272,6 @@ class ConditionMgr
PhaseDefinitionConditionContainer PhaseDefinitionsConditionStore;
};
-#define sConditionMgr ACE_Singleton<ConditionMgr, ACE_Null_Mutex>::instance()
+#define sConditionMgr ConditionMgr::instance()
#endif
diff --git a/src/server/game/Conditions/DisableMgr.cpp b/src/server/game/Conditions/DisableMgr.cpp
index b29959cac50..3f325be1e83 100644
--- a/src/server/game/Conditions/DisableMgr.cpp
+++ b/src/server/game/Conditions/DisableMgr.cpp
@@ -339,7 +339,7 @@ bool IsDisabledFor(DisableType type, uint32 entry, Unit const* unit, uint8 flags
else if (spellFlags & SPELL_DISABLE_DEPRECATED_SPELL) // call not from spellcast
return true;
else if (flags & SPELL_DISABLE_LOS)
- return spellFlags & SPELL_DISABLE_LOS;
+ return (spellFlags & SPELL_DISABLE_LOS) != 0;
break;
}
@@ -355,13 +355,13 @@ bool IsDisabledFor(DisableType type, uint32 entry, Unit const* unit, uint8 flags
switch (targetDifficulty)
{
case DUNGEON_DIFFICULTY_NORMAL:
- return disabledModes & DUNGEON_STATUSFLAG_NORMAL;
+ return (disabledModes & DUNGEON_STATUSFLAG_NORMAL) != 0;
case DUNGEON_DIFFICULTY_HEROIC:
- return disabledModes & DUNGEON_STATUSFLAG_HEROIC;
+ return (disabledModes & DUNGEON_STATUSFLAG_HEROIC) != 0;
case RAID_DIFFICULTY_10MAN_HEROIC:
- return disabledModes & RAID_STATUSFLAG_10MAN_HEROIC;
+ return (disabledModes & RAID_STATUSFLAG_10MAN_HEROIC) != 0;
case RAID_DIFFICULTY_25MAN_HEROIC:
- return disabledModes & RAID_STATUSFLAG_25MAN_HEROIC;
+ return (disabledModes & RAID_STATUSFLAG_25MAN_HEROIC) != 0;
}
}
else if (mapEntry->map_type == MAP_COMMON)
@@ -381,7 +381,7 @@ bool IsDisabledFor(DisableType type, uint32 entry, Unit const* unit, uint8 flags
case DISABLE_TYPE_MMAP:
return true;
case DISABLE_TYPE_VMAP:
- return flags & itr->second.flags;
+ return (flags & itr->second.flags) != 0;
}
return false;
diff --git a/src/server/game/DataStores/DBCStructure.h b/src/server/game/DataStores/DBCStructure.h
index cc1cc20d3ce..001392aee4c 100644
--- a/src/server/game/DataStores/DBCStructure.h
+++ b/src/server/game/DataStores/DBCStructure.h
@@ -563,7 +563,7 @@ struct AreaTableEntry
{
if (mapid == 609)
return true;
- return (flags & AREA_FLAG_SANCTUARY);
+ return (flags & AREA_FLAG_SANCTUARY) != 0;
}
};
@@ -1534,7 +1534,7 @@ struct MapEntry
return MapID == 0 || MapID == 1 || MapID == 530 || MapID == 571;
}
- bool IsDynamicDifficultyMap() const { return Flags & MAP_FLAG_DYNAMIC_DIFFICULTY; }
+ bool IsDynamicDifficultyMap() const { return (Flags & MAP_FLAG_DYNAMIC_DIFFICULTY) != 0; }
};
struct MapDifficultyEntry
@@ -2356,12 +2356,12 @@ struct VehicleSeatEntry
uint32 m_flagsB; // 45
// 46-57 added in 3.1, floats mostly
- bool CanEnterOrExit() const { return m_flags & VEHICLE_SEAT_FLAG_CAN_ENTER_OR_EXIT; }
- bool CanSwitchFromSeat() const { return m_flags & VEHICLE_SEAT_FLAG_CAN_SWITCH; }
+ bool CanEnterOrExit() const { return (m_flags & VEHICLE_SEAT_FLAG_CAN_ENTER_OR_EXIT) != 0; }
+ bool CanSwitchFromSeat() const { return (m_flags & VEHICLE_SEAT_FLAG_CAN_SWITCH) != 0; }
bool IsUsableByOverride() const { return (m_flags & (VEHICLE_SEAT_FLAG_UNCONTROLLED | VEHICLE_SEAT_FLAG_UNK18)
|| (m_flagsB & (VEHICLE_SEAT_FLAG_B_USABLE_FORCED | VEHICLE_SEAT_FLAG_B_USABLE_FORCED_2 |
VEHICLE_SEAT_FLAG_B_USABLE_FORCED_3 | VEHICLE_SEAT_FLAG_B_USABLE_FORCED_4))); }
- bool IsEjectable() const { return m_flagsB & VEHICLE_SEAT_FLAG_B_EJECTABLE; }
+ bool IsEjectable() const { return (m_flagsB & VEHICLE_SEAT_FLAG_B_EJECTABLE) != 0; }
};
struct WMOAreaTableEntry
diff --git a/src/server/game/DungeonFinding/LFGMgr.cpp b/src/server/game/DungeonFinding/LFGMgr.cpp
index e0adbb6c6a2..0efc7fd6230 100644
--- a/src/server/game/DungeonFinding/LFGMgr.cpp
+++ b/src/server/game/DungeonFinding/LFGMgr.cpp
@@ -1879,7 +1879,7 @@ void LFGMgr::Clean()
bool LFGMgr::isOptionEnabled(uint32 option)
{
- return m_options & option;
+ return (m_options & option) != 0;
}
uint32 LFGMgr::GetOptions()
diff --git a/src/server/game/DungeonFinding/LFGMgr.h b/src/server/game/DungeonFinding/LFGMgr.h
index bca19a6b627..c42777c494c 100644
--- a/src/server/game/DungeonFinding/LFGMgr.h
+++ b/src/server/game/DungeonFinding/LFGMgr.h
@@ -18,7 +18,6 @@
#ifndef _LFGMGR_H
#define _LFGMGR_H
-#include <ace/Singleton.h>
#include "DBCStructure.h"
#include "Field.h"
#include "LFG.h"
@@ -275,7 +274,7 @@ struct LFGDungeonData
LFGDungeonData(LFGDungeonEntry const* dbc): id(dbc->ID), name(dbc->name), map(dbc->map),
type(dbc->type), expansion(dbc->expansion), group(dbc->grouptype),
minlevel(dbc->minlevel), maxlevel(dbc->maxlevel), difficulty(Difficulty(dbc->difficulty)),
- seasonal(dbc->flags & LFG_FLAG_SEASONAL), x(0.0f), y(0.0f), z(0.0f), o(0.0f),
+ seasonal((dbc->flags & LFG_FLAG_SEASONAL) != 0), x(0.0f), y(0.0f), z(0.0f), o(0.0f),
requiredItemLevel(0)
{ }
@@ -298,13 +297,17 @@ struct LFGDungeonData
class LFGMgr
{
- friend class ACE_Singleton<LFGMgr, ACE_Null_Mutex>;
-
private:
LFGMgr();
~LFGMgr();
public:
+ static LFGMgr* instance()
+ {
+ static LFGMgr* instance = new LFGMgr();
+ return instance;
+ }
+
// Functions used outside lfg namespace
void Update(uint32 diff);
@@ -476,5 +479,5 @@ class LFGMgr
} // namespace lfg
-#define sLFGMgr ACE_Singleton<lfg::LFGMgr, ACE_Null_Mutex>::instance()
+#define sLFGMgr lfg::LFGMgr::instance()
#endif
diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp
index 020727970ff..992894a1a3c 100644
--- a/src/server/game/Entities/Creature/Creature.cpp
+++ b/src/server/game/Entities/Creature/Creature.cpp
@@ -1658,7 +1658,7 @@ bool Creature::isWorldBoss() const
if (IsPet())
return false;
- return GetCreatureTemplate()->type_flags & CREATURE_TYPEFLAGS_BOSS;
+ return (GetCreatureTemplate()->type_flags & CREATURE_TYPEFLAGS_BOSS) != 0;
}
SpellInfo const* Creature::reachWithSpellAttack(Unit* victim)
diff --git a/src/server/game/Entities/Creature/Creature.h b/src/server/game/Entities/Creature/Creature.h
index 991f37d604d..f5a0abfc469 100644
--- a/src/server/game/Entities/Creature/Creature.h
+++ b/src/server/game/Entities/Creature/Creature.h
@@ -457,12 +457,12 @@ class Creature : public Unit, public GridObject<Creature>, public MapObject
void SetCorpseDelay(uint32 delay) { m_corpseDelay = delay; }
uint32 GetCorpseDelay() const { return m_corpseDelay; }
bool IsRacialLeader() const { return GetCreatureTemplate()->RacialLeader; }
- bool IsCivilian() const { return GetCreatureTemplate()->flags_extra & CREATURE_FLAG_EXTRA_CIVILIAN; }
- bool IsTrigger() const { return GetCreatureTemplate()->flags_extra & CREATURE_FLAG_EXTRA_TRIGGER; }
- bool IsGuard() const { return GetCreatureTemplate()->flags_extra & CREATURE_FLAG_EXTRA_GUARD; }
- bool CanWalk() const { return GetCreatureTemplate()->InhabitType & INHABIT_GROUND; }
- bool CanSwim() const { return GetCreatureTemplate()->InhabitType & INHABIT_WATER || IsPet(); }
- bool CanFly() const { return GetCreatureTemplate()->InhabitType & INHABIT_AIR; }
+ bool IsCivilian() const { return (GetCreatureTemplate()->flags_extra & CREATURE_FLAG_EXTRA_CIVILIAN) != 0; }
+ bool IsTrigger() const { return (GetCreatureTemplate()->flags_extra & CREATURE_FLAG_EXTRA_TRIGGER) != 0; }
+ bool IsGuard() const { return (GetCreatureTemplate()->flags_extra & CREATURE_FLAG_EXTRA_GUARD) != 0; }
+ bool CanWalk() const { return (GetCreatureTemplate()->InhabitType & INHABIT_GROUND) != 0; }
+ bool CanSwim() const { return (GetCreatureTemplate()->InhabitType & INHABIT_WATER) != 0 || IsPet(); }
+ bool CanFly() const { return (GetCreatureTemplate()->InhabitType & INHABIT_AIR) != 0; }
void SetReactState(ReactStates st) { m_reactState = st; }
ReactStates GetReactState() { return m_reactState; }
@@ -562,7 +562,7 @@ class Creature : public Unit, public GridObject<Creature>, public MapObject
void AllLootRemovedFromCorpse();
uint16 GetLootMode() { return m_LootMode; }
- bool HasLootMode(uint16 lootMode) { return m_LootMode & lootMode; }
+ bool HasLootMode(uint16 lootMode) { return (m_LootMode & lootMode) != 0; }
void SetLootMode(uint16 lootMode) { m_LootMode = lootMode; }
void AddLootMode(uint16 lootMode) { m_LootMode |= lootMode; }
void RemoveLootMode(uint16 lootMode) { m_LootMode &= ~lootMode; }
diff --git a/src/server/game/Entities/Creature/CreatureGroups.h b/src/server/game/Entities/Creature/CreatureGroups.h
index b790853f5e1..29832e4ff76 100644
--- a/src/server/game/Entities/Creature/CreatureGroups.h
+++ b/src/server/game/Entities/Creature/CreatureGroups.h
@@ -40,10 +40,17 @@ typedef std::unordered_map<uint32/*memberDBGUID*/, FormationInfo*> CreatureGro
class FormationMgr
{
- friend class ACE_Singleton<FormationMgr, ACE_Null_Mutex>;
- public:
+ private:
FormationMgr() { }
~FormationMgr();
+
+ public:
+ static FormationMgr* instance()
+ {
+ static FormationMgr* instance = new FormationMgr();
+ return instance;
+ }
+
void AddCreatureToGroup(uint32 group_id, Creature* creature);
void RemoveCreatureFromGroup(CreatureGroup* group, Creature* creature);
void LoadCreatureFormations();
@@ -78,6 +85,6 @@ class CreatureGroup
void MemberAttackStart(Creature* member, Unit* target);
};
-#define sFormationMgr ACE_Singleton<FormationMgr, ACE_Null_Mutex>::instance()
+#define sFormationMgr FormationMgr::instance()
#endif
diff --git a/src/server/game/Entities/GameObject/GameObject.h b/src/server/game/Entities/GameObject/GameObject.h
index 123c5e3bebe..09c84c71244 100644
--- a/src/server/game/Entities/GameObject/GameObject.h
+++ b/src/server/game/Entities/GameObject/GameObject.h
@@ -407,8 +407,8 @@ struct GameObjectTemplate
{
switch (type)
{
- case GAMEOBJECT_TYPE_CHEST: return chest.consumable;
- case GAMEOBJECT_TYPE_GOOBER: return goober.consumable;
+ case GAMEOBJECT_TYPE_CHEST: return chest.consumable != 0;
+ case GAMEOBJECT_TYPE_GOOBER: return goober.consumable != 0;
default: return false;
}
}
@@ -417,10 +417,10 @@ struct GameObjectTemplate
{
switch (type)
{
- case GAMEOBJECT_TYPE_QUESTGIVER: return questgiver.allowMounted;
- case GAMEOBJECT_TYPE_TEXT: return text.allowMounted;
- case GAMEOBJECT_TYPE_GOOBER: return goober.allowMounted;
- case GAMEOBJECT_TYPE_SPELLCASTER: return spellcaster.allowMounted;
+ case GAMEOBJECT_TYPE_QUESTGIVER: return questgiver.allowMounted != 0;
+ case GAMEOBJECT_TYPE_TEXT: return text.allowMounted != 0;
+ case GAMEOBJECT_TYPE_GOOBER: return goober.allowMounted != 0;
+ case GAMEOBJECT_TYPE_SPELLCASTER: return spellcaster.allowMounted != 0;
default: return false;
}
}
@@ -448,12 +448,12 @@ struct GameObjectTemplate
{
switch (type)
{
- case GAMEOBJECT_TYPE_DOOR: return door.noDamageImmune;
- case GAMEOBJECT_TYPE_BUTTON: return button.noDamageImmune;
- case GAMEOBJECT_TYPE_QUESTGIVER: return questgiver.noDamageImmune;
- case GAMEOBJECT_TYPE_GOOBER: return goober.noDamageImmune;
- case GAMEOBJECT_TYPE_FLAGSTAND: return flagstand.noDamageImmune;
- case GAMEOBJECT_TYPE_FLAGDROP: return flagdrop.noDamageImmune;
+ case GAMEOBJECT_TYPE_DOOR: return door.noDamageImmune != 0;
+ case GAMEOBJECT_TYPE_BUTTON: return button.noDamageImmune != 0;
+ case GAMEOBJECT_TYPE_QUESTGIVER: return questgiver.noDamageImmune != 0;
+ case GAMEOBJECT_TYPE_GOOBER: return goober.noDamageImmune != 0;
+ case GAMEOBJECT_TYPE_FLAGSTAND: return flagstand.noDamageImmune != 0;
+ case GAMEOBJECT_TYPE_FLAGDROP: return flagdrop.noDamageImmune != 0;
default: return true;
}
}
@@ -737,7 +737,7 @@ class GameObject : public WorldObject, public GridObject<GameObject>, public Map
void SetLootState(LootState s, Unit* unit = NULL);
uint16 GetLootMode() { return m_LootMode; }
- bool HasLootMode(uint16 lootMode) { return m_LootMode & lootMode; }
+ bool HasLootMode(uint16 lootMode) { return (m_LootMode & lootMode) != 0; }
void SetLootMode(uint16 lootMode) { m_LootMode = lootMode; }
void AddLootMode(uint16 lootMode) { m_LootMode |= lootMode; }
void RemoveLootMode(uint16 lootMode) { m_LootMode &= ~lootMode; }
diff --git a/src/server/game/Entities/Item/Item.cpp b/src/server/game/Entities/Item/Item.cpp
index 2c12c82b80a..dcf534690db 100644
--- a/src/server/game/Entities/Item/Item.cpp
+++ b/src/server/game/Entities/Item/Item.cpp
@@ -315,7 +315,7 @@ void Item::UpdateDuration(Player* owner, uint32 diff)
void Item::SaveToDB(SQLTransaction& trans)
{
- bool isInTransaction = !(trans.null());
+ bool isInTransaction = bool(trans);
if (!isInTransaction)
trans = CharacterDatabase.BeginTransaction();
@@ -1110,7 +1110,7 @@ void Item::SaveRefundDataToDB()
void Item::DeleteRefundDataFromDB(SQLTransaction* trans)
{
- if (trans && !trans->null())
+ if (trans)
{
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_ITEM_REFUND_INSTANCE);
stmt->setUInt32(0, GetGUIDLow());
diff --git a/src/server/game/Entities/Item/ItemPrototype.h b/src/server/game/Entities/Item/ItemPrototype.h
index b4357d4a1a1..e470afac1ab 100644
--- a/src/server/game/Entities/Item/ItemPrototype.h
+++ b/src/server/game/Entities/Item/ItemPrototype.h
@@ -724,7 +724,7 @@ struct ItemTemplate
return false;
}
- bool IsCurrencyToken() const { return BagFamily & BAG_FAMILY_MASK_CURRENCY_TOKENS; }
+ bool IsCurrencyToken() const { return (BagFamily & BAG_FAMILY_MASK_CURRENCY_TOKENS) != 0; }
uint32 GetMaxStackSize() const
{
diff --git a/src/server/game/Entities/Object/Object.h b/src/server/game/Entities/Object/Object.h
index 2d7a6f12016..cefe482c585 100644
--- a/src/server/game/Entities/Object/Object.h
+++ b/src/server/game/Entities/Object/Object.h
@@ -198,7 +198,7 @@ class Object
virtual void SetObjectScale(float scale) { SetFloatValue(OBJECT_FIELD_SCALE_X, scale); }
TypeID GetTypeId() const { return m_objectTypeId; }
- bool isType(uint16 mask) const { return (mask & m_objectType); }
+ bool isType(uint16 mask) const { return (mask & m_objectType) != 0; }
virtual void BuildCreateUpdateBlockForPlayer(UpdateData* data, Player* target) const;
void SendUpdateToPlayer(Player* player);
@@ -530,13 +530,13 @@ struct MovementInfo
void SetMovementFlags(uint32 flag) { flags = flag; }
void AddMovementFlag(uint32 flag) { flags |= flag; }
void RemoveMovementFlag(uint32 flag) { flags &= ~flag; }
- bool HasMovementFlag(uint32 flag) const { return flags & flag; }
+ bool HasMovementFlag(uint32 flag) const { return (flags & flag) != 0; }
uint16 GetExtraMovementFlags() const { return flags2; }
void SetExtraMovementFlags(uint16 flag) { flags2 = flag; }
void AddExtraMovementFlag(uint16 flag) { flags2 |= flag; }
void RemoveExtraMovementFlag(uint16 flag) { flags2 &= ~flag; }
- bool HasExtraMovementFlag(uint16 flag) const { return flags2 & flag; }
+ bool HasExtraMovementFlag(uint16 flag) const { return (flags2 & flag) != 0; }
void SetFallTime(uint32 time) { jump.fallTime = time; }
@@ -679,7 +679,7 @@ class WorldObject : public Object, public WorldLocation
virtual void SetInPhase(uint32 id, bool update, bool apply);
uint32 GetPhaseMask() const { return m_phaseMask; }
bool InSamePhase(WorldObject const* obj) const;
- bool InSamePhase(uint32 phasemask) const { return (GetPhaseMask() & phasemask); }
+ bool InSamePhase(uint32 phasemask) const { return (GetPhaseMask() & phasemask) != 0; }
bool IsInPhase(uint32 phase) const { return _phases.find(phase) != _phases.end(); }
bool IsInPhase(WorldObject const* obj) const;
std::set<uint32> const& GetPhases() const { return _phases; }
@@ -795,9 +795,9 @@ class WorldObject : public Object, public WorldLocation
//relocation and visibility system functions
void AddToNotify(uint16 f) { m_notifyflags |= f;}
- bool isNeedNotify(uint16 f) const { return m_notifyflags & f;}
+ bool isNeedNotify(uint16 f) const { return (m_notifyflags & f) != 0; }
uint16 GetNotifyFlags() const { return m_notifyflags; }
- bool NotifyExecuted(uint16 f) const { return m_executed_notifies & f;}
+ bool NotifyExecuted(uint16 f) const { return (m_executed_notifies & f) != 0; }
void SetNotified(uint16 f) { m_executed_notifies |= f;}
void ResetAllNotifies() { m_notifyflags = 0; m_executed_notifies = 0; }
diff --git a/src/server/game/Entities/Pet/Pet.cpp b/src/server/game/Entities/Pet/Pet.cpp
index 91c1aa52592..5c731c6f8f7 100644
--- a/src/server/game/Entities/Pet/Pet.cpp
+++ b/src/server/game/Entities/Pet/Pet.cpp
@@ -1050,7 +1050,7 @@ bool Pet::HaveInDiet(ItemTemplate const* item) const
uint32 diet = cFamily->petFoodMask;
uint32 FoodMask = 1 << (item->FoodType-1);
- return diet & FoodMask;
+ return (diet & FoodMask) != 0;
}
uint32 Pet::GetCurrentFoodBenefitLevel(uint32 itemlevel) const
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index 35d3267605a..241bc452706 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -3851,7 +3851,7 @@ bool Player::AddSpell(uint32 spellId, bool active, bool learning, bool dependent
if (spellInfo->IsPrimaryProfessionFirstRank())
SetFreePrimaryProfessions(freeProfs-1);
}
-
+
SkillLineAbilityMapBounds skill_bounds = sSpellMgr->GetSkillLineAbilityMapBounds(spellId);
// add dependent skills if this spell is not learned from adding skill already
@@ -20004,7 +20004,7 @@ void Player::_SaveMail(SQLTransaction& trans)
void Player::_SaveQuestStatus(SQLTransaction& trans)
{
- bool isTransaction = !trans.null();
+ bool isTransaction = bool(trans);
if (!isTransaction)
trans = CharacterDatabase.BeginTransaction();
@@ -24663,7 +24663,7 @@ uint32 Player::GetCorpseReclaimDelay(bool pvp) const
void Player::UpdateCorpseReclaimDelay()
{
- bool pvp = m_ExtraFlags & PLAYER_EXTRA_PVP_DEATH;
+ bool pvp = (m_ExtraFlags & PLAYER_EXTRA_PVP_DEATH) != 0;
if ((pvp && !sWorld->getBoolConfig(CONFIG_DEATH_CORPSE_RECLAIM_DELAY_PVP)) ||
(!pvp && !sWorld->getBoolConfig(CONFIG_DEATH_CORPSE_RECLAIM_DELAY_PVE)))
@@ -24692,7 +24692,7 @@ int32 Player::CalculateCorpseReclaimDelay(bool load)
if (load && !corpse)
return -1;
- bool pvp = corpse ? corpse->GetType() == CORPSE_RESURRECTABLE_PVP : m_ExtraFlags & PLAYER_EXTRA_PVP_DEATH;
+ bool pvp = corpse ? corpse->GetType() == CORPSE_RESURRECTABLE_PVP : (m_ExtraFlags & PLAYER_EXTRA_PVP_DEATH) != 0;
uint32 delay;
diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h
index d54b9aa9a65..9d1dbcc9215 100644
--- a/src/server/game/Entities/Player/Player.h
+++ b/src/server/game/Entities/Player/Player.h
@@ -1290,13 +1290,13 @@ class Player : public Unit, public GridObject<Player>
void CleanupAfterTaxiFlight();
void ContinueTaxiFlight();
// mount_id can be used in scripting calls
- bool isAcceptWhispers() const { return m_ExtraFlags & PLAYER_EXTRA_ACCEPT_WHISPERS; }
+ bool isAcceptWhispers() const { return (m_ExtraFlags & PLAYER_EXTRA_ACCEPT_WHISPERS) != 0; }
void SetAcceptWhispers(bool on) { if (on) m_ExtraFlags |= PLAYER_EXTRA_ACCEPT_WHISPERS; else m_ExtraFlags &= ~PLAYER_EXTRA_ACCEPT_WHISPERS; }
- bool IsGameMaster() const { return m_ExtraFlags & PLAYER_EXTRA_GM_ON; }
+ bool IsGameMaster() const { return (m_ExtraFlags & PLAYER_EXTRA_GM_ON) != 0; }
void SetGameMaster(bool on);
- bool isGMChat() const { return m_ExtraFlags & PLAYER_EXTRA_GM_CHAT; }
+ bool isGMChat() const { return (m_ExtraFlags & PLAYER_EXTRA_GM_CHAT) != 0; }
void SetGMChat(bool on) { if (on) m_ExtraFlags |= PLAYER_EXTRA_GM_CHAT; else m_ExtraFlags &= ~PLAYER_EXTRA_GM_CHAT; }
- bool isTaxiCheater() const { return m_ExtraFlags & PLAYER_EXTRA_TAXICHEAT; }
+ bool isTaxiCheater() const { return (m_ExtraFlags & PLAYER_EXTRA_TAXICHEAT) != 0; }
void SetTaxiCheater(bool on) { if (on) m_ExtraFlags |= PLAYER_EXTRA_TAXICHEAT; else m_ExtraFlags &= ~PLAYER_EXTRA_TAXICHEAT; }
bool isGMVisible() const { return !(m_ExtraFlags & PLAYER_EXTRA_GM_INVISIBLE); }
void SetGMVisible(bool on);
@@ -1308,7 +1308,7 @@ class Player : public Unit, public GridObject<Player>
void InitStatsForLevel(bool reapplyMods = false);
// .cheat command related
- bool GetCommandStatus(uint32 command) const { return _activeCheats & command; }
+ bool GetCommandStatus(uint32 command) const { return (_activeCheats & command) != 0; }
void SetCommandStatusOn(uint32 command) { _activeCheats |= command; }
void SetCommandStatusOff(uint32 command) { _activeCheats &= ~command; }
@@ -2377,7 +2377,7 @@ class Player : public Unit, public GridObject<Player>
uint8 m_forced_speed_changes[MAX_MOVE_TYPE];
- bool HasAtLoginFlag(AtLoginFlags f) const { return m_atLoginFlags & f; }
+ bool HasAtLoginFlag(AtLoginFlags f) const { return (m_atLoginFlags & f) != 0; }
void SetAtLoginFlag(AtLoginFlags f) { m_atLoginFlags |= f; }
void RemoveAtLoginFlag(AtLoginFlags flags, bool persist = false);
diff --git a/src/server/game/Entities/Player/SocialMgr.cpp b/src/server/game/Entities/Player/SocialMgr.cpp
index 6e593951f2c..c351aeac482 100644
--- a/src/server/game/Entities/Player/SocialMgr.cpp
+++ b/src/server/game/Entities/Player/SocialMgr.cpp
@@ -188,7 +188,7 @@ bool PlayerSocial::HasIgnore(uint32 ignore_guid)
{
PlayerSocialMap::const_iterator itr = m_playerSocialMap.find(ignore_guid);
if (itr != m_playerSocialMap.end())
- return itr->second.Flags & SOCIAL_FLAG_IGNORED;
+ return (itr->second.Flags & SOCIAL_FLAG_IGNORED) != 0;
return false;
}
diff --git a/src/server/game/Entities/Player/SocialMgr.h b/src/server/game/Entities/Player/SocialMgr.h
index 910c9164738..68c25fbf648 100644
--- a/src/server/game/Entities/Player/SocialMgr.h
+++ b/src/server/game/Entities/Player/SocialMgr.h
@@ -19,7 +19,6 @@
#ifndef __TRINITY_SOCIALMGR_H
#define __TRINITY_SOCIALMGR_H
-#include <ace/Singleton.h>
#include "DatabaseEnv.h"
#include "Common.h"
@@ -123,13 +122,17 @@ class PlayerSocial
class SocialMgr
{
- friend class ACE_Singleton<SocialMgr, ACE_Null_Mutex>;
-
private:
SocialMgr();
~SocialMgr();
public:
+ static SocialMgr* instance()
+ {
+ static SocialMgr* instance = new SocialMgr();
+ return instance;
+ }
+
// Misc
void RemovePlayerSocial(uint32 guid) { m_socialMap.erase(guid); }
@@ -144,5 +147,5 @@ class SocialMgr
SocialMap m_socialMap;
};
-#define sSocialMgr ACE_Singleton<SocialMgr, ACE_Null_Mutex>::instance()
+#define sSocialMgr SocialMgr::instance()
#endif
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
index da721cfc575..8a32f629513 100644
--- a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -363,7 +363,7 @@ void Unit::Update(uint32 p_time)
bool Unit::haveOffhandWeapon() const
{
if (Player const* player = ToPlayer())
- return player->GetWeaponForAttack(OFF_ATTACK, true);
+ return player->GetWeaponForAttack(OFF_ATTACK, true) != nullptr;
return CanDualWield();
}
@@ -2236,7 +2236,7 @@ SpellMissInfo Unit::MeleeSpellHitResult(Unit* victim, SpellInfo const* spellInfo
bool canDodge = true;
bool canParry = true;
- bool canBlock = spellInfo->AttributesEx3 & SPELL_ATTR3_BLOCKABLE_SPELL;
+ bool canBlock = (spellInfo->AttributesEx3 & SPELL_ATTR3_BLOCKABLE_SPELL) != 0;
// Same spells cannot be parry/dodge
if (spellInfo->Attributes & SPELL_ATTR0_IMPOSSIBLE_DODGE_PARRY_BLOCK)
@@ -3553,7 +3553,7 @@ void Unit::RemoveAurasDueToSpellBySteal(uint32 spellId, uint64 casterGUID, Unit*
}
}
- bool stealCharge = aura->GetSpellInfo()->AttributesEx7 & SPELL_ATTR7_DISPEL_CHARGES;
+ bool stealCharge = (aura->GetSpellInfo()->AttributesEx7 & SPELL_ATTR7_DISPEL_CHARGES) != 0;
// Cast duration to unsigned to prevent permanent aura's such as Righteous Fury being permanently added to caster
uint32 dur = std::min(2u * MINUTE * IN_MILLISECONDS, uint32(aura->GetDuration()));
@@ -4075,7 +4075,7 @@ void Unit::GetDispellableAuraList(Unit* caster, uint32 dispelMask, DispelCharges
// The charges / stack amounts don't count towards the total number of auras that can be dispelled.
// Ie: A dispel on a target with 5 stacks of Winters Chill and a Polymorph has 1 / (1 + 1) -> 50% chance to dispell
// Polymorph instead of 1 / (5 + 1) -> 16%.
- bool dispel_charges = aura->GetSpellInfo()->AttributesEx7 & SPELL_ATTR7_DISPEL_CHARGES;
+ bool dispel_charges = (aura->GetSpellInfo()->AttributesEx7 & SPELL_ATTR7_DISPEL_CHARGES) != 0;
uint8 charges = dispel_charges ? aura->GetCharges() : aura->GetStackAmount();
if (charges > 0)
dispelList.push_back(std::make_pair(aura, charges));
@@ -13614,7 +13614,7 @@ void Unit::Kill(Unit* victim, bool durabilityLoss)
if (group)
{
- group->BroadcastPacket(&data, group->GetMemberGroup(player->GetGUID()));
+ group->BroadcastPacket(&data, group->GetMemberGroup(player->GetGUID()) != 0);
if (creature)
{
diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h
index eb0882e3b64..035c3a6aa0e 100644
--- a/src/server/game/Entities/Unit/Unit.h
+++ b/src/server/game/Entities/Unit/Unit.h
@@ -1360,18 +1360,18 @@ class Unit : public WorldObject
void SendMeleeAttackStart(Unit* victim);
void AddUnitState(uint32 f) { m_state |= f; }
- bool HasUnitState(const uint32 f) const { return (m_state & f); }
+ bool HasUnitState(const uint32 f) const { return (m_state & f) != 0; }
void ClearUnitState(uint32 f) { m_state &= ~f; }
bool CanFreeMove() const;
uint32 HasUnitTypeMask(uint32 mask) const { return mask & m_unitTypeMask; }
void AddUnitTypeMask(uint32 mask) { m_unitTypeMask |= mask; }
- bool IsSummon() const { return m_unitTypeMask & UNIT_MASK_SUMMON; }
- bool IsGuardian() const { return m_unitTypeMask & UNIT_MASK_GUARDIAN; }
- bool IsPet() const { return m_unitTypeMask & UNIT_MASK_PET; }
- bool IsHunterPet() const{ return m_unitTypeMask & UNIT_MASK_HUNTER_PET; }
- bool IsTotem() const { return m_unitTypeMask & UNIT_MASK_TOTEM; }
- bool IsVehicle() const { return m_unitTypeMask & UNIT_MASK_VEHICLE; }
+ bool IsSummon() const { return (m_unitTypeMask & UNIT_MASK_SUMMON) != 0; }
+ bool IsGuardian() const { return (m_unitTypeMask & UNIT_MASK_GUARDIAN) != 0; }
+ bool IsPet() const { return (m_unitTypeMask & UNIT_MASK_PET) != 0; }
+ bool IsHunterPet() const{ return (m_unitTypeMask & UNIT_MASK_HUNTER_PET) != 0; }
+ bool IsTotem() const { return (m_unitTypeMask & UNIT_MASK_TOTEM) != 0; }
+ bool IsVehicle() const { return (m_unitTypeMask & UNIT_MASK_VEHICLE) != 0; }
uint8 getLevel() const { return uint8(GetUInt32Value(UNIT_FIELD_LEVEL)); }
uint8 getLevelForTarget(WorldObject const* /*target*/) const { return getLevel(); }
diff --git a/src/server/game/Entities/Vehicle/VehicleDefines.h b/src/server/game/Entities/Vehicle/VehicleDefines.h
index 2c466255dc0..2a800008e8b 100644
--- a/src/server/game/Entities/Vehicle/VehicleDefines.h
+++ b/src/server/game/Entities/Vehicle/VehicleDefines.h
@@ -105,7 +105,7 @@ struct VehicleAccessory
VehicleAccessory(uint32 entry, int8 seatId, bool isMinion, uint8 summonType, uint32 summonTime) :
AccessoryEntry(entry), IsMinion(isMinion), SummonTime(summonTime), SeatId(seatId), SummonedType(summonType) { }
uint32 AccessoryEntry;
- uint32 IsMinion;
+ bool IsMinion;
uint32 SummonTime;
int8 SeatId;
uint8 SummonedType;
diff --git a/src/server/game/Events/GameEventMgr.cpp b/src/server/game/Events/GameEventMgr.cpp
index 175524d7208..217919ff574 100644
--- a/src/server/game/Events/GameEventMgr.cpp
+++ b/src/server/game/Events/GameEventMgr.cpp
@@ -1164,7 +1164,7 @@ void GameEventMgr::GameEventSpawn(int16 event_id)
if (internal_event_id < 0 || internal_event_id >= int32(mGameEventCreatureGuids.size()))
{
- TC_LOG_ERROR("gameevent", "GameEventMgr::GameEventSpawn attempt access to out of range mGameEventCreatureGuids element %i (size: " SIZEFMTD ")",
+ TC_LOG_ERROR("gameevent", "GameEventMgr::GameEventSpawn attempt access to out of range mGameEventCreatureGuids element %i (size: %zu)",
internal_event_id, mGameEventCreatureGuids.size());
return;
}
@@ -1191,7 +1191,7 @@ void GameEventMgr::GameEventSpawn(int16 event_id)
if (internal_event_id < 0 || internal_event_id >= int32(mGameEventGameobjectGuids.size()))
{
- TC_LOG_ERROR("gameevent", "GameEventMgr::GameEventSpawn attempt access to out of range mGameEventGameobjectGuids element %i (size: " SIZEFMTD ")",
+ TC_LOG_ERROR("gameevent", "GameEventMgr::GameEventSpawn attempt access to out of range mGameEventGameobjectGuids element %i (size: %zu)",
internal_event_id, mGameEventGameobjectGuids.size());
return;
}
@@ -1224,7 +1224,7 @@ void GameEventMgr::GameEventSpawn(int16 event_id)
if (internal_event_id < 0 || internal_event_id >= int32(mGameEventPoolIds.size()))
{
- TC_LOG_ERROR("gameevent", "GameEventMgr::GameEventSpawn attempt access to out of range mGameEventPoolIds element %u (size: " SIZEFMTD ")",
+ TC_LOG_ERROR("gameevent", "GameEventMgr::GameEventSpawn attempt access to out of range mGameEventPoolIds element %u (size: %zu)",
internal_event_id, mGameEventPoolIds.size());
return;
}
@@ -1239,7 +1239,7 @@ void GameEventMgr::GameEventUnspawn(int16 event_id)
if (internal_event_id < 0 || internal_event_id >= int32(mGameEventCreatureGuids.size()))
{
- TC_LOG_ERROR("gameevent", "GameEventMgr::GameEventUnspawn attempt access to out of range mGameEventCreatureGuids element %i (size: " SIZEFMTD ")",
+ TC_LOG_ERROR("gameevent", "GameEventMgr::GameEventUnspawn attempt access to out of range mGameEventCreatureGuids element %i (size: %zu)",
internal_event_id, mGameEventCreatureGuids.size());
return;
}
@@ -1261,7 +1261,7 @@ void GameEventMgr::GameEventUnspawn(int16 event_id)
if (internal_event_id < 0 || internal_event_id >= int32(mGameEventGameobjectGuids.size()))
{
- TC_LOG_ERROR("gameevent", "GameEventMgr::GameEventUnspawn attempt access to out of range mGameEventGameobjectGuids element %i (size: " SIZEFMTD ")",
+ TC_LOG_ERROR("gameevent", "GameEventMgr::GameEventUnspawn attempt access to out of range mGameEventGameobjectGuids element %i (size: %zu)",
internal_event_id, mGameEventGameobjectGuids.size());
return;
}
@@ -1282,7 +1282,7 @@ void GameEventMgr::GameEventUnspawn(int16 event_id)
}
if (internal_event_id < 0 || internal_event_id >= int32(mGameEventPoolIds.size()))
{
- TC_LOG_ERROR("gameevent", "GameEventMgr::GameEventUnspawn attempt access to out of range mGameEventPoolIds element %u (size: " SIZEFMTD ")", internal_event_id, mGameEventPoolIds.size());
+ TC_LOG_ERROR("gameevent", "GameEventMgr::GameEventUnspawn attempt access to out of range mGameEventPoolIds element %u (size: %zu)", internal_event_id, mGameEventPoolIds.size());
return;
}
@@ -1601,14 +1601,14 @@ void GameEventMgr::RunSmartAIScripts(uint16 event_id, bool activate)
//! Iterate over every supported source type (creature and gameobject)
//! Not entirely sure how this will affect units in non-loaded grids.
{
- TRINITY_READ_GUARD(HashMapHolder<Creature>::LockType, *HashMapHolder<Creature>::GetLock());
+ boost::shared_lock<boost::shared_mutex> lock(*HashMapHolder<Creature>::GetLock());
HashMapHolder<Creature>::MapType const& m = ObjectAccessor::GetCreatures();
for (HashMapHolder<Creature>::MapType::const_iterator iter = m.begin(); iter != m.end(); ++iter)
if (iter->second->IsInWorld())
iter->second->AI()->sOnGameEvent(activate, event_id);
}
{
- TRINITY_READ_GUARD(HashMapHolder<GameObject>::LockType, *HashMapHolder<GameObject>::GetLock());
+ boost::shared_lock<boost::shared_mutex> lock(*HashMapHolder<GameObject>::GetLock());
HashMapHolder<GameObject>::MapType const& m = ObjectAccessor::GetGameObjects();
for (HashMapHolder<GameObject>::MapType::const_iterator iter = m.begin(); iter != m.end(); ++iter)
if (iter->second->IsInWorld())
diff --git a/src/server/game/Events/GameEventMgr.h b/src/server/game/Events/GameEventMgr.h
index 4b63402caa8..99b94357a63 100644
--- a/src/server/game/Events/GameEventMgr.h
+++ b/src/server/game/Events/GameEventMgr.h
@@ -22,7 +22,6 @@
#include "Common.h"
#include "SharedDefines.h"
#include "Define.h"
-#include <ace/Singleton.h>
#define max_ge_check_delay DAY // 1 day in seconds
@@ -96,13 +95,17 @@ class Quest;
class GameEventMgr
{
- friend class ACE_Singleton<GameEventMgr, ACE_Null_Mutex>;
-
private:
GameEventMgr();
~GameEventMgr() { };
public:
+ static GameEventMgr* instance()
+ {
+ static GameEventMgr* instance = new GameEventMgr();
+ return instance;
+ }
+
typedef std::set<uint16> ActiveEvents;
typedef std::vector<GameEventData> GameEventDataMap;
ActiveEvents const& GetActiveEventList() const { return m_ActiveEvents; }
@@ -181,7 +184,7 @@ class GameEventMgr
GameEventGuidMap mGameEventGameobjectGuids;
};
-#define sGameEventMgr ACE_Singleton<GameEventMgr, ACE_Null_Mutex>::instance()
+#define sGameEventMgr GameEventMgr::instance()
bool IsHolidayActive(HolidayIds id);
bool IsEventActive(uint16 event_id);
diff --git a/src/server/game/Globals/ObjectAccessor.cpp b/src/server/game/Globals/ObjectAccessor.cpp
index 13609f8e949..d2426effa8e 100644
--- a/src/server/game/Globals/ObjectAccessor.cpp
+++ b/src/server/game/Globals/ObjectAccessor.cpp
@@ -16,6 +16,9 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/thread/locks.hpp>
+
#include "ObjectAccessor.h"
#include "CellImpl.h"
#include "Corpse.h"
@@ -214,7 +217,8 @@ Unit* ObjectAccessor::FindUnit(uint64 guid)
Player* ObjectAccessor::FindPlayerByName(std::string const& name)
{
- TRINITY_READ_GUARD(HashMapHolder<Player>::LockType, *HashMapHolder<Player>::GetLock());
+ 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();
@@ -233,7 +237,8 @@ Player* ObjectAccessor::FindPlayerByName(std::string const& name)
void ObjectAccessor::SaveAllPlayers()
{
- TRINITY_READ_GUARD(HashMapHolder<Player>::LockType, *HashMapHolder<Player>::GetLock());
+ boost::shared_lock<boost::shared_mutex> lock(*HashMapHolder<Player>::GetLock());
+
HashMapHolder<Player>::MapType const& m = GetPlayers();
for (HashMapHolder<Player>::MapType::const_iterator itr = m.begin(); itr != m.end(); ++itr)
itr->second->SaveToDB();
@@ -241,7 +246,7 @@ void ObjectAccessor::SaveAllPlayers()
Corpse* ObjectAccessor::GetCorpseForPlayerGUID(uint64 guid)
{
- TRINITY_READ_GUARD(ACE_RW_Thread_Mutex, i_corpseLock);
+ boost::shared_lock<boost::shared_mutex> lock(_corpseLock);
Player2CorpsesMapType::iterator iter = i_player2corpse.find(guid);
if (iter == i_player2corpse.end())
@@ -256,6 +261,8 @@ void ObjectAccessor::RemoveCorpse(Corpse* corpse)
{
ASSERT(corpse && corpse->GetType() != CORPSE_BONES);
+ boost::upgrade_lock<boost::shared_mutex> lock(_corpseLock);
+
/// @todo more works need to be done for corpse and other world object
if (Map* map = corpse->FindMap())
{
@@ -274,7 +281,7 @@ void ObjectAccessor::RemoveCorpse(Corpse* corpse)
// Critical section
{
- TRINITY_WRITE_GUARD(ACE_RW_Thread_Mutex, i_corpseLock);
+ boost::upgrade_to_unique_lock<boost::shared_mutex> uniqueLock(lock);
Player2CorpsesMapType::iterator iter = i_player2corpse.find(corpse->GetOwnerGUID());
if (iter == i_player2corpse.end()) /// @todo Fix this
@@ -294,7 +301,7 @@ void ObjectAccessor::AddCorpse(Corpse* corpse)
// Critical section
{
- TRINITY_WRITE_GUARD(ACE_RW_Thread_Mutex, i_corpseLock);
+ boost::unique_lock<boost::shared_mutex> lock(_corpseLock);
ASSERT(i_player2corpse.find(corpse->GetOwnerGUID()) == i_player2corpse.end());
i_player2corpse[corpse->GetOwnerGUID()] = corpse;
@@ -307,7 +314,7 @@ void ObjectAccessor::AddCorpse(Corpse* corpse)
void ObjectAccessor::AddCorpsesToGrid(GridCoord const& gridpair, GridType& grid, Map* map)
{
- TRINITY_READ_GUARD(ACE_RW_Thread_Mutex, i_corpseLock);
+ boost::shared_lock<boost::shared_mutex> lock(_corpseLock);
for (Player2CorpsesMapType::iterator iter = i_player2corpse.begin(); iter != i_player2corpse.end(); ++iter)
{
@@ -439,8 +446,8 @@ void ObjectAccessor::UnloadAll()
/// Define the static members of HashMapHolder
-template <class T> std::unordered_map< uint64, T* > HashMapHolder<T>::m_objectMap;
-template <class T> typename HashMapHolder<T>::LockType HashMapHolder<T>::i_lock;
+template <class T> std::unordered_map< uint64, T* > HashMapHolder<T>::_objectMap;
+template <class T> boost::shared_mutex HashMapHolder<T>::_lock;
/// Global definitions for the hashmap storage
diff --git a/src/server/game/Globals/ObjectAccessor.h b/src/server/game/Globals/ObjectAccessor.h
index f65486850ac..dff783f4276 100644
--- a/src/server/game/Globals/ObjectAccessor.h
+++ b/src/server/game/Globals/ObjectAccessor.h
@@ -19,17 +19,17 @@
#ifndef TRINITY_OBJECTACCESSOR_H
#define TRINITY_OBJECTACCESSOR_H
-#include "Define.h"
-#include <ace/Singleton.h>
-#include <ace/Thread_Mutex.h>
+#include <mutex>
+#include <set>
#include <unordered_map>
+#include <boost/thread/locks.hpp>
+#include <boost/thread/shared_mutex.hpp>
-#include "UpdateData.h"
-
+#include "Define.h"
#include "GridDefines.h"
+#include "UpdateData.h"
#include "Object.h"
-#include <set>
class Creature;
class Corpse;
@@ -48,42 +48,41 @@ class HashMapHolder
public:
typedef std::unordered_map<uint64, T*> MapType;
- typedef ACE_RW_Thread_Mutex LockType;
static void Insert(T* o)
{
- TRINITY_WRITE_GUARD(LockType, i_lock);
- m_objectMap[o->GetGUID()] = o;
+ boost::shared_lock<boost::shared_mutex> lock(_lock);
+
+ _objectMap[o->GetGUID()] = o;
}
static void Remove(T* o)
{
- TRINITY_WRITE_GUARD(LockType, i_lock);
- m_objectMap.erase(o->GetGUID());
+ boost::unique_lock<boost::shared_mutex> lock(_lock);
+ _objectMap.erase(o->GetGUID());
}
static T* Find(uint64 guid)
{
- TRINITY_READ_GUARD(LockType, i_lock);
- typename MapType::iterator itr = m_objectMap.find(guid);
- return (itr != m_objectMap.end()) ? itr->second : NULL;
+ boost::shared_lock<boost::shared_mutex> lock(_lock);
+ typename MapType::iterator itr = _objectMap.find(guid);
+ return (itr != _objectMap.end()) ? itr->second : NULL;
}
- static MapType& GetContainer() { return m_objectMap; }
+ static MapType& GetContainer() { return _objectMap; }
- static LockType* GetLock() { return &i_lock; }
+ static boost::shared_mutex* GetLock() { return &_lock; }
private:
//Non instanceable only static
HashMapHolder() { }
- static LockType i_lock;
- static MapType m_objectMap;
+ static boost::shared_mutex _lock;
+ static MapType _objectMap;
};
class ObjectAccessor
{
- friend class ACE_Singleton<ObjectAccessor, ACE_Null_Mutex>;
private:
ObjectAccessor();
~ObjectAccessor();
@@ -93,6 +92,12 @@ class ObjectAccessor
public:
/// @todo: Override these template functions for each holder type and add assertions
+ static ObjectAccessor* instance()
+ {
+ static ObjectAccessor *instance = new ObjectAccessor();
+ return instance;
+ }
+
template<class T> static T* GetObjectInOrOutOfWorld(uint64 guid, T* /*typeSpecifier*/)
{
return HashMapHolder<T>::Find(guid);
@@ -196,13 +201,13 @@ class ObjectAccessor
//non-static functions
void AddUpdateObject(Object* obj)
{
- TRINITY_GUARD(ACE_Thread_Mutex, i_objectLock);
+ std::lock_guard<std::mutex> lock(_objectLock);
i_objects.insert(obj);
}
void RemoveUpdateObject(Object* obj)
{
- TRINITY_GUARD(ACE_Thread_Mutex, i_objectLock);
+ std::lock_guard<std::mutex> lock(_objectLock);
i_objects.erase(obj);
}
@@ -229,9 +234,9 @@ class ObjectAccessor
std::set<Object*> i_objects;
Player2CorpsesMapType i_player2corpse;
- ACE_Thread_Mutex i_objectLock;
- ACE_RW_Thread_Mutex i_corpseLock;
+ std::mutex _objectLock;
+ boost::shared_mutex _corpseLock;
};
-#define sObjectAccessor ACE_Singleton<ObjectAccessor, ACE_Null_Mutex>::instance()
+#define sObjectAccessor ObjectAccessor::instance()
#endif
diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp
index ec151d4d58b..93c06146c06 100644
--- a/src/server/game/Globals/ObjectMgr.cpp
+++ b/src/server/game/Globals/ObjectMgr.cpp
@@ -5486,7 +5486,7 @@ void ObjectMgr::ReturnOrDeleteOldMails(bool serverUp)
time_t curTime = time(NULL);
tm lt;
- ACE_OS::localtime_r(&curTime, &lt);
+ localtime_r(&curTime, &lt);
uint64 basetime(curTime);
TC_LOG_INFO("misc", "Returning mails current time: hour: %d, minute: %d, second: %d ", lt.tm_hour, lt.tm_min, lt.tm_sec);
@@ -7047,7 +7047,7 @@ void ObjectMgr::LoadReputationOnKill()
repOnKill.IsTeamAward2 = fields[6].GetBool();
repOnKill.ReputationMaxCap2 = fields[7].GetUInt8();
repOnKill.RepValue2 = fields[8].GetInt32();
- repOnKill.TeamDependent = fields[9].GetUInt8();
+ repOnKill.TeamDependent = fields[9].GetBool();
if (!GetCreatureTemplate(creature_id))
{
diff --git a/src/server/game/Globals/ObjectMgr.h b/src/server/game/Globals/ObjectMgr.h
index a6e2ce9b067..46561fd7773 100644
--- a/src/server/game/Globals/ObjectMgr.h
+++ b/src/server/game/Globals/ObjectMgr.h
@@ -35,7 +35,6 @@
#include "Map.h"
#include "ObjectAccessor.h"
#include "ObjectDefines.h"
-#include <ace/Singleton.h>
#include "VehicleDefines.h"
#include <string>
#include <map>
@@ -723,13 +722,18 @@ class PlayerDumpReader;
class ObjectMgr
{
friend class PlayerDumpReader;
- friend class ACE_Singleton<ObjectMgr, ACE_Null_Mutex>;
private:
ObjectMgr();
~ObjectMgr();
public:
+ static ObjectMgr* instance()
+ {
+ static ObjectMgr* instance = new ObjectMgr();
+ return instance;
+ }
+
typedef std::unordered_map<uint32, Item*> ItemMap;
typedef std::unordered_map<uint32, Quest*> QuestMap;
@@ -1326,7 +1330,7 @@ class ObjectMgr
void LoadFactionChangeSpells();
void LoadFactionChangeTitles();
- bool IsTransportMap(uint32 mapId) const { return _transportMaps.count(mapId); }
+ bool IsTransportMap(uint32 mapId) const { return _transportMaps.count(mapId) != 0; }
void LoadHotfixData();
HotfixData const& GetHotfixData() const { return _hotfixData; }
@@ -1494,6 +1498,6 @@ class ObjectMgr
std::set<uint32> _transportMaps; // Helper container storing map ids that are for transports only, loaded from gameobject_template
};
-#define sObjectMgr ACE_Singleton<ObjectMgr, ACE_Null_Mutex>::instance()
+#define sObjectMgr ObjectMgr::instance()
#endif
diff --git a/src/server/game/Groups/Group.cpp b/src/server/game/Groups/Group.cpp
index e9ebfb1eff6..e6f0b0f459a 100644
--- a/src/server/game/Groups/Group.cpp
+++ b/src/server/game/Groups/Group.cpp
@@ -523,7 +523,7 @@ bool Group::RemoveMember(uint64 guid, const RemoveMethod& method /*= GROUP_REMOV
// LFG group vote kick handled in scripts
if (isLFGGroup() && method == GROUP_REMOVEMETHOD_KICK)
- return m_memberSlots.size();
+ return !m_memberSlots.empty();
// 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))
@@ -2218,12 +2218,12 @@ bool Group::IsFull() const
bool Group::isLFGGroup() const
{
- return m_groupType & GROUPTYPE_LFG;
+ return (m_groupType & GROUPTYPE_LFG) != 0;
}
bool Group::isRaidGroup() const
{
- return m_groupType & GROUPTYPE_RAID;
+ return (m_groupType & GROUPTYPE_RAID) != 0;
}
bool Group::isBGGroup() const
diff --git a/src/server/game/Groups/GroupMgr.cpp b/src/server/game/Groups/GroupMgr.cpp
index 39735f5dce3..23b6998d688 100644
--- a/src/server/game/Groups/GroupMgr.cpp
+++ b/src/server/game/Groups/GroupMgr.cpp
@@ -226,7 +226,7 @@ void GroupMgr::LoadGroups()
diff = 0; // default for both difficaly types
}
- InstanceSave* save = sInstanceSaveMgr->AddInstanceSave(mapEntry->MapID, fields[2].GetUInt32(), Difficulty(diff), time_t(fields[5].GetUInt32()), (bool)fields[6].GetUInt64(), true);
+ InstanceSave* save = sInstanceSaveMgr->AddInstanceSave(mapEntry->MapID, fields[2].GetUInt32(), Difficulty(diff), time_t(fields[5].GetUInt32()), fields[6].GetUInt64() != 0, true);
group->BindToInstance(save, fields[3].GetBool(), true);
++count;
}
diff --git a/src/server/game/Groups/GroupMgr.h b/src/server/game/Groups/GroupMgr.h
index a805b7514da..4bf440c881e 100644
--- a/src/server/game/Groups/GroupMgr.h
+++ b/src/server/game/Groups/GroupMgr.h
@@ -22,12 +22,17 @@
class GroupMgr
{
- friend class ACE_Singleton<GroupMgr, ACE_Null_Mutex>;
private:
GroupMgr();
~GroupMgr();
public:
+ static GroupMgr* instance()
+ {
+ static GroupMgr* instance = new GroupMgr();
+ return instance;
+ }
+
typedef std::map<uint32, Group*> GroupContainer;
typedef std::vector<Group*> GroupDbContainer;
@@ -53,6 +58,6 @@ protected:
GroupDbContainer GroupDbStore;
};
-#define sGroupMgr ACE_Singleton<GroupMgr, ACE_Null_Mutex>::instance()
+#define sGroupMgr GroupMgr::instance()
#endif
diff --git a/src/server/game/Guilds/Guild.cpp b/src/server/game/Guilds/Guild.cpp
index 2df57099c99..9e86039e4af 100644
--- a/src/server/game/Guilds/Guild.cpp
+++ b/src/server/game/Guilds/Guild.cpp
@@ -3191,7 +3191,7 @@ bool Guild::_DoItemsMove(MoveItemData* pSrc, MoveItemData* pDest, bool sendError
Item* pDestItem = pDest->GetItem();
bool swap = (pDestItem != NULL);
- Item* pSrcItem = pSrc->GetItem(splitedAmount);
+ Item* pSrcItem = pSrc->GetItem(splitedAmount != 0);
// 1. Can store source item in destination
if (!pDest->CanStore(pSrcItem, swap, sendError))
return false;
diff --git a/src/server/game/Guilds/GuildMgr.h b/src/server/game/Guilds/GuildMgr.h
index 2dcc0202993..318445fe844 100644
--- a/src/server/game/Guilds/GuildMgr.h
+++ b/src/server/game/Guilds/GuildMgr.h
@@ -22,13 +22,17 @@
class GuildMgr
{
- friend class ACE_Singleton<GuildMgr, ACE_Null_Mutex>;
-
private:
GuildMgr();
~GuildMgr();
public:
+ static GuildMgr* instance()
+ {
+ static GuildMgr* instance = new GuildMgr();
+ return instance;
+ }
+
Guild* GetGuildByLeader(uint64 guid) const;
Guild* GetGuildById(uint32 guildId) const;
Guild* GetGuildByGuid(uint64 guid) const;
@@ -61,6 +65,6 @@ protected:
std::vector<GuildReward> GuildRewards;
};
-#define sGuildMgr ACE_Singleton<GuildMgr, ACE_Null_Mutex>::instance()
+#define sGuildMgr GuildMgr::instance()
#endif
diff --git a/src/server/game/Handlers/AddonHandler.cpp b/src/server/game/Handlers/AddonHandler.cpp
index 806cbd1c7fc..8a00ddc22f4 100644
--- a/src/server/game/Handlers/AddonHandler.cpp
+++ b/src/server/game/Handlers/AddonHandler.cpp
@@ -22,10 +22,6 @@
#include "Opcodes.h"
#include "Log.h"
-AddonHandler::AddonHandler() { }
-
-AddonHandler::~AddonHandler() { }
-
bool AddonHandler::BuildAddonPacket(WorldPacket* source, WorldPacket* target)
{
ByteBuffer AddOnPacked;
diff --git a/src/server/game/Handlers/AddonHandler.h b/src/server/game/Handlers/AddonHandler.h
index 97a541753d0..31bbfa01900 100644
--- a/src/server/game/Handlers/AddonHandler.h
+++ b/src/server/game/Handlers/AddonHandler.h
@@ -21,20 +21,23 @@
#include "Common.h"
#include "Config.h"
-#include <ace/Singleton.h>
#include "WorldPacket.h"
class AddonHandler
{
- /* Construction */
- friend class ACE_Singleton<AddonHandler, ACE_Null_Mutex>;
- AddonHandler();
-
public:
- ~AddonHandler();
- //build addon packet
+ static AddonHandler* instance()
+ {
+ static AddonHandler* instance = new AddonHandler();
+ return instance;
+ }
+
bool BuildAddonPacket(WorldPacket* Source, WorldPacket* Target);
+
+ private:
+ AddonHandler() { }
+ ~AddonHandler() { }
};
-#define sAddOnHandler ACE_Singleton<AddonHandler, ACE_Null_Mutex>::instance()
+#define sAddOnHandler AddonHandler::instance()
#endif
diff --git a/src/server/game/Handlers/CharacterHandler.cpp b/src/server/game/Handlers/CharacterHandler.cpp
index dd4d9c9bc9f..422e5ce206b 100644
--- a/src/server/game/Handlers/CharacterHandler.cpp
+++ b/src/server/game/Handlers/CharacterHandler.cpp
@@ -312,10 +312,10 @@ void WorldSession::HandleCharCreateOpcode(WorldPacket& recvData)
switch (team)
{
case ALLIANCE:
- disabled = mask & (1 << 0);
+ disabled = (mask & (1 << 0)) != 0;
break;
case HORDE:
- disabled = mask & (1 << 1);
+ disabled = (mask & (1 << 1)) != 0;
break;
}
@@ -1152,7 +1152,7 @@ void WorldSession::HandleSetFactionAtWar(WorldPacket& recvData)
recvData >> repListID;
recvData >> flag;
- GetPlayer()->GetReputationMgr().SetAtWar(repListID, flag);
+ GetPlayer()->GetReputationMgr().SetAtWar(repListID, flag != 0);
}
//I think this function is never used :/ I dunno, but i guess this opcode not exists
@@ -1205,7 +1205,7 @@ void WorldSession::HandleSetFactionInactiveOpcode(WorldPacket& recvData)
uint8 inactive;
recvData >> replistid >> inactive;
- _player->GetReputationMgr().SetInactive(replistid, inactive);
+ _player->GetReputationMgr().SetInactive(replistid, inactive != 0);
}
void WorldSession::HandleShowingHelmOpcode(WorldPacket& recvData)
diff --git a/src/server/game/Handlers/GroupHandler.cpp b/src/server/game/Handlers/GroupHandler.cpp
index 8565da90f40..d74aebaaa1f 100644
--- a/src/server/game/Handlers/GroupHandler.cpp
+++ b/src/server/game/Handlers/GroupHandler.cpp
@@ -1377,5 +1377,5 @@ void WorldSession::HandleOptOutOfLootOpcode(WorldPacket& recvData)
return;
}
- GetPlayer()->SetPassOnGroupLoot(passOnLoot);
+ GetPlayer()->SetPassOnGroupLoot(passOnLoot != 0);
}
diff --git a/src/server/game/Handlers/GuildHandler.cpp b/src/server/game/Handlers/GuildHandler.cpp
index d40f2102c77..97d5ea8310e 100644
--- a/src/server/game/Handlers/GuildHandler.cpp
+++ b/src/server/game/Handlers/GuildHandler.cpp
@@ -538,7 +538,7 @@ void WorldSession::HandleGuildBankSwapItems(WorldPacket& recvPacket)
if (!Player::IsInventoryPos(playerBag, playerSlotId) && !(playerBag == NULL_BAG && playerSlotId == NULL_SLOT))
GetPlayer()->SendEquipError(EQUIP_ERR_INTERNAL_BAG_ERROR, NULL);
else
- guild->SwapItemsWithInventory(GetPlayer(), toChar, tabId, slotId, playerBag, playerSlotId, splitedAmount);
+ guild->SwapItemsWithInventory(GetPlayer(), toChar != 0, tabId, slotId, playerBag, playerSlotId, splitedAmount);
}
}
diff --git a/src/server/game/Handlers/MiscHandler.cpp b/src/server/game/Handlers/MiscHandler.cpp
index 26f27ad817d..c9891de3c16 100644
--- a/src/server/game/Handlers/MiscHandler.cpp
+++ b/src/server/game/Handlers/MiscHandler.cpp
@@ -256,7 +256,8 @@ void WorldSession::HandleWhoOpcode(WorldPacket& recvData)
data << uint32(matchcount); // placeholder, count of players matching criteria
data << uint32(displaycount); // placeholder, count of players displayed
- TRINITY_READ_GUARD(HashMapHolder<Player>::LockType, *HashMapHolder<Player>::GetLock());
+ boost::shared_lock<boost::shared_mutex> lock(*HashMapHolder<Player>::GetLock());
+
HashMapHolder<Player>::MapType const& m = sObjectAccessor->GetPlayers();
for (HashMapHolder<Player>::MapType::const_iterator itr = m.begin(); itr != m.end(); ++itr)
{
diff --git a/src/server/game/Handlers/NPCHandler.cpp b/src/server/game/Handlers/NPCHandler.cpp
index 1ce1197c3db..02651a1af09 100644
--- a/src/server/game/Handlers/NPCHandler.cpp
+++ b/src/server/game/Handlers/NPCHandler.cpp
@@ -907,12 +907,12 @@ void WorldSession::HandleRepairItemOpcode(WorldPacket& recvData)
Item* item = _player->GetItemByGuid(itemGUID);
if (item)
- _player->DurabilityRepair(item->GetPos(), true, discountMod, guildBank);
+ _player->DurabilityRepair(item->GetPos(), true, discountMod, guildBank != 0);
}
else
{
TC_LOG_DEBUG("network", "ITEM: Repair all items, npcGUID = %u", GUID_LOPART(npcGUID));
- _player->DurabilityRepairAll(true, discountMod, guildBank);
+ _player->DurabilityRepairAll(true, discountMod, guildBank != 0);
}
}
diff --git a/src/server/game/Handlers/PetHandler.cpp b/src/server/game/Handlers/PetHandler.cpp
index 39d18178a01..f3dc24a8c01 100644
--- a/src/server/game/Handlers/PetHandler.cpp
+++ b/src/server/game/Handlers/PetHandler.cpp
@@ -744,11 +744,11 @@ void WorldSession::HandlePetSpellAutocastOpcode(WorldPacket& recvPacket)
}
if (pet->IsPet())
- ((Pet*)pet)->ToggleAutocast(spellInfo, state);
+ ((Pet*)pet)->ToggleAutocast(spellInfo, state != 0);
else
- pet->GetCharmInfo()->ToggleCreatureAutocast(spellInfo, state);
+ pet->GetCharmInfo()->ToggleCreatureAutocast(spellInfo, state != 0);
- charmInfo->SetSpellAutocast(spellInfo, state);
+ charmInfo->SetSpellAutocast(spellInfo, state != 0);
}
void WorldSession::HandlePetCastSpellOpcode(WorldPacket& recvPacket)
diff --git a/src/server/game/Instances/InstanceSaveMgr.h b/src/server/game/Instances/InstanceSaveMgr.h
index cf852b7c952..de8a0e0fc8e 100644
--- a/src/server/game/Instances/InstanceSaveMgr.h
+++ b/src/server/game/Instances/InstanceSaveMgr.h
@@ -19,12 +19,12 @@
#ifndef _INSTANCESAVEMGR_H
#define _INSTANCESAVEMGR_H
-#include "Define.h"
-#include <ace/Singleton.h>
-#include <ace/Thread_Mutex.h>
#include <list>
#include <map>
+#include <mutex>
#include <unordered_map>
+
+#include "Define.h"
#include "DatabaseEnv.h"
#include "DBCEnums.h"
#include "ObjectDefines.h"
@@ -80,13 +80,18 @@ class InstanceSave
/* online players bound to the instance (perm/solo)
does not include the members of the group unless they have permanent saves */
- void AddPlayer(Player* player) { TRINITY_GUARD(ACE_Thread_Mutex, _lock); m_playerList.push_back(player); }
+ void AddPlayer(Player* player)
+ {
+ std::lock_guard<std::mutex> lock(_playerListLock);
+ m_playerList.push_back(player);
+ }
+
bool RemovePlayer(Player* player)
{
- _lock.acquire();
+ _playerListLock.lock();
m_playerList.remove(player);
bool isStillValid = UnloadIfEmpty();
- _lock.release();
+ _playerListLock.unlock();
//delete here if needed, after releasing the lock
if (m_toDelete)
@@ -137,14 +142,13 @@ class InstanceSave
bool m_canReset;
bool m_toDelete;
- ACE_Thread_Mutex _lock;
+ std::mutex _playerListLock;
};
typedef std::unordered_map<uint32 /*PAIR32(map, difficulty)*/, time_t /*resetTime*/> ResetTimeByMapDifficultyMap;
class InstanceSaveManager
{
- friend class ACE_Singleton<InstanceSaveManager, ACE_Thread_Mutex>;
friend class InstanceSave;
private:
@@ -154,6 +158,12 @@ class InstanceSaveManager
public:
typedef std::unordered_map<uint32 /*InstanceId*/, InstanceSave*> InstanceSaveHashMap;
+ static InstanceSaveManager* instance()
+ {
+ static InstanceSaveManager *instance = new InstanceSaveManager();
+ return instance;
+ }
+
/* resetTime is a global propery of each (raid/heroic) map
all instances of that map reset at the same time */
struct InstResetEvent
@@ -221,5 +231,5 @@ class InstanceSaveManager
ResetTimeQueue m_resetTimeQueue;
};
-#define sInstanceSaveMgr ACE_Singleton<InstanceSaveManager, ACE_Thread_Mutex>::instance()
+#define sInstanceSaveMgr InstanceSaveManager::instance()
#endif
diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp
index 21572858b2b..c69f7863ef6 100644
--- a/src/server/game/Maps/Map.cpp
+++ b/src/server/game/Maps/Map.cpp
@@ -387,7 +387,7 @@ void Map::DeleteFromWorld(Player* player)
void Map::EnsureGridCreated(const GridCoord &p)
{
- TRINITY_GUARD(ACE_Thread_Mutex, GridLock);
+ std::lock_guard<std::mutex> lock(_gridLock);
EnsureGridCreated_i(p);
}
@@ -2195,13 +2195,13 @@ inline bool IsOutdoorWMO(uint32 mogpFlags, int32 /*adtId*/, int32 /*rootId*/, in
return false;
}
- outdoor = mogpFlags&0x8;
+ outdoor = (mogpFlags & 0x8) != 0;
if (wmoEntry)
{
if (wmoEntry->Flags & 4)
return true;
- if ((wmoEntry->Flags & 2)!=0)
+ if (wmoEntry->Flags & 2)
outdoor = false;
}
return outdoor;
@@ -2442,12 +2442,12 @@ bool Map::IsInWater(float x, float y, float pZ, LiquidData* data) const
{
LiquidData liquid_status;
LiquidData* liquid_ptr = data ? data : &liquid_status;
- return getLiquidStatus(x, y, pZ, MAP_ALL_LIQUIDS, liquid_ptr) & (LIQUID_MAP_IN_WATER | LIQUID_MAP_UNDER_WATER);
+ return (getLiquidStatus(x, y, pZ, MAP_ALL_LIQUIDS, liquid_ptr) & (LIQUID_MAP_IN_WATER | LIQUID_MAP_UNDER_WATER)) != 0;
}
bool Map::IsUnderWater(float x, float y, float z) const
{
- return getLiquidStatus(x, y, z, MAP_LIQUID_TYPE_WATER|MAP_LIQUID_TYPE_OCEAN) & LIQUID_MAP_UNDER_WATER;
+ return (getLiquidStatus(x, y, z, MAP_LIQUID_TYPE_WATER | MAP_LIQUID_TYPE_OCEAN) & LIQUID_MAP_UNDER_WATER) != 0;
}
bool Map::CheckGridIntegrity(Creature* c, bool moved) const
@@ -2924,7 +2924,7 @@ bool InstanceMap::AddPlayerToMap(Player* player)
// Is it needed?
{
- TRINITY_GUARD(ACE_Thread_Mutex, Lock);
+ std::lock_guard<std::mutex> lock(_mapLock);
// Check moved to void WorldSession::HandleMoveWorldportAckOpcode()
//if (!CanEnter(player))
//return false;
@@ -3266,7 +3266,7 @@ bool BattlegroundMap::CanEnter(Player* player)
bool BattlegroundMap::AddPlayerToMap(Player* player)
{
{
- TRINITY_GUARD(ACE_Thread_Mutex, Lock);
+ std::lock_guard<std::mutex> lock(_mapLock);
//Check moved to void WorldSession::HandleMoveWorldportAckOpcode()
//if (!CanEnter(player))
//return false;
diff --git a/src/server/game/Maps/Map.h b/src/server/game/Maps/Map.h
index 3b66fd0fed5..c676a5c5ce0 100644
--- a/src/server/game/Maps/Map.h
+++ b/src/server/game/Maps/Map.h
@@ -20,8 +20,6 @@
#define TRINITY_MAP_H
#include "Define.h"
-#include <ace/RW_Thread_Mutex.h>
-#include <ace/Thread_Mutex.h>
#include "DBCStructure.h"
#include "GridDefines.h"
@@ -576,8 +574,8 @@ class Map : public GridRefManager<NGridType>
protected:
void SetUnloadReferenceLock(const GridCoord &p, bool on) { getNGrid(p.x_coord, p.y_coord)->setUnloadReferenceLock(on); }
- ACE_Thread_Mutex Lock;
- ACE_Thread_Mutex GridLock;
+ std::mutex _mapLock;
+ std::mutex _gridLock;
MapEntry const* i_mapEntry;
uint8 i_spawnMode;
diff --git a/src/server/game/Maps/MapInstanced.cpp b/src/server/game/Maps/MapInstanced.cpp
index e914a5c3eee..498c669ba01 100644
--- a/src/server/game/Maps/MapInstanced.cpp
+++ b/src/server/game/Maps/MapInstanced.cpp
@@ -187,7 +187,7 @@ Map* MapInstanced::CreateInstanceForPlayer(const uint32 mapId, Player* player)
InstanceMap* MapInstanced::CreateInstance(uint32 InstanceId, InstanceSave* save, Difficulty difficulty)
{
// load/create a map
- TRINITY_GUARD(ACE_Thread_Mutex, Lock);
+ std::lock_guard<std::mutex> lock(_mapLock);
// make sure we have a valid map id
const MapEntry* entry = sMapStore.LookupEntry(GetId());
@@ -223,7 +223,7 @@ InstanceMap* MapInstanced::CreateInstance(uint32 InstanceId, InstanceSave* save,
BattlegroundMap* MapInstanced::CreateBattleground(uint32 InstanceId, Battleground* bg)
{
// load/create a map
- TRINITY_GUARD(ACE_Thread_Mutex, Lock);
+ std::lock_guard<std::mutex> lock(_mapLock);
TC_LOG_DEBUG("maps", "MapInstanced::CreateBattleground: map bg %d for %d created.", InstanceId, GetId());
diff --git a/src/server/game/Maps/MapManager.cpp b/src/server/game/Maps/MapManager.cpp
index d6c849f4387..cc408988428 100644
--- a/src/server/game/Maps/MapManager.cpp
+++ b/src/server/game/Maps/MapManager.cpp
@@ -52,8 +52,8 @@ void MapManager::Initialize()
int num_threads(sWorld->getIntConfig(CONFIG_NUMTHREADS));
// Start mtmaps if needed.
- if (num_threads > 0 && m_updater.activate(num_threads) == -1)
- abort();
+ if (num_threads > 0)
+ m_updater.activate(num_threads);
}
void MapManager::InitializeVisibilityDistanceInfo()
@@ -68,7 +68,7 @@ Map* MapManager::CreateBaseMap(uint32 id)
if (map == NULL)
{
- TRINITY_GUARD(ACE_Thread_Mutex, Lock);
+ std::lock_guard<std::mutex> lock(_mapsLock);
MapEntry const* entry = sMapStore.LookupEntry(id);
ASSERT(entry);
@@ -296,7 +296,7 @@ void MapManager::UnloadAll()
uint32 MapManager::GetNumInstances()
{
- TRINITY_GUARD(ACE_Thread_Mutex, Lock);
+ std::lock_guard<std::mutex> lock(_mapsLock);
uint32 ret = 0;
for (MapMapType::iterator itr = i_maps.begin(); itr != i_maps.end(); ++itr)
@@ -313,7 +313,7 @@ uint32 MapManager::GetNumInstances()
uint32 MapManager::GetNumPlayersInInstances()
{
- TRINITY_GUARD(ACE_Thread_Mutex, Lock);
+ std::lock_guard<std::mutex> lock(_mapsLock);
uint32 ret = 0;
for (MapMapType::iterator itr = i_maps.begin(); itr != i_maps.end(); ++itr)
diff --git a/src/server/game/Maps/MapManager.h b/src/server/game/Maps/MapManager.h
index b7fb0617a46..990d5e80c1a 100644
--- a/src/server/game/Maps/MapManager.h
+++ b/src/server/game/Maps/MapManager.h
@@ -24,18 +24,18 @@
#include "GridStates.h"
#include "MapUpdater.h"
-#include <ace/Singleton.h>
-#include <ace/Thread_Mutex.h>
-
-
class Transport;
struct TransportCreatureProto;
class MapManager
{
- friend class ACE_Singleton<MapManager, ACE_Thread_Mutex>;
-
public:
+ static MapManager* instance()
+ {
+ static MapManager* instance = new MapManager();
+ return instance;
+ }
+
Map* CreateBaseMap(uint32 mapId);
Map* FindBaseNonInstanceMap(uint32 mapId) const;
Map* CreateMap(uint32 mapId, Player* player);
@@ -141,7 +141,7 @@ class MapManager
MapManager(const MapManager &);
MapManager& operator=(const MapManager &);
- ACE_Thread_Mutex Lock;
+ std::mutex _mapsLock;
uint32 i_gridCleanUpDelay;
MapMapType i_maps;
IntervalTimer i_timer;
@@ -150,5 +150,5 @@ class MapManager
uint32 _nextInstanceId;
MapUpdater m_updater;
};
-#define sMapMgr ACE_Singleton<MapManager, ACE_Thread_Mutex>::instance()
+#define sMapMgr MapManager::instance()
#endif
diff --git a/src/server/game/Maps/MapUpdater.cpp b/src/server/game/Maps/MapUpdater.cpp
index dd697719d54..c456f57bd20 100644
--- a/src/server/game/Maps/MapUpdater.cpp
+++ b/src/server/game/Maps/MapUpdater.cpp
@@ -1,97 +1,125 @@
+/*
+* 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 <mutex>
+#include <condition_variable>
+
#include "MapUpdater.h"
-#include "DelayExecutor.h"
#include "Map.h"
-#include "DatabaseEnv.h"
-#include <ace/Guard_T.h>
-#include <ace/Method_Request.h>
-class MapUpdateRequest : public ACE_Method_Request
+class MapUpdateRequest
{
private:
Map& m_map;
MapUpdater& m_updater;
- ACE_UINT32 m_diff;
+ uint32 m_diff;
public:
- MapUpdateRequest(Map& m, MapUpdater& u, ACE_UINT32 d)
+ MapUpdateRequest(Map& m, MapUpdater& u, uint32 d)
: m_map(m), m_updater(u), m_diff(d)
{
}
- virtual int call()
+ void call()
{
m_map.Update (m_diff);
m_updater.update_finished();
- return 0;
}
};
-MapUpdater::MapUpdater():
-m_executor(), m_mutex(), m_condition(m_mutex), pending_requests(0) { }
+MapUpdater::MapUpdater() : _cancelationToken(false), pending_requests(0) {}
MapUpdater::~MapUpdater()
{
deactivate();
}
-int MapUpdater::activate(size_t num_threads)
+void MapUpdater::activate(size_t num_threads)
{
- return m_executor.start((int)num_threads);
+ for (size_t i = 0; i < num_threads; ++i)
+ {
+ _workerThreads.push_back(std::thread(&MapUpdater::WorkerThread, this));
+ }
}
-int MapUpdater::deactivate()
+void MapUpdater::deactivate()
{
+ _cancelationToken = true;
+
wait();
- return m_executor.deactivate();
+ _queue.Cancel();
+
+ for (auto& thread : _workerThreads)
+ {
+ thread.join();
+ }
}
-int MapUpdater::wait()
+void MapUpdater::wait()
{
- TRINITY_GUARD(ACE_Thread_Mutex, m_mutex);
+ std::unique_lock<std::mutex> lock(_lock);
while (pending_requests > 0)
- m_condition.wait();
+ _condition.wait(lock);
- return 0;
+ lock.unlock();
}
-int MapUpdater::schedule_update(Map& map, ACE_UINT32 diff)
+void MapUpdater::schedule_update(Map& map, uint32 diff)
{
- TRINITY_GUARD(ACE_Thread_Mutex, m_mutex);
+ std::lock_guard<std::mutex> lock(_lock);
++pending_requests;
- if (m_executor.execute(new MapUpdateRequest(map, *this, diff)) == -1)
- {
- ACE_DEBUG((LM_ERROR, ACE_TEXT("(%t) \n"), ACE_TEXT("Failed to schedule Map Update")));
-
- --pending_requests;
- return -1;
- }
-
- return 0;
+ _queue.Push(new MapUpdateRequest(map, *this, diff));
}
bool MapUpdater::activated()
{
- return m_executor.activated();
+ return _workerThreads.size() > 0;
}
void MapUpdater::update_finished()
{
- TRINITY_GUARD(ACE_Thread_Mutex, m_mutex);
+ std::lock_guard<std::mutex> lock(_lock);
- if (pending_requests == 0)
+ --pending_requests;
+
+ _condition.notify_all();
+}
+
+void MapUpdater::WorkerThread()
+{
+ while (1)
{
- ACE_ERROR((LM_ERROR, ACE_TEXT("(%t)\n"), ACE_TEXT("MapUpdater::update_finished BUG, report to devs")));
- return;
- }
+ MapUpdateRequest* request = nullptr;
- --pending_requests;
+ _queue.WaitAndPop(request);
+
+ if (_cancelationToken)
+ return;
- m_condition.broadcast();
+ request->call();
+
+ delete request;
+ }
}
diff --git a/src/server/game/Maps/MapUpdater.h b/src/server/game/Maps/MapUpdater.h
index 89798026339..c499110173e 100644
--- a/src/server/game/Maps/MapUpdater.h
+++ b/src/server/game/Maps/MapUpdater.h
@@ -1,11 +1,31 @@
+/*
+* 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 _MAP_UPDATER_H_INCLUDED
#define _MAP_UPDATER_H_INCLUDED
-#include <ace/Thread_Mutex.h>
-#include <ace/Condition_Thread_Mutex.h>
-
-#include "DelayExecutor.h"
+#include "Define.h"
+#include <mutex>
+#include <thread>
+#include <condition_variable>
+#include "ProducerConsumerQueue.h"
+class MapUpdateRequest;
class Map;
class MapUpdater
@@ -17,24 +37,30 @@ class MapUpdater
friend class MapUpdateRequest;
- int schedule_update(Map& map, ACE_UINT32 diff);
+ void schedule_update(Map& map, uint32 diff);
- int wait();
+ void wait();
- int activate(size_t num_threads);
+ void activate(size_t num_threads);
- int deactivate();
+ void deactivate();
bool activated();
private:
- DelayExecutor m_executor;
- ACE_Thread_Mutex m_mutex;
- ACE_Condition_Thread_Mutex m_condition;
+ ProducerConsumerQueue<MapUpdateRequest*> _queue;
+
+ std::vector<std::thread> _workerThreads;
+ std::atomic<bool> _cancelationToken;
+
+ std::mutex _lock;
+ std::condition_variable _condition;
size_t pending_requests;
void update_finished();
+
+ void WorkerThread();
};
#endif //_MAP_UPDATER_H_INCLUDED
diff --git a/src/server/game/Maps/TransportMgr.h b/src/server/game/Maps/TransportMgr.h
index 759b761c3f1..e023c8be4ee 100644
--- a/src/server/game/Maps/TransportMgr.h
+++ b/src/server/game/Maps/TransportMgr.h
@@ -18,7 +18,6 @@
#ifndef TRANSPORTMGR_H
#define TRANSPORTMGR_H
-#include <ace/Singleton.h>
#include <G3D/Quat.h>
#include "Spline.h"
#include "DBCStores.h"
@@ -96,10 +95,15 @@ typedef std::map<uint32, TransportAnimation> TransportAnimationContainer;
class TransportMgr
{
- friend class ACE_Singleton<TransportMgr, ACE_Thread_Mutex>;
friend void LoadDBCStores(std::string const&);
public:
+ static TransportMgr* instance()
+ {
+ static TransportMgr* instance = new TransportMgr();
+ return instance;
+ }
+
void Unload();
void LoadTransportTemplates();
@@ -155,6 +159,6 @@ class TransportMgr
TransportAnimationContainer _transportAnimations;
};
-#define sTransportMgr ACE_Singleton<TransportMgr, ACE_Thread_Mutex>::instance()
+#define sTransportMgr TransportMgr::instance()
#endif // TRANSPORTMGR_H
diff --git a/src/server/game/Movement/MovementGenerator.h b/src/server/game/Movement/MovementGenerator.h
index f545f9fd314..12116b5505d 100755
--- a/src/server/game/Movement/MovementGenerator.h
+++ b/src/server/game/Movement/MovementGenerator.h
@@ -20,7 +20,6 @@
#define TRINITY_MOVEMENTGENERATOR_H
#include "Define.h"
-#include <ace/Singleton.h>
#include "ObjectRegistry.h"
#include "FactoryHolder.h"
#include "Common.h"
@@ -92,5 +91,4 @@ struct MovementGeneratorFactory : public SelectableMovement
typedef FactoryHolder<MovementGenerator, MovementGeneratorType> MovementGeneratorCreator;
typedef FactoryHolder<MovementGenerator, MovementGeneratorType>::FactoryHolderRegistry MovementGeneratorRegistry;
-typedef FactoryHolder<MovementGenerator, MovementGeneratorType>::FactoryHolderRepository MovementGeneratorRepository;
#endif
diff --git a/src/server/game/Movement/PathGenerator.cpp b/src/server/game/Movement/PathGenerator.cpp
index d9b9b88d3dd..6acee7f7a9c 100644
--- a/src/server/game/Movement/PathGenerator.cpp
+++ b/src/server/game/Movement/PathGenerator.cpp
@@ -795,8 +795,8 @@ dtStatus PathGenerator::FindSmoothPath(float const* startPos, float const* endPo
if (!GetSteerTarget(iterPos, targetPos, SMOOTH_PATH_SLOP, polys, npolys, steerPos, steerPosFlag, steerPosRef))
break;
- bool endOfPath = (steerPosFlag & DT_STRAIGHTPATH_END);
- bool offMeshConnection = (steerPosFlag & DT_STRAIGHTPATH_OFFMESH_CONNECTION);
+ bool endOfPath = (steerPosFlag & DT_STRAIGHTPATH_END) != 0;
+ bool offMeshConnection = (steerPosFlag & DT_STRAIGHTPATH_OFFMESH_CONNECTION) != 0;
// Find movement delta.
float delta[VERTEX_SIZE];
diff --git a/src/server/game/Movement/Spline/MoveSplineFlag.h b/src/server/game/Movement/Spline/MoveSplineFlag.h
index f86ce6431ed..f9151c53fc2 100644
--- a/src/server/game/Movement/Spline/MoveSplineFlag.h
+++ b/src/server/game/Movement/Spline/MoveSplineFlag.h
@@ -86,9 +86,9 @@ namespace Movement
// Constant interface
- bool isSmooth() const { return raw() & Catmullrom; }
+ bool isSmooth() const { return (raw() & Catmullrom) != 0; }
bool isLinear() const { return !isSmooth(); }
- bool isFacing() const { return raw() & Mask_Final_Facing; }
+ bool isFacing() const { return (raw() & Mask_Final_Facing) != 0; }
uint8 getAnimationId() const { return animId; }
bool hasAllFlags(uint32 f) const { return (raw() & f) == f; }
diff --git a/src/server/game/Movement/Waypoints/WaypointManager.h b/src/server/game/Movement/Waypoints/WaypointManager.h
index bafc6322e71..b12396293aa 100644
--- a/src/server/game/Movement/Waypoints/WaypointManager.h
+++ b/src/server/game/Movement/Waypoints/WaypointManager.h
@@ -19,8 +19,6 @@
#ifndef TRINITY_WAYPOINTMANAGER_H
#define TRINITY_WAYPOINTMANAGER_H
-#include <ace/Singleton.h>
-#include <ace/Null_Mutex.h>
#include <vector>
struct WaypointData
@@ -38,9 +36,13 @@ typedef std::unordered_map<uint32, WaypointPath> WaypointPathContainer;
class WaypointMgr
{
- friend class ACE_Singleton<WaypointMgr, ACE_Null_Mutex>;
-
public:
+ static WaypointMgr* instance()
+ {
+ static WaypointMgr* instance = new WaypointMgr();
+ return instance;
+ }
+
// Attempts to reload a single path from database
void ReloadPath(uint32 id);
@@ -58,13 +60,12 @@ class WaypointMgr
}
private:
- // Only allow instantiation from ACE_Singleton
WaypointMgr();
~WaypointMgr();
WaypointPathContainer _waypointStore;
};
-#define sWaypointMgr ACE_Singleton<WaypointMgr, ACE_Null_Mutex>::instance()
+#define sWaypointMgr WaypointMgr::instance()
#endif
diff --git a/src/server/game/OutdoorPvP/OutdoorPvPMgr.h b/src/server/game/OutdoorPvP/OutdoorPvPMgr.h
index 54ea2f3ba1d..ab1908e273d 100644
--- a/src/server/game/OutdoorPvP/OutdoorPvPMgr.h
+++ b/src/server/game/OutdoorPvP/OutdoorPvPMgr.h
@@ -21,7 +21,6 @@
#define OUTDOORPVP_OBJECTIVE_UPDATE_INTERVAL 1000
#include "OutdoorPvP.h"
-#include <ace/Singleton.h>
class Player;
class GameObject;
@@ -38,13 +37,17 @@ struct OutdoorPvPData
// class to handle player enter / leave / areatrigger / GO use events
class OutdoorPvPMgr
{
- friend class ACE_Singleton<OutdoorPvPMgr, ACE_Null_Mutex>;
-
private:
OutdoorPvPMgr();
~OutdoorPvPMgr() { };
public:
+ static OutdoorPvPMgr* instance()
+ {
+ static OutdoorPvPMgr* instance = new OutdoorPvPMgr();
+ return instance;
+ }
+
// create outdoor pvp events
void InitOutdoorPvP();
@@ -101,6 +104,6 @@ class OutdoorPvPMgr
uint32 m_UpdateTimer;
};
-#define sOutdoorPvPMgr ACE_Singleton<OutdoorPvPMgr, ACE_Null_Mutex>::instance()
+#define sOutdoorPvPMgr OutdoorPvPMgr::instance()
#endif /*OUTDOOR_PVP_MGR_H_*/
diff --git a/src/server/game/Pools/PoolMgr.h b/src/server/game/Pools/PoolMgr.h
index 2bc404b3a36..0a3f52b55f6 100644
--- a/src/server/game/Pools/PoolMgr.h
+++ b/src/server/game/Pools/PoolMgr.h
@@ -20,7 +20,6 @@
#define TRINITY_POOLHANDLER_H
#include "Define.h"
-#include <ace/Singleton.h>
#include "Creature.h"
#include "GameObject.h"
#include "QuestDef.h"
@@ -104,13 +103,17 @@ typedef std::pair<PooledQuestRelation::iterator, PooledQuestRelation::iterator>
class PoolMgr
{
- friend class ACE_Singleton<PoolMgr, ACE_Null_Mutex>;
-
private:
PoolMgr();
~PoolMgr() { };
public:
+ static PoolMgr* instance()
+ {
+ static PoolMgr* instance = new PoolMgr();
+ return instance;
+ }
+
void LoadFromDB();
void LoadQuestPools();
void SaveQuestsToDB();
@@ -164,7 +167,7 @@ class PoolMgr
ActivePoolData mSpawnedData;
};
-#define sPoolMgr ACE_Singleton<PoolMgr, ACE_Null_Mutex>::instance()
+#define sPoolMgr PoolMgr::instance()
// Method that tell if the creature is part of a pool and return the pool id if yes
template<>
diff --git a/src/server/game/PrecompiledHeaders/gamePCH.h b/src/server/game/PrecompiledHeaders/gamePCH.h
index 68f628430c4..c7c6ca5d2d6 100644
--- a/src/server/game/PrecompiledHeaders/gamePCH.h
+++ b/src/server/game/PrecompiledHeaders/gamePCH.h
@@ -1,9 +1,6 @@
//add here most rarely modified headers to speed up debug build compilation
-#include "WorldSocket.h" // must be first to make ACE happy with ACE includes in it
-
#include "Common.h"
-
#include "MapManager.h"
#include "Log.h"
#include "ObjectAccessor.h"
diff --git a/src/server/game/Quests/QuestDef.cpp b/src/server/game/Quests/QuestDef.cpp
index 5f811714f3a..7c089eee07b 100644
--- a/src/server/game/Quests/QuestDef.cpp
+++ b/src/server/game/Quests/QuestDef.cpp
@@ -321,12 +321,12 @@ uint32 Quest::GetRewMoneyMaxLevel() const
bool Quest::IsAutoAccept() const
{
- return sWorld->getBoolConfig(CONFIG_QUEST_IGNORE_AUTO_ACCEPT) ? false : (Flags & QUEST_FLAGS_AUTO_ACCEPT);
+ return !sWorld->getBoolConfig(CONFIG_QUEST_IGNORE_AUTO_ACCEPT) && HasFlag(QUEST_FLAGS_AUTO_ACCEPT);
}
bool Quest::IsAutoComplete() const
{
- return sWorld->getBoolConfig(CONFIG_QUEST_IGNORE_AUTO_COMPLETE) || (Method == 0);
+ return !sWorld->getBoolConfig(CONFIG_QUEST_IGNORE_AUTO_COMPLETE) && Method == 0;
}
bool Quest::IsRaidQuest(Difficulty difficulty) const
diff --git a/src/server/game/Quests/QuestDef.h b/src/server/game/Quests/QuestDef.h
index 9f84795f488..79b7a4b428e 100644
--- a/src/server/game/Quests/QuestDef.h
+++ b/src/server/game/Quests/QuestDef.h
@@ -288,14 +288,14 @@ class Quest
uint32 GetRewardReputationMask() const { return RewardReputationMask; }
uint32 GetQuestGiverPortrait() const { return QuestGiverPortrait; }
uint32 GetQuestTurnInPortrait() const { return QuestTurnInPortrait; }
- bool IsDaily() const { return Flags & QUEST_FLAGS_DAILY; }
- bool IsWeekly() const { return Flags & QUEST_FLAGS_WEEKLY; }
- bool IsMonthly() const { return SpecialFlags & QUEST_SPECIAL_FLAGS_MONTHLY; }
+ bool IsDaily() const { return (Flags & QUEST_FLAGS_DAILY) != 0; }
+ bool IsWeekly() const { return (Flags & QUEST_FLAGS_WEEKLY) != 0; }
+ bool IsMonthly() const { return (SpecialFlags & QUEST_SPECIAL_FLAGS_MONTHLY) != 0; }
bool IsSeasonal() const { return (ZoneOrSort == -QUEST_SORT_SEASONAL || ZoneOrSort == -QUEST_SORT_SPECIAL || ZoneOrSort == -QUEST_SORT_LUNAR_FESTIVAL || ZoneOrSort == -QUEST_SORT_MIDSUMMER || ZoneOrSort == -QUEST_SORT_BREWFEST || ZoneOrSort == -QUEST_SORT_LOVE_IS_IN_THE_AIR || ZoneOrSort == -QUEST_SORT_NOBLEGARDEN) && !IsRepeatable(); }
- bool IsDailyOrWeekly() const { return Flags & (QUEST_FLAGS_DAILY | QUEST_FLAGS_WEEKLY); }
+ bool IsDailyOrWeekly() const { return (Flags & (QUEST_FLAGS_DAILY | QUEST_FLAGS_WEEKLY)) != 0; }
bool IsRaidQuest(Difficulty difficulty) const;
bool IsAllowedInRaid(Difficulty difficulty) const;
- bool IsDFQuest() const { return SpecialFlags & QUEST_SPECIAL_FLAGS_DF_QUEST; }
+ bool IsDFQuest() const { return (SpecialFlags & QUEST_SPECIAL_FLAGS_DF_QUEST) != 0; }
uint32 CalculateHonorGain(uint8 level) const;
// multiple values
diff --git a/src/server/game/Reputation/ReputationMgr.cpp b/src/server/game/Reputation/ReputationMgr.cpp
index df6497f2513..b136e6893cd 100644
--- a/src/server/game/Reputation/ReputationMgr.cpp
+++ b/src/server/game/Reputation/ReputationMgr.cpp
@@ -60,7 +60,7 @@ bool ReputationMgr::IsAtWar(FactionEntry const* factionEntry) const
return false;
if (FactionState const* factionState = GetState(factionEntry))
- return (factionState->Flags & FACTION_FLAG_AT_WAR);
+ return (factionState->Flags & FACTION_FLAG_AT_WAR) != 0;
return false;
}
diff --git a/src/server/game/Scripting/MapScripts.cpp b/src/server/game/Scripting/MapScripts.cpp
index 58ad725d570..7c82b806cf8 100644
--- a/src/server/game/Scripting/MapScripts.cpp
+++ b/src/server/game/Scripting/MapScripts.cpp
@@ -806,7 +806,7 @@ void Map::ScriptsProcess()
if (!sWaypointMgr->GetPath(step.script->LoadPath.PathID))
TC_LOG_ERROR("scripts", "%s source object has an invalid path (%u), skipping.", step.script->GetDebugInfo().c_str(), step.script->LoadPath.PathID);
else
- unit->GetMotionMaster()->MovePath(step.script->LoadPath.PathID, step.script->LoadPath.IsRepeatable);
+ unit->GetMotionMaster()->MovePath(step.script->LoadPath.PathID, step.script->LoadPath.IsRepeatable != 0);
}
break;
diff --git a/src/server/game/Scripting/ScriptMgr.cpp b/src/server/game/Scripting/ScriptMgr.cpp
index ee0cb11983e..e437875d57a 100644
--- a/src/server/game/Scripting/ScriptMgr.cpp
+++ b/src/server/game/Scripting/ScriptMgr.cpp
@@ -175,8 +175,10 @@ struct TSpellSummary
uint8 Effects; // set of enum SelectEffect
} *SpellSummary;
-ScriptMgr::ScriptMgr()
- : _scriptCount(0), _scheduledScripts(0) { }
+ScriptMgr::ScriptMgr() : _scriptCount(0)
+{
+ _scheduledScripts = 0;
+}
ScriptMgr::~ScriptMgr() { }
@@ -398,35 +400,35 @@ void ScriptMgr::OnNetworkStop()
FOREACH_SCRIPT(ServerScript)->OnNetworkStop();
}
-void ScriptMgr::OnSocketOpen(WorldSocket* socket)
+void ScriptMgr::OnSocketOpen(std::shared_ptr<WorldSocket> socket)
{
ASSERT(socket);
FOREACH_SCRIPT(ServerScript)->OnSocketOpen(socket);
}
-void ScriptMgr::OnSocketClose(WorldSocket* socket, bool wasNew)
+void ScriptMgr::OnSocketClose(std::shared_ptr<WorldSocket> socket, bool wasNew)
{
ASSERT(socket);
FOREACH_SCRIPT(ServerScript)->OnSocketClose(socket, wasNew);
}
-void ScriptMgr::OnPacketReceive(WorldSocket* socket, WorldPacket packet)
+void ScriptMgr::OnPacketReceive(std::shared_ptr<WorldSocket> socket, WorldPacket packet)
{
ASSERT(socket);
FOREACH_SCRIPT(ServerScript)->OnPacketReceive(socket, packet);
}
-void ScriptMgr::OnPacketSend(WorldSocket* socket, WorldPacket packet)
+void ScriptMgr::OnPacketSend(std::shared_ptr<WorldSocket> socket, WorldPacket packet)
{
ASSERT(socket);
FOREACH_SCRIPT(ServerScript)->OnPacketSend(socket, packet);
}
-void ScriptMgr::OnUnknownPacketReceive(WorldSocket* socket, WorldPacket packet)
+void ScriptMgr::OnUnknownPacketReceive(std::shared_ptr<WorldSocket> socket, WorldPacket packet)
{
ASSERT(socket);
diff --git a/src/server/game/Scripting/ScriptMgr.h b/src/server/game/Scripting/ScriptMgr.h
index 00060bea90c..fc06dca6355 100644
--- a/src/server/game/Scripting/ScriptMgr.h
+++ b/src/server/game/Scripting/ScriptMgr.h
@@ -19,10 +19,8 @@
#ifndef SC_SCRIPTMGR_H
#define SC_SCRIPTMGR_H
+#include <atomic>
#include "Common.h"
-#include <ace/Singleton.h>
-#include <ace/Atomic_Op.h>
-
#include "DBCStores.h"
#include "QuestDef.h"
#include "SharedDefines.h"
@@ -215,30 +213,30 @@ class ServerScript : public ScriptObject
public:
- // Called when reactive socket I/O is started (WorldSocketMgr).
+ // Called when reactive socket I/O is started (WorldTcpSessionMgr).
virtual void OnNetworkStart() { }
// Called when reactive I/O is stopped.
virtual void OnNetworkStop() { }
// Called when a remote socket establishes a connection to the server. Do not store the socket object.
- virtual void OnSocketOpen(WorldSocket* /*socket*/) { }
+ virtual void OnSocketOpen(std::shared_ptr<WorldSocket> /*socket*/) { }
// Called when a socket is closed. Do not store the socket object, and do not rely on the connection
// being open; it is not.
- virtual void OnSocketClose(WorldSocket* /*socket*/, bool /*wasNew*/) { }
+ virtual void OnSocketClose(std::shared_ptr<WorldSocket> /*socket*/, bool /*wasNew*/) { }
// Called when a packet is sent to a client. The packet object is a copy of the original packet, so reading
// and modifying it is safe.
- virtual void OnPacketSend(WorldSocket* /*socket*/, WorldPacket& /*packet*/) { }
+ virtual void OnPacketSend(std::shared_ptr<WorldSocket> /*socket*/, WorldPacket& /*packet*/) { }
// Called when a (valid) packet is received by a client. The packet object is a copy of the original packet, so
// reading and modifying it is safe.
- virtual void OnPacketReceive(WorldSocket* /*socket*/, WorldPacket& /*packet*/) { }
+ virtual void OnPacketReceive(std::shared_ptr<WorldSocket> /*socket*/, WorldPacket& /*packet*/) { }
// Called when an invalid (unknown opcode) packet is received by a client. The packet is a reference to the orignal
// packet; not a copy. This allows you to actually handle unknown packets (for whatever purpose).
- virtual void OnUnknownPacketReceive(WorldSocket* /*socket*/, WorldPacket& /*packet*/) { }
+ virtual void OnUnknownPacketReceive(std::shared_ptr<WorldSocket> /*socket*/, WorldPacket& /*packet*/) { }
};
class WorldScript : public ScriptObject
@@ -868,20 +866,23 @@ class GroupScript : public ScriptObject
};
// Placed here due to ScriptRegistry::AddScript dependency.
-#define sScriptMgr ACE_Singleton<ScriptMgr, ACE_Null_Mutex>::instance()
+#define sScriptMgr ScriptMgr::instance()
// Manages registration, loading, and execution of scripts.
class ScriptMgr
{
- friend class ACE_Singleton<ScriptMgr, ACE_Null_Mutex>;
friend class ScriptObject;
private:
-
ScriptMgr();
virtual ~ScriptMgr();
public: /* Initialization */
+ static ScriptMgr* instance()
+ {
+ static ScriptMgr* instance = new ScriptMgr();
+ return instance;
+ }
void Initialize();
void LoadDatabase();
@@ -906,11 +907,11 @@ class ScriptMgr
void OnNetworkStart();
void OnNetworkStop();
- void OnSocketOpen(WorldSocket* socket);
- void OnSocketClose(WorldSocket* socket, bool wasNew);
- void OnPacketReceive(WorldSocket* socket, WorldPacket packet);
- void OnPacketSend(WorldSocket* socket, WorldPacket packet);
- void OnUnknownPacketReceive(WorldSocket* socket, WorldPacket packet);
+ void OnSocketOpen(std::shared_ptr<WorldSocket> socket);
+ void OnSocketClose(std::shared_ptr<WorldSocket> socket, bool wasNew);
+ void OnPacketReceive(std::shared_ptr<WorldSocket> socket, WorldPacket packet);
+ void OnPacketSend(std::shared_ptr<WorldSocket> socket, WorldPacket packet);
+ void OnUnknownPacketReceive(std::shared_ptr<WorldSocket> socket, WorldPacket packet);
public: /* WorldScript */
@@ -1125,7 +1126,7 @@ class ScriptMgr
uint32 _scriptCount;
//atomic op counter for active scripts amount
- ACE_Atomic_Op<ACE_Thread_Mutex, long> _scheduledScripts;
+ std::atomic_long _scheduledScripts;
};
#endif
diff --git a/src/server/game/Scripting/ScriptSystem.h b/src/server/game/Scripting/ScriptSystem.h
index 11120f3031b..636343838c1 100644
--- a/src/server/game/Scripting/ScriptSystem.h
+++ b/src/server/game/Scripting/ScriptSystem.h
@@ -6,7 +6,6 @@
#define SC_SYSTEM_H
#include "ScriptMgr.h"
-#include <ace/Singleton.h>
#define TEXT_SOURCE_RANGE -1000000 //the amount of entries each text source has available
@@ -48,11 +47,17 @@ typedef std::vector<ScriptPointMove> ScriptPointVector;
class SystemMgr
{
- friend class ACE_Singleton<SystemMgr, ACE_Null_Mutex>;
+ private:
SystemMgr() { }
~SystemMgr() { }
public:
+ static SystemMgr* instance()
+ {
+ static SystemMgr* instance = new SystemMgr();
+ return instance;
+ }
+
typedef std::unordered_map<uint32, ScriptPointVector> PointMoveMap;
//Database
@@ -75,6 +80,6 @@ class SystemMgr
static ScriptPointVector const _empty;
};
-#define sScriptSystemMgr ACE_Singleton<SystemMgr, ACE_Null_Mutex>::instance()
+#define sScriptSystemMgr SystemMgr::instance()
#endif
diff --git a/src/server/game/Server/Protocol/PacketLog.h b/src/server/game/Server/Protocol/PacketLog.h
index 9c60655e627..71d87bf45ae 100644
--- a/src/server/game/Server/Protocol/PacketLog.h
+++ b/src/server/game/Server/Protocol/PacketLog.h
@@ -19,7 +19,6 @@
#define TRINITY_PACKETLOG_H
#include "Common.h"
-#include <ace/Singleton.h>
enum Direction
{
@@ -31,13 +30,17 @@ class WorldPacket;
class PacketLog
{
- friend class ACE_Singleton<PacketLog, ACE_Thread_Mutex>;
-
private:
PacketLog();
~PacketLog();
public:
+ static PacketLog* instance()
+ {
+ static PacketLog* instance = new PacketLog();
+ return instance;
+ }
+
void Initialize();
bool CanLogPacket() const { return (_file != NULL); }
void LogPacket(WorldPacket const& packet, Direction direction);
@@ -46,5 +49,5 @@ class PacketLog
FILE* _file;
};
-#define sPacketLog ACE_Singleton<PacketLog, ACE_Thread_Mutex>::instance()
+#define sPacketLog PacketLog::instance()
#endif
diff --git a/src/server/game/Server/Protocol/ServerPktHeader.h b/src/server/game/Server/Protocol/ServerPktHeader.h
new file mode 100644
index 00000000000..4b0dae9f0f3
--- /dev/null
+++ b/src/server/game/Server/Protocol/ServerPktHeader.h
@@ -0,0 +1,59 @@
+/*
+* 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 __SERVERPKTHDR_H__
+#define __SERVERPKTHDR_H__
+
+#include "Log.h"
+
+struct ServerPktHeader
+{
+ /**
+ * size is the length of the payload _plus_ the length of the opcode
+ */
+ ServerPktHeader(uint32 size, uint16 cmd) : size(size)
+ {
+ uint8 headerIndex=0;
+ if (isLargePacket())
+ {
+ TC_LOG_DEBUG("network", "initializing large server to client packet. Size: %u, cmd: %u", size, cmd);
+ header[headerIndex++] = 0x80 | (0xFF & (size >> 16));
+ }
+ header[headerIndex++] = 0xFF &(size >> 8);
+ header[headerIndex++] = 0xFF & size;
+
+ header[headerIndex++] = 0xFF & cmd;
+ header[headerIndex++] = 0xFF & (cmd >> 8);
+ }
+
+ uint8 getHeaderLength()
+ {
+ // cmd = 2 bytes, size= 2||3bytes
+ return 2 + (isLargePacket() ? 3 : 2);
+ }
+
+ bool isLargePacket() const
+ {
+ return size > 0x7FFF;
+ }
+
+ const uint32 size;
+ uint8 header[5];
+};
+
+#endif
diff --git a/src/server/game/Server/WorldSession.cpp b/src/server/game/Server/WorldSession.cpp
index 2ece2942a56..cabb0ef0494 100644
--- a/src/server/game/Server/WorldSession.cpp
+++ b/src/server/game/Server/WorldSession.cpp
@@ -20,7 +20,7 @@
\ingroup u2w
*/
-#include "WorldSocket.h" // must be first to make ACE happy with ACE includes in it
+#include "WorldSocket.h"
#include <zlib.h>
#include "Config.h"
#include "Common.h"
@@ -99,7 +99,7 @@ bool WorldSessionFilter::Process(WorldPacket* packet)
}
/// WorldSession constructor
-WorldSession::WorldSession(uint32 id, uint32 battlenetAccountId, WorldSocket* sock, AccountTypes sec, uint8 expansion, time_t mute_time, LocaleConstant locale, uint32 recruiter, bool isARecruiter):
+WorldSession::WorldSession(uint32 id, uint32 battlenetAccountId, std::shared_ptr<WorldSocket> sock, AccountTypes sec, uint8 expansion, time_t mute_time, LocaleConstant locale, uint32 recruiter, bool isARecruiter):
m_muteTime(mute_time),
m_timeOutTime(0),
AntiDOS(this),
@@ -134,8 +134,7 @@ WorldSession::WorldSession(uint32 id, uint32 battlenetAccountId, WorldSocket* so
if (sock)
{
- m_Address = sock->GetRemoteAddress();
- sock->AddReference();
+ m_Address = sock->GetRemoteIpAddress();
ResetTimeOutTime();
LoginDatabase.PExecute("UPDATE account SET online = 1 WHERE id = %u;", GetAccountId()); // One-time query
}
@@ -164,8 +163,7 @@ WorldSession::~WorldSession()
if (m_Socket)
{
m_Socket->CloseSocket();
- m_Socket->RemoveReference();
- m_Socket = NULL;
+ m_Socket = nullptr;
}
delete _warden;
@@ -268,8 +266,7 @@ void WorldSession::SendPacket(WorldPacket const* packet, bool forced /*= false*/
}
#endif // !TRINITY_DEBUG
- if (m_Socket->SendPacket(*packet) == -1)
- m_Socket->CloseSocket();
+ m_Socket->AsyncWrite(*packet);
}
/// Add an incoming packet to the queue
@@ -322,9 +319,7 @@ bool WorldSession::Update(uint32 diff, PacketFilter& updater)
uint32 processedPackets = 0;
time_t currentTime = time(NULL);
- while (m_Socket && !m_Socket->IsClosed() &&
- !_recvQueue.empty() && _recvQueue.peek(true) != firstDelayedPacket &&
- _recvQueue.next(packet, updater))
+ while (m_Socket && !_recvQueue.empty() && _recvQueue.peek(true) != firstDelayedPacket && _recvQueue.next(packet, updater))
{
if (!AntiDOS.EvaluateOpcode(*packet, currentTime))
KickPlayer();
@@ -433,7 +428,7 @@ bool WorldSession::Update(uint32 diff, PacketFilter& updater)
break;
}
- if (m_Socket && !m_Socket->IsClosed() && _warden)
+ if (m_Socket && m_Socket->IsOpen() && _warden)
_warden->Update();
ProcessQueryCallbacks();
@@ -451,13 +446,12 @@ bool WorldSession::Update(uint32 diff, PacketFilter& updater)
_warden->Update();
///- Cleanup socket pointer if need
- if (m_Socket && m_Socket->IsClosed())
+ if (m_Socket && !m_Socket->IsOpen())
{
expireTime -= expireTime > diff ? diff : expireTime;
if (expireTime < diff || forceExit)
{
- m_Socket->RemoveReference();
- m_Socket = NULL;
+ m_Socket = nullptr;
}
}
@@ -823,7 +817,7 @@ void WorldSession::SaveTutorialsData(SQLTransaction &trans)
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_HAS_TUTORIALS);
stmt->setUInt32(0, GetAccountId());
- bool hasTutorials = !CharacterDatabase.Query(stmt).null();
+ bool hasTutorials = bool(CharacterDatabase.Query(stmt));
// Modify data in DB
stmt = CharacterDatabase.GetPreparedStatement(hasTutorials ? CHAR_UPD_TUTORIALS : CHAR_INS_TUTORIALS);
for (uint8 i = 0; i < MAX_ACCOUNT_TUTORIAL_VALUES; ++i)
@@ -1046,27 +1040,23 @@ void WorldSession::ProcessQueryCallbacks()
PreparedQueryResult result;
//! HandleCharEnumOpcode
- if (_charEnumCallback.ready())
+ if (_charEnumCallback.valid() && _charEnumCallback.wait_for(std::chrono::seconds(0)) == std::future_status::ready)
{
- _charEnumCallback.get(result);
+ result = _charEnumCallback.get();
HandleCharEnum(result);
- _charEnumCallback.cancel();
}
if (_charCreateCallback.IsReady())
{
_charCreateCallback.GetResult(result);
HandleCharCreateCallback(result, _charCreateCallback.GetParam());
- // Don't call FreeResult() here, the callback handler will do that depending on the events in the callback chain
}
//! HandlePlayerLoginOpcode
- if (_charLoginCallback.ready())
+ if (_charLoginCallback.valid() && _charLoginCallback.wait_for(std::chrono::seconds(0)) == std::future_status::ready)
{
- SQLQueryHolder* param;
- _charLoginCallback.get(param);
+ SQLQueryHolder* param = _charLoginCallback.get();
HandlePlayerLogin((LoginQueryHolder*)param);
- _charLoginCallback.cancel();
}
//! HandleAddFriendOpcode
@@ -1088,11 +1078,10 @@ void WorldSession::ProcessQueryCallbacks()
}
//- HandleCharAddIgnoreOpcode
- if (_addIgnoreCallback.ready())
+ if (_addIgnoreCallback.valid() && _addIgnoreCallback.wait_for(std::chrono::seconds(0)) == std::future_status::ready)
{
- _addIgnoreCallback.get(result);
+ result = _addIgnoreCallback.get();
HandleAddIgnoreOpcodeCallBack(result);
- _addIgnoreCallback.cancel();
}
//- SendStabledPet
@@ -1105,11 +1094,10 @@ void WorldSession::ProcessQueryCallbacks()
}
//- HandleStablePet
- if (_stablePetCallback.ready())
+ if (_stablePetCallback.valid() && _stablePetCallback.wait_for(std::chrono::seconds(0)) == std::future_status::ready)
{
- _stablePetCallback.get(result);
+ result = _stablePetCallback.get();
HandleStablePetCallback(result);
- _stablePetCallback.cancel();
}
//- HandleUnstablePet
diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h
index 96f7d3d2535..96a66bf2421 100644
--- a/src/server/game/Server/WorldSession.h
+++ b/src/server/game/Server/WorldSession.h
@@ -215,7 +215,7 @@ struct PacketCounter
class WorldSession
{
public:
- WorldSession(uint32 id, uint32 battlenetAccountId, WorldSocket* sock, AccountTypes sec, uint8 expansion, time_t mute_time, LocaleConstant locale, uint32 recruiter, bool isARecruiter);
+ WorldSession(uint32 id, uint32 battlenetAccountId, std::shared_ptr<WorldSocket> sock, AccountTypes sec, uint8 expansion, time_t mute_time, LocaleConstant locale, uint32 recruiter, bool isARecruiter);
~WorldSession();
bool PlayerLoading() const { return m_playerLoading; }
@@ -379,10 +379,11 @@ class WorldSession
void SetLatency(uint32 latency) { m_latency = latency; }
void ResetClientTimeDelay() { m_clientTimeDelay = 0; }
- ACE_Atomic_Op<ACE_Thread_Mutex, time_t> m_timeOutTime;
+ std::atomic<time_t> m_timeOutTime;
+
void UpdateTimeOutTime(uint32 diff)
{
- if (time_t(diff) > m_timeOutTime.value())
+ if (time_t(diff) > m_timeOutTime)
m_timeOutTime = 0;
else
m_timeOutTime -= diff;
@@ -1038,7 +1039,7 @@ class WorldSession
uint32 m_GUIDLow; // set logined or recently logout player (while m_playerRecentlyLogout set)
Player* _player;
- WorldSocket* m_Socket;
+ std::shared_ptr<WorldSocket> m_Socket;
std::string m_Address; // Current Remote Address
// std::string m_LAddress; // Last Attempted Remote Adress - we can not set attempted ip for a non-existing session!
@@ -1060,8 +1061,8 @@ class WorldSession
bool m_playerSave;
LocaleConstant m_sessionDbcLocale;
LocaleConstant m_sessionDbLocaleIndex;
- uint32 m_latency;
- uint32 m_clientTimeDelay;
+ std::atomic<uint32> m_latency;
+ std::atomic<uint32> m_clientTimeDelay;
AccountData m_accountData[NUM_ACCOUNT_DATA_TYPES];
uint32 m_Tutorials[MAX_ACCOUNT_TUTORIAL_VALUES];
bool m_TutorialsChanged;
@@ -1070,7 +1071,7 @@ class WorldSession
bool _filterAddonMessages;
uint32 recruiterId;
bool isRecruiter;
- ACE_Based::LockedQueue<WorldPacket*, ACE_Thread_Mutex> _recvQueue;
+ LockedQueue<WorldPacket*> _recvQueue;
z_stream_s* _compressionStream;
rbac::RBACData* _RBACData;
uint32 expireTime;
diff --git a/src/server/game/Server/WorldSocket.cpp b/src/server/game/Server/WorldSocket.cpp
index d06d680aea5..2aa24e10d9d 100644
--- a/src/server/game/Server/WorldSocket.cpp
+++ b/src/server/game/Server/WorldSocket.cpp
@@ -16,782 +16,205 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include <ace/Message_Block.h>
-#include <ace/OS_NS_string.h>
-#include <ace/OS_NS_unistd.h>
-#include <ace/os_include/arpa/os_inet.h>
-#include <ace/os_include/netinet/os_tcp.h>
-#include <ace/os_include/sys/os_types.h>
-#include <ace/os_include/sys/os_socket.h>
-#include <ace/OS_NS_string.h>
-#include <ace/Reactor.h>
-#include <ace/Auto_Ptr.h>
-
+#include <boost/asio/write.hpp>
+#include <boost/asio/read_until.hpp>
+#include <memory>
#include "WorldSocket.h"
-#include "Common.h"
-#include "Player.h"
-#include "Util.h"
-#include "World.h"
-#include "WorldPacket.h"
-#include "SharedDefines.h"
-#include "ByteBuffer.h"
-#include "Opcodes.h"
-#include "DatabaseEnv.h"
+#include "ServerPktHeader.h"
#include "BigNumber.h"
-#include "SHA1.h"
-#include "WorldSession.h"
-#include "WorldSocketMgr.h"
-#include "Log.h"
-#include "PacketLog.h"
+#include "Opcodes.h"
#include "ScriptMgr.h"
-#include "AccountMgr.h"
+#include "SHA1.h"
#include "BattlenetAccountMgr.h"
-#if defined(__GNUC__)
-#pragma pack(1)
-#else
-#pragma pack(push, 1)
-#endif
-
-struct ServerPktHeader
-{
- /**
- * size is the length of the payload _plus_ the length of the opcode
- */
- ServerPktHeader(uint32 size, uint16 cmd) : size(size)
- {
- uint8 headerIndex=0;
- if (isLargePacket())
- {
- TC_LOG_DEBUG("network", "initializing large server to client packet. Size: %u, cmd: %u", size, cmd);
- header[headerIndex++] = 0x80 | (0xFF & (size >> 16));
- }
- header[headerIndex++] = 0xFF &(size >> 8);
- header[headerIndex++] = 0xFF & size;
-
- header[headerIndex++] = 0xFF & cmd;
- header[headerIndex++] = 0xFF & (cmd >> 8);
- }
-
- uint8 getHeaderLength()
- {
- // cmd = 2 bytes, size= 2||3bytes
- return 2 + (isLargePacket() ? 3 : 2);
- }
-
- bool isLargePacket() const
- {
- return size > 0x7FFF;
- }
-
- const uint32 size;
- uint8 header[5];
-};
-
-struct ClientPktHeader
-{
- uint16 size;
- uint32 cmd;
-};
-
-#if defined(__GNUC__)
-#pragma pack()
-#else
-#pragma pack(pop)
-#endif
-
-WorldSocket::WorldSocket (void): WorldHandler(),
-m_LastPingTime(ACE_Time_Value::zero), m_OverSpeedPings(0), m_Session(0),
-m_RecvWPct(0), m_RecvPct(), m_Header(sizeof (ClientPktHeader)),
-m_OutBuffer(0), m_OutBufferSize(65536), m_OutActive(false),
-m_Seed(static_cast<uint32> (rand32()))
-{
- reference_counting_policy().value (ACE_Event_Handler::Reference_Counting_Policy::ENABLED);
-
- msg_queue()->high_water_mark(8 * 1024 * 1024);
- msg_queue()->low_water_mark(8 * 1024 * 1024);
-}
-
-WorldSocket::~WorldSocket (void)
-{
- delete m_RecvWPct;
-
- if (m_OutBuffer)
- m_OutBuffer->release();
-
- closing_ = true;
-
- peer().close();
-}
-
-bool WorldSocket::IsClosed (void) const
-{
- return closing_;
-}
-
-void WorldSocket::CloseSocket (void)
-{
- {
- ACE_GUARD (LockType, Guard, m_OutBufferLock);
-
- if (closing_)
- return;
-
- closing_ = true;
- peer().close_writer();
- }
-
- {
- ACE_GUARD (LockType, Guard, m_SessionLock);
-
- m_Session = NULL;
- }
-}
-
-const std::string& WorldSocket::GetRemoteAddress (void) const
-{
- return m_Address;
-}
-
-int WorldSocket::SendPacket(WorldPacket const& pct)
-{
- ACE_GUARD_RETURN (LockType, Guard, m_OutBufferLock, -1);
-
- if (closing_)
- return -1;
-
- // Dump outgoing packet
- if (sPacketLog->CanLogPacket())
- sPacketLog->LogPacket(pct, SERVER_TO_CLIENT);
-
- WorldPacket const* pkt = &pct;
-
- // Empty buffer used in case packet should be compressed
- WorldPacket buff;
- if (m_Session && pkt->size() > 0x400)
- {
- buff.Compress(m_Session->GetCompressionStream(), pkt);
- pkt = &buff;
- }
-
- if (m_Session)
- TC_LOG_TRACE("network.opcode", "S->C: %s %s", m_Session->GetPlayerInfo().c_str(), GetOpcodeNameForLogging(pkt->GetOpcode()).c_str());
+using boost::asio::ip::tcp;
+using boost::asio::streambuf;
- sScriptMgr->OnPacketSend(this, *pkt);
-
- ServerPktHeader header(pkt->size()+2, pkt->GetOpcode());
- m_Crypt.EncryptSend ((uint8*)header.header, header.getHeaderLength());
-
- if (m_OutBuffer->space() >= pkt->size() + header.getHeaderLength() && msg_queue()->is_empty())
- {
- // Put the packet on the buffer.
- if (m_OutBuffer->copy((char*) header.header, header.getHeaderLength()) == -1)
- ACE_ASSERT (false);
-
- if (!pkt->empty())
- if (m_OutBuffer->copy((char*) pkt->contents(), pkt->size()) == -1)
- ACE_ASSERT (false);
- }
- else
- {
- // Enqueue the packet.
- ACE_Message_Block* mb;
-
- ACE_NEW_RETURN(mb, ACE_Message_Block(pkt->size() + header.getHeaderLength()), -1);
-
- mb->copy((char*) header.header, header.getHeaderLength());
-
- if (!pkt->empty())
- mb->copy((const char*)pkt->contents(), pkt->size());
-
- if (msg_queue()->enqueue_tail(mb, (ACE_Time_Value*)&ACE_Time_Value::zero) == -1)
- {
- TC_LOG_ERROR("network", "WorldSocket::SendPacket enqueue_tail failed");
- mb->release();
- return -1;
- }
- }
-
- return 0;
-}
-
-long WorldSocket::AddReference (void)
+WorldSocket::WorldSocket(tcp::socket&& socket)
+ : _socket(std::move(socket)), _authSeed(static_cast<uint32>(rand32())), _OverSpeedPings(0), _worldSession(nullptr)
{
- return static_cast<long> (add_reference());
}
-long WorldSocket::RemoveReference (void)
+void WorldSocket::Start()
{
- return static_cast<long> (remove_reference());
-}
-
-int WorldSocket::open (void *a)
-{
- ACE_UNUSED_ARG (a);
-
- // Prevent double call to this func.
- if (m_OutBuffer)
- return -1;
-
- // This will also prevent the socket from being Updated
- // while we are initializing it.
- m_OutActive = true;
-
- // Hook for the manager.
- if (sWorldSocketMgr->OnSocketOpen(this) == -1)
- return -1;
-
- // Allocate the buffer.
- ACE_NEW_RETURN (m_OutBuffer, ACE_Message_Block (m_OutBufferSize), -1);
-
- // Store peer address.
- ACE_INET_Addr remote_addr;
-
- if (peer().get_remote_addr(remote_addr) == -1)
- {
- TC_LOG_ERROR("network", "WorldSocket::open: peer().get_remote_addr errno = %s", ACE_OS::strerror (errno));
- return -1;
- }
-
- m_Address = remote_addr.get_host_addr();
+ AsyncReadHeader();
// not an opcode. this packet sends raw string WORLD OF WARCRAFT CONNECTION - SERVER TO CLIENT"
- // because of our implementation, bytes "WO" become the opcode
+ // because of our implementation of WorldPacket sending, bytes "WO" become the opcode
WorldPacket packet(MSG_VERIFY_CONNECTIVITY);
packet << "RLD OF WARCRAFT CONNECTION - SERVER TO CLIENT";
-
- if (SendPacket(packet) == -1)
- return -1;
-
- // Register with ACE Reactor
- if (reactor()->register_handler(this, ACE_Event_Handler::READ_MASK | ACE_Event_Handler::WRITE_MASK) == -1)
- {
- TC_LOG_ERROR("network", "WorldSocket::open: unable to register client handler errno = %s", ACE_OS::strerror (errno));
- return -1;
- }
-
- // reactor takes care of the socket from now on
- remove_reference();
-
- return 0;
+ AsyncWrite(packet);
}
-int WorldSocket::close(u_long)
+void WorldSocket::HandleSendAuthSession()
{
- shutdown();
-
- closing_ = true;
+ WorldPacket packet(SMSG_AUTH_CHALLENGE, 37);
+ BigNumber seed1;
+ seed1.SetRand(16 * 8);
+ packet.append(seed1.AsByteArray(16).get(), 16); // new encryption seeds
- remove_reference();
+ BigNumber seed2;
+ seed2.SetRand(16 * 8);
+ packet.append(seed2.AsByteArray(16).get(), 16); // new encryption seeds
- return 0;
+ packet << uint32(_authSeed);
+ packet << uint8(1);
+ AsyncWrite(packet);
}
-int WorldSocket::handle_input(ACE_HANDLE)
+void WorldSocket::AsyncReadHeader()
{
- if (closing_)
- return -1;
-
- switch (handle_input_missing_data())
+ auto self(shared_from_this());
+ _socket.async_read_some(boost::asio::buffer(_readBuffer, sizeof(ClientPktHeader)), [this, self](boost::system::error_code error, size_t transferedBytes)
{
- case -1 :
+ if (!error && transferedBytes == sizeof(ClientPktHeader))
{
- if ((errno == EWOULDBLOCK) ||
- (errno == EAGAIN))
- {
- return Update(); // interesting line, isn't it ?
- }
+ ClientPktHeader* header = (ClientPktHeader*)&_readBuffer;
- TC_LOG_DEBUG("network", "WorldSocket::handle_input: Peer error closing connection errno = %s", ACE_OS::strerror (errno));
+ if (_worldSession)
+ _authCrypt.DecryptRecv((uint8*)header, sizeof(ClientPktHeader));
- errno = ECONNRESET;
- return -1;
- }
- case 0:
- {
- TC_LOG_DEBUG("network", "WorldSocket::handle_input: Peer has closed connection");
+ EndianConvertReverse(header->size);
+ EndianConvert(header->cmd);
- errno = ECONNRESET;
- return -1;
+ AsyncReadData(header->size - sizeof(header->cmd));
}
- case 1:
- return 1;
- default:
- return Update(); // another interesting line ;)
- }
-
- ACE_NOTREACHED(return -1);
-}
-
-int WorldSocket::handle_output(ACE_HANDLE)
-{
- ACE_GUARD_RETURN (LockType, Guard, m_OutBufferLock, -1);
-
- if (closing_)
- return -1;
-
- size_t send_len = m_OutBuffer->length();
-
- if (send_len == 0)
- return handle_output_queue(Guard);
-
-#ifdef MSG_NOSIGNAL
- ssize_t n = peer().send (m_OutBuffer->rd_ptr(), send_len, MSG_NOSIGNAL);
-#else
- ssize_t n = peer().send (m_OutBuffer->rd_ptr(), send_len);
-#endif // MSG_NOSIGNAL
-
- if (n == 0)
- return -1;
- else if (n == -1)
- {
- if (errno == EWOULDBLOCK || errno == EAGAIN)
- return schedule_wakeup_output (Guard);
-
- return -1;
- }
- else if (n < (ssize_t)send_len) //now n > 0
- {
- m_OutBuffer->rd_ptr (static_cast<size_t> (n));
-
- // move the data to the base of the buffer
- m_OutBuffer->crunch();
-
- return schedule_wakeup_output (Guard);
- }
- else //now n == send_len
- {
- m_OutBuffer->reset();
-
- return handle_output_queue (Guard);
- }
-
- ACE_NOTREACHED (return 0);
-}
-
-int WorldSocket::handle_output_queue(GuardType& g)
-{
- if (msg_queue()->is_empty())
- return cancel_wakeup_output(g);
-
- ACE_Message_Block* mblk;
-
- if (msg_queue()->dequeue_head(mblk, (ACE_Time_Value*)&ACE_Time_Value::zero) == -1)
- {
- TC_LOG_ERROR("network", "WorldSocket::handle_output_queue dequeue_head");
- return -1;
- }
-
- const size_t send_len = mblk->length();
-
-#ifdef MSG_NOSIGNAL
- ssize_t n = peer().send(mblk->rd_ptr(), send_len, MSG_NOSIGNAL);
-#else
- ssize_t n = peer().send(mblk->rd_ptr(), send_len);
-#endif // MSG_NOSIGNAL
-
- if (n == 0)
- {
- mblk->release();
-
- return -1;
- }
- else if (n == -1)
- {
- if (errno == EWOULDBLOCK || errno == EAGAIN)
- {
- msg_queue()->enqueue_head(mblk, (ACE_Time_Value*) &ACE_Time_Value::zero);
- return schedule_wakeup_output (g);
- }
-
- mblk->release();
- return -1;
- }
- else if (n < (ssize_t)send_len) //now n > 0
- {
- mblk->rd_ptr(static_cast<size_t> (n));
-
- if (msg_queue()->enqueue_head(mblk, (ACE_Time_Value*) &ACE_Time_Value::zero) == -1)
+ else
{
- TC_LOG_ERROR("network", "WorldSocket::handle_output_queue enqueue_head");
- mblk->release();
- return -1;
+ _socket.close();
}
-
- return schedule_wakeup_output (g);
- }
- else //now n == send_len
- {
- mblk->release();
-
- return msg_queue()->is_empty() ? cancel_wakeup_output(g) : ACE_Event_Handler::WRITE_MASK;
- }
-
- ACE_NOTREACHED(return -1);
-}
-
-int WorldSocket::handle_close(ACE_HANDLE h, ACE_Reactor_Mask)
-{
- // Critical section
- {
- ACE_GUARD_RETURN (LockType, Guard, m_OutBufferLock, -1);
-
- closing_ = true;
-
- if (h == ACE_INVALID_HANDLE)
- peer().close_writer();
- }
-
- // Critical section
- {
- ACE_GUARD_RETURN (LockType, Guard, m_SessionLock, -1);
-
- m_Session = NULL;
- }
-
- reactor()->remove_handler(this, ACE_Event_Handler::DONT_CALL | ACE_Event_Handler::ALL_EVENTS_MASK);
- return 0;
-}
-
-int WorldSocket::Update (void)
-{
- if (closing_)
- return -1;
-
- if (m_OutActive)
- return 0;
-
- {
- ACE_GUARD_RETURN (LockType, Guard, m_OutBufferLock, 0);
- if (m_OutBuffer->length() == 0 && msg_queue()->is_empty())
- return 0;
- }
-
- int ret;
- do
- ret = handle_output(get_handle());
- while (ret > 0);
-
- return ret;
+ });
}
-int WorldSocket::handle_input_header (void)
+void WorldSocket::AsyncReadData(size_t dataSize)
{
- ACE_ASSERT(m_RecvWPct == NULL);
-
- ACE_ASSERT(m_Header.length() == sizeof(ClientPktHeader));
-
- m_Crypt.DecryptRecv ((uint8*)m_Header.rd_ptr(), sizeof(ClientPktHeader));
-
- ClientPktHeader& header = *((ClientPktHeader*)m_Header.rd_ptr());
-
- EndianConvertReverse(header.size);
- EndianConvert(header.cmd);
-
- if ((header.size < 4) || (header.size > 10240) || (header.cmd > 0xFFFF && (header.cmd >> 16) != 0x4C52)) // LR (from MSG_VERIFY_CONNECTIVITY)
+ auto self(shared_from_this());
+ _socket.async_read_some(boost::asio::buffer(&_readBuffer[sizeof(ClientPktHeader)], dataSize), [this, dataSize, self](boost::system::error_code error, size_t transferedBytes)
{
- Player* _player = m_Session ? m_Session->GetPlayer() : NULL;
- TC_LOG_ERROR("network", "WorldSocket::handle_input_header(): client (account: %u, char [GUID: %u, name: %s]) sent malformed packet (size: %d, cmd: %d)",
- m_Session ? m_Session->GetAccountId() : 0,
- _player ? _player->GetGUIDLow() : 0,
- _player ? _player->GetName().c_str() : "<none>",
- header.size, header.cmd);
-
- errno = EINVAL;
- return -1;
- }
-
- header.size -= 4;
-
- ACE_NEW_RETURN(m_RecvWPct, WorldPacket (PacketFilter::DropHighBytes(Opcodes(header.cmd)), header.size), -1);
-
- if (header.size > 0)
- {
- m_RecvWPct->resize(header.size);
- m_RecvPct.base ((char*) m_RecvWPct->contents(), m_RecvWPct->size());
- }
- else
- {
- ACE_ASSERT(m_RecvPct.space() == 0);
- }
-
- return 0;
-}
-
-int WorldSocket::handle_input_payload (void)
-{
- // set errno properly here on error !!!
- // now have a header and payload
-
- ACE_ASSERT (m_RecvPct.space() == 0);
- ACE_ASSERT (m_Header.space() == 0);
- ACE_ASSERT (m_RecvWPct != NULL);
-
- const int ret = ProcessIncoming (m_RecvWPct);
-
- m_RecvPct.base (NULL, 0);
- m_RecvPct.reset();
- m_RecvWPct = NULL;
-
- m_Header.reset();
-
- if (ret == -1)
- errno = EINVAL;
-
- return ret;
-}
-
-int WorldSocket::handle_input_missing_data (void)
-{
- char buf [4096];
-
- ACE_Data_Block db (sizeof (buf),
- ACE_Message_Block::MB_DATA,
- buf,
- 0,
- 0,
- ACE_Message_Block::DONT_DELETE,
- 0);
-
- ACE_Message_Block message_block(&db,
- ACE_Message_Block::DONT_DELETE,
- 0);
-
- const size_t recv_size = message_block.space();
+ if (!error && transferedBytes == dataSize)
+ {
+ ClientPktHeader* header = (ClientPktHeader*)&_readBuffer;
- const ssize_t n = peer().recv (message_block.wr_ptr(),
- recv_size);
+ header->size -= sizeof(header->cmd);
- if (n <= 0)
- return int(n);
+ Opcodes opcode = PacketFilter::DropHighBytes(Opcodes(header->cmd));
- message_block.wr_ptr (n);
+ std::string opcodeName = GetOpcodeNameForLogging(opcode);
- while (message_block.length() > 0)
- {
- if (m_Header.space() > 0)
- {
- //need to receive the header
- const size_t to_header = (message_block.length() > m_Header.space() ? m_Header.space() : message_block.length());
- m_Header.copy (message_block.rd_ptr(), to_header);
- message_block.rd_ptr (to_header);
+ WorldPacket packet(opcode, header->size);
- if (m_Header.space() > 0)
+ if (header->size > 0)
{
- // Couldn't receive the whole header this time.
- ACE_ASSERT (message_block.length() == 0);
- errno = EWOULDBLOCK;
- return -1;
- }
+ packet.resize(header->size);
- // We just received nice new header
- if (handle_input_header() == -1)
- {
- ACE_ASSERT ((errno != EWOULDBLOCK) && (errno != EAGAIN));
- return -1;
+ std::memcpy(packet.contents(), &_readBuffer[sizeof(ClientPktHeader)], header->size);
}
- }
- // Its possible on some error situations that this happens
- // for example on closing when epoll receives more chunked data and stuff
- // hope this is not hack, as proper m_RecvWPct is asserted around
- if (!m_RecvWPct)
- {
- TC_LOG_ERROR("network", "Forcing close on input m_RecvWPct = NULL");
- errno = EINVAL;
- return -1;
- }
-
- // We have full read header, now check the data payload
- if (m_RecvPct.space() > 0)
- {
- //need more data in the payload
- const size_t to_data = (message_block.length() > m_RecvPct.space() ? m_RecvPct.space() : message_block.length());
- m_RecvPct.copy (message_block.rd_ptr(), to_data);
- message_block.rd_ptr (to_data);
-
- if (m_RecvPct.space() > 0)
+ switch (opcode)
{
- // Couldn't receive the whole data this time.
- ACE_ASSERT (message_block.length() == 0);
- errno = EWOULDBLOCK;
- return -1;
+ case CMSG_PING:
+ HandlePing(packet);
+ break;
+ case CMSG_AUTH_SESSION:
+ if (_worldSession)
+ {
+ TC_LOG_ERROR("network", "WorldSocket::ProcessIncoming: received duplicate CMSG_AUTH_SESSION from %s", _worldSession->GetPlayerInfo().c_str());
+ break;
+ }
+
+ sScriptMgr->OnPacketReceive(shared_from_this(), packet);
+ HandleAuthSession(packet);
+ break;
+ case CMSG_KEEP_ALIVE:
+ TC_LOG_DEBUG("network", "%s", opcodeName.c_str());
+ sScriptMgr->OnPacketReceive(shared_from_this(), packet);
+ break;
+ case CMSG_LOG_DISCONNECT:
+ packet.rfinish(); // contains uint32 disconnectReason;
+ TC_LOG_DEBUG("network", "%s", opcodeName.c_str());
+ sScriptMgr->OnPacketReceive(shared_from_this(), packet);
+ return;
+ // not an opcode, client sends string "WORLD OF WARCRAFT CONNECTION - CLIENT TO SERVER" without opcode
+ // first 4 bytes become the opcode (2 dropped)
+ case MSG_VERIFY_CONNECTIVITY:
+ {
+ TC_LOG_DEBUG("network", "%s", opcodeName.c_str());
+ sScriptMgr->OnPacketReceive(shared_from_this(), packet);
+ std::string str;
+ packet >> str;
+ if (str != "D OF WARCRAFT CONNECTION - CLIENT TO SERVER")
+ {
+ _socket.close();
+ break;
+ }
+
+ HandleSendAuthSession();
+ break;
+ }
+ case CMSG_ENABLE_NAGLE:
+ {
+ TC_LOG_DEBUG("network", "%s", opcodeName.c_str());
+ sScriptMgr->OnPacketReceive(shared_from_this(), packet);
+ if (_worldSession)
+ _worldSession->HandleEnableNagleAlgorithm();
+ break;
+ }
+ default:
+ {
+ if (!_worldSession)
+ {
+ TC_LOG_ERROR("network.opcode", "ProcessIncoming: Client not authed opcode = %u", uint32(opcode));
+ break;
+ }
+
+ // Our Idle timer will reset on any non PING opcodes.
+ // Catches people idling on the login screen and any lingering ingame connections.
+ _worldSession->ResetTimeOutTime();
+
+ // Copy the packet to the heap before enqueuing
+ _worldSession->QueuePacket(new WorldPacket(packet));
+ break;
+ }
}
- }
- //just received fresh new payload
- if (handle_input_payload() == -1)
+ AsyncReadHeader();
+ }
+ else
{
- ACE_ASSERT ((errno != EWOULDBLOCK) && (errno != EAGAIN));
- return -1;
+ _socket.close();
}
- }
-
- return size_t(n) == recv_size ? 1 : 2;
-}
-
-int WorldSocket::cancel_wakeup_output(GuardType& g)
-{
- if (!m_OutActive)
- return 0;
-
- m_OutActive = false;
-
- g.release();
-
- if (reactor()->cancel_wakeup
- (this, ACE_Event_Handler::WRITE_MASK) == -1)
- {
- // would be good to store errno from reactor with errno guard
- TC_LOG_ERROR("network", "WorldSocket::cancel_wakeup_output");
- return -1;
- }
-
- return 0;
+ });
}
-int WorldSocket::schedule_wakeup_output(GuardType& g)
+void WorldSocket::AsyncWrite(WorldPacket const& packet)
{
- if (m_OutActive)
- return 0;
+ ServerPktHeader header(packet.size() + 2, packet.GetOpcode());
+ _authCrypt.EncryptSend((uint8*)header.header, header.getHeaderLength());
- m_OutActive = true;
+ auto data = new char[header.getHeaderLength() + packet.size()];
+ std::memcpy(data, (char*)header.header, header.getHeaderLength());
- g.release();
+ if (!packet.empty())
+ std::memcpy(data + header.getHeaderLength(), (char const*)packet.contents(), packet.size());
- if (reactor()->schedule_wakeup
- (this, ACE_Event_Handler::WRITE_MASK) == -1)
+ // Use a shared_ptr here to prevent leaking memory after the async operation has completed
+ std::shared_ptr<char> buffer(data, [=](char* _b)
{
- TC_LOG_ERROR("network", "WorldSocket::schedule_wakeup_output");
- return -1;
- }
-
- return 0;
-}
-
-int WorldSocket::ProcessIncoming(WorldPacket* new_pct)
-{
- ACE_ASSERT (new_pct);
-
- // manage memory ;)
- ACE_Auto_Ptr<WorldPacket> aptr(new_pct);
-
- Opcodes opcode = PacketFilter::DropHighBytes(new_pct->GetOpcode());
-
- if (closing_)
- return -1;
-
- // Dump received packet.
- if (sPacketLog->CanLogPacket())
- sPacketLog->LogPacket(*new_pct, CLIENT_TO_SERVER);
+ delete[] _b; // Ensure that the data is deleted as an array
+ });
- std::string opcodeName = GetOpcodeNameForLogging(opcode);
- if (m_Session)
- TC_LOG_TRACE("network.opcode", "C->S: %s %s", m_Session->GetPlayerInfo().c_str(), opcodeName.c_str());
+ auto self(shared_from_this());
- try
+ boost::asio::async_write(_socket, boost::asio::buffer(buffer.get(), header.getHeaderLength() + packet.size()), [this, self, buffer](boost::system::error_code error, std::size_t /*length*/)
{
- switch (opcode)
+ if (error)
{
- case CMSG_PING:
- return HandlePing(*new_pct);
- case CMSG_AUTH_SESSION:
- if (m_Session)
- {
- TC_LOG_ERROR("network", "WorldSocket::ProcessIncoming: received duplicate CMSG_AUTH_SESSION from %s", m_Session->GetPlayerInfo().c_str());
- return -1;
- }
-
- sScriptMgr->OnPacketReceive(this, WorldPacket(*new_pct));
- return HandleAuthSession(*new_pct);
- case CMSG_KEEP_ALIVE:
- TC_LOG_DEBUG("network", "%s", opcodeName.c_str());
- sScriptMgr->OnPacketReceive(this, WorldPacket(*new_pct));
- return 0;
- case CMSG_LOG_DISCONNECT:
- new_pct->rfinish(); // contains uint32 disconnectReason;
- TC_LOG_DEBUG("network", "%s", opcodeName.c_str());
- sScriptMgr->OnPacketReceive(this, WorldPacket(*new_pct));
- return 0;
- // not an opcode, client sends string "WORLD OF WARCRAFT CONNECTION - CLIENT TO SERVER" without opcode
- // first 4 bytes become the opcode (2 dropped)
- case MSG_VERIFY_CONNECTIVITY:
- {
- TC_LOG_DEBUG("network", "%s", opcodeName.c_str());
- sScriptMgr->OnPacketReceive(this, WorldPacket(*new_pct));
- std::string str;
- *new_pct >> str;
- if (str != "D OF WARCRAFT CONNECTION - CLIENT TO SERVER")
- return -1;
- return HandleSendAuthSession();
- }
- case CMSG_ENABLE_NAGLE:
- {
- TC_LOG_DEBUG("network", "%s", opcodeName.c_str());
- sScriptMgr->OnPacketReceive(this, WorldPacket(*new_pct));
- return m_Session ? m_Session->HandleEnableNagleAlgorithm() : -1;
- }
- default:
- {
- ACE_GUARD_RETURN(LockType, Guard, m_SessionLock, -1);
- if (!m_Session)
- {
- TC_LOG_ERROR("network.opcode", "ProcessIncoming: Client not authed opcode = %u", uint32(opcode));
- return -1;
- }
-
- // prevent invalid memory access/crash with custom opcodes
- if (opcode >= NUM_OPCODE_HANDLERS)
- return 0;
-
- OpcodeHandler const* handler = opcodeTable[opcode];
- if (!handler || handler->Status == STATUS_UNHANDLED)
- {
- TC_LOG_ERROR("network.opcode", "No defined handler for opcode %s sent by %s", GetOpcodeNameForLogging(new_pct->GetOpcode()).c_str(), m_Session->GetPlayerInfo().c_str());
- return 0;
- }
-
- // Our Idle timer will reset on any non PING opcodes.
- // Catches people idling on the login screen and any lingering ingame connections.
- m_Session->ResetTimeOutTime();
-
- // OK, give the packet to WorldSession
- aptr.release();
- // WARNING here we call it with locks held.
- // Its possible to cause deadlock if QueuePacket calls back
- m_Session->QueuePacket(new_pct);
- return 0;
- }
+ _socket.close();
}
- }
- catch (ByteBufferException &)
- {
- TC_LOG_ERROR("network", "WorldSocket::ProcessIncoming ByteBufferException occured while parsing an instant handled packet %s from client %s, accountid=%i. Disconnected client.",
- opcodeName.c_str(), GetRemoteAddress().c_str(), m_Session ? int32(m_Session->GetAccountId()) : -1);
- new_pct->hexlike();
- return -1;
- }
-
- ACE_NOTREACHED (return 0);
+ });
}
-int WorldSocket::HandleSendAuthSession()
-{
- WorldPacket packet(SMSG_AUTH_CHALLENGE, 37);
- BigNumber seed1;
- seed1.SetRand(16 * 8);
- packet.append(seed1.AsByteArray(16).get(), 16); // new encryption seeds
-
- BigNumber seed2;
- seed2.SetRand(16 * 8);
- packet.append(seed2.AsByteArray(16).get(), 16); // new encryption seeds
-
- packet << m_Seed;
- packet << uint8(1);
- return SendPacket(packet);
-}
-
-int WorldSocket::HandleAuthSession(WorldPacket& recvPacket)
+void WorldSocket::HandleAuthSession(WorldPacket& recvPacket)
{
uint8 digest[20];
uint32 clientSeed;
@@ -851,8 +274,8 @@ int WorldSocket::HandleAuthSession(WorldPacket& recvPacket)
if (sWorld->IsClosed())
{
SendAuthResponseError(AUTH_REJECT);
- TC_LOG_ERROR("network", "WorldSocket::HandleAuthSession: World closed, denying client (%s).", GetRemoteAddress().c_str());
- return -1;
+ TC_LOG_ERROR("network", "WorldSocket::HandleAuthSession: World closed, denying client (%s).", GetRemoteIpAddress().c_str());
+ return;
}
// Get the account information from the realmd database
@@ -881,7 +304,7 @@ int WorldSocket::HandleAuthSession(WorldPacket& recvPacket)
// We can not log here, as we do not know the account. Thus, no accountId.
SendAuthResponseError(AUTH_UNKNOWN_ACCOUNT);
TC_LOG_ERROR("network", "WorldSocket::HandleAuthSession: Sent Auth Response (unknown account).");
- return -1;
+ return;
}
Field* fields = result->Fetch();
@@ -892,7 +315,7 @@ int WorldSocket::HandleAuthSession(WorldPacket& recvPacket)
expansion = world_expansion;
// For hook purposes, we get Remoteaddress at this point.
- std::string address = GetRemoteAddress();
+ std::string address = GetRemoteIpAddress();
// As we don't know if attempted login process by ip works, we update last_attempt_ip right away
stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_LAST_ATTEMPT_IP);
@@ -909,13 +332,13 @@ int WorldSocket::HandleAuthSession(WorldPacket& recvPacket)
///- Re-check ip locking (same check as in realmd).
if (fields[3].GetUInt8() == 1) // if ip is locked
{
- if (strcmp (fields[2].GetCString(), address.c_str()))
+ if (strcmp(fields[2].GetCString(), address.c_str()))
{
SendAuthResponseError(AUTH_FAILED);
TC_LOG_DEBUG("network", "WorldSocket::HandleAuthSession: Sent Auth Response (Account IP differs. Original IP: %s, new IP: %s).", fields[2].GetCString(), address.c_str());
// We could log on hook only instead of an additional db log, however action logger is config based. Better keep DB logging as well
sScriptMgr->OnFailedAccountLogin(id);
- return -1;
+ return;
}
}
@@ -935,7 +358,7 @@ int WorldSocket::HandleAuthSession(WorldPacket& recvPacket)
LoginDatabase.Execute(stmt);
}
- locale = LocaleConstant (fields[6].GetUInt8());
+ locale = LocaleConstant(fields[6].GetUInt8());
if (locale >= TOTAL_LOCALES)
locale = LOCALE_enUS;
@@ -947,7 +370,7 @@ int WorldSocket::HandleAuthSession(WorldPacket& recvPacket)
{
SendAuthResponseError(AUTH_REJECT);
TC_LOG_ERROR("network", "WorldSocket::HandleAuthSession: Client %s attempted to log in using invalid client OS (%s).", address.c_str(), os.c_str());
- return -1;
+ return;
}
// Checks gmlevel per Realm
@@ -979,7 +402,7 @@ int WorldSocket::HandleAuthSession(WorldPacket& recvPacket)
SendAuthResponseError(AUTH_BANNED);
TC_LOG_ERROR("network", "WorldSocket::HandleAuthSession: Sent Auth Response (Account banned).");
sScriptMgr->OnFailedAccountLogin(id);
- return -1;
+ return;
}
// Check locked state for server
@@ -990,17 +413,16 @@ int WorldSocket::HandleAuthSession(WorldPacket& recvPacket)
SendAuthResponseError(AUTH_UNAVAILABLE);
TC_LOG_INFO("network", "WorldSocket::HandleAuthSession: User tries to login but his security level is not enough");
sScriptMgr->OnFailedAccountLogin(id);
- return -1;
+ return;
}
// Check that Key and account name are the same on client and server
uint32 t = 0;
- uint32 seed = m_Seed;
sha.UpdateData(account);
sha.UpdateData((uint8*)&t, 4);
sha.UpdateData((uint8*)&clientSeed, 4);
- sha.UpdateData((uint8*)&seed, 4);
+ sha.UpdateData((uint8*)&_authSeed, 4);
sha.UpdateBigNumbers(&k, NULL);
sha.Finalize();
@@ -1008,7 +430,7 @@ int WorldSocket::HandleAuthSession(WorldPacket& recvPacket)
{
SendAuthResponseError(AUTH_FAILED);
TC_LOG_ERROR("network", "WorldSocket::HandleAuthSession: Authentication failed for account: %u ('%s') address: %s", id, account.c_str(), address.c_str());
- return -1;
+ return;
}
TC_LOG_DEBUG("network", "WorldSocket::HandleAuthSession: Client '%s' authenticated successfully from %s.",
@@ -1035,31 +457,36 @@ int WorldSocket::HandleAuthSession(WorldPacket& recvPacket)
LoginDatabase.Execute(stmt);
// NOTE ATM the socket is single-threaded, have this in mind ...
- ACE_NEW_RETURN(m_Session, WorldSession(id, battlenetAccountId, this, AccountTypes(security), expansion, mutetime, locale, recruiter, isRecruiter), -1);
+ _worldSession = new WorldSession(id, battlenetAccountId, shared_from_this(), AccountTypes(security), expansion, mutetime, locale, recruiter, isRecruiter);
- m_Crypt.Init(&k);
+ _authCrypt.Init(&k);
- m_Session->LoadGlobalAccountData();
- m_Session->LoadTutorialsData();
- m_Session->ReadAddonsInfo(addonsData);
- m_Session->LoadPermissions();
+ _worldSession->LoadGlobalAccountData();
+ _worldSession->LoadTutorialsData();
+ _worldSession->ReadAddonsInfo(recvPacket);
+ _worldSession->LoadPermissions();
// At this point, we can safely hook a successful login
sScriptMgr->OnAccountLogin(id);
// Initialize Warden system only if it is enabled by config
if (wardenActive)
- m_Session->InitWarden(&k, os);
+ _worldSession->InitWarden(&k, os);
- // Sleep this Network thread for
- uint32 sleepTime = sWorld->getIntConfig(CONFIG_SESSION_ADD_DELAY);
- ACE_OS::sleep(ACE_Time_Value(0, sleepTime));
+ sWorld->AddSession(_worldSession);
+}
- sWorld->AddSession(m_Session);
- return 0;
+void WorldSocket::SendAuthResponseError(uint8 code)
+{
+ WorldPacket packet(SMSG_AUTH_RESPONSE, 1);
+ packet.WriteBit(0); // has queue info
+ packet.WriteBit(0); // has account info
+ packet << uint8(code);
+
+ AsyncWrite(packet);
}
-int WorldSocket::HandlePing(WorldPacket& recvPacket)
+void WorldSocket::HandlePing(WorldPacket& recvPacket)
{
uint32 ping;
uint32 latency;
@@ -1068,67 +495,55 @@ int WorldSocket::HandlePing(WorldPacket& recvPacket)
recvPacket >> latency;
recvPacket >> ping;
- if (m_LastPingTime == ACE_Time_Value::zero)
- m_LastPingTime = ACE_OS::gettimeofday(); // for 1st ping
+ if (_LastPingTime == steady_clock::time_point())
+ {
+ _LastPingTime = steady_clock::now();
+ }
else
{
- ACE_Time_Value cur_time = ACE_OS::gettimeofday();
- ACE_Time_Value diff_time (cur_time);
- diff_time -= m_LastPingTime;
- m_LastPingTime = cur_time;
+ steady_clock::time_point now = steady_clock::now();
+
+ steady_clock::duration diff = now - _LastPingTime;
+
+ _LastPingTime = now;
- if (diff_time < ACE_Time_Value (27))
+ if (diff < seconds(27))
{
- ++m_OverSpeedPings;
+ ++_OverSpeedPings;
- uint32 max_count = sWorld->getIntConfig (CONFIG_MAX_OVERSPEED_PINGS);
+ uint32 maxAllowed = sWorld->getIntConfig(CONFIG_MAX_OVERSPEED_PINGS);
- if (max_count && m_OverSpeedPings > max_count)
+ if (maxAllowed && _OverSpeedPings > maxAllowed)
{
- ACE_GUARD_RETURN (LockType, Guard, m_SessionLock, -1);
-
- if (m_Session && !m_Session->HasPermission(rbac::RBAC_PERM_SKIP_CHECK_OVERSPEED_PING))
+ if (_worldSession && !_worldSession->HasPermission(rbac::RBAC_PERM_SKIP_CHECK_OVERSPEED_PING))
{
TC_LOG_ERROR("network", "WorldSocket::HandlePing: %s kicked for over-speed pings (address: %s)",
- m_Session->GetPlayerInfo().c_str(), GetRemoteAddress().c_str());
+ _worldSession->GetPlayerInfo().c_str(), GetRemoteIpAddress().c_str());
- return -1;
+ _socket.close();
+ return;
}
}
}
else
- m_OverSpeedPings = 0;
+ _OverSpeedPings = 0;
}
- // critical section
+ if (_worldSession)
+ {
+ _worldSession->SetLatency(latency);
+ _worldSession->ResetClientTimeDelay();
+ }
+ else
{
- ACE_GUARD_RETURN (LockType, Guard, m_SessionLock, -1);
+ TC_LOG_ERROR("network", "WorldSocket::HandlePing: peer sent CMSG_PING, but is not authenticated or got recently kicked, address = %s",
+ GetRemoteIpAddress().c_str());
- if (m_Session)
- {
- m_Session->SetLatency (latency);
- m_Session->ResetClientTimeDelay();
- }
- else
- {
- TC_LOG_ERROR("network", "WorldSocket::HandlePing: peer sent CMSG_PING, "
- "but is not authenticated or got recently kicked, "
- " address = %s",
- GetRemoteAddress().c_str());
- return -1;
- }
+ _socket.close();
+ return;
}
WorldPacket packet(SMSG_PONG, 4);
packet << ping;
- return SendPacket(packet);
-}
-
-void WorldSocket::SendAuthResponseError(uint8 code)
-{
- WorldPacket packet(SMSG_AUTH_RESPONSE, 1);
- packet.WriteBit(0); // has queue info
- packet.WriteBit(0); // has account info
- packet << uint8(code);
- SendPacket(packet);
+ return AsyncWrite(packet);
}
diff --git a/src/server/game/Server/WorldSocket.h b/src/server/game/Server/WorldSocket.h
index 306a50c083a..e46c6b3fe5c 100644
--- a/src/server/game/Server/WorldSocket.h
+++ b/src/server/game/Server/WorldSocket.h
@@ -1,219 +1,85 @@
/*
- * 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/>.
- */
-
-/** \addtogroup u2w User to World Communication
- * @{
- * \file WorldSocket.h
- * \author Derex <derex101@gmail.com>
- */
-
-#ifndef _WORLDSOCKET_H
-#define _WORLDSOCKET_H
-
-#include <ace/Basic_Types.h>
-#include <ace/Synch_Traits.h>
-#include <ace/Svc_Handler.h>
-#include <ace/SOCK_Stream.h>
-#include <ace/Thread_Mutex.h>
-#include <ace/Guard_T.h>
-#include <ace/Unbounded_Queue.h>
-#include <ace/Message_Block.h>
-
-#if !defined (ACE_LACKS_PRAGMA_ONCE)
-#pragma once
-#endif /* ACE_LACKS_PRAGMA_ONCE */
-
+* 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 __WORLDSOCKET_H__
+#define __WORLDSOCKET_H__
+
+#include <memory>
+#include <chrono>
+#include <boost/asio/ip/tcp.hpp>
+#include <boost/asio/streambuf.hpp>
#include "Common.h"
#include "WorldPacketCrypt.h"
+#include "Util.h"
+#include "WorldPacket.h"
+#include "WorldSession.h"
-class ACE_Message_Block;
-class WorldPacket;
-class WorldSession;
-
-/// Handler that can communicate over stream sockets.
-typedef ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_NULL_SYNCH> WorldHandler;
-
-/**
- * WorldSocket.
- *
- * This class is responsible for the communication with
- * remote clients.
- * Most methods return -1 on failure.
- * The class uses reference counting.
- *
- * For output the class uses one buffer (64K usually) and
- * a queue where it stores packet if there is no place on
- * the queue. The reason this is done, is because the server
- * does really a lot of small-size writes to it, and it doesn't
- * scale well to allocate memory for every. When something is
- * written to the output buffer the socket is not immediately
- * activated for output (again for the same reason), there
- * is 10ms celling (thats why there is Update() method).
- * This concept is similar to TCP_CORK, but TCP_CORK
- * uses 200ms celling. As result overhead generated by
- * sending packets from "producer" threads is minimal,
- * and doing a lot of writes with small size is tolerated.
- *
- * The calls to Update() method are managed by WorldSocketMgr
- * and ReactorRunnable.
- *
- * For input, the class uses one 4096 bytes buffer on stack
- * to which it does recv() calls. And then received data is
- * distributed where its needed. 4096 matches pretty well the
- * traffic generated by client for now.
- *
- * The input/output do speculative reads/writes (AKA it tryes
- * to read all data available in the kernel buffer or tryes to
- * write everything available in userspace buffer),
- * which is ok for using with Level and Edge Triggered IO
- * notification.
- *
- */
-class WorldSocket : public WorldHandler
-{
- public:
- WorldSocket (void);
- virtual ~WorldSocket (void);
-
- friend class WorldSocketMgr;
-
- /// Mutex type used for various synchronizations.
- typedef ACE_Thread_Mutex LockType;
- typedef ACE_Guard<LockType> GuardType;
-
- /// Check if socket is closed.
- bool IsClosed(void) const;
-
- /// Close the socket.
- void CloseSocket(void);
-
- /// Get address of connected peer.
- const std::string& GetRemoteAddress(void) const;
-
- /// Send A packet on the socket, this function is reentrant.
- /// @param pct packet to send
- /// @return -1 of failure
- int SendPacket(const WorldPacket& pct);
-
- /// Add reference to this object.
- long AddReference(void);
-
- /// Remove reference to this object.
- long RemoveReference(void);
-
- /// things called by ACE framework.
-
- /// Called on open, the void* is the acceptor.
- virtual int open(void *);
-
- /// Called on failures inside of the acceptor, don't call from your code.
- virtual int close(u_long);
-
- /// Called when we can read from the socket.
- virtual int handle_input(ACE_HANDLE = ACE_INVALID_HANDLE);
+using boost::asio::ip::tcp;
- /// Called when the socket can write.
- virtual int handle_output(ACE_HANDLE = ACE_INVALID_HANDLE);
+#pragma pack(push, 1)
- /// Called when connection is closed or error happens.
- virtual int handle_close(ACE_HANDLE = ACE_INVALID_HANDLE,
- ACE_Reactor_Mask = ACE_Event_Handler::ALL_EVENTS_MASK);
-
- /// Called by WorldSocketMgr/ReactorRunnable.
- int Update(void);
-
- private:
- /// Helper functions for processing incoming data.
- int handle_input_header(void);
- int handle_input_payload(void);
- int handle_input_missing_data(void);
-
- /// Help functions to mark/unmark the socket for output.
- /// @param g the guard is for m_OutBufferLock, the function will release it
- int cancel_wakeup_output(GuardType& g);
- int schedule_wakeup_output(GuardType& g);
-
- /// Drain the queue if its not empty.
- int handle_output_queue(GuardType& g);
-
- /// process one incoming packet.
- /// @param new_pct received packet, note that you need to delete it.
- int ProcessIncoming(WorldPacket* new_pct);
-
- /// Called by ProcessIncoming() on CMSG_AUTH_SESSION.
- int HandleAuthSession(WorldPacket& recvPacket);
-
- /// Called by ProcessIncoming() on CMSG_PING.
- int HandlePing(WorldPacket& recvPacket);
-
- /// Called by CMSG_VERIFY_CONNECTIVITY_RESPONSE
- int HandleSendAuthSession();
+struct ClientPktHeader
+{
+ uint16 size;
+ uint32 cmd;
+};
- private:
- void SendAuthResponseError(uint8);
- /// Time in which the last ping was received
- ACE_Time_Value m_LastPingTime;
+#pragma pack(pop)
- /// Keep track of over-speed pings, to prevent ping flood.
- uint32 m_OverSpeedPings;
+class WorldSocket : public std::enable_shared_from_this<WorldSocket>
+{
+public:
+ WorldSocket(tcp::socket&& socket);
- /// Address of the remote peer
- std::string m_Address;
+ WorldSocket(WorldSocket const& right) = delete;
+ WorldSocket& operator=(WorldSocket const& right) = delete;
- /// Class used for managing encryption of the headers
- WorldPacketCrypt m_Crypt;
+ void Start();
- /// Mutex lock to protect m_Session
- LockType m_SessionLock;
+ const std::string GetRemoteIpAddress() const { return _socket.remote_endpoint().address().to_string(); };
+ unsigned short GetRemotePort() const { return _socket.remote_endpoint().port(); }
- /// Session to which received packets are routed
- WorldSession* m_Session;
+ void CloseSocket() { _socket.close(); };
+ bool IsOpen() { return _socket.is_open(); };
- /// here are stored the fragments of the received data
- WorldPacket* m_RecvWPct;
+ void AsyncWrite(WorldPacket const& packet);
- /// This block actually refers to m_RecvWPct contents,
- /// which allows easy and safe writing to it.
- /// It wont free memory when its deleted. m_RecvWPct takes care of freeing.
- ACE_Message_Block m_RecvPct;
+private:
+ void HandleSendAuthSession();
+ void HandleAuthSession(WorldPacket& recvPacket);
+ void SendAuthResponseError(uint8 code);
- /// Fragment of the received header.
- ACE_Message_Block m_Header;
+ void HandlePing(WorldPacket& recvPacket);
- /// Mutex for protecting output related data.
- LockType m_OutBufferLock;
+ void AsyncReadHeader();
+ void AsyncReadData(size_t dataSize);
- /// Buffer used for writing output.
- ACE_Message_Block* m_OutBuffer;
+ tcp::socket _socket;
- /// Size of the m_OutBuffer.
- size_t m_OutBufferSize;
+ char _readBuffer[4096];
- /// True if the socket is registered with the reactor for output
- bool m_OutActive;
+ uint32 _authSeed;
+ AuthCrypt _authCrypt;
- uint32 m_Seed;
+ std::chrono::steady_clock::time_point _LastPingTime;
+ uint32 _OverSpeedPings;
- WorldSocket(WorldSocket const& right) = delete;
- WorldSocket& operator=(WorldSocket const& right) = delete;
+ WorldSession* _worldSession;
};
-#endif /* _WORLDSOCKET_H */
-
-/// @}
-
+#endif
diff --git a/src/server/game/Server/WorldSocketAcceptor.h b/src/server/game/Server/WorldSocketAcceptor.h
deleted file mode 100644
index 0b07196a0cd..00000000000
--- a/src/server/game/Server/WorldSocketAcceptor.h
+++ /dev/null
@@ -1,67 +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/>.
- */
-
-/** \addtogroup u2w User to World Communication
- * @{
- * \file WorldSocketMgr.h
- */
-
-#ifndef __WORLDSOCKETACCEPTOR_H_
-#define __WORLDSOCKETACCEPTOR_H_
-
-#include "Common.h"
-
-#include <ace/Acceptor.h>
-#include <ace/SOCK_Acceptor.h>
-
-#include "WorldSocket.h"
-
-class WorldSocketAcceptor : public ACE_Acceptor<WorldSocket, ACE_SOCK_Acceptor>
-{
-public:
- WorldSocketAcceptor(void) { }
- virtual ~WorldSocketAcceptor(void)
- {
- if (reactor())
- reactor()->cancel_timer(this, 1);
- }
-
-protected:
-
- virtual int handle_timeout(const ACE_Time_Value& /*current_time*/, const void* /*act = 0*/)
- {
- TC_LOG_DEBUG("misc", "Resuming acceptor");
- reactor()->cancel_timer(this, 1);
- return reactor()->register_handler(this, ACE_Event_Handler::ACCEPT_MASK);
- }
-
- virtual int handle_accept_error(void)
- {
-#if defined(ENFILE) && defined(EMFILE)
- if (errno == ENFILE || errno == EMFILE)
- {
- TC_LOG_ERROR("misc", "Out of file descriptors, suspending incoming connections for 10 seconds");
- reactor()->remove_handler(this, ACE_Event_Handler::ACCEPT_MASK | ACE_Event_Handler::DONT_CALL);
- reactor()->schedule_timer(this, NULL, ACE_Time_Value(10));
- }
-#endif
- return 0;
- }
-};
-
-#endif /* __WORLDSOCKETACCEPTOR_H_ */
-/// @}
diff --git a/src/server/game/Server/WorldSocketMgr.cpp b/src/server/game/Server/WorldSocketMgr.cpp
deleted file mode 100644
index 7880552ffa1..00000000000
--- a/src/server/game/Server/WorldSocketMgr.cpp
+++ /dev/null
@@ -1,360 +0,0 @@
-/*
- * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
- * Copyright (C) 2005-2008 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 WorldSocketMgr.cpp
-* \ingroup u2w
-* \author Derex <derex101@gmail.com>
-*/
-
-#include "WorldSocketMgr.h"
-
-#include <ace/ACE.h>
-#include <ace/Log_Msg.h>
-#include <ace/Reactor.h>
-#include <ace/Reactor_Impl.h>
-#include <ace/TP_Reactor.h>
-#include <ace/Dev_Poll_Reactor.h>
-#include <ace/Guard_T.h>
-#include <ace/Atomic_Op.h>
-#include <ace/os_include/arpa/os_inet.h>
-#include <ace/os_include/netinet/os_tcp.h>
-#include <ace/os_include/sys/os_types.h>
-#include <ace/os_include/sys/os_socket.h>
-
-#include <set>
-
-#include "Log.h"
-#include "Common.h"
-#include "Config.h"
-#include "DatabaseEnv.h"
-#include "WorldSocket.h"
-#include "WorldSocketAcceptor.h"
-#include "ScriptMgr.h"
-
-/**
-* This is a helper class to WorldSocketMgr, that manages
-* network threads, and assigning connections from acceptor thread
-* to other network threads
-*/
-class ReactorRunnable : protected ACE_Task_Base
-{
- public:
-
- ReactorRunnable() :
- m_Reactor(0),
- m_Connections(0),
- m_ThreadId(-1)
- {
- ACE_Reactor_Impl* imp;
-
- #if defined (ACE_HAS_EVENT_POLL) || defined (ACE_HAS_DEV_POLL)
-
- imp = new ACE_Dev_Poll_Reactor();
-
- imp->max_notify_iterations (128);
- imp->restart (1);
-
- #else
-
- imp = new ACE_TP_Reactor();
- imp->max_notify_iterations (128);
-
- #endif
-
- m_Reactor = new ACE_Reactor (imp, 1);
- }
-
- virtual ~ReactorRunnable()
- {
- Stop();
- Wait();
-
- delete m_Reactor;
- }
-
- void Stop()
- {
- m_Reactor->end_reactor_event_loop();
- }
-
- int Start()
- {
- if (m_ThreadId != -1)
- return -1;
-
- return (m_ThreadId = activate());
- }
-
- void Wait() { ACE_Task_Base::wait(); }
-
- long Connections()
- {
- return static_cast<long> (m_Connections.value());
- }
-
- int AddSocket (WorldSocket* sock)
- {
- TRINITY_GUARD(ACE_Thread_Mutex, m_NewSockets_Lock);
-
- ++m_Connections;
- sock->AddReference();
- sock->reactor (m_Reactor);
- m_NewSockets.insert (sock);
-
- sScriptMgr->OnSocketOpen(sock);
-
- return 0;
- }
-
- ACE_Reactor* GetReactor()
- {
- return m_Reactor;
- }
-
- protected:
-
- void AddNewSockets()
- {
- TRINITY_GUARD(ACE_Thread_Mutex, m_NewSockets_Lock);
-
- if (m_NewSockets.empty())
- return;
-
- for (SocketSet::const_iterator i = m_NewSockets.begin(); i != m_NewSockets.end(); ++i)
- {
- WorldSocket* sock = (*i);
-
- if (sock->IsClosed())
- {
- sScriptMgr->OnSocketClose(sock, true);
-
- sock->RemoveReference();
- --m_Connections;
- }
- else
- m_Sockets.insert (sock);
- }
-
- m_NewSockets.clear();
- }
-
- virtual int svc()
- {
- TC_LOG_DEBUG("misc", "Network Thread Starting");
-
- ACE_ASSERT (m_Reactor);
-
- SocketSet::iterator i, t;
-
- while (!m_Reactor->reactor_event_loop_done())
- {
- // dont be too smart to move this outside the loop
- // the run_reactor_event_loop will modify interval
- ACE_Time_Value interval (0, 10000);
-
- if (m_Reactor->run_reactor_event_loop (interval) == -1)
- break;
-
- AddNewSockets();
-
- for (i = m_Sockets.begin(); i != m_Sockets.end();)
- {
- if ((*i)->Update() == -1)
- {
- t = i;
- ++i;
-
- (*t)->CloseSocket();
-
- sScriptMgr->OnSocketClose((*t), false);
-
- (*t)->RemoveReference();
- --m_Connections;
- m_Sockets.erase (t);
- }
- else
- ++i;
- }
- }
-
- TC_LOG_DEBUG("misc", "Network Thread exits");
-
- return 0;
- }
-
- private:
- typedef ACE_Atomic_Op<ACE_SYNCH_MUTEX, long> AtomicInt;
- typedef std::set<WorldSocket*> SocketSet;
-
- ACE_Reactor* m_Reactor;
- AtomicInt m_Connections;
- int m_ThreadId;
-
- SocketSet m_Sockets;
-
- SocketSet m_NewSockets;
- ACE_Thread_Mutex m_NewSockets_Lock;
-};
-
-WorldSocketMgr::WorldSocketMgr() :
- m_NetThreads(0),
- m_NetThreadsCount(0),
- m_SockOutKBuff(-1),
- m_SockOutUBuff(65536),
- m_UseNoDelay(true),
- m_Acceptor (0) { }
-
-WorldSocketMgr::~WorldSocketMgr()
-{
- delete [] m_NetThreads;
- delete m_Acceptor;
-}
-
-int
-WorldSocketMgr::StartReactiveIO (ACE_UINT16 port, const char* address)
-{
- m_UseNoDelay = sConfigMgr->GetBoolDefault ("Network.TcpNodelay", true);
-
- int num_threads = sConfigMgr->GetIntDefault ("Network.Threads", 1);
-
- if (num_threads <= 0)
- {
- TC_LOG_ERROR("misc", "Network.Threads is wrong in your config file");
- return -1;
- }
-
- m_NetThreadsCount = static_cast<size_t> (num_threads + 1);
-
- m_NetThreads = new ReactorRunnable[m_NetThreadsCount];
-
- TC_LOG_DEBUG("misc", "Max allowed socket connections %d", ACE::max_handles());
-
- // -1 means use default
- m_SockOutKBuff = sConfigMgr->GetIntDefault ("Network.OutKBuff", -1);
-
- m_SockOutUBuff = sConfigMgr->GetIntDefault ("Network.OutUBuff", 65536);
-
- if (m_SockOutUBuff <= 0)
- {
- TC_LOG_ERROR("misc", "Network.OutUBuff is wrong in your config file");
- return -1;
- }
-
- m_Acceptor = new WorldSocketAcceptor;
-
- ACE_INET_Addr listen_addr (port, address);
-
- if (m_Acceptor->open(listen_addr, m_NetThreads[0].GetReactor(), ACE_NONBLOCK) == -1)
- {
- TC_LOG_ERROR("misc", "Failed to open acceptor, check if the port is free");
- return -1;
- }
-
- for (size_t i = 0; i < m_NetThreadsCount; ++i)
- m_NetThreads[i].Start();
-
- return 0;
-}
-
-int
-WorldSocketMgr::StartNetwork (ACE_UINT16 port, const char* address)
-{
- if (!sLog->ShouldLog("misc", LOG_LEVEL_DEBUG))
- ACE_Log_Msg::instance()->priority_mask (LM_ERROR, ACE_Log_Msg::PROCESS);
-
- if (StartReactiveIO(port, address) == -1)
- return -1;
-
- sScriptMgr->OnNetworkStart();
-
- return 0;
-}
-
-void
-WorldSocketMgr::StopNetwork()
-{
- if (m_Acceptor)
- {
- m_Acceptor->close();
- }
-
- if (m_NetThreadsCount != 0)
- {
- for (size_t i = 0; i < m_NetThreadsCount; ++i)
- m_NetThreads[i].Stop();
- }
-
- Wait();
-
- sScriptMgr->OnNetworkStop();
-}
-
-void
-WorldSocketMgr::Wait()
-{
- if (m_NetThreadsCount != 0)
- {
- for (size_t i = 0; i < m_NetThreadsCount; ++i)
- m_NetThreads[i].Wait();
- }
-}
-
-int
-WorldSocketMgr::OnSocketOpen (WorldSocket* sock)
-{
- // set some options here
- if (m_SockOutKBuff >= 0)
- {
- if (sock->peer().set_option (SOL_SOCKET,
- SO_SNDBUF,
- (void*) & m_SockOutKBuff,
- sizeof (int)) == -1 && errno != ENOTSUP)
- {
- TC_LOG_ERROR("misc", "WorldSocketMgr::OnSocketOpen set_option SO_SNDBUF");
- return -1;
- }
- }
-
- static const int ndoption = 1;
-
- // Set TCP_NODELAY.
- if (m_UseNoDelay)
- {
- if (sock->peer().set_option (ACE_IPPROTO_TCP,
- TCP_NODELAY,
- (void*)&ndoption,
- sizeof (int)) == -1)
- {
- TC_LOG_ERROR("misc", "WorldSocketMgr::OnSocketOpen: peer().set_option TCP_NODELAY errno = %s", ACE_OS::strerror (errno));
- return -1;
- }
- }
-
- sock->m_OutBufferSize = static_cast<size_t> (m_SockOutUBuff);
-
- // we skip the Acceptor Thread
- size_t min = 1;
-
- ACE_ASSERT (m_NetThreadsCount >= 1);
-
- for (size_t i = 1; i < m_NetThreadsCount; ++i)
- if (m_NetThreads[i].Connections() < m_NetThreads[min].Connections())
- min = i;
-
- return m_NetThreads[min].AddSocket (sock);
-}
diff --git a/src/server/game/Server/WorldSocketMgr.h b/src/server/game/Server/WorldSocketMgr.h
deleted file mode 100644
index fb8ddb42b9e..00000000000
--- a/src/server/game/Server/WorldSocketMgr.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * 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/>.
- */
-
-/** \addtogroup u2w User to World Communication
- * @{
- * \file WorldSocketMgr.h
- * \author Derex <derex101@gmail.com>
- */
-
-#ifndef __WORLDSOCKETMGR_H
-#define __WORLDSOCKETMGR_H
-
-#include <ace/Basic_Types.h>
-#include <ace/Singleton.h>
-#include <ace/Thread_Mutex.h>
-
-class WorldSocket;
-class ReactorRunnable;
-class ACE_Event_Handler;
-
-/// Manages all sockets connected to peers and network threads
-class WorldSocketMgr
-{
-public:
- friend class WorldSocket;
- friend class ACE_Singleton<WorldSocketMgr, ACE_Thread_Mutex>;
-
- /// Start network, listen at address:port .
- int StartNetwork(ACE_UINT16 port, const char* address);
-
- /// Stops all network threads, It will wait for all running threads .
- void StopNetwork();
-
- /// Wait untill all network threads have "joined" .
- void Wait();
-
-private:
- int OnSocketOpen(WorldSocket* sock);
-
- int StartReactiveIO(ACE_UINT16 port, const char* address);
-
-private:
- WorldSocketMgr();
- virtual ~WorldSocketMgr();
-
- ReactorRunnable* m_NetThreads;
- size_t m_NetThreadsCount;
-
- int m_SockOutKBuff;
- int m_SockOutUBuff;
- bool m_UseNoDelay;
-
- class WorldSocketAcceptor* m_Acceptor;
-};
-
-#define sWorldSocketMgr ACE_Singleton<WorldSocketMgr, ACE_Thread_Mutex>::instance()
-
-#endif
-/// @}
diff --git a/src/server/game/Spells/Auras/SpellAuras.cpp b/src/server/game/Spells/Auras/SpellAuras.cpp
index ab7f0eac759..e38dc8fdf4a 100644
--- a/src/server/game/Spells/Auras/SpellAuras.cpp
+++ b/src/server/game/Spells/Auras/SpellAuras.cpp
@@ -1065,7 +1065,7 @@ void Aura::SetLoadedState(int32 maxduration, int32 duration, int32 charges, uint
if (m_effects[i])
{
m_effects[i]->SetAmount(amount[i]);
- m_effects[i]->SetCanBeRecalculated(recalculateMask & (1<<i));
+ m_effects[i]->SetCanBeRecalculated((recalculateMask & (1 << i)) != 0);
m_effects[i]->CalculatePeriodic(caster, false, true);
m_effects[i]->CalculateSpellMod();
m_effects[i]->RecalculateAmount(caster);
diff --git a/src/server/game/Spells/Auras/SpellAuras.h b/src/server/game/Spells/Auras/SpellAuras.h
index 8c426ea2175..19c77c2ac7e 100644
--- a/src/server/game/Spells/Auras/SpellAuras.h
+++ b/src/server/game/Spells/Auras/SpellAuras.h
@@ -67,9 +67,9 @@ class AuraApplication
uint8 GetSlot() const { return _slot; }
uint8 GetFlags() const { return _flags; }
uint8 GetEffectMask() const { return _flags & (AFLAG_EFF_INDEX_0 | AFLAG_EFF_INDEX_1 | AFLAG_EFF_INDEX_2); }
- bool HasEffect(uint8 effect) const { ASSERT(effect < MAX_SPELL_EFFECTS); return _flags & (1<<effect); }
- bool IsPositive() const { return _flags & AFLAG_POSITIVE; }
- bool IsSelfcast() const { return _flags & AFLAG_CASTER; }
+ bool HasEffect(uint8 effect) const { ASSERT(effect < MAX_SPELL_EFFECTS); return (_flags & (1 << effect)) != 0; }
+ bool IsPositive() const { return (_flags & AFLAG_POSITIVE) != 0; }
+ bool IsSelfcast() const { return (_flags & AFLAG_CASTER) != 0; }
uint8 GetEffectsToApply() const { return _effectsToApply; }
void SetRemoveMode(AuraRemoveMode mode) { _removeMode = mode; }
diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp
index 6a2d54910f5..411f3c7343e 100644
--- a/src/server/game/Spells/Spell.cpp
+++ b/src/server/game/Spells/Spell.cpp
@@ -1755,8 +1755,8 @@ void Spell::SearchTargets(SEARCHER& searcher, uint32 containerMask, Unit* refere
return;
// search world and grid for possible targets
- bool searchInGrid = containerMask & (GRID_MAP_TYPE_MASK_CREATURE | GRID_MAP_TYPE_MASK_GAMEOBJECT);
- bool searchInWorld = containerMask & (GRID_MAP_TYPE_MASK_CREATURE | GRID_MAP_TYPE_MASK_PLAYER | GRID_MAP_TYPE_MASK_CORPSE);
+ bool searchInGrid = (containerMask & (GRID_MAP_TYPE_MASK_CREATURE | GRID_MAP_TYPE_MASK_GAMEOBJECT)) != 0;
+ bool searchInWorld = (containerMask & (GRID_MAP_TYPE_MASK_CREATURE | GRID_MAP_TYPE_MASK_PLAYER | GRID_MAP_TYPE_MASK_CORPSE)) != 0;
if (searchInGrid || searchInWorld)
{
float x, y;
@@ -2527,7 +2527,7 @@ SpellMissInfo Spell::DoSpellHitOnUnit(Unit* unit, uint32 effectMask, bool scaleA
aura_effmask |= 1 << i;
// Get Data Needed for Diminishing Returns, some effects may have multiple auras, so this must be done on spell hit, not aura add
- m_diminishGroup = GetDiminishingReturnsGroupForSpell(m_spellInfo, m_triggeredByAuraSpell);
+ m_diminishGroup = GetDiminishingReturnsGroupForSpell(m_spellInfo, m_triggeredByAuraSpell != nullptr);
if (m_diminishGroup && aura_effmask)
{
m_diminishLevel = unit->GetDiminishing(m_diminishGroup);
@@ -5579,7 +5579,7 @@ SpellCastResult Spell::CheckCasterAuras() const
mechanic_immune = IMMUNE_TO_MOVEMENT_IMPAIRMENT_AND_LOSS_CONTROL_MASK;
}
- bool usableInStun = m_spellInfo->AttributesEx5 & SPELL_ATTR5_USABLE_WHILE_STUNNED;
+ bool usableInStun = (m_spellInfo->AttributesEx5 & SPELL_ATTR5_USABLE_WHILE_STUNNED) != 0;
// Glyph of Pain Suppression
// Allow Pain Suppression and Guardian Spirit to be cast while stunned
@@ -6508,7 +6508,7 @@ bool Spell::CheckEffectTarget(Unit const* target, uint32 eff) const
bool Spell::IsNextMeleeSwingSpell() const
{
- return m_spellInfo->Attributes & SPELL_ATTR0_ON_NEXT_SWING;
+ return (m_spellInfo->Attributes & SPELL_ATTR0_ON_NEXT_SWING) != 0;
}
bool Spell::IsAutoActionResetSpell() const
@@ -6687,7 +6687,7 @@ void Spell::HandleLaunchPhase()
if (m_applyMultiplierMask & (1 << i))
multiplier[i] = m_spellInfo->Effects[i].CalcDamageMultiplier(m_originalCaster, this);
- bool usesAmmo = m_spellInfo->AttributesCu & SPELL_ATTR0_CU_DIRECT_DAMAGE;
+ bool usesAmmo = (m_spellInfo->AttributesCu & SPELL_ATTR0_CU_DIRECT_DAMAGE) != 0;
for (std::list<TargetInfo>::iterator ihit= m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
{
diff --git a/src/server/game/Spells/Spell.h b/src/server/game/Spells/Spell.h
index ae5bba9ed1a..5b976ced426 100644
--- a/src/server/game/Spells/Spell.h
+++ b/src/server/game/Spells/Spell.h
@@ -150,8 +150,8 @@ class SpellCastTargets
void ModDst(SpellDestination const& spellDest);
void RemoveDst();
- bool HasSrc() const { return GetTargetMask() & TARGET_FLAG_SOURCE_LOCATION; }
- bool HasDst() const { return GetTargetMask() & TARGET_FLAG_DEST_LOCATION; }
+ bool HasSrc() const { return (GetTargetMask() & TARGET_FLAG_SOURCE_LOCATION) != 0; }
+ bool HasDst() const { return (GetTargetMask() & TARGET_FLAG_DEST_LOCATION) != 0; }
bool HasTraj() const { return m_speed != 0; }
float GetElevation() const { return m_elevation; }
@@ -471,7 +471,7 @@ class Spell
void SetAutoRepeat(bool rep) { m_autoRepeat = rep; }
void ReSetTimer() { m_timer = m_casttime > 0 ? m_casttime : 0; }
bool IsNextMeleeSwingSpell() const;
- bool IsTriggered() const { return _triggeredCastFlags & TRIGGERED_FULL_MASK; }
+ bool IsTriggered() const { return (_triggeredCastFlags & TRIGGERED_FULL_MASK) != 0; }
bool IsChannelActive() const { return m_caster->GetUInt32Value(UNIT_CHANNEL_SPELL) != 0; }
bool IsAutoActionResetSpell() const;
diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp
index 301f33646dd..daef0208678 100644
--- a/src/server/game/Spells/SpellEffects.cpp
+++ b/src/server/game/Spells/SpellEffects.cpp
@@ -5072,7 +5072,7 @@ void Spell::EffectStealBeneficialBuff(SpellEffIndex effIndex)
// The charges / stack amounts don't count towards the total number of auras that can be dispelled.
// Ie: A dispel on a target with 5 stacks of Winters Chill and a Polymorph has 1 / (1 + 1) -> 50% chance to dispell
// Polymorph instead of 1 / (5 + 1) -> 16%.
- bool dispel_charges = aura->GetSpellInfo()->AttributesEx7 & SPELL_ATTR7_DISPEL_CHARGES;
+ bool dispel_charges = (aura->GetSpellInfo()->AttributesEx7 & SPELL_ATTR7_DISPEL_CHARGES) != 0;
uint8 charges = dispel_charges ? aura->GetCharges() : aura->GetStackAmount();
if (charges > 0)
steal_list.push_back(std::make_pair(aura, charges));
diff --git a/src/server/game/Spells/SpellInfo.cpp b/src/server/game/Spells/SpellInfo.cpp
index cc10569f28f..e2c66dc6b3a 100644
--- a/src/server/game/Spells/SpellInfo.cpp
+++ b/src/server/game/Spells/SpellInfo.cpp
@@ -1170,7 +1170,7 @@ bool SpellInfo::IsTargetingArea() const
bool SpellInfo::NeedsExplicitUnitTarget() const
{
- return GetExplicitTargetMask() & TARGET_FLAG_UNIT_MASK;
+ return (GetExplicitTargetMask() & TARGET_FLAG_UNIT_MASK) != 0;
}
bool SpellInfo::NeedsToBeTriggeredByCaster(SpellInfo const* triggeringSpell) const
@@ -1211,7 +1211,7 @@ bool SpellInfo::NeedsToBeTriggeredByCaster(SpellInfo const* triggeringSpell) con
bool SpellInfo::IsPassive() const
{
- return Attributes & SPELL_ATTR0_PASSIVE;
+ return (Attributes & SPELL_ATTR0_PASSIVE) != 0;
}
bool SpellInfo::IsAutocastable() const
@@ -1279,12 +1279,12 @@ bool SpellInfo::IsCooldownStartedOnEvent() const
bool SpellInfo::IsDeathPersistent() const
{
- return AttributesEx3 & SPELL_ATTR3_DEATH_PERSISTENT;
+ return (AttributesEx3 & SPELL_ATTR3_DEATH_PERSISTENT) != 0;
}
bool SpellInfo::IsRequiringDeadTarget() const
{
- return AttributesEx3 & SPELL_ATTR3_ONLY_TARGET_GHOSTS;
+ return (AttributesEx3 & SPELL_ATTR3_ONLY_TARGET_GHOSTS) != 0;
}
bool SpellInfo::IsAllowingDeadTarget() const
@@ -1318,12 +1318,12 @@ bool SpellInfo::IsPositiveEffect(uint8 effIndex) const
bool SpellInfo::IsChanneled() const
{
- return (AttributesEx & (SPELL_ATTR1_CHANNELED_1 | SPELL_ATTR1_CHANNELED_2));
+ return (AttributesEx & (SPELL_ATTR1_CHANNELED_1 | SPELL_ATTR1_CHANNELED_2)) != 0;
}
bool SpellInfo::NeedsComboPoints() const
{
- return (AttributesEx & (SPELL_ATTR1_REQ_COMBO_POINTS1 | SPELL_ATTR1_REQ_COMBO_POINTS2));
+ return (AttributesEx & (SPELL_ATTR1_REQ_COMBO_POINTS1 | SPELL_ATTR1_REQ_COMBO_POINTS2)) != 0;
}
bool SpellInfo::IsBreakingStealth() const
@@ -1339,7 +1339,7 @@ bool SpellInfo::IsRangedWeaponSpell() const
bool SpellInfo::IsAutoRepeatRangedSpell() const
{
- return AttributesEx2 & SPELL_ATTR2_AUTOREPEAT_FLAG;
+ return (AttributesEx2 & SPELL_ATTR2_AUTOREPEAT_FLAG) != 0;
}
bool SpellInfo::IsAffectedBySpellMods() const
diff --git a/src/server/game/Spells/SpellMgr.h b/src/server/game/Spells/SpellMgr.h
index 4f6364cf036..775d3f0c36d 100644
--- a/src/server/game/Spells/SpellMgr.h
+++ b/src/server/game/Spells/SpellMgr.h
@@ -21,8 +21,6 @@
// For static or at-server-startup loaded spell data
-#include <ace/Singleton.h>
-
#include "Define.h"
#include "DBCStructure.h"
#include "SharedDefines.h"
@@ -603,7 +601,6 @@ bool IsDiminishingReturnsGroupDurationLimited(DiminishingGroup group);
class SpellMgr
{
- friend class ACE_Singleton<SpellMgr, ACE_Null_Mutex>;
// Constructors
private:
SpellMgr();
@@ -611,6 +608,13 @@ class SpellMgr
// Accessors (const or static functions)
public:
+ static SpellMgr* instance()
+ {
+ static SpellMgr* instance = new SpellMgr();
+
+ return instance;
+ }
+
// Spell correctness for client using
static bool IsSpellValid(SpellInfo const* spellInfo, Player* player = NULL, bool msg = true);
@@ -766,6 +770,6 @@ class SpellMgr
SpellInfoMap mSpellInfoMap;
};
-#define sSpellMgr ACE_Singleton<SpellMgr, ACE_Null_Mutex>::instance()
+#define sSpellMgr SpellMgr::instance()
#endif
diff --git a/src/server/game/Spells/SpellScript.cpp b/src/server/game/Spells/SpellScript.cpp
index c0bcd477e5b..7132e0583e8 100644
--- a/src/server/game/Spells/SpellScript.cpp
+++ b/src/server/game/Spells/SpellScript.cpp
@@ -87,7 +87,7 @@ uint8 _SpellScript::EffectHook::GetAffectedEffectsMask(SpellInfo const* spellEnt
bool _SpellScript::EffectHook::IsEffectAffected(SpellInfo const* spellEntry, uint8 effIndex)
{
- return GetAffectedEffectsMask(spellEntry) & 1<<effIndex;
+ return (GetAffectedEffectsMask(spellEntry) & 1 << effIndex) != 0;
}
std::string _SpellScript::EffectHook::EffIndexToString()
diff --git a/src/server/game/Spells/SpellScript.h b/src/server/game/Spells/SpellScript.h
index 32b8781fb89..43d8a577fa3 100644
--- a/src/server/game/Spells/SpellScript.h
+++ b/src/server/game/Spells/SpellScript.h
@@ -256,8 +256,8 @@ class SpellScript : public _SpellScript
bool _Validate(SpellInfo const* entry);
bool _Load(Spell* spell);
void _InitHit();
- bool _IsEffectPrevented(SpellEffIndex effIndex) { return m_hitPreventEffectMask & (1<<effIndex); }
- bool _IsDefaultEffectPrevented(SpellEffIndex effIndex) { return m_hitPreventDefaultEffectMask & (1<<effIndex); }
+ bool _IsEffectPrevented(SpellEffIndex effIndex) { return (m_hitPreventEffectMask & (1 << effIndex)) != 0; }
+ bool _IsDefaultEffectPrevented(SpellEffIndex effIndex) { return (m_hitPreventDefaultEffectMask & (1 << effIndex)) != 0; }
void _PrepareScriptCall(SpellScriptHookType hookType);
void _FinishScriptCall();
bool IsInCheckCastHook() const;
diff --git a/src/server/game/Texts/CreatureTextMgr.h b/src/server/game/Texts/CreatureTextMgr.h
index 28722ae70f4..d1db202ca68 100644
--- a/src/server/game/Texts/CreatureTextMgr.h
+++ b/src/server/game/Texts/CreatureTextMgr.h
@@ -82,11 +82,17 @@ typedef std::unordered_map<uint64, CreatureTextRepeatGroup> CreatureTextRepeatMa
class CreatureTextMgr
{
- friend class ACE_Singleton<CreatureTextMgr, ACE_Null_Mutex>;
- CreatureTextMgr() { };
+ private:
+ CreatureTextMgr() { };
+ ~CreatureTextMgr() { };
public:
- ~CreatureTextMgr() { };
+ static CreatureTextMgr* instance()
+ {
+ static CreatureTextMgr* instance = new CreatureTextMgr();
+ return instance;
+ }
+
void LoadCreatureTexts();
void LoadCreatureTextLocales();
CreatureTextMap const& GetTextMap() const { return mTextMap; }
@@ -113,7 +119,7 @@ class CreatureTextMgr
LocaleCreatureTextMap mLocaleTextMap;
};
-#define sCreatureTextMgr ACE_Singleton<CreatureTextMgr, ACE_Null_Mutex>::instance()
+#define sCreatureTextMgr CreatureTextMgr::instance()
template<class Builder>
class CreatureTextLocalizer
diff --git a/src/server/game/Tickets/TicketMgr.h b/src/server/game/Tickets/TicketMgr.h
index 5bfe78abbba..00b4e228fab 100644
--- a/src/server/game/Tickets/TicketMgr.h
+++ b/src/server/game/Tickets/TicketMgr.h
@@ -19,7 +19,6 @@
#define _TICKETMGR_H
#include <string>
-#include <ace/Singleton.h>
#include "ObjectMgr.h"
@@ -85,7 +84,7 @@ public:
GmTicket(Player* player);
~GmTicket();
- bool IsClosed() const { return _closedBy; }
+ bool IsClosed() const { return _closedBy != 0; }
bool IsCompleted() const { return _completed; }
bool IsFromPlayer(uint64 guid) const { return guid == _playerGuid; }
bool IsAssigned() const { return _assignedTo != 0; }
@@ -174,13 +173,17 @@ typedef std::map<uint32, GmTicket*> GmTicketList;
class TicketMgr
{
- friend class ACE_Singleton<TicketMgr, ACE_Null_Mutex>;
-
private:
TicketMgr();
~TicketMgr();
public:
+ static TicketMgr* instance()
+ {
+ static TicketMgr* instance = new TicketMgr();
+ return instance;
+ }
+
void LoadTickets();
void LoadSurveys();
@@ -246,6 +249,6 @@ protected:
uint64 _lastChange;
};
-#define sTicketMgr ACE_Singleton<TicketMgr, ACE_Null_Mutex>::instance()
+#define sTicketMgr TicketMgr::instance()
#endif // _TICKETMGR_H
diff --git a/src/server/game/Tools/CharacterDatabaseCleaner.cpp b/src/server/game/Tools/CharacterDatabaseCleaner.cpp
index 758c78b685d..11ed54bfa81 100644
--- a/src/server/game/Tools/CharacterDatabaseCleaner.cpp
+++ b/src/server/game/Tools/CharacterDatabaseCleaner.cpp
@@ -108,7 +108,7 @@ void CharacterDatabaseCleaner::CheckUnique(const char* column, const char* table
bool CharacterDatabaseCleaner::AchievementProgressCheck(uint32 criteria)
{
- return sAchievementMgr->GetAchievementCriteria(criteria);
+ return sAchievementMgr->GetAchievementCriteria(criteria) != nullptr;
}
void CharacterDatabaseCleaner::CleanCharacterAchievementProgress()
@@ -118,7 +118,7 @@ void CharacterDatabaseCleaner::CleanCharacterAchievementProgress()
bool CharacterDatabaseCleaner::SkillCheck(uint32 skill)
{
- return sSkillLineStore.LookupEntry(skill);
+ return sSkillLineStore.LookupEntry(skill) != nullptr;
}
void CharacterDatabaseCleaner::CleanCharacterSkills()
@@ -142,7 +142,7 @@ bool CharacterDatabaseCleaner::TalentCheck(uint32 talent_id)
if (!talentInfo)
return false;
- return sTalentTabStore.LookupEntry(talentInfo->TalentTab);
+ return sTalentTabStore.LookupEntry(talentInfo->TalentTab) != nullptr;
}
void CharacterDatabaseCleaner::CleanCharacterTalent()
diff --git a/src/server/game/Warden/WardenCheckMgr.cpp b/src/server/game/Warden/WardenCheckMgr.cpp
index 44bab1d31b3..98ed381a2b1 100644
--- a/src/server/game/Warden/WardenCheckMgr.cpp
+++ b/src/server/game/Warden/WardenCheckMgr.cpp
@@ -164,7 +164,7 @@ void WardenCheckMgr::LoadWardenOverrides()
uint32 count = 0;
- ACE_WRITE_GUARD(ACE_RW_Mutex, g, _checkStoreLock);
+ boost::unique_lock<boost::shared_mutex> lock(sWardenCheckMgr->_checkStoreLock);
do
{
diff --git a/src/server/game/Warden/WardenCheckMgr.h b/src/server/game/Warden/WardenCheckMgr.h
index 8f2fa37400d..c9e26283060 100644
--- a/src/server/game/Warden/WardenCheckMgr.h
+++ b/src/server/game/Warden/WardenCheckMgr.h
@@ -20,6 +20,8 @@
#define _WARDENCHECKMGR_H
#include <map>
+#include <boost/thread/locks.hpp>
+#include <boost/thread/shared_mutex.hpp>
#include "Cryptography/BigNumber.h"
enum WardenActions
@@ -48,11 +50,17 @@ struct WardenCheckResult
class WardenCheckMgr
{
- friend class ACE_Singleton<WardenCheckMgr, ACE_Null_Mutex>;
- WardenCheckMgr();
- ~WardenCheckMgr();
+ private:
+ WardenCheckMgr();
+ ~WardenCheckMgr();
public:
+ static WardenCheckMgr* instance()
+ {
+ static WardenCheckMgr* instance = new WardenCheckMgr();
+ return instance;
+ }
+
// We have a linear key without any gaps, so we use vector for fast access
typedef std::vector<WardenCheck*> CheckContainer;
typedef std::map<uint32, WardenCheckResult*> CheckResultContainer;
@@ -66,13 +74,13 @@ class WardenCheckMgr
void LoadWardenChecks();
void LoadWardenOverrides();
- ACE_RW_Mutex _checkStoreLock;
+ boost::shared_mutex _checkStoreLock;
private:
CheckContainer CheckStore;
CheckResultContainer CheckResultStore;
};
-#define sWardenCheckMgr ACE_Singleton<WardenCheckMgr, ACE_Null_Mutex>::instance()
+#define sWardenCheckMgr WardenCheckMgr::instance()
#endif
diff --git a/src/server/game/Warden/WardenWin.cpp b/src/server/game/Warden/WardenWin.cpp
index 3428708ed69..9de4ff0958e 100644
--- a/src/server/game/Warden/WardenWin.cpp
+++ b/src/server/game/Warden/WardenWin.cpp
@@ -206,7 +206,7 @@ void WardenWin::RequestData()
ByteBuffer buff;
buff << uint8(WARDEN_SMSG_CHEAT_CHECKS_REQUEST);
- ACE_READ_GUARD(ACE_RW_Mutex, g, sWardenCheckMgr->_checkStoreLock);
+ boost::shared_lock<boost::shared_mutex> lock(sWardenCheckMgr->_checkStoreLock);
for (uint32 i = 0; i < sWorld->getIntConfig(CONFIG_WARDEN_NUM_OTHER_CHECKS); ++i)
{
@@ -369,7 +369,7 @@ void WardenWin::HandleData(ByteBuffer &buff)
uint8 type;
uint16 checkFailed = 0;
- ACE_READ_GUARD(ACE_RW_Mutex, g, sWardenCheckMgr->_checkStoreLock);
+ boost::shared_lock<boost::shared_mutex> lock(sWardenCheckMgr->_checkStoreLock);
for (std::list<uint16>::iterator itr = _currentChecks.begin(); itr != _currentChecks.end(); ++itr)
{
diff --git a/src/server/game/Weather/Weather.cpp b/src/server/game/Weather/Weather.cpp
index 79b4fbd8c69..cab232931b9 100644
--- a/src/server/game/Weather/Weather.cpp
+++ b/src/server/game/Weather/Weather.cpp
@@ -95,7 +95,7 @@ bool Weather::ReGenerate()
// season source http://aa.usno.navy.mil/data/docs/EarthSeasons.html
time_t gtime = sWorld->GetGameTime();
struct tm ltime;
- ACE_OS::localtime_r(&gtime, &ltime);
+ localtime_r(&gtime, &ltime);
uint32 season = ((ltime.tm_yday - 78 + 365)/91)%4;
static char const* seasonName[WEATHER_SEASONS] = { "spring", "summer", "fall", "winter" };
diff --git a/src/server/game/Weather/WeatherMgr.cpp b/src/server/game/Weather/WeatherMgr.cpp
index 7a48d935a21..f18809b107a 100644
--- a/src/server/game/Weather/WeatherMgr.cpp
+++ b/src/server/game/Weather/WeatherMgr.cpp
@@ -24,7 +24,6 @@
#include "Weather.h"
#include "Log.h"
#include "ObjectMgr.h"
-#include "AutoPtr.h"
#include "Player.h"
#include "WorldPacket.h"
#include "Opcodes.h"
@@ -35,7 +34,7 @@ namespace WeatherMgr
namespace
{
- typedef std::unordered_map<uint32, Trinity::AutoPtr<Weather, ACE_Null_Mutex> > WeatherMap;
+ typedef std::unordered_map<uint32, std::shared_ptr<Weather> > WeatherMap;
typedef std::unordered_map<uint32, WeatherData> WeatherZoneMap;
WeatherMap m_weathers;
diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp
index 1bc22317d11..e5dc9ba1a4c 100644
--- a/src/server/game/World/World.cpp
+++ b/src/server/game/World/World.cpp
@@ -20,6 +20,7 @@
\ingroup world
*/
+#include <atomic>
#include "Common.h"
#include "Memory.h"
#include "DatabaseEnv.h"
@@ -83,9 +84,10 @@
#include "BattlefieldMgr.h"
#include "TransportMgr.h"
-ACE_Atomic_Op<ACE_Thread_Mutex, bool> World::m_stopEvent = false;
+
+std::atomic<bool> World::m_stopEvent(false);
uint8 World::m_ExitCode = SHUTDOWN_EXIT_CODE;
-ACE_Atomic_Op<ACE_Thread_Mutex, uint32> World::m_worldLoopCounter = 0;
+std::atomic<uint32> World::m_worldLoopCounter(0);
float World::m_MaxVisibleDistanceOnContinents = DEFAULT_VISIBILITY_DISTANCE;
float World::m_MaxVisibleDistanceInInstances = DEFAULT_VISIBILITY_INSTANCE;
@@ -681,7 +683,7 @@ void World::LoadConfigSettings(bool reload)
m_bool_configs[CONFIG_ALLOW_TWO_SIDE_INTERACTION_GROUP] = sConfigMgr->GetBoolDefault("AllowTwoSide.Interaction.Group", false);
m_bool_configs[CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD] = sConfigMgr->GetBoolDefault("AllowTwoSide.Interaction.Guild", false);
m_bool_configs[CONFIG_ALLOW_TWO_SIDE_INTERACTION_AUCTION] = sConfigMgr->GetBoolDefault("AllowTwoSide.Interaction.Auction", false);
- m_bool_configs[CONFIG_ALLOW_TWO_SIDE_TRADE] = sConfigMgr->GetBoolDefault("AllowTwoSide.trade", false);
+ m_bool_configs[CONFIG_ALLOW_TWO_SIDE_TRADE] = sConfigMgr->GetBoolDefault("AllowTwoSide.Trade", false);
m_int_configs[CONFIG_STRICT_PLAYER_NAMES] = sConfigMgr->GetIntDefault ("StrictPlayerNames", 0);
m_int_configs[CONFIG_STRICT_CHARTER_NAMES] = sConfigMgr->GetIntDefault ("StrictCharterNames", 0);
m_int_configs[CONFIG_STRICT_PET_NAMES] = sConfigMgr->GetIntDefault ("StrictPetNames", 0);
@@ -990,7 +992,7 @@ void World::LoadConfigSettings(bool reload)
m_int_configs[CONFIG_CHATFLOOD_MESSAGE_DELAY] = sConfigMgr->GetIntDefault("ChatFlood.MessageDelay", 1);
m_int_configs[CONFIG_CHATFLOOD_MUTE_TIME] = sConfigMgr->GetIntDefault("ChatFlood.MuteTime", 10);
- m_bool_configs[CONFIG_EVENT_ANNOUNCE] = sConfigMgr->GetIntDefault("Event.Announce", false);
+ m_bool_configs[CONFIG_EVENT_ANNOUNCE] = sConfigMgr->GetBoolDefault("Event.Announce", false);
m_float_configs[CONFIG_CREATURE_FAMILY_FLEE_ASSISTANCE_RADIUS] = sConfigMgr->GetFloatDefault("CreatureFamilyFleeAssistanceRadius", 30.0f);
m_float_configs[CONFIG_CREATURE_FAMILY_ASSISTANCE_RADIUS] = sConfigMgr->GetFloatDefault("CreatureFamilyAssistanceRadius", 10.0f);
@@ -1301,8 +1303,6 @@ void World::LoadConfigSettings(bool reload)
m_bool_configs[CONFIG_IP_BASED_ACTION_LOGGING] = sConfigMgr->GetBoolDefault("Allow.IP.Based.Action.Logging", false);
- m_bool_configs[CONFIG_IP_BASED_LOGIN_LOGGING] = sConfigMgr->GetBoolDefault("Wrong.Password.Login.Logging", false);
-
// call ScriptMgr if we're reloading the configuration
if (reload)
sScriptMgr->OnConfigLoad(reload);
@@ -1816,7 +1816,7 @@ void World::SetInitialWorldSettings()
//one second is 1000 -(tested on win system)
/// @todo Get rid of magic numbers
tm localTm;
- ACE_OS::localtime_r(&m_gameTime, &localTm);
+ localtime_r(&m_gameTime, &localTm);
mail_timer = ((((localTm.tm_hour + 20) % 24)* HOUR * IN_MILLISECONDS) / m_timers[WUPDATE_AUCTIONS].GetInterval());
//1440
mail_timer_expires = ((DAY * IN_MILLISECONDS) / (m_timers[WUPDATE_AUCTIONS].GetInterval()));
@@ -2636,7 +2636,7 @@ void World::ShutdownMsg(bool show, Player* player)
void World::ShutdownCancel()
{
// nothing cancel or too later
- if (!m_ShutdownTimer || m_stopEvent.value())
+ if (!m_ShutdownTimer || m_stopEvent)
return;
ServerMessageType msgid = (m_ShutdownMask & SHUTDOWN_MASK_RESTART) ? SERVER_MSG_RESTART_CANCELLED : SERVER_MSG_SHUTDOWN_CANCELLED;
@@ -2779,7 +2779,7 @@ void World::UpdateRealmCharCount(uint32 accountId)
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHARACTER_COUNT);
stmt->setUInt32(0, accountId);
PreparedQueryResultFuture result = CharacterDatabase.AsyncQuery(stmt);
- m_realmCharCallbacks.insert(result);
+ m_realmCharCallbacks.push_back(std::move(result));
}
void World::_UpdateRealmCharCount(PreparedQueryResult resultCharCount)
@@ -2827,7 +2827,7 @@ void World::InitDailyQuestResetTime()
// FIX ME: client not show day start time
time_t curTime = time(NULL);
tm localTm;
- ACE_OS::localtime_r(&curTime, &localTm);
+ localtime_r(&curTime, &localTm);
localTm.tm_hour = 6;
localTm.tm_min = 0;
localTm.tm_sec = 0;
@@ -2861,7 +2861,7 @@ void World::InitRandomBGResetTime()
// generate time by config
time_t curTime = time(NULL);
tm localTm;
- ACE_OS::localtime_r(&curTime, &localTm);
+ localtime_r(&curTime, &localTm);
localTm.tm_hour = getIntConfig(CONFIG_RANDOM_BG_RESET_HOUR);
localTm.tm_min = 0;
localTm.tm_sec = 0;
@@ -2889,7 +2889,7 @@ void World::InitGuildResetTime()
// generate time by config
time_t curTime = time(NULL);
tm localTm;
- ACE_OS::localtime_r(&curTime, &localTm);
+ localtime_r(&curTime, &localTm);
localTm.tm_hour = getIntConfig(CONFIG_GUILD_RESET_HOUR);
localTm.tm_min = 0;
localTm.tm_sec = 0;
@@ -3015,7 +3015,7 @@ void World::ResetMonthlyQuests()
// generate time
time_t curTime = time(NULL);
tm localTm;
- ACE_OS::localtime_r(&curTime, &localTm);
+ localtime_r(&curTime, &localTm);
int month = localTm.tm_mon;
int year = localTm.tm_year;
@@ -3180,19 +3180,17 @@ void World::ProcessQueryCallbacks()
{
PreparedQueryResult result;
- while (!m_realmCharCallbacks.is_empty())
+ for (std::deque<std::future<PreparedQueryResult>>::iterator itr = m_realmCharCallbacks.begin(); itr != m_realmCharCallbacks.end(); )
{
- ACE_Future<PreparedQueryResult> lResult;
- ACE_Time_Value timeout = ACE_Time_Value::zero;
- if (m_realmCharCallbacks.next_readable(lResult, &timeout) != 1)
- break;
-
- if (lResult.ready())
+ if ((*itr).wait_for(std::chrono::seconds(0)) != std::future_status::ready)
{
- lResult.get(result);
- _UpdateRealmCharCount(result);
- lResult.cancel();
+ ++itr;
+ continue;
}
+
+ result = (*itr).get();
+ _UpdateRealmCharCount(result);
+ itr = m_realmCharCallbacks.erase(itr);
}
}
diff --git a/src/server/game/World/World.h b/src/server/game/World/World.h
index 8a371bd75c2..557a0e62965 100644
--- a/src/server/game/World/World.h
+++ b/src/server/game/World/World.h
@@ -25,12 +25,11 @@
#include "Common.h"
#include "Timer.h"
-#include <ace/Singleton.h>
-#include <ace/Atomic_Op.h>
#include "SharedDefines.h"
#include "QueryResult.h"
#include "Callback.h"
+#include <atomic>
#include <map>
#include <set>
#include <list>
@@ -163,7 +162,6 @@ enum WorldBoolConfigs
CONFIG_STATS_LIMITS_ENABLE,
CONFIG_INSTANCES_RESET_ANNOUNCE,
CONFIG_IP_BASED_ACTION_LOGGING,
- CONFIG_IP_BASED_LOGIN_LOGGING,
BOOL_CONFIG_VALUE_COUNT
};
@@ -539,10 +537,13 @@ struct CharacterNameData
class World
{
public:
- static ACE_Atomic_Op<ACE_Thread_Mutex, uint32> m_worldLoopCounter;
+ static World* instance()
+ {
+ static World* instance = new World();
+ return instance;
+ }
- World();
- ~World();
+ static std::atomic<uint32> m_worldLoopCounter;
WorldSession* FindSession(uint32 id) const;
void AddSession(WorldSession* s);
@@ -655,7 +656,7 @@ class World
void ShutdownMsg(bool show = false, Player* player = NULL);
static uint8 GetExitCode() { return m_ExitCode; }
static void StopNow(uint8 exitcode) { m_stopEvent = true; m_ExitCode = exitcode; }
- static bool IsStopped() { return m_stopEvent.value(); }
+ static bool IsStopped() { return m_stopEvent; }
void Update(uint32 diff);
@@ -780,7 +781,10 @@ class World
void ResetGuildCap();
void ResetCurrencyWeekCap();
private:
- static ACE_Atomic_Op<ACE_Thread_Mutex, bool> m_stopEvent;
+ World();
+ ~World();
+
+ static std::atomic<bool> m_stopEvent;
static uint8 m_ExitCode;
uint32 m_ShutdownTimer;
uint32 m_ShutdownMask;
@@ -832,7 +836,7 @@ class World
static int32 m_visibility_notify_periodInBGArenas;
// CLI command holder to be thread safe
- ACE_Based::LockedQueue<CliCommandHolder*, ACE_Thread_Mutex> cliCmdQueue;
+ LockedQueue<CliCommandHolder*> cliCmdQueue;
// scheduled reset times
time_t m_NextDailyQuestReset;
@@ -847,7 +851,7 @@ class World
// sessions that are added async
void AddSession_(WorldSession* s);
- ACE_Based::LockedQueue<WorldSession*, ACE_Thread_Mutex> addSessQueue;
+ LockedQueue<WorldSession*> addSessQueue;
// used versions
std::string m_DBVersion;
@@ -862,11 +866,11 @@ class World
void LoadCharacterNameData();
void ProcessQueryCallbacks();
- ACE_Future_Set<PreparedQueryResult> m_realmCharCallbacks;
+ std::deque<std::future<PreparedQueryResult>> m_realmCharCallbacks;
};
extern uint32 realmID;
-#define sWorld ACE_Singleton<World, ACE_Null_Mutex>::instance()
+#define sWorld World::instance()
#endif
/// @}
diff --git a/src/server/scripts/CMakeLists.txt b/src/server/scripts/CMakeLists.txt
index c12f16a7ab5..b634cebdc86 100644
--- a/src/server/scripts/CMakeLists.txt
+++ b/src/server/scripts/CMakeLists.txt
@@ -143,7 +143,6 @@ include_directories(
${CMAKE_SOURCE_DIR}/src/server/game/Weather
${CMAKE_SOURCE_DIR}/src/server/game/World
${CMAKE_CURRENT_SOURCE_DIR}/PrecompiledHeaders
- ${ACE_INCLUDE_DIR}
${MYSQL_INCLUDE_DIR}
)
diff --git a/src/server/scripts/Commands/cs_ban.cpp b/src/server/scripts/Commands/cs_ban.cpp
index 58accad1bf7..2f74132fe21 100644
--- a/src/server/scripts/Commands/cs_ban.cpp
+++ b/src/server/scripts/Commands/cs_ban.cpp
@@ -459,7 +459,7 @@ public:
{
time_t timeBan = time_t(fields2[0].GetUInt32());
tm tmBan;
- ACE_OS::localtime_r(&timeBan, &tmBan);
+ localtime_r(&timeBan, &tmBan);
if (fields2[0].GetUInt32() == fields2[1].GetUInt32())
{
@@ -471,7 +471,7 @@ public:
{
time_t timeUnban = time_t(fields2[1].GetUInt32());
tm tmUnban;
- ACE_OS::localtime_r(&timeUnban, &tmUnban);
+ localtime_r(&timeUnban, &tmUnban);
handler->PSendSysMessage("|%-15.15s|%02d-%02d-%02d %02d:%02d|%02d-%02d-%02d %02d:%02d|%-15.15s|%-15.15s|",
accountName.c_str(), tmBan.tm_year%100, tmBan.tm_mon+1, tmBan.tm_mday, tmBan.tm_hour, tmBan.tm_min,
tmUnban.tm_year%100, tmUnban.tm_mon+1, tmUnban.tm_mday, tmUnban.tm_hour, tmUnban.tm_min,
@@ -548,7 +548,7 @@ public:
{
time_t timeBan = time_t(banFields[0].GetUInt32());
tm tmBan;
- ACE_OS::localtime_r(&timeBan, &tmBan);
+ localtime_r(&timeBan, &tmBan);
if (banFields[0].GetUInt32() == banFields[1].GetUInt32())
{
@@ -560,7 +560,7 @@ public:
{
time_t timeUnban = time_t(banFields[1].GetUInt32());
tm tmUnban;
- ACE_OS::localtime_r(&timeUnban, &tmUnban);
+ localtime_r(&timeUnban, &tmUnban);
handler->PSendSysMessage("|%-15.15s|%02d-%02d-%02d %02d:%02d|%02d-%02d-%02d %02d:%02d|%-15.15s|%-15.15s|",
char_name.c_str(), tmBan.tm_year%100, tmBan.tm_mon+1, tmBan.tm_mday, tmBan.tm_hour, tmBan.tm_min,
tmUnban.tm_year%100, tmUnban.tm_mon+1, tmUnban.tm_mday, tmUnban.tm_hour, tmUnban.tm_min,
@@ -630,7 +630,7 @@ public:
Field* fields = result->Fetch();
time_t timeBan = time_t(fields[1].GetUInt32());
tm tmBan;
- ACE_OS::localtime_r(&timeBan, &tmBan);
+ localtime_r(&timeBan, &tmBan);
if (fields[1].GetUInt32() == fields[2].GetUInt32())
{
handler->PSendSysMessage("|%-15.15s|%02d-%02d-%02d %02d:%02d| permanent |%-15.15s|%-15.15s|",
@@ -641,7 +641,7 @@ public:
{
time_t timeUnban = time_t(fields[2].GetUInt32());
tm tmUnban;
- ACE_OS::localtime_r(&timeUnban, &tmUnban);
+ localtime_r(&timeUnban, &tmUnban);
handler->PSendSysMessage("|%-15.15s|%02d-%02d-%02d %02d:%02d|%02d-%02d-%02d %02d:%02d|%-15.15s|%-15.15s|",
fields[0].GetCString(), tmBan.tm_year%100, tmBan.tm_mon+1, tmBan.tm_mday, tmBan.tm_hour, tmBan.tm_min,
tmUnban.tm_year%100, tmUnban.tm_mon+1, tmUnban.tm_mday, tmUnban.tm_hour, tmUnban.tm_min,
diff --git a/src/server/scripts/Commands/cs_debug.cpp b/src/server/scripts/Commands/cs_debug.cpp
index d88d46e8ea6..4ff7efd2f0a 100644
--- a/src/server/scripts/Commands/cs_debug.cpp
+++ b/src/server/scripts/Commands/cs_debug.cpp
@@ -746,14 +746,14 @@ public:
if (item->GetOwnerGUID() != player->GetGUID())
{
- handler->PSendSysMessage("queue(" SIZEFMTD "): For the item with guid %d, the owner's guid (%d) and the player's guid (%d) don't match!", i, item->GetGUIDLow(), GUID_LOPART(item->GetOwnerGUID()), player->GetGUIDLow());
+ 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(), GUID_LOPART(item->GetOwnerGUID()), player->GetGUIDLow());
error = true;
continue;
}
if (item->GetQueuePos() != i)
{
- handler->PSendSysMessage("queue(" SIZEFMTD "): 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 with guid %d, the queuepos doesn't match it's position in the queue!", i, item->GetGUIDLow());
error = true;
continue;
}
@@ -765,14 +765,14 @@ public:
if (test == NULL)
{
- handler->PSendSysMessage("queue(" SIZEFMTD "): 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 the item with guid %d are incorrect, the player doesn't have any item at that position!", i, item->GetBagSlot(), item->GetSlot(), item->GetGUIDLow());
error = true;
continue;
}
if (test != item)
{
- handler->PSendSysMessage("queue(" SIZEFMTD "): 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 item with guid %d are incorrect, an item which guid is %d is there instead!", i, item->GetBagSlot(), item->GetSlot(), item->GetGUIDLow(), test->GetGUIDLow());
error = true;
continue;
}
@@ -910,7 +910,7 @@ public:
handler->GetSession()->GetPlayer()->GetClosePoint(x, y, z, handler->GetSession()->GetPlayer()->GetObjectSize());
if (!i)
- return handler->GetSession()->GetPlayer()->SummonCreature(entry, x, y, z, o);
+ return handler->GetSession()->GetPlayer()->SummonCreature(entry, x, y, z, o) != nullptr;
uint32 id = (uint32)atoi(i);
@@ -1126,28 +1126,28 @@ public:
uint64 guid = target->GetGUID();
- uint32 opcode = (uint32)atoi(x);
- if (opcode >= target->GetValuesCount())
+ uint32 field = (uint32)atoi(x);
+ if (field >= target->GetValuesCount())
{
- handler->PSendSysMessage(LANG_TOO_BIG_INDEX, opcode, GUID_LOPART(guid), target->GetValuesCount());
+ handler->PSendSysMessage(LANG_TOO_BIG_INDEX, field, GUID_LOPART(guid), target->GetValuesCount());
return false;
}
bool isInt32 = true;
if (z)
- isInt32 = (bool)atoi(z);
+ isInt32 = atoi(z) != 0;
if (isInt32)
{
uint32 value = (uint32)atoi(y);
- target->SetUInt32Value(opcode, value);
- handler->PSendSysMessage(LANG_SET_UINT_FIELD, GUID_LOPART(guid), opcode, value);
+ target->SetUInt32Value(field, value);
+ handler->PSendSysMessage(LANG_SET_UINT_FIELD, GUID_LOPART(guid), field, value);
}
else
{
float value = (float)atof(y);
- target->SetFloatValue(opcode, value);
- handler->PSendSysMessage(LANG_SET_FLOAT_FIELD, GUID_LOPART(guid), opcode, value);
+ target->SetFloatValue(field, value);
+ handler->PSendSysMessage(LANG_SET_FLOAT_FIELD, GUID_LOPART(guid), field, value);
}
return true;
@@ -1183,7 +1183,7 @@ public:
bool isInt32 = true;
if (z)
- isInt32 = (bool)atoi(z);
+ isInt32 = atoi(z) != 0;
if (isInt32)
{
diff --git a/src/server/scripts/Commands/cs_gm.cpp b/src/server/scripts/Commands/cs_gm.cpp
index eebb1b80002..d12ba9ad9b4 100644
--- a/src/server/scripts/Commands/cs_gm.cpp
+++ b/src/server/scripts/Commands/cs_gm.cpp
@@ -120,7 +120,7 @@ public:
bool first = true;
bool footer = false;
- TRINITY_READ_GUARD(HashMapHolder<Player>::LockType, *HashMapHolder<Player>::GetLock());
+ boost::shared_lock<boost::shared_mutex> lock(*HashMapHolder<Player>::GetLock());
HashMapHolder<Player>::MapType const& m = sObjectAccessor->GetPlayers();
for (HashMapHolder<Player>::MapType::const_iterator itr = m.begin(); itr != m.end(); ++itr)
{
diff --git a/src/server/scripts/Commands/cs_lfg.cpp b/src/server/scripts/Commands/cs_lfg.cpp
index 2bb2ff24aae..2f6afd29e9f 100644
--- a/src/server/scripts/Commands/cs_lfg.cpp
+++ b/src/server/scripts/Commands/cs_lfg.cpp
@@ -118,7 +118,7 @@ public:
static bool HandleLfgQueueInfoCommand(ChatHandler* handler, char const* args)
{
- handler->SendSysMessage(sLFGMgr->DumpQueueInfo(*args).c_str());
+ handler->SendSysMessage(sLFGMgr->DumpQueueInfo(atoi(args) != 0).c_str());
return true;
}
diff --git a/src/server/scripts/Commands/cs_misc.cpp b/src/server/scripts/Commands/cs_misc.cpp
index a3e8649854b..b476a2e0a13 100644
--- a/src/server/scripts/Commands/cs_misc.cpp
+++ b/src/server/scripts/Commands/cs_misc.cpp
@@ -30,7 +30,6 @@
#include "SpellAuras.h"
#include "TargetedMovementGenerator.h"
#include "WeatherMgr.h"
-#include "ace/INET_Addr.h"
#include "Player.h"
#include "Pet.h"
#include "LFG.h"
@@ -1343,7 +1342,7 @@ public:
return false;
}
- bool targetHasSkill = target->GetSkillValue(skill);
+ bool targetHasSkill = target->GetSkillValue(skill) != 0;
// If our target does not yet have the skill they are trying to add to them, the chosen level also becomes
// the max level of the new profession.
diff --git a/src/server/scripts/Commands/cs_mmaps.cpp b/src/server/scripts/Commands/cs_mmaps.cpp
index 19a276fbbc0..969027139fc 100644
--- a/src/server/scripts/Commands/cs_mmaps.cpp
+++ b/src/server/scripts/Commands/cs_mmaps.cpp
@@ -98,7 +98,7 @@ public:
Movement::PointsArray const& pointPath = path.GetPath();
handler->PSendSysMessage("%s's path to %s:", target->GetName().c_str(), player->GetName().c_str());
handler->PSendSysMessage("Building: %s", useStraightPath ? "StraightPath" : "SmoothPath");
- handler->PSendSysMessage("Result: %s - Length: " SIZEFMTD " - Type: %u", (result ? "true" : "false"), pointPath.size(), path.GetPathType());
+ handler->PSendSysMessage("Result: %s - Length: %zu - Type: %u", (result ? "true" : "false"), pointPath.size(), path.GetPathType());
G3D::Vector3 const &start = path.GetStartPosition();
G3D::Vector3 const &end = path.GetEndPosition();
@@ -273,7 +273,7 @@ public:
if (!creatureList.empty())
{
- handler->PSendSysMessage("Found " SIZEFMTD " Creatures.", creatureList.size());
+ handler->PSendSysMessage("Found %zu Creatures.", creatureList.size());
uint32 paths = 0;
uint32 uStartTime = getMSTime();
diff --git a/src/server/scripts/Commands/cs_reset.cpp b/src/server/scripts/Commands/cs_reset.cpp
index de0fd21d139..495dc522414 100644
--- a/src/server/scripts/Commands/cs_reset.cpp
+++ b/src/server/scripts/Commands/cs_reset.cpp
@@ -294,7 +294,7 @@ public:
stmt->setUInt16(0, uint16(atLogin));
CharacterDatabase.Execute(stmt);
- TRINITY_READ_GUARD(HashMapHolder<Player>::LockType, *HashMapHolder<Player>::GetLock());
+ boost::shared_lock<boost::shared_mutex> lock(*HashMapHolder<Player>::GetLock());
HashMapHolder<Player>::MapType const& plist = sObjectAccessor->GetPlayers();
for (HashMapHolder<Player>::MapType::const_iterator itr = plist.begin(); itr != plist.end(); ++itr)
itr->second->SetAtLoginFlag(atLogin);
diff --git a/src/server/scripts/EasternKingdoms/MagistersTerrace/instance_magisters_terrace.cpp b/src/server/scripts/EasternKingdoms/MagistersTerrace/instance_magisters_terrace.cpp
index 1f8ccfbd5d8..950d3c3d8f6 100644
--- a/src/server/scripts/EasternKingdoms/MagistersTerrace/instance_magisters_terrace.cpp
+++ b/src/server/scripts/EasternKingdoms/MagistersTerrace/instance_magisters_terrace.cpp
@@ -84,8 +84,8 @@ class instance_magisters_terrace : public InstanceMapScript
DelrissaDeathCount = 0;
break;
case DATA_KAELTHAS_STATUES:
- HandleGameObject(KaelStatue[0], data);
- HandleGameObject(KaelStatue[1], data);
+ HandleGameObject(KaelStatue[0], data != 0);
+ HandleGameObject(KaelStatue[1], data != 0);
break;
default:
break;
diff --git a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kiljaeden.cpp b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kiljaeden.cpp
index 565d40a802e..849b7014d3a 100644
--- a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kiljaeden.cpp
+++ b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kiljaeden.cpp
@@ -1171,7 +1171,7 @@ public:
c = 0;
mx = ShieldOrbLocations[0][0];
my = ShieldOrbLocations[0][1];
- bClockwise = urand(0, 1);
+ bClockwise = roll_chance_i(50);
}
void UpdateAI(uint32 diff) override
diff --git a/src/server/scripts/Northrend/ChamberOfAspects/ObsidianSanctum/obsidian_sanctum.cpp b/src/server/scripts/Northrend/ChamberOfAspects/ObsidianSanctum/obsidian_sanctum.cpp
index 2caa16fc19d..e332e7959ce 100644
--- a/src/server/scripts/Northrend/ChamberOfAspects/ObsidianSanctum/obsidian_sanctum.cpp
+++ b/src/server/scripts/Northrend/ChamberOfAspects/ObsidianSanctum/obsidian_sanctum.cpp
@@ -192,7 +192,7 @@ struct dummy_dragonAI : public ScriptedAI
void SetData(uint32 type, uint32 value) override
{
if (type == DATA_CAN_LOOT)
- _canLoot = value;
+ _canLoot = value != 0;
}
void MovementInform(uint32 type, uint32 pointId) override
diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/boss_grand_champions.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/boss_grand_champions.cpp
index b39734224f6..23753278e27 100644
--- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/boss_grand_champions.cpp
+++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/boss_grand_champions.cpp
@@ -674,7 +674,7 @@ public:
if (uiHealingWaveTimer <= uiDiff)
{
- bool bChance = urand(0, 1);
+ bool bChance = roll_chance_i(50);
if (!bChance)
{
diff --git a/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.cpp b/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.cpp
index 21a0f92c7b5..022c43f4395 100644
--- a/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.cpp
+++ b/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.cpp
@@ -1316,7 +1316,7 @@ class npc_the_lich_king_escape_hor : public CreatureScript
{
if (Unit* victim = me->SelectVictim())
AttackStart(victim);
- return me->GetVictim();
+ return me->GetVictim() != nullptr;
}
else if (me->getThreatManager().getThreatList().size() < 2 && me->HasAura(SPELL_REMORSELESS_WINTER))
{
diff --git a/src/server/scripts/Northrend/Gundrak/boss_drakkari_colossus.cpp b/src/server/scripts/Northrend/Gundrak/boss_drakkari_colossus.cpp
index b02a319abdc..68929d2aa01 100644
--- a/src/server/scripts/Northrend/Gundrak/boss_drakkari_colossus.cpp
+++ b/src/server/scripts/Northrend/Gundrak/boss_drakkari_colossus.cpp
@@ -205,7 +205,7 @@ class boss_drakkari_colossus : public CreatureScript
void SetData(uint32 type, uint32 data) override
{
if (type == DATA_INTRO_DONE)
- introDone = data;
+ introDone = data != 0;
}
void UpdateAI(uint32 diff) override
diff --git a/src/server/scripts/Northrend/Gundrak/boss_slad_ran.cpp b/src/server/scripts/Northrend/Gundrak/boss_slad_ran.cpp
index a8e539b02fd..98c8481b5ae 100644
--- a/src/server/scripts/Northrend/Gundrak/boss_slad_ran.cpp
+++ b/src/server/scripts/Northrend/Gundrak/boss_slad_ran.cpp
@@ -201,7 +201,7 @@ public:
bool WasWrapped(uint64 guid)
{
- return lWrappedPlayers.count(guid);
+ return lWrappedPlayers.count(guid) != 0;
}
};
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_icecrown_gunship_battle.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_icecrown_gunship_battle.cpp
index c0c909e4878..a0f6039d703 100644
--- a/src/server/scripts/Northrend/IcecrownCitadel/boss_icecrown_gunship_battle.cpp
+++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_icecrown_gunship_battle.cpp
@@ -626,7 +626,8 @@ protected:
{
if (Unit* victim = me->SelectVictim())
AttackStart(victim);
- return me->GetVictim();
+
+ return me->GetVictim() != nullptr;
}
else if (me->getThreatManager().isThreatListEmpty())
{
@@ -1872,7 +1873,7 @@ class spell_igb_rocket_pack_useable : public SpellScriptLoader
bool Load()
{
- return GetOwner()->GetInstanceScript();
+ return GetOwner()->GetInstanceScript() != nullptr;
}
bool CheckAreaTarget(Unit* target)
@@ -2328,7 +2329,7 @@ class spell_igb_gunship_fall_teleport : public SpellScriptLoader
bool Load()
{
- return GetCaster()->GetInstanceScript();
+ return GetCaster()->GetInstanceScript() != nullptr;
}
void SelectTransport(WorldObject*& target)
@@ -2417,7 +2418,7 @@ class spell_igb_teleport_players_on_victory : public SpellScriptLoader
bool Load() override
{
- return GetCaster()->GetInstanceScript();
+ return GetCaster()->GetInstanceScript() != nullptr;
}
void FilterTargets(std::list<WorldObject*>& targets)
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp
index 3bf8fd8d305..f60a7ba278b 100644
--- a/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp
+++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp
@@ -558,7 +558,7 @@ class boss_professor_putricide : public CreatureScript
void SetData(uint32 id, uint32 data) override
{
if (id == DATA_EXPERIMENT_STAGE)
- _experimentState = bool(data);
+ _experimentState = data != 0;
}
void UpdateAI(uint32 diff) override
diff --git a/src/server/scripts/Northrend/Naxxramas/boss_gothik.cpp b/src/server/scripts/Northrend/Naxxramas/boss_gothik.cpp
index d973ce867f2..554c7957d2a 100644
--- a/src/server/scripts/Northrend/Naxxramas/boss_gothik.cpp
+++ b/src/server/scripts/Northrend/Naxxramas/boss_gothik.cpp
@@ -522,7 +522,7 @@ class npc_gothik_minion : public CreatureScript
void DoAction(int32 param) override
{
- gateClose = param;
+ gateClose = param != 0;
}
void DamageTaken(Unit* attacker, uint32 &damage) override
diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_flame_leviathan.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_flame_leviathan.cpp
index 16dac4b2d4d..17f7c5681d2 100644
--- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_flame_leviathan.cpp
+++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_flame_leviathan.cpp
@@ -1368,7 +1368,7 @@ class achievement_unbroken : public AchievementCriteriaScript
{
if (target)
if (InstanceScript* instance = target->GetInstanceScript())
- return instance->GetData(DATA_UNBROKEN);
+ return instance->GetData(DATA_UNBROKEN) != 0;
return false;
}
diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_ignis.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_ignis.cpp
index 6be3586de28..28a87b37f5b 100644
--- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_ignis.cpp
+++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_ignis.cpp
@@ -477,7 +477,7 @@ class achievement_ignis_shattered : public AchievementCriteriaScript
bool OnCheck(Player* /*source*/, Unit* target) override
{
if (target && target->IsAIEnabled)
- return target->GetAI()->GetData(DATA_SHATTERED);
+ return target->GetAI()->GetData(DATA_SHATTERED) != 0;
return false;
}
diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_razorscale.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_razorscale.cpp
index e0d46ad21ba..ed909d459ca 100644
--- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_razorscale.cpp
+++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_razorscale.cpp
@@ -918,7 +918,7 @@ class npc_darkrune_guardian : public CreatureScript
void SetData(uint32 type, uint32 value) override
{
if (type == DATA_IRON_DWARF_MEDIUM_RARE)
- killedByBreath = value;
+ killedByBreath = value != 0;
}
diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_xt002.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_xt002.cpp
index 87192f39a5c..8520e317ba3 100644
--- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_xt002.cpp
+++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_xt002.cpp
@@ -1066,7 +1066,7 @@ class achievement_heartbreaker : public AchievementCriteriaScript
if (!target || !target->GetAI())
return false;
- return target->GetAI()->GetData(DATA_HARD_MODE);
+ return target->GetAI()->GetData(DATA_HARD_MODE) != 0;
}
};
diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_yogg_saron.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_yogg_saron.cpp
index 9ce5733ab0b..4abf46be448 100644
--- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_yogg_saron.cpp
+++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_yogg_saron.cpp
@@ -1137,7 +1137,7 @@ class npc_ominous_cloud : public CreatureScript
void DoAction(int32 action) override
{
Movement::MoveSplineInit init(me);
- FillCirclePath(YoggSaronSpawnPos, me->GetDistance2d(YoggSaronSpawnPos.GetPositionX(), YoggSaronSpawnPos.GetPositionY()), me->GetPositionZ(), init.Path(), action);
+ FillCirclePath(YoggSaronSpawnPos, me->GetDistance2d(YoggSaronSpawnPos.GetPositionX(), YoggSaronSpawnPos.GetPositionY()), me->GetPositionZ(), init.Path(), action != 0);
init.SetWalk(true);
init.SetCyclic();
init.Launch();
diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/instance_ulduar.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/instance_ulduar.cpp
index 6437a76ee95..6aa753eac98 100644
--- a/src/server/scripts/Northrend/Ulduar/Ulduar/instance_ulduar.cpp
+++ b/src/server/scripts/Northrend/Ulduar/Ulduar/instance_ulduar.cpp
@@ -773,7 +773,7 @@ class instance_ulduar : public InstanceMapScript
}
break;
case DATA_UNBROKEN:
- Unbroken = bool(data);
+ Unbroken = data != 0;
break;
case DATA_ILLUSION:
illusion = data;
diff --git a/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/boss_ingvar_the_plunderer.cpp b/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/boss_ingvar_the_plunderer.cpp
index 67bf6214374..7a1566df71d 100644
--- a/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/boss_ingvar_the_plunderer.cpp
+++ b/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/boss_ingvar_the_plunderer.cpp
@@ -433,7 +433,7 @@ class spell_ingvar_woe_strike : public SpellScriptLoader
bool CheckProc(ProcEventInfo& eventInfo)
{
- return eventInfo.GetHealInfo()->GetHeal();
+ return eventInfo.GetHealInfo()->GetHeal() != 0;
}
void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo)
diff --git a/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/boss_keleseth.cpp b/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/boss_keleseth.cpp
index a840f29072f..f8e0f3fe38c 100644
--- a/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/boss_keleseth.cpp
+++ b/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/boss_keleseth.cpp
@@ -157,7 +157,7 @@ class boss_keleseth : public CreatureScript
void SetData(uint32 data, uint32 value) override
{
if (data == DATA_ON_THE_ROCKS)
- onTheRocks = value;
+ onTheRocks = value != 0;
}
uint32 GetData(uint32 data) const override
diff --git a/src/server/scripts/Northrend/zone_storm_peaks.cpp b/src/server/scripts/Northrend/zone_storm_peaks.cpp
index a7faf776721..cfee2e0f187 100644
--- a/src/server/scripts/Northrend/zone_storm_peaks.cpp
+++ b/src/server/scripts/Northrend/zone_storm_peaks.cpp
@@ -814,7 +814,7 @@ class spell_close_rift : public SpellScriptLoader
bool Validate(SpellInfo const* /*spell*/) override
{
- return sSpellMgr->GetSpellInfo(SPELL_DESPAWN_RIFT);
+ return sSpellMgr->GetSpellInfo(SPELL_DESPAWN_RIFT) != nullptr;
}
void HandlePeriodic(AuraEffect const* /* aurEff */)
diff --git a/src/server/scripts/OutdoorPvP/OutdoorPvPNA.cpp b/src/server/scripts/OutdoorPvP/OutdoorPvPNA.cpp
index 08253022ec4..9008b0867d7 100644
--- a/src/server/scripts/OutdoorPvP/OutdoorPvPNA.cpp
+++ b/src/server/scripts/OutdoorPvP/OutdoorPvPNA.cpp
@@ -265,31 +265,31 @@ void OPvPCapturePointNA::FillInitialWorldStates(WorldPacket &data)
data << NA_UI_TOWER_SLIDER_POS << uint32(50);
data << NA_UI_TOWER_SLIDER_N << uint32(100);
- data << NA_MAP_WYVERN_NORTH_NEU_H << uint32(bool(m_WyvernStateNorth & WYVERN_NEU_HORDE));
- data << NA_MAP_WYVERN_NORTH_NEU_A << uint32(bool(m_WyvernStateNorth & WYVERN_NEU_ALLIANCE));
- data << NA_MAP_WYVERN_NORTH_H << uint32(bool(m_WyvernStateNorth & WYVERN_HORDE));
- data << NA_MAP_WYVERN_NORTH_A << uint32(bool(m_WyvernStateNorth & WYVERN_ALLIANCE));
-
- data << NA_MAP_WYVERN_SOUTH_NEU_H << uint32(bool(m_WyvernStateSouth & WYVERN_NEU_HORDE));
- data << NA_MAP_WYVERN_SOUTH_NEU_A << uint32(bool(m_WyvernStateSouth & WYVERN_NEU_ALLIANCE));
- data << NA_MAP_WYVERN_SOUTH_H << uint32(bool(m_WyvernStateSouth & WYVERN_HORDE));
- data << NA_MAP_WYVERN_SOUTH_A << uint32(bool(m_WyvernStateSouth & WYVERN_ALLIANCE));
-
- data << NA_MAP_WYVERN_WEST_NEU_H << uint32(bool(m_WyvernStateWest & WYVERN_NEU_HORDE));
- data << NA_MAP_WYVERN_WEST_NEU_A << uint32(bool(m_WyvernStateWest & WYVERN_NEU_ALLIANCE));
- data << NA_MAP_WYVERN_WEST_H << uint32(bool(m_WyvernStateWest & WYVERN_HORDE));
- data << NA_MAP_WYVERN_WEST_A << uint32(bool(m_WyvernStateWest & WYVERN_ALLIANCE));
-
- data << NA_MAP_WYVERN_EAST_NEU_H << uint32(bool(m_WyvernStateEast & WYVERN_NEU_HORDE));
- data << NA_MAP_WYVERN_EAST_NEU_A << uint32(bool(m_WyvernStateEast & WYVERN_NEU_ALLIANCE));
- data << NA_MAP_WYVERN_EAST_H << uint32(bool(m_WyvernStateEast & WYVERN_HORDE));
- data << NA_MAP_WYVERN_EAST_A << uint32(bool(m_WyvernStateEast & WYVERN_ALLIANCE));
-
- data << NA_MAP_HALAA_NEUTRAL << uint32(bool(m_HalaaState & HALAA_N));
- data << NA_MAP_HALAA_NEU_A << uint32(bool(m_HalaaState & HALAA_N_A));
- data << NA_MAP_HALAA_NEU_H << uint32(bool(m_HalaaState & HALAA_N_H));
- data << NA_MAP_HALAA_HORDE << uint32(bool(m_HalaaState & HALAA_H));
- data << NA_MAP_HALAA_ALLIANCE << uint32(bool(m_HalaaState & HALAA_A));
+ data << NA_MAP_WYVERN_NORTH_NEU_H << uint32((m_WyvernStateNorth & WYVERN_NEU_HORDE) != 0);
+ data << NA_MAP_WYVERN_NORTH_NEU_A << uint32((m_WyvernStateNorth & WYVERN_NEU_ALLIANCE) != 0);
+ data << NA_MAP_WYVERN_NORTH_H << uint32((m_WyvernStateNorth & WYVERN_HORDE) != 0);
+ data << NA_MAP_WYVERN_NORTH_A << uint32((m_WyvernStateNorth & WYVERN_ALLIANCE) != 0);
+
+ data << NA_MAP_WYVERN_SOUTH_NEU_H << uint32((m_WyvernStateSouth & WYVERN_NEU_HORDE) != 0);
+ data << NA_MAP_WYVERN_SOUTH_NEU_A << uint32((m_WyvernStateSouth & WYVERN_NEU_ALLIANCE) != 0);
+ data << NA_MAP_WYVERN_SOUTH_H << uint32((m_WyvernStateSouth & WYVERN_HORDE) != 0);
+ data << NA_MAP_WYVERN_SOUTH_A << uint32((m_WyvernStateSouth & WYVERN_ALLIANCE) != 0);
+
+ data << NA_MAP_WYVERN_WEST_NEU_H << uint32((m_WyvernStateWest & WYVERN_NEU_HORDE) != 0);
+ data << NA_MAP_WYVERN_WEST_NEU_A << uint32((m_WyvernStateWest & WYVERN_NEU_ALLIANCE) != 0);
+ data << NA_MAP_WYVERN_WEST_H << uint32((m_WyvernStateWest & WYVERN_HORDE) != 0);
+ data << NA_MAP_WYVERN_WEST_A << uint32((m_WyvernStateWest & WYVERN_ALLIANCE) != 0);
+
+ data << NA_MAP_WYVERN_EAST_NEU_H << uint32((m_WyvernStateEast & WYVERN_NEU_HORDE) != 0);
+ data << NA_MAP_WYVERN_EAST_NEU_A << uint32((m_WyvernStateEast & WYVERN_NEU_ALLIANCE) != 0);
+ data << NA_MAP_WYVERN_EAST_H << uint32((m_WyvernStateEast & WYVERN_HORDE) != 0);
+ data << NA_MAP_WYVERN_EAST_A << uint32((m_WyvernStateEast & WYVERN_ALLIANCE) != 0);
+
+ data << NA_MAP_HALAA_NEUTRAL << uint32((m_HalaaState & HALAA_N) != 0);
+ data << NA_MAP_HALAA_NEU_A << uint32((m_HalaaState & HALAA_N_A) != 0);
+ data << NA_MAP_HALAA_NEU_H << uint32((m_HalaaState & HALAA_N_H) != 0);
+ data << NA_MAP_HALAA_HORDE << uint32((m_HalaaState & HALAA_H) != 0);
+ data << NA_MAP_HALAA_ALLIANCE << uint32((m_HalaaState & HALAA_A) != 0);
}
void OutdoorPvPNA::SendRemoveWorldStates(Player* player)
@@ -620,41 +620,41 @@ void OPvPCapturePointNA::SendChangePhase()
void OPvPCapturePointNA::UpdateHalaaWorldState()
{
- m_PvP->SendUpdateWorldState(NA_MAP_HALAA_NEUTRAL, uint32(bool(m_HalaaState & HALAA_N)));
- m_PvP->SendUpdateWorldState(NA_MAP_HALAA_NEU_A, uint32(bool(m_HalaaState & HALAA_N_A)));
- m_PvP->SendUpdateWorldState(NA_MAP_HALAA_NEU_H, uint32(bool(m_HalaaState & HALAA_N_H)));
- m_PvP->SendUpdateWorldState(NA_MAP_HALAA_HORDE, uint32(bool(m_HalaaState & HALAA_H)));
- m_PvP->SendUpdateWorldState(NA_MAP_HALAA_ALLIANCE, uint32(bool(m_HalaaState & HALAA_A)));
+ m_PvP->SendUpdateWorldState(NA_MAP_HALAA_NEUTRAL, uint32((m_HalaaState & HALAA_N) != 0));
+ m_PvP->SendUpdateWorldState(NA_MAP_HALAA_NEU_A, uint32((m_HalaaState & HALAA_N_A) != 0));
+ m_PvP->SendUpdateWorldState(NA_MAP_HALAA_NEU_H, uint32((m_HalaaState & HALAA_N_H) != 0));
+ m_PvP->SendUpdateWorldState(NA_MAP_HALAA_HORDE, uint32((m_HalaaState & HALAA_H) != 0));
+ m_PvP->SendUpdateWorldState(NA_MAP_HALAA_ALLIANCE, uint32((m_HalaaState & HALAA_A) != 0));
}
void OPvPCapturePointNA::UpdateWyvernRoostWorldState(uint32 roost)
{
switch (roost)
{
- case NA_ROOST_S:
- m_PvP->SendUpdateWorldState(NA_MAP_WYVERN_SOUTH_NEU_H, uint32(bool(m_WyvernStateSouth & WYVERN_NEU_HORDE)));
- m_PvP->SendUpdateWorldState(NA_MAP_WYVERN_SOUTH_NEU_A, uint32(bool(m_WyvernStateSouth & WYVERN_NEU_ALLIANCE)));
- m_PvP->SendUpdateWorldState(NA_MAP_WYVERN_SOUTH_H, uint32(bool(m_WyvernStateSouth & WYVERN_HORDE)));
- m_PvP->SendUpdateWorldState(NA_MAP_WYVERN_SOUTH_A, uint32(bool(m_WyvernStateSouth & WYVERN_ALLIANCE)));
- break;
- case NA_ROOST_N:
- m_PvP->SendUpdateWorldState(NA_MAP_WYVERN_NORTH_NEU_H, uint32(bool(m_WyvernStateNorth & WYVERN_NEU_HORDE)));
- m_PvP->SendUpdateWorldState(NA_MAP_WYVERN_NORTH_NEU_A, uint32(bool(m_WyvernStateNorth & WYVERN_NEU_ALLIANCE)));
- m_PvP->SendUpdateWorldState(NA_MAP_WYVERN_NORTH_H, uint32(bool(m_WyvernStateNorth & WYVERN_HORDE)));
- m_PvP->SendUpdateWorldState(NA_MAP_WYVERN_NORTH_A, uint32(bool(m_WyvernStateNorth & WYVERN_ALLIANCE)));
- break;
- case NA_ROOST_W:
- m_PvP->SendUpdateWorldState(NA_MAP_WYVERN_WEST_NEU_H, uint32(bool(m_WyvernStateWest & WYVERN_NEU_HORDE)));
- m_PvP->SendUpdateWorldState(NA_MAP_WYVERN_WEST_NEU_A, uint32(bool(m_WyvernStateWest & WYVERN_NEU_ALLIANCE)));
- m_PvP->SendUpdateWorldState(NA_MAP_WYVERN_WEST_H, uint32(bool(m_WyvernStateWest & WYVERN_HORDE)));
- m_PvP->SendUpdateWorldState(NA_MAP_WYVERN_WEST_A, uint32(bool(m_WyvernStateWest & WYVERN_ALLIANCE)));
- break;
- case NA_ROOST_E:
- m_PvP->SendUpdateWorldState(NA_MAP_WYVERN_EAST_NEU_H, uint32(bool(m_WyvernStateEast & WYVERN_NEU_HORDE)));
- m_PvP->SendUpdateWorldState(NA_MAP_WYVERN_EAST_NEU_A, uint32(bool(m_WyvernStateEast & WYVERN_NEU_ALLIANCE)));
- m_PvP->SendUpdateWorldState(NA_MAP_WYVERN_EAST_H, uint32(bool(m_WyvernStateEast & WYVERN_HORDE)));
- m_PvP->SendUpdateWorldState(NA_MAP_WYVERN_EAST_A, uint32(bool(m_WyvernStateEast & WYVERN_ALLIANCE)));
- break;
+ case NA_ROOST_S:
+ m_PvP->SendUpdateWorldState(NA_MAP_WYVERN_SOUTH_NEU_H, uint32((m_WyvernStateSouth & WYVERN_NEU_HORDE) != 0));
+ m_PvP->SendUpdateWorldState(NA_MAP_WYVERN_SOUTH_NEU_A, uint32((m_WyvernStateSouth & WYVERN_NEU_ALLIANCE) != 0));
+ m_PvP->SendUpdateWorldState(NA_MAP_WYVERN_SOUTH_H, uint32((m_WyvernStateSouth & WYVERN_HORDE) != 0));
+ m_PvP->SendUpdateWorldState(NA_MAP_WYVERN_SOUTH_A, uint32((m_WyvernStateSouth & WYVERN_ALLIANCE) != 0));
+ break;
+ case NA_ROOST_N:
+ m_PvP->SendUpdateWorldState(NA_MAP_WYVERN_NORTH_NEU_H, uint32((m_WyvernStateNorth & WYVERN_NEU_HORDE) != 0));
+ m_PvP->SendUpdateWorldState(NA_MAP_WYVERN_NORTH_NEU_A, uint32((m_WyvernStateNorth & WYVERN_NEU_ALLIANCE) != 0));
+ m_PvP->SendUpdateWorldState(NA_MAP_WYVERN_NORTH_H, uint32((m_WyvernStateNorth & WYVERN_HORDE) != 0));
+ m_PvP->SendUpdateWorldState(NA_MAP_WYVERN_NORTH_A, uint32((m_WyvernStateNorth & WYVERN_ALLIANCE) != 0));
+ break;
+ case NA_ROOST_W:
+ m_PvP->SendUpdateWorldState(NA_MAP_WYVERN_WEST_NEU_H, uint32((m_WyvernStateWest & WYVERN_NEU_HORDE) != 0));
+ m_PvP->SendUpdateWorldState(NA_MAP_WYVERN_WEST_NEU_A, uint32((m_WyvernStateWest & WYVERN_NEU_ALLIANCE) != 0));
+ m_PvP->SendUpdateWorldState(NA_MAP_WYVERN_WEST_H, uint32((m_WyvernStateWest & WYVERN_HORDE) != 0));
+ m_PvP->SendUpdateWorldState(NA_MAP_WYVERN_WEST_A, uint32((m_WyvernStateWest & WYVERN_ALLIANCE) != 0));
+ break;
+ case NA_ROOST_E:
+ m_PvP->SendUpdateWorldState(NA_MAP_WYVERN_EAST_NEU_H, uint32((m_WyvernStateEast & WYVERN_NEU_HORDE) != 0));
+ m_PvP->SendUpdateWorldState(NA_MAP_WYVERN_EAST_NEU_A, uint32((m_WyvernStateEast & WYVERN_NEU_ALLIANCE) != 0));
+ m_PvP->SendUpdateWorldState(NA_MAP_WYVERN_EAST_H, uint32((m_WyvernStateEast & WYVERN_HORDE) != 0));
+ m_PvP->SendUpdateWorldState(NA_MAP_WYVERN_EAST_A, uint32((m_WyvernStateEast & WYVERN_ALLIANCE) != 0));
+ break;
}
}
diff --git a/src/server/scripts/OutdoorPvP/OutdoorPvPTF.cpp b/src/server/scripts/OutdoorPvP/OutdoorPvPTF.cpp
index f9590634008..c8c707a1958 100644
--- a/src/server/scripts/OutdoorPvP/OutdoorPvPTF.cpp
+++ b/src/server/scripts/OutdoorPvP/OutdoorPvPTF.cpp
@@ -49,9 +49,9 @@ OPvPCapturePointTF::OPvPCapturePointTF(OutdoorPvP* pvp, OutdoorPvPTF_TowerType t
void OPvPCapturePointTF::FillInitialWorldStates(WorldPacket &data)
{
- data << uint32(TFTowerWorldStates[m_TowerType].n) << uint32(bool(m_TowerState & TF_TOWERSTATE_N));
- data << uint32(TFTowerWorldStates[m_TowerType].h) << uint32(bool(m_TowerState & TF_TOWERSTATE_H));
- data << uint32(TFTowerWorldStates[m_TowerType].a) << uint32(bool(m_TowerState & TF_TOWERSTATE_A));
+ data << uint32(TFTowerWorldStates[m_TowerType].n) << uint32((m_TowerState & TF_TOWERSTATE_N) != 0);
+ data << uint32(TFTowerWorldStates[m_TowerType].h) << uint32((m_TowerState & TF_TOWERSTATE_H) != 0);
+ data << uint32(TFTowerWorldStates[m_TowerType].a) << uint32((m_TowerState & TF_TOWERSTATE_A) != 0);
}
void OutdoorPvPTF::FillInitialWorldStates(WorldPacket &data)
@@ -106,9 +106,9 @@ void OutdoorPvPTF::SendRemoveWorldStates(Player* player)
void OPvPCapturePointTF::UpdateTowerState()
{
- m_PvP->SendUpdateWorldState(uint32(TFTowerWorldStates[m_TowerType].n), uint32(bool(m_TowerState & TF_TOWERSTATE_N)));
- m_PvP->SendUpdateWorldState(uint32(TFTowerWorldStates[m_TowerType].h), uint32(bool(m_TowerState & TF_TOWERSTATE_H)));
- m_PvP->SendUpdateWorldState(uint32(TFTowerWorldStates[m_TowerType].a), uint32(bool(m_TowerState & TF_TOWERSTATE_A)));
+ m_PvP->SendUpdateWorldState(uint32(TFTowerWorldStates[m_TowerType].n), uint32((m_TowerState & TF_TOWERSTATE_N) != 0));
+ m_PvP->SendUpdateWorldState(uint32(TFTowerWorldStates[m_TowerType].h), uint32((m_TowerState & TF_TOWERSTATE_H) != 0));
+ m_PvP->SendUpdateWorldState(uint32(TFTowerWorldStates[m_TowerType].a), uint32((m_TowerState & TF_TOWERSTATE_A) != 0));
}
bool OPvPCapturePointTF::HandlePlayerEnter(Player* player)
diff --git a/src/server/scripts/OutdoorPvP/OutdoorPvPZM.cpp b/src/server/scripts/OutdoorPvP/OutdoorPvPZM.cpp
index c4b811859ef..d54a4f7d4d7 100644
--- a/src/server/scripts/OutdoorPvP/OutdoorPvPZM.cpp
+++ b/src/server/scripts/OutdoorPvP/OutdoorPvPZM.cpp
@@ -34,22 +34,22 @@ OPvPCapturePointZM_Beacon::OPvPCapturePointZM_Beacon(OutdoorPvP* pvp, ZM_BeaconT
void OPvPCapturePointZM_Beacon::FillInitialWorldStates(WorldPacket &data)
{
- data << uint32(ZMBeaconInfo[m_TowerType].ui_tower_n) << uint32(bool(m_TowerState & ZM_TOWERSTATE_N));
- data << uint32(ZMBeaconInfo[m_TowerType].map_tower_n) << uint32(bool(m_TowerState & ZM_TOWERSTATE_N));
- data << uint32(ZMBeaconInfo[m_TowerType].ui_tower_a) << uint32(bool(m_TowerState & ZM_TOWERSTATE_A));
- data << uint32(ZMBeaconInfo[m_TowerType].map_tower_a) << uint32(bool(m_TowerState & ZM_TOWERSTATE_A));
- data << uint32(ZMBeaconInfo[m_TowerType].ui_tower_h) << uint32(bool(m_TowerState & ZM_TOWERSTATE_H));
- data << uint32(ZMBeaconInfo[m_TowerType].map_tower_h) << uint32(bool(m_TowerState & ZM_TOWERSTATE_H));
+ data << uint32(ZMBeaconInfo[m_TowerType].ui_tower_n) << uint32((m_TowerState & ZM_TOWERSTATE_N) != 0);
+ data << uint32(ZMBeaconInfo[m_TowerType].map_tower_n) << uint32((m_TowerState & ZM_TOWERSTATE_N) != 0);
+ data << uint32(ZMBeaconInfo[m_TowerType].ui_tower_a) << uint32((m_TowerState & ZM_TOWERSTATE_A) != 0);
+ data << uint32(ZMBeaconInfo[m_TowerType].map_tower_a) << uint32((m_TowerState & ZM_TOWERSTATE_A) != 0);
+ data << uint32(ZMBeaconInfo[m_TowerType].ui_tower_h) << uint32((m_TowerState & ZM_TOWERSTATE_H) != 0);
+ data << uint32(ZMBeaconInfo[m_TowerType].map_tower_h) << uint32((m_TowerState & ZM_TOWERSTATE_H) != 0);
}
void OPvPCapturePointZM_Beacon::UpdateTowerState()
{
- m_PvP->SendUpdateWorldState(uint32(ZMBeaconInfo[m_TowerType].ui_tower_n), uint32(bool(m_TowerState & ZM_TOWERSTATE_N)));
- m_PvP->SendUpdateWorldState(uint32(ZMBeaconInfo[m_TowerType].map_tower_n), uint32(bool(m_TowerState & ZM_TOWERSTATE_N)));
- m_PvP->SendUpdateWorldState(uint32(ZMBeaconInfo[m_TowerType].ui_tower_a), uint32(bool(m_TowerState & ZM_TOWERSTATE_A)));
- m_PvP->SendUpdateWorldState(uint32(ZMBeaconInfo[m_TowerType].map_tower_a), uint32(bool(m_TowerState & ZM_TOWERSTATE_A)));
- m_PvP->SendUpdateWorldState(uint32(ZMBeaconInfo[m_TowerType].ui_tower_h), uint32(bool(m_TowerState & ZM_TOWERSTATE_H)));
- m_PvP->SendUpdateWorldState(uint32(ZMBeaconInfo[m_TowerType].map_tower_h), uint32(bool(m_TowerState & ZM_TOWERSTATE_H)));
+ m_PvP->SendUpdateWorldState(uint32(ZMBeaconInfo[m_TowerType].ui_tower_n), uint32((m_TowerState & ZM_TOWERSTATE_N) != 0));
+ m_PvP->SendUpdateWorldState(uint32(ZMBeaconInfo[m_TowerType].map_tower_n), uint32((m_TowerState & ZM_TOWERSTATE_N) != 0));
+ m_PvP->SendUpdateWorldState(uint32(ZMBeaconInfo[m_TowerType].ui_tower_a), uint32((m_TowerState & ZM_TOWERSTATE_A) != 0));
+ m_PvP->SendUpdateWorldState(uint32(ZMBeaconInfo[m_TowerType].map_tower_a), uint32((m_TowerState & ZM_TOWERSTATE_A) != 0));
+ m_PvP->SendUpdateWorldState(uint32(ZMBeaconInfo[m_TowerType].ui_tower_h), uint32((m_TowerState & ZM_TOWERSTATE_H) != 0));
+ m_PvP->SendUpdateWorldState(uint32(ZMBeaconInfo[m_TowerType].map_tower_h), uint32((m_TowerState & ZM_TOWERSTATE_H) != 0));
}
bool OPvPCapturePointZM_Beacon::HandlePlayerEnter(Player* player)
@@ -264,9 +264,9 @@ OPvPCapturePointZM_GraveYard::OPvPCapturePointZM_GraveYard(OutdoorPvP* pvp)
void OPvPCapturePointZM_GraveYard::UpdateTowerState()
{
- m_PvP->SendUpdateWorldState(ZM_MAP_GRAVEYARD_N, uint32(bool(m_GraveYardState & ZM_GRAVEYARD_N)));
- m_PvP->SendUpdateWorldState(ZM_MAP_GRAVEYARD_H, uint32(bool(m_GraveYardState & ZM_GRAVEYARD_H)));
- m_PvP->SendUpdateWorldState(ZM_MAP_GRAVEYARD_A, uint32(bool(m_GraveYardState & ZM_GRAVEYARD_A)));
+ m_PvP->SendUpdateWorldState(ZM_MAP_GRAVEYARD_N, uint32((m_GraveYardState & ZM_GRAVEYARD_N) != 0));
+ m_PvP->SendUpdateWorldState(ZM_MAP_GRAVEYARD_H, uint32((m_GraveYardState & ZM_GRAVEYARD_H) != 0));
+ m_PvP->SendUpdateWorldState(ZM_MAP_GRAVEYARD_A, uint32((m_GraveYardState & ZM_GRAVEYARD_A) != 0));
m_PvP->SendUpdateWorldState(ZM_MAP_ALLIANCE_FLAG_READY, uint32(m_BothControllingFaction == ALLIANCE));
m_PvP->SendUpdateWorldState(ZM_MAP_ALLIANCE_FLAG_NOT_READY, uint32(m_BothControllingFaction != ALLIANCE));
@@ -276,9 +276,9 @@ void OPvPCapturePointZM_GraveYard::UpdateTowerState()
void OPvPCapturePointZM_GraveYard::FillInitialWorldStates(WorldPacket &data)
{
- data << ZM_MAP_GRAVEYARD_N << uint32(bool(m_GraveYardState & ZM_GRAVEYARD_N));
- data << ZM_MAP_GRAVEYARD_H << uint32(bool(m_GraveYardState & ZM_GRAVEYARD_H));
- data << ZM_MAP_GRAVEYARD_A << uint32(bool(m_GraveYardState & ZM_GRAVEYARD_A));
+ data << ZM_MAP_GRAVEYARD_N << uint32((m_GraveYardState & ZM_GRAVEYARD_N) != 0);
+ data << ZM_MAP_GRAVEYARD_H << uint32((m_GraveYardState & ZM_GRAVEYARD_H) != 0);
+ data << ZM_MAP_GRAVEYARD_A << uint32((m_GraveYardState & ZM_GRAVEYARD_A) != 0);
data << ZM_MAP_ALLIANCE_FLAG_READY << uint32(m_BothControllingFaction == ALLIANCE);
data << ZM_MAP_ALLIANCE_FLAG_NOT_READY << uint32(m_BothControllingFaction != ALLIANCE);
diff --git a/src/server/scripts/Outland/BlackTemple/illidari_council.cpp b/src/server/scripts/Outland/BlackTemple/illidari_council.cpp
index 8fd9a421a49..49762275169 100644
--- a/src/server/scripts/Outland/BlackTemple/illidari_council.cpp
+++ b/src/server/scripts/Outland/BlackTemple/illidari_council.cpp
@@ -880,7 +880,7 @@ public:
bool Validate(SpellInfo const* /*spellInfo*/) override
{
- return sSpellMgr->GetSpellInfo(SPELL_REFLECTIVE_SHIELD_T);
+ return sSpellMgr->GetSpellInfo(SPELL_REFLECTIVE_SHIELD_T) != nullptr;
}
void Trigger(AuraEffect* aurEff, DamageInfo & dmgInfo, uint32 & absorbAmount)
diff --git a/src/server/scripts/Outland/zone_blades_edge_mountains.cpp b/src/server/scripts/Outland/zone_blades_edge_mountains.cpp
index d21b92d3e92..ebcddafe309 100644
--- a/src/server/scripts/Outland/zone_blades_edge_mountains.cpp
+++ b/src/server/scripts/Outland/zone_blades_edge_mountains.cpp
@@ -731,7 +731,7 @@ class npc_simon_bunny : public CreatureScript
{
me->SetCanFly(true);
- large = (bool)id;
+ large = id != 0;
playerGUID = guid;
StartGame();
}
diff --git a/src/server/scripts/Spells/spell_dk.cpp b/src/server/scripts/Spells/spell_dk.cpp
index a98734e8308..299be87833e 100644
--- a/src/server/scripts/Spells/spell_dk.cpp
+++ b/src/server/scripts/Spells/spell_dk.cpp
@@ -289,7 +289,7 @@ class spell_dk_blood_gorged : public SpellScriptLoader
bool CheckProc(ProcEventInfo& /*eventInfo*/)
{
_procTarget = GetTarget()->GetOwner();
- return _procTarget;
+ return _procTarget != nullptr;
}
void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo)
diff --git a/src/server/scripts/Spells/spell_generic.cpp b/src/server/scripts/Spells/spell_generic.cpp
index 30e794579e8..267a2f3cbf7 100644
--- a/src/server/scripts/Spells/spell_generic.cpp
+++ b/src/server/scripts/Spells/spell_generic.cpp
@@ -2861,7 +2861,7 @@ class spell_gen_replenishment : public SpellScriptLoader
bool Load() override
{
- return GetUnitOwner()->GetPower(POWER_MANA);
+ return GetUnitOwner()->getPowerType() == POWER_MANA;
}
void CalculateAmount(AuraEffect const* /*aurEff*/, int32& amount, bool& /*canBeRecalculated*/)
diff --git a/src/server/scripts/Spells/spell_hunter.cpp b/src/server/scripts/Spells/spell_hunter.cpp
index eb03b47e6fe..892853b600f 100644
--- a/src/server/scripts/Spells/spell_hunter.cpp
+++ b/src/server/scripts/Spells/spell_hunter.cpp
@@ -494,7 +494,7 @@ class spell_hun_misdirection : public SpellScriptLoader
bool CheckProc(ProcEventInfo& /*eventInfo*/)
{
- return GetTarget()->GetRedirectThreatTarget();
+ return GetTarget()->GetRedirectThreatTarget() != nullptr;
}
void HandleProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/)
diff --git a/src/server/scripts/Spells/spell_item.cpp b/src/server/scripts/Spells/spell_item.cpp
index f2d206e50e6..003aa6b1bc1 100644
--- a/src/server/scripts/Spells/spell_item.cpp
+++ b/src/server/scripts/Spells/spell_item.cpp
@@ -166,7 +166,7 @@ class spell_item_blessing_of_ancient_kings : public SpellScriptLoader
bool CheckProc(ProcEventInfo& eventInfo)
{
- return eventInfo.GetProcTarget();
+ return eventInfo.GetProcTarget() != nullptr;
}
void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo)
diff --git a/src/server/scripts/Spells/spell_mage.cpp b/src/server/scripts/Spells/spell_mage.cpp
index d69978875f8..a7a13b48d39 100644
--- a/src/server/scripts/Spells/spell_mage.cpp
+++ b/src/server/scripts/Spells/spell_mage.cpp
@@ -943,7 +943,7 @@ class spell_mage_master_of_elements : public SpellScriptLoader
bool CheckProc(ProcEventInfo& eventInfo)
{
- return eventInfo.GetDamageInfo()->GetSpellInfo(); // eventInfo.GetSpellInfo()
+ return eventInfo.GetDamageInfo()->GetSpellInfo() != nullptr;
}
void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo)
diff --git a/src/server/scripts/Spells/spell_paladin.cpp b/src/server/scripts/Spells/spell_paladin.cpp
index 2efcbd5d35e..bf77619b2d0 100644
--- a/src/server/scripts/Spells/spell_paladin.cpp
+++ b/src/server/scripts/Spells/spell_paladin.cpp
@@ -1165,7 +1165,7 @@ class spell_pal_seal_of_righteousness : public SpellScriptLoader
bool CheckProc(ProcEventInfo& eventInfo)
{
- return eventInfo.GetProcTarget();
+ return eventInfo.GetProcTarget() != nullptr;
}
void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo)
diff --git a/src/server/scripts/Spells/spell_priest.cpp b/src/server/scripts/Spells/spell_priest.cpp
index ae9edfc3929..9b9b774fdcc 100644
--- a/src/server/scripts/Spells/spell_priest.cpp
+++ b/src/server/scripts/Spells/spell_priest.cpp
@@ -281,7 +281,7 @@ class spell_pri_divine_aegis : public SpellScriptLoader
bool CheckProc(ProcEventInfo& eventInfo)
{
- return eventInfo.GetProcTarget();
+ return eventInfo.GetProcTarget() != nullptr;
}
void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo)
@@ -673,7 +673,7 @@ class spell_pri_mana_leech : public SpellScriptLoader
bool CheckProc(ProcEventInfo& /*eventInfo*/)
{
_procTarget = GetTarget()->GetOwner();
- return _procTarget;
+ return _procTarget != nullptr;
}
void HandleProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/)
diff --git a/src/server/scripts/Spells/spell_quest.cpp b/src/server/scripts/Spells/spell_quest.cpp
index f895381574e..316ce973319 100644
--- a/src/server/scripts/Spells/spell_quest.cpp
+++ b/src/server/scripts/Spells/spell_quest.cpp
@@ -1810,12 +1810,11 @@ class spell_q13011_bear_flank_master : public SpellScriptLoader
void HandleScript(SpellEffIndex /*effIndex*/)
{
- bool failed = RAND(0, 1); // 50% chance
- Creature* creature = GetCaster()->ToCreature();
if (Player* player = GetHitPlayer())
{
- if (failed)
+ if (roll_chance_i(50))
{
+ Creature* creature = GetCaster()->ToCreature();
player->CastSpell(creature, SPELL_BEAR_FLANK_FAIL);
creature->AI()->Talk(0, player);
}
diff --git a/src/server/scripts/Spells/spell_rogue.cpp b/src/server/scripts/Spells/spell_rogue.cpp
index 98fe019bcc6..d0c2e18c353 100644
--- a/src/server/scripts/Spells/spell_rogue.cpp
+++ b/src/server/scripts/Spells/spell_rogue.cpp
@@ -136,7 +136,7 @@ class spell_rog_cheat_death : public SpellScriptLoader
bool Load() override
{
absorbChance = GetSpellInfo()->Effects[EFFECT_0].CalcValue();
- return GetUnitOwner()->ToPlayer();
+ return GetUnitOwner()->GetTypeId() == TYPEID_PLAYER;
}
void CalculateAmount(AuraEffect const* /*aurEff*/, int32 & amount, bool & /*canBeRecalculated*/)
@@ -904,7 +904,7 @@ class spell_rog_tricks_of_the_trade : public SpellScriptLoader
bool CheckProc(ProcEventInfo& /*eventInfo*/)
{
_redirectTarget = GetTarget()->GetRedirectThreatTarget();
- return _redirectTarget;
+ return _redirectTarget != nullptr;
}
void HandleProc(AuraEffect const* /*aurEff*/, ProcEventInfo& /*eventInfo*/)
diff --git a/src/server/scripts/Spells/spell_warrior.cpp b/src/server/scripts/Spells/spell_warrior.cpp
index e8c95c8392e..8898456c0a6 100644
--- a/src/server/scripts/Spells/spell_warrior.cpp
+++ b/src/server/scripts/Spells/spell_warrior.cpp
@@ -855,7 +855,7 @@ class spell_warr_sweeping_strikes : public SpellScriptLoader
bool CheckProc(ProcEventInfo& eventInfo)
{
_procTarget = eventInfo.GetActor()->SelectNearbyTarget(eventInfo.GetProcTarget());
- return _procTarget;
+ return _procTarget != nullptr;
}
void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo)
diff --git a/src/server/shared/AutoPtr.h b/src/server/shared/AutoPtr.h
deleted file mode 100644
index 96ecbfc79fe..00000000000
--- a/src/server/shared/AutoPtr.h
+++ /dev/null
@@ -1,53 +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 _TRINITY_AUTO_PTR_H
-#define _TRINITY_AUTO_PTR_H
-
-#include <ace/Bound_Ptr.h>
-
-namespace Trinity
-{
-
-template <class Pointer, class Lock>
-class AutoPtr : public ACE_Strong_Bound_Ptr<Pointer, Lock>
-{
- typedef ACE_Strong_Bound_Ptr<Pointer, Lock> Base;
-
-public:
- AutoPtr()
- : Base()
- { }
-
- AutoPtr(Pointer* x)
- : Base(x)
- { }
-
- operator bool() const
- {
- return !Base::null();
- }
-
- bool operator !() const
- {
- return Base::null();
- }
-};
-
-} // namespace Trinity
-
-#endif
diff --git a/src/server/shared/CMakeLists.txt b/src/server/shared/CMakeLists.txt
index af113801067..a61248f01ea 100644
--- a/src/server/shared/CMakeLists.txt
+++ b/src/server/shared/CMakeLists.txt
@@ -18,6 +18,7 @@ file(GLOB_RECURSE sources_Database Database/*.cpp Database/*.h)
file(GLOB_RECURSE sources_DataStores DataStores/*.cpp DataStores/*.h)
file(GLOB_RECURSE sources_Dynamic Dynamic/*.cpp Dynamic/*.h)
file(GLOB_RECURSE sources_Logging Logging/*.cpp Logging/*.h)
+file(GLOB_RECURSE sources_Networking Networking/*.cpp Networking/*.h)
file(GLOB_RECURSE sources_Packets Packets/*.cpp Packets/*.h)
file(GLOB_RECURSE sources_Threading Threading/*.cpp Threading/*.h)
file(GLOB_RECURSE sources_Utilities Utilities/*.cpp Utilities/*.h)
@@ -47,6 +48,7 @@ set(shared_STAT_SRCS
${sources_Debugging}
${sources_Dynamic}
${sources_Logging}
+ ${sources_Networking}
${sources_Packets}
${sources_Threading}
${sources_Utilities}
@@ -68,11 +70,11 @@ include_directories(
${CMAKE_CURRENT_SOURCE_DIR}/Debugging
${CMAKE_CURRENT_SOURCE_DIR}/Dynamic
${CMAKE_CURRENT_SOURCE_DIR}/Logging
+ ${CMAKE_CURRENT_SOURCE_DIR}/Networking
${CMAKE_CURRENT_SOURCE_DIR}/Packets
${CMAKE_CURRENT_SOURCE_DIR}/Threading
${CMAKE_CURRENT_SOURCE_DIR}/Utilities
${CMAKE_SOURCE_DIR}/src/server/game/Entities/Object
- ${ACE_INCLUDE_DIR}
${MYSQL_INCLUDE_DIR}
${OPENSSL_INCLUDE_DIR}
)
@@ -82,10 +84,6 @@ add_library(shared STATIC
${shared_STAT_PCH_SRC}
)
-target_link_libraries(shared
- ${ACE_LIBRARY}
-)
-
# Generate precompiled header
if (USE_COREPCH)
add_cxx_pch(shared ${shared_STAT_PCH_HDR} ${shared_STAT_PCH_SRC})
diff --git a/src/server/shared/Common.h b/src/server/shared/Common.h
index 0485b6b7cc7..1e3b0e46221 100644
--- a/src/server/shared/Common.h
+++ b/src/server/shared/Common.h
@@ -79,22 +79,12 @@
#include <sstream>
#include <algorithm>
-#include "Threading/LockedQueue.h"
-#include "Threading/Threading.h"
+#include "Debugging/Errors.h"
-#include <ace/Basic_Types.h>
-#include <ace/Guard_T.h>
-#include <ace/RW_Thread_Mutex.h>
-#include <ace/Thread_Mutex.h>
-#include <ace/OS_NS_time.h>
+#include "Threading/LockedQueue.h"
#if PLATFORM == PLATFORM_WINDOWS
-# include <ace/config-all.h>
-// XP winver - needed to compile with standard leak check in MemoryLeaks.h
-// uncomment later if needed
-//#define _WIN32_WINNT 0x0501
# include <ws2tcpip.h>
-//#undef WIN32_WINNT
#else
# include <sys/types.h>
# include <sys/ioctl.h>
@@ -123,8 +113,6 @@
inline float finiteAlways(float f) { return finite(f) ? f : 0.0f; }
-#define atol(a) strtoul( a, NULL, 10)
-
#define STRINGIZE(a) #a
enum TimeConstants
@@ -204,20 +192,4 @@ struct LocalizedString
#define MAX_QUERY_LEN 32*1024
-#define TRINITY_GUARD(MUTEX, LOCK) \
- ACE_Guard< MUTEX > TRINITY_GUARD_OBJECT (LOCK); \
- if (TRINITY_GUARD_OBJECT.locked() == 0) ASSERT(false);
-
-//! For proper implementation of multiple-read, single-write pattern, use
-//! ACE_RW_Mutex as underlying @MUTEX
-# define TRINITY_WRITE_GUARD(MUTEX, LOCK) \
- ACE_Write_Guard< MUTEX > TRINITY_GUARD_OBJECT (LOCK); \
- if (TRINITY_GUARD_OBJECT.locked() == 0) ASSERT(false);
-
-//! For proper implementation of multiple-read, single-write pattern, use
-//! ACE_RW_Mutex as underlying @MUTEX
-# define TRINITY_READ_GUARD(MUTEX, LOCK) \
- ACE_Read_Guard< MUTEX > TRINITY_GUARD_OBJECT (LOCK); \
- if (TRINITY_GUARD_OBJECT.locked() == 0) ASSERT(false);
-
#endif
diff --git a/src/server/shared/Configuration/Config.cpp b/src/server/shared/Configuration/Config.cpp
index 3f8997e6d55..5cd7ef52f82 100644
--- a/src/server/shared/Configuration/Config.cpp
+++ b/src/server/shared/Configuration/Config.cpp
@@ -16,57 +16,38 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+#include <algorithm>
+#include <mutex>
+#include <boost/property_tree/ptree.hpp>
+#include <boost/property_tree/ini_parser.hpp>
#include "Config.h"
#include "Errors.h"
-// Defined here as it must not be exposed to end-users.
-bool ConfigMgr::GetValueHelper(const char* name, ACE_TString &result)
-{
- GuardType guard(_configLock);
-
- if (_config.get() == 0)
- return false;
-
- ACE_TString section_name;
- ACE_Configuration_Section_Key section_key;
- const ACE_Configuration_Section_Key &root_key = _config->root_section();
+using namespace boost::property_tree;
- int i = 0;
- while (_config->enumerate_sections(root_key, i, section_name) == 0)
- {
- _config->open_section(root_key, section_name.c_str(), 0, section_key);
- if (_config->get_string_value(section_key, name, result) == 0)
- return true;
- ++i;
- }
-
- return false;
-}
-
-bool ConfigMgr::LoadInitial(char const* file)
+bool ConfigMgr::LoadInitial(std::string const& file)
{
- ASSERT(file);
-
- GuardType guard(_configLock);
+ std::lock_guard<std::mutex> lock(_configLock);
_filename = file;
- _config.reset(new ACE_Configuration_Heap());
- if (_config->open() == 0)
- if (LoadData(_filename.c_str()))
- return true;
- _config.reset();
- return false;
-}
+ try
+ {
+ ptree fullTree;
+ boost::property_tree::ini_parser::read_ini(file, fullTree);
-bool ConfigMgr::LoadMore(char const* file)
-{
- ASSERT(file);
- ASSERT(_config);
+ if (fullTree.empty())
+ return false;
- GuardType guard(_configLock);
+ // Since we're using only one section per config file, we skip the section and have direct property access
+ _config = fullTree.begin()->second;
+ }
+ catch (std::exception const& /*ex*/)
+ {
+ return false;
+ }
- return LoadData(file);
+ return true;
}
bool ConfigMgr::Reload()
@@ -74,78 +55,54 @@ bool ConfigMgr::Reload()
return LoadInitial(_filename.c_str());
}
-bool ConfigMgr::LoadData(char const* file)
+std::string ConfigMgr::GetStringDefault(std::string const& name, const std::string& def)
{
- ACE_Ini_ImpExp config_importer(*_config.get());
- if (config_importer.import_config(file) == 0)
- return true;
+ std::string value = _config.get<std::string>(ptree::path_type(name, '/'), def);
- return false;
-}
+ value.erase(std::remove(value.begin(), value.end(), '"'), value.end());
-std::string ConfigMgr::GetStringDefault(const char* name, const std::string &def)
-{
- ACE_TString val;
- return GetValueHelper(name, val) ? val.c_str() : def;
+ return value;
}
-bool ConfigMgr::GetBoolDefault(const char* name, bool def)
+bool ConfigMgr::GetBoolDefault(std::string const& name, bool def)
{
- ACE_TString val;
-
- if (!GetValueHelper(name, val))
+ try
+ {
+ std::string val = _config.get<std::string>(ptree::path_type(name, '/'));
+ val.erase(std::remove(val.begin(), val.end(), '"'), val.end());
+ return (val == "true" || val == "TRUE" || val == "yes" || val == "YES" || val == "1");
+ }
+ catch (std::exception const& /*ex*/)
+ {
return def;
-
- return (val == "true" || val == "TRUE" || val == "yes" || val == "YES" ||
- val == "1");
+ }
}
-int ConfigMgr::GetIntDefault(const char* name, int def)
+int ConfigMgr::GetIntDefault(std::string const& name, int def)
{
- ACE_TString val;
- return GetValueHelper(name, val) ? atoi(val.c_str()) : def;
+ return _config.get<int>(ptree::path_type(name, '/'), def);
}
-float ConfigMgr::GetFloatDefault(const char* name, float def)
+float ConfigMgr::GetFloatDefault(std::string const& name, float def)
{
- ACE_TString val;
- return GetValueHelper(name, val) ? (float)atof(val.c_str()) : def;
+ return _config.get<float>(ptree::path_type(name, '/'), def);
}
std::string const& ConfigMgr::GetFilename()
{
- GuardType guard(_configLock);
+ std::lock_guard<std::mutex> lock(_configLock);
return _filename;
}
std::list<std::string> ConfigMgr::GetKeysByString(std::string const& name)
{
- GuardType guard(_configLock);
+ std::lock_guard<std::mutex> lock(_configLock);
std::list<std::string> keys;
- if (_config.get() == 0)
- return keys;
-
- ACE_TString section_name;
- ACE_Configuration_Section_Key section_key;
- const ACE_Configuration_Section_Key &root_key = _config->root_section();
-
- int i = 0;
- while (_config->enumerate_sections(root_key, i++, section_name) == 0)
- {
- _config->open_section(root_key, section_name.c_str(), 0, section_key);
-
- ACE_TString key_name;
- ACE_Configuration::VALUETYPE type;
- int j = 0;
- while (_config->enumerate_values(section_key, j++, key_name, type) == 0)
- {
- std::string temp = key_name.c_str();
-
- if (!temp.find(name))
- keys.push_back(temp);
- }
- }
+ for (const ptree::value_type& child : _config)
+ if (child.first.compare(0, name.length(), name) == 0)
+ keys.push_back(child.first);
+
return keys;
}
diff --git a/src/server/shared/Configuration/Config.h b/src/server/shared/Configuration/Config.h
index 4693b21a0c7..68daca5440f 100644
--- a/src/server/shared/Configuration/Config.h
+++ b/src/server/shared/Configuration/Config.h
@@ -21,58 +21,43 @@
#include <string>
#include <list>
-#include <ace/Singleton.h>
-#include <ace/Configuration_Import_Export.h>
-#include <ace/Thread_Mutex.h>
-#include <AutoPtr.h>
-
-typedef Trinity::AutoPtr<ACE_Configuration_Heap, ACE_Null_Mutex> Config;
+#include <mutex>
+#include <boost/property_tree/ptree.hpp>
class ConfigMgr
{
- friend class ACE_Singleton<ConfigMgr, ACE_Null_Mutex>;
- friend class ConfigLoader;
-
ConfigMgr() { }
~ConfigMgr() { }
public:
/// Method used only for loading main configuration files (authserver.conf and worldserver.conf)
- bool LoadInitial(char const* file);
+ bool LoadInitial(std::string const& file);
- /**
- * This method loads additional configuration files
- * It is recommended to use this method in WorldScript::OnConfigLoad hooks
- *
- * @return true if loading was successful
- */
- bool LoadMore(char const* file);
+ static ConfigMgr* instance()
+ {
+ static ConfigMgr *instance = new ConfigMgr();
+ return instance;
+ }
bool Reload();
- std::string GetStringDefault(const char* name, const std::string& def);
- bool GetBoolDefault(const char* name, bool def);
- int GetIntDefault(const char* name, int def);
- float GetFloatDefault(const char* name, float def);
+ std::string GetStringDefault(std::string const& name, const std::string& def);
+ bool GetBoolDefault(std::string const& name, bool def);
+ int GetIntDefault(std::string const& name, int def);
+ float GetFloatDefault(std::string const& name, float def);
std::string const& GetFilename();
std::list<std::string> GetKeysByString(std::string const& name);
private:
- bool GetValueHelper(const char* name, ACE_TString &result);
- bool LoadData(char const* file);
-
- typedef ACE_Thread_Mutex LockType;
- typedef ACE_Guard<LockType> GuardType;
-
std::string _filename;
- Config _config;
- LockType _configLock;
+ boost::property_tree::ptree _config;
+ std::mutex _configLock;
ConfigMgr(ConfigMgr const&);
ConfigMgr& operator=(ConfigMgr const&);
};
-#define sConfigMgr ACE_Singleton<ConfigMgr, ACE_Null_Mutex>::instance()
+#define sConfigMgr ConfigMgr::instance()
#endif
diff --git a/src/server/shared/Cryptography/ARC4.h b/src/server/shared/Cryptography/ARC4.h
index 5304b0730a6..11d3d4ba87b 100644
--- a/src/server/shared/Cryptography/ARC4.h
+++ b/src/server/shared/Cryptography/ARC4.h
@@ -19,8 +19,8 @@
#ifndef _AUTH_SARC4_H
#define _AUTH_SARC4_H
-#include "Define.h"
#include <openssl/evp.h>
+#include "Define.h"
class ARC4
{
diff --git a/src/server/shared/Cryptography/BigNumber.cpp b/src/server/shared/Cryptography/BigNumber.cpp
index 1c82314bdba..364bb8e452f 100644
--- a/src/server/shared/Cryptography/BigNumber.cpp
+++ b/src/server/shared/Cryptography/BigNumber.cpp
@@ -16,13 +16,11 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include <ace/Guard_T.h>
-
#include "Cryptography/BigNumber.h"
#include <openssl/bn.h>
#include <openssl/crypto.h>
#include <algorithm>
-#include <ace/Auto_Ptr.h>
+#include <memory>
BigNumber::BigNumber()
: _bn(BN_new())
@@ -170,7 +168,7 @@ bool BigNumber::isZero() const
return BN_is_zero(_bn);
}
-ACE_Auto_Array_Ptr<uint8> BigNumber::AsByteArray(int32 minSize, bool littleEndian)
+std::unique_ptr<uint8[]> BigNumber::AsByteArray(int32 minSize, bool littleEndian)
{
int length = (minSize >= GetNumBytes()) ? minSize : GetNumBytes();
@@ -186,7 +184,7 @@ ACE_Auto_Array_Ptr<uint8> BigNumber::AsByteArray(int32 minSize, bool littleEndia
if (littleEndian)
std::reverse(array, array + length);
- ACE_Auto_Array_Ptr<uint8> ret(array);
+ std::unique_ptr<uint8[]> ret(array);
return ret;
}
diff --git a/src/server/shared/Cryptography/BigNumber.h b/src/server/shared/Cryptography/BigNumber.h
index 7de53b442ae..df19ba60b71 100644
--- a/src/server/shared/Cryptography/BigNumber.h
+++ b/src/server/shared/Cryptography/BigNumber.h
@@ -19,8 +19,8 @@
#ifndef _AUTH_BIGNUMBER_H
#define _AUTH_BIGNUMBER_H
+#include <memory>
#include "Define.h"
-#include <ace/Auto_Ptr.h>
#include <string>
struct bignum_st;
@@ -88,7 +88,7 @@ class BigNumber
uint32 AsDword();
- ACE_Auto_Array_Ptr<uint8> AsByteArray(int32 minSize = 0, bool littleEndian = true);
+ std::unique_ptr<uint8[]> AsByteArray(int32 minSize = 0, bool littleEndian = true);
std::string AsHexStr() const;
std::string AsDecStr() const;
diff --git a/src/server/shared/Cryptography/OpenSSLCrypto.cpp b/src/server/shared/Cryptography/OpenSSLCrypto.cpp
index bd72459e9df..6d8d6584e6c 100644
--- a/src/server/shared/Cryptography/OpenSSLCrypto.cpp
+++ b/src/server/shared/Cryptography/OpenSSLCrypto.cpp
@@ -17,28 +17,23 @@
#include <OpenSSLCrypto.h>
#include <openssl/crypto.h>
-#include <ace/Thread_Mutex.h>
#include <vector>
-#include <ace/Thread.h>
+#include <thread>
+#include <mutex>
-std::vector<ACE_Thread_Mutex*> cryptoLocks;
+std::vector<std::mutex*> cryptoLocks;
static void lockingCallback(int mode, int type, const char* /*file*/, int /*line*/)
{
if (mode & CRYPTO_LOCK)
- cryptoLocks[type]->acquire();
+ cryptoLocks[type]->lock();
else
- cryptoLocks[type]->release();
+ cryptoLocks[type]->unlock();
}
static void threadIdCallback(CRYPTO_THREADID * id)
{
-/// ACE_thread_t turns out to be a struct under Mac OS.
-#ifndef __APPLE__
- CRYPTO_THREADID_set_numeric(id, ACE_Thread::self());
-#else
- CRYPTO_THREADID_set_pointer(id, ACE_Thread::self());
-#endif
+ CRYPTO_THREADID_set_numeric(id, std::hash<std::thread::id>()(std::this_thread::get_id()));
}
void OpenSSLCrypto::threadsSetup()
@@ -46,7 +41,7 @@ void OpenSSLCrypto::threadsSetup()
cryptoLocks.resize(CRYPTO_num_locks());
for(int i = 0 ; i < CRYPTO_num_locks(); ++i)
{
- cryptoLocks[i] = new ACE_Thread_Mutex();
+ cryptoLocks[i] = new std::mutex;
}
CRYPTO_THREADID_set_callback(threadIdCallback);
CRYPTO_set_locking_callback(lockingCallback);
@@ -61,4 +56,4 @@ void OpenSSLCrypto::threadsCleanup()
delete cryptoLocks[i];
}
cryptoLocks.resize(0);
-} \ No newline at end of file
+}
diff --git a/src/server/shared/Database/AdhocStatement.cpp b/src/server/shared/Database/AdhocStatement.cpp
index 896fefde5b7..7fae9173d20 100644
--- a/src/server/shared/Database/AdhocStatement.cpp
+++ b/src/server/shared/Database/AdhocStatement.cpp
@@ -19,22 +19,20 @@
#include "MySQLConnection.h"
/*! Basic, ad-hoc queries. */
-BasicStatementTask::BasicStatementTask(const char* sql) :
-m_has_result(false)
-{
- m_sql = strdup(sql);
-}
-
-BasicStatementTask::BasicStatementTask(const char* sql, QueryResultFuture result) :
-m_has_result(true),
-m_result(result)
+BasicStatementTask::BasicStatementTask(const char* sql, bool async) :
+m_result(nullptr)
{
m_sql = strdup(sql);
+ m_has_result = async; // If the operation is async, then there's a result
+ if (async)
+ m_result = new QueryResultPromise();
}
BasicStatementTask::~BasicStatementTask()
{
free((void*)m_sql);
+ if (m_has_result && m_result != nullptr)
+ delete m_result;
}
bool BasicStatementTask::Execute()
@@ -45,11 +43,11 @@ bool BasicStatementTask::Execute()
if (!result || !result->GetRowCount() || !result->NextRow())
{
delete result;
- m_result.set(QueryResult(NULL));
+ m_result->set_value(QueryResult(NULL));
return false;
}
- m_result.set(QueryResult(result));
+ m_result->set_value(QueryResult(result));
return true;
}
diff --git a/src/server/shared/Database/AdhocStatement.h b/src/server/shared/Database/AdhocStatement.h
index 44a9fa3d3ee..40c1dbb7098 100644
--- a/src/server/shared/Database/AdhocStatement.h
+++ b/src/server/shared/Database/AdhocStatement.h
@@ -18,24 +18,26 @@
#ifndef _ADHOCSTATEMENT_H
#define _ADHOCSTATEMENT_H
-#include <ace/Future.h>
+#include <future>
#include "SQLOperation.h"
-typedef ACE_Future<QueryResult> QueryResultFuture;
+typedef std::future<QueryResult> QueryResultFuture;
+typedef std::promise<QueryResult> QueryResultPromise;
+
/*! Raw, ad-hoc query. */
class BasicStatementTask : public SQLOperation
{
public:
- BasicStatementTask(const char* sql);
- BasicStatementTask(const char* sql, QueryResultFuture result);
+ BasicStatementTask(const char* sql, bool async = false);
~BasicStatementTask();
- bool Execute();
+ bool Execute() override;
+ QueryResultFuture GetFuture() { return m_result->get_future(); }
private:
const char* m_sql; //- Raw query to be executed
bool m_has_result;
- QueryResultFuture m_result;
+ QueryResultPromise* m_result;
};
#endif \ No newline at end of file
diff --git a/src/server/shared/Database/DatabaseWorker.cpp b/src/server/shared/Database/DatabaseWorker.cpp
index 3581f8e0211..ca48ebdd811 100644
--- a/src/server/shared/Database/DatabaseWorker.cpp
+++ b/src/server/shared/Database/DatabaseWorker.cpp
@@ -20,32 +20,42 @@
#include "SQLOperation.h"
#include "MySQLConnection.h"
#include "MySQLThreading.h"
+#include "ProducerConsumerQueue.h"
-DatabaseWorker::DatabaseWorker(ACE_Activation_Queue* new_queue, MySQLConnection* con) :
-m_queue(new_queue),
-m_conn(con)
+DatabaseWorker::DatabaseWorker(ProducerConsumerQueue<SQLOperation*>* newQueue, MySQLConnection* connection)
{
- /// Assign thread to task
- activate();
+ _connection = connection;
+ _queue = newQueue;
+ _cancelationToken = false;
+ _workerThread = std::thread(&DatabaseWorker::WorkerThread, this);
}
-int DatabaseWorker::svc()
+DatabaseWorker::~DatabaseWorker()
{
- if (!m_queue)
- return -1;
+ _cancelationToken = true;
- SQLOperation *request = NULL;
- while (1)
+ _queue->Cancel();
+
+ _workerThread.join();
+}
+
+void DatabaseWorker::WorkerThread()
+{
+ if (!_queue)
+ return;
+
+ for (;;)
{
- request = (SQLOperation*)(m_queue->dequeue());
- if (!request)
- break;
+ SQLOperation* operation = nullptr;
- request->SetConnection(m_conn);
- request->call();
+ _queue->WaitAndPop(operation);
- delete request;
- }
+ if (_cancelationToken)
+ return;
- return 0;
+ operation->SetConnection(_connection);
+ operation->call();
+
+ delete operation;
+ }
}
diff --git a/src/server/shared/Database/DatabaseWorker.h b/src/server/shared/Database/DatabaseWorker.h
index dc883dd3428..6f452c767f6 100644
--- a/src/server/shared/Database/DatabaseWorker.h
+++ b/src/server/shared/Database/DatabaseWorker.h
@@ -18,24 +18,26 @@
#ifndef _WORKERTHREAD_H
#define _WORKERTHREAD_H
-#include "Define.h"
-#include <ace/Task.h>
-#include <ace/Activation_Queue.h>
+#include <thread>
+#include "ProducerConsumerQueue.h"
class MySQLConnection;
+class SQLOperation;
-class DatabaseWorker : protected ACE_Task_Base
+class DatabaseWorker
{
public:
- DatabaseWorker(ACE_Activation_Queue* new_queue, MySQLConnection* con);
-
- ///- Inherited from ACE_Task_Base
- int svc();
- int wait() { return ACE_Task_Base::wait(); }
+ DatabaseWorker(ProducerConsumerQueue<SQLOperation*>* newQueue, MySQLConnection* connection);
+ ~DatabaseWorker();
private:
- ACE_Activation_Queue* m_queue;
- MySQLConnection* m_conn;
+ ProducerConsumerQueue<SQLOperation*>* _queue;
+ MySQLConnection* _connection;
+
+ void WorkerThread();
+ std::thread _workerThread;
+
+ std::atomic_bool _cancelationToken;
DatabaseWorker(DatabaseWorker const& right) = delete;
DatabaseWorker& operator=(DatabaseWorker const& right) = delete;
diff --git a/src/server/shared/Database/DatabaseWorkerPool.h b/src/server/shared/Database/DatabaseWorkerPool.h
index 9c56c75bf71..f0b540022da 100644
--- a/src/server/shared/Database/DatabaseWorkerPool.h
+++ b/src/server/shared/Database/DatabaseWorkerPool.h
@@ -18,8 +18,6 @@
#ifndef _DATABASEWORKERPOOL_H
#define _DATABASEWORKERPOOL_H
-#include <ace/Thread_Mutex.h>
-
#include "Common.h"
#include "Callback.h"
#include "MySQLConnection.h"
@@ -51,8 +49,7 @@ class DatabaseWorkerPool
/* Activity state */
DatabaseWorkerPool() : _connectionInfo(NULL)
{
- _messageQueue = new ACE_Message_Queue<ACE_SYNCH>(8 * 1024 * 1024, 8 * 1024 * 1024);
- _queue = new ACE_Activation_Queue(_messageQueue);
+ _queue = new ProducerConsumerQueue<SQLOperation*>();
memset(_connectionCount, 0, sizeof(_connectionCount));
_connections.resize(IDX_SIZE);
@@ -107,16 +104,10 @@ class DatabaseWorkerPool
{
TC_LOG_INFO("sql.driver", "Closing down DatabasePool '%s'.", GetDatabaseName());
- //! Shuts down delaythreads for this connection pool by underlying deactivate().
- //! The next dequeue attempt in the worker thread tasks will result in an error,
- //! ultimately ending the worker thread task.
- _queue->queue()->close();
-
for (uint8 i = 0; i < _connectionCount[IDX_ASYNC]; ++i)
{
T* t = _connections[IDX_ASYNC][i];
DatabaseWorker* worker = t->m_worker;
- worker->wait(); //! Block until no more threads are running this task.
delete worker;
t->Close(); //! Closes the actualy MySQL connection.
}
@@ -131,9 +122,7 @@ class DatabaseWorkerPool
for (uint8 i = 0; i < _connectionCount[IDX_SYNCH]; ++i)
_connections[IDX_SYNCH][i]->Close();
- //! Deletes the ACE_Activation_Queue object and its underlying ACE_Message_Queue
delete _queue;
- delete _messageQueue;
TC_LOG_INFO("sql.driver", "All connections on DatabasePool '%s' closed.", GetDatabaseName());
@@ -307,10 +296,9 @@ class DatabaseWorkerPool
//! The return value is then processed in ProcessQueryCallback methods.
QueryResultFuture AsyncQuery(const char* sql)
{
- QueryResultFuture res;
- BasicStatementTask* task = new BasicStatementTask(sql, res);
+ BasicStatementTask* task = new BasicStatementTask(sql, true);
Enqueue(task);
- return res; //! Actual return value has no use yet
+ return task->GetFuture(); //! Actual return value has no use yet
}
//! Enqueues a query in string format -with variable args- that will set the value of the QueryResultFuture return object as soon as the query is executed.
@@ -331,10 +319,9 @@ class DatabaseWorkerPool
//! Statement must be prepared with CONNECTION_ASYNC flag.
PreparedQueryResultFuture AsyncQuery(PreparedStatement* stmt)
{
- PreparedQueryResultFuture res;
- PreparedStatementTask* task = new PreparedStatementTask(stmt, res);
+ PreparedStatementTask* task = new PreparedStatementTask(stmt, true);
Enqueue(task);
- return res;
+ return task->GetFuture();
}
//! Enqueues a vector of SQL operations (can be both adhoc and prepared) that will set the value of the QueryResultHolderFuture
@@ -343,10 +330,9 @@ class DatabaseWorkerPool
//! Any prepared statements added to this holder need to be prepared with the CONNECTION_ASYNC flag.
QueryResultHolderFuture DelayQueryHolder(SQLQueryHolder* holder)
{
- QueryResultHolderFuture res;
- SQLQueryHolderTask* task = new SQLQueryHolderTask(holder, res);
+ SQLQueryHolderTask* task = new SQLQueryHolderTask(holder);
Enqueue(task);
- return res; //! Fool compiler, has no use yet
+ return task->GetFuture();
}
/**
@@ -416,7 +402,7 @@ class DatabaseWorkerPool
//! Will be wrapped in a transaction if valid object is present, otherwise executed standalone.
void ExecuteOrAppend(SQLTransaction& trans, PreparedStatement* stmt)
{
- if (trans.null())
+ if (!trans)
Execute(stmt);
else
trans->Append(stmt);
@@ -426,7 +412,7 @@ class DatabaseWorkerPool
//! Will be wrapped in a transaction if valid object is present, otherwise executed standalone.
void ExecuteOrAppend(SQLTransaction& trans, const char* sql)
{
- if (trans.null())
+ if (!trans)
Execute(sql);
else
trans->Append(sql);
@@ -488,7 +474,7 @@ class DatabaseWorkerPool
void Enqueue(SQLOperation* op)
{
- _queue->enqueue(op);
+ _queue->Push(op);
}
//! Gets a free connection in the synchronous connection pool.
@@ -523,11 +509,10 @@ class DatabaseWorkerPool
IDX_SIZE
};
- ACE_Message_Queue<ACE_SYNCH>* _messageQueue; //! Message Queue used by ACE_Activation_Queue
- ACE_Activation_Queue* _queue; //! Queue shared by async worker threads.
- std::vector< std::vector<T*> > _connections;
- uint32 _connectionCount[2]; //! Counter of MySQL connections;
- MySQLConnectionInfo* _connectionInfo;
+ ProducerConsumerQueue<SQLOperation*>* _queue; //! Queue shared by async worker threads.
+ std::vector< std::vector<T*> > _connections;
+ uint32 _connectionCount[2]; //! Counter of MySQL connections;
+ MySQLConnectionInfo* _connectionInfo;
};
#endif
diff --git a/src/server/shared/Database/Implementation/CharacterDatabase.h b/src/server/shared/Database/Implementation/CharacterDatabase.h
index 7fd299852c1..73eac6e30d6 100644
--- a/src/server/shared/Database/Implementation/CharacterDatabase.h
+++ b/src/server/shared/Database/Implementation/CharacterDatabase.h
@@ -26,7 +26,7 @@ class CharacterDatabaseConnection : public MySQLConnection
public:
//- Constructors for sync and async connections
CharacterDatabaseConnection(MySQLConnectionInfo& connInfo) : MySQLConnection(connInfo) { }
- CharacterDatabaseConnection(ACE_Activation_Queue* q, MySQLConnectionInfo& connInfo) : MySQLConnection(q, connInfo) { }
+ CharacterDatabaseConnection(ProducerConsumerQueue<SQLOperation*>* q, MySQLConnectionInfo& connInfo) : MySQLConnection(q, connInfo) { }
//- Loads database type specific prepared statements
void DoPrepareStatements();
diff --git a/src/server/shared/Database/Implementation/LoginDatabase.h b/src/server/shared/Database/Implementation/LoginDatabase.h
index 83432009cbf..830fd625931 100644
--- a/src/server/shared/Database/Implementation/LoginDatabase.h
+++ b/src/server/shared/Database/Implementation/LoginDatabase.h
@@ -26,7 +26,7 @@ class LoginDatabaseConnection : public MySQLConnection
public:
//- Constructors for sync and async connections
LoginDatabaseConnection(MySQLConnectionInfo& connInfo) : MySQLConnection(connInfo) { }
- LoginDatabaseConnection(ACE_Activation_Queue* q, MySQLConnectionInfo& connInfo) : MySQLConnection(q, connInfo) { }
+ LoginDatabaseConnection(ProducerConsumerQueue<SQLOperation*>* q, MySQLConnectionInfo& connInfo) : MySQLConnection(q, connInfo) { }
//- Loads database type specific prepared statements
void DoPrepareStatements();
diff --git a/src/server/shared/Database/Implementation/WorldDatabase.h b/src/server/shared/Database/Implementation/WorldDatabase.h
index a815373a1c6..c8c38d8a629 100644
--- a/src/server/shared/Database/Implementation/WorldDatabase.h
+++ b/src/server/shared/Database/Implementation/WorldDatabase.h
@@ -26,7 +26,7 @@ class WorldDatabaseConnection : public MySQLConnection
public:
//- Constructors for sync and async connections
WorldDatabaseConnection(MySQLConnectionInfo& connInfo) : MySQLConnection(connInfo) { }
- WorldDatabaseConnection(ACE_Activation_Queue* q, MySQLConnectionInfo& connInfo) : MySQLConnection(q, connInfo) { }
+ WorldDatabaseConnection(ProducerConsumerQueue<SQLOperation*>* q, MySQLConnectionInfo& connInfo) : MySQLConnection(q, connInfo) { }
//- Loads database type specific prepared statements
void DoPrepareStatements();
diff --git a/src/server/shared/Database/MySQLConnection.cpp b/src/server/shared/Database/MySQLConnection.cpp
index 55d47c76430..8b24f508331 100644
--- a/src/server/shared/Database/MySQLConnection.cpp
+++ b/src/server/shared/Database/MySQLConnection.cpp
@@ -33,6 +33,7 @@
#include "DatabaseWorker.h"
#include "Timer.h"
#include "Log.h"
+#include "ProducerConsumerQueue.h"
MySQLConnection::MySQLConnection(MySQLConnectionInfo& connInfo) :
m_reconnecting(false),
@@ -43,7 +44,7 @@ m_Mysql(NULL),
m_connectionInfo(connInfo),
m_connectionFlags(CONNECTION_SYNCH) { }
-MySQLConnection::MySQLConnection(ACE_Activation_Queue* queue, MySQLConnectionInfo& connInfo) :
+MySQLConnection::MySQLConnection(ProducerConsumerQueue<SQLOperation*>* queue, MySQLConnectionInfo& connInfo) :
m_reconnecting(false),
m_prepareError(false),
m_queue(queue),
@@ -500,8 +501,8 @@ bool MySQLConnection::_HandleMySQLErrno(uint32 errNo)
}
uint32 lErrno = mysql_errno(GetHandle()); // It's possible this attempted reconnect throws 2006 at us. To prevent crazy recursive calls, sleep here.
- ACE_OS::sleep(3); // Sleep 3 seconds
- return _HandleMySQLErrno(lErrno); // Call self (recursive)
+ std::this_thread::sleep_for(std::chrono::seconds(3)); // Sleep 3 seconds
+ return _HandleMySQLErrno(lErrno); // Call self (recursive)
}
case ER_LOCK_DEADLOCK:
@@ -515,12 +516,12 @@ bool MySQLConnection::_HandleMySQLErrno(uint32 errNo)
case ER_BAD_FIELD_ERROR:
case ER_NO_SUCH_TABLE:
TC_LOG_ERROR("sql.sql", "Your database structure is not up to date. Please make sure you've executed all queries in the sql/updates folders.");
- ACE_OS::sleep(10);
+ std::this_thread::sleep_for(std::chrono::seconds(10));
std::abort();
return false;
case ER_PARSE_ERROR:
TC_LOG_ERROR("sql.sql", "Error while parsing SQL. Core fix required.");
- ACE_OS::sleep(10);
+ std::this_thread::sleep_for(std::chrono::seconds(10));
std::abort();
return false;
default:
diff --git a/src/server/shared/Database/MySQLConnection.h b/src/server/shared/Database/MySQLConnection.h
index 512df7c16c7..61b3b37cbc2 100644
--- a/src/server/shared/Database/MySQLConnection.h
+++ b/src/server/shared/Database/MySQLConnection.h
@@ -15,11 +15,10 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include <ace/Activation_Queue.h>
-
#include "DatabaseWorkerPool.h"
#include "Transaction.h"
#include "Util.h"
+#include "ProducerConsumerQueue.h"
#ifndef _MYSQLCONNECTION_H
#define _MYSQLCONNECTION_H
@@ -70,7 +69,7 @@ class MySQLConnection
public:
MySQLConnection(MySQLConnectionInfo& connInfo); //! Constructor for synchronous connections.
- MySQLConnection(ACE_Activation_Queue* queue, MySQLConnectionInfo& connInfo); //! Constructor for asynchronous connections.
+ MySQLConnection(ProducerConsumerQueue<SQLOperation*>* queue, MySQLConnectionInfo& connInfo); //! Constructor for asynchronous connections.
virtual ~MySQLConnection();
virtual bool Open();
@@ -99,13 +98,13 @@ class MySQLConnection
{
/// Tries to acquire lock. If lock is acquired by another thread
/// the calling parent will just try another connection
- return m_Mutex.tryacquire() != -1;
+ return m_Mutex.try_lock();
}
void Unlock()
{
/// Called by parent databasepool. Will let other threads access this connection
- m_Mutex.release();
+ m_Mutex.unlock();
}
MYSQL* GetHandle() { return m_Mysql; }
@@ -125,12 +124,12 @@ class MySQLConnection
bool _HandleMySQLErrno(uint32 errNo);
private:
- ACE_Activation_Queue* m_queue; //! Queue shared with other asynchronous connections.
+ ProducerConsumerQueue<SQLOperation*>* m_queue; //! Queue shared with other asynchronous connections.
DatabaseWorker* m_worker; //! Core worker task.
MYSQL * m_Mysql; //! MySQL Handle.
MySQLConnectionInfo& m_connectionInfo; //! Connection info (used for logging)
ConnectionFlags m_connectionFlags; //! Connection flags (for preparing relevant statements)
- ACE_Thread_Mutex m_Mutex;
+ std::mutex m_Mutex;
MySQLConnection(MySQLConnection const& right) = delete;
MySQLConnection& operator=(MySQLConnection const& right) = delete;
diff --git a/src/server/shared/Database/MySQLThreading.h b/src/server/shared/Database/MySQLThreading.h
index 0f6af8ace20..da234138879 100644
--- a/src/server/shared/Database/MySQLThreading.h
+++ b/src/server/shared/Database/MySQLThreading.h
@@ -23,31 +23,6 @@
class MySQL
{
public:
- /*! Create a thread on the MySQL server to mirrior the calling thread,
- initializes thread-specific variables and allows thread-specific
- operations without concurrence from other threads.
- This should only be called if multiple core threads are running
- on the same MySQL connection. Seperate MySQL connections implicitly
- create a mirror thread.
- */
- static void Thread_Init()
- {
- mysql_thread_init();
- TC_LOG_WARN("sql.sql", "Core thread with ID [" UI64FMTD "] initializing MySQL thread.",
- (uint64)ACE_Based::Thread::currentId());
- }
-
- /*! Shuts down MySQL thread and frees resources, should only be called
- when we terminate. MySQL threads and connections are not configurable
- during runtime.
- */
- static void Thread_End()
- {
- mysql_thread_end();
- TC_LOG_WARN("sql.sql", "Core thread with ID [" UI64FMTD "] shutting down MySQL thread.",
- (uint64)ACE_Based::Thread::currentId());
- }
-
static void Library_Init()
{
mysql_library_init(-1, NULL, NULL);
@@ -59,4 +34,4 @@ class MySQL
}
};
-#endif \ No newline at end of file
+#endif
diff --git a/src/server/shared/Database/PreparedStatement.cpp b/src/server/shared/Database/PreparedStatement.cpp
index fe052bf5043..fb1bfa687d0 100644
--- a/src/server/shared/Database/PreparedStatement.cpp
+++ b/src/server/shared/Database/PreparedStatement.cpp
@@ -445,19 +445,19 @@ std::string MySQLPreparedStatement::getQueryString(std::string const& sqlPattern
}
//- Execution
-PreparedStatementTask::PreparedStatementTask(PreparedStatement* stmt) :
-m_stmt(stmt),
-m_has_result(false) { }
-
-PreparedStatementTask::PreparedStatementTask(PreparedStatement* stmt, PreparedQueryResultFuture result) :
-m_stmt(stmt),
-m_has_result(true),
-m_result(result) { }
-
+PreparedStatementTask::PreparedStatementTask(PreparedStatement* stmt, bool async) :
+m_stmt(stmt)
+{
+ m_has_result = async; // If it's async, then there's a result
+ if (async)
+ m_result = new PreparedQueryResultPromise();
+}
PreparedStatementTask::~PreparedStatementTask()
{
delete m_stmt;
+ if (m_has_result && m_result != nullptr)
+ delete m_result;
}
bool PreparedStatementTask::Execute()
@@ -468,10 +468,10 @@ bool PreparedStatementTask::Execute()
if (!result || !result->GetRowCount())
{
delete result;
- m_result.set(PreparedQueryResult(NULL));
+ m_result->set_value(PreparedQueryResult(NULL));
return false;
}
- m_result.set(PreparedQueryResult(result));
+ m_result->set_value(PreparedQueryResult(result));
return true;
}
diff --git a/src/server/shared/Database/PreparedStatement.h b/src/server/shared/Database/PreparedStatement.h
index 6afb309db2c..16f7a9141d3 100644
--- a/src/server/shared/Database/PreparedStatement.h
+++ b/src/server/shared/Database/PreparedStatement.h
@@ -18,8 +18,8 @@
#ifndef _PREPAREDSTATEMENT_H
#define _PREPAREDSTATEMENT_H
+#include <future>
#include "SQLOperation.h"
-#include <ace/Future.h>
#ifdef __APPLE__
#undef TYPE_BOOL
@@ -153,21 +153,22 @@ class MySQLPreparedStatement
MySQLPreparedStatement& operator=(MySQLPreparedStatement const& right) = delete;
};
-typedef ACE_Future<PreparedQueryResult> PreparedQueryResultFuture;
+typedef std::future<PreparedQueryResult> PreparedQueryResultFuture;
+typedef std::promise<PreparedQueryResult> PreparedQueryResultPromise;
//- Lower-level class, enqueuable operation
class PreparedStatementTask : public SQLOperation
{
public:
- PreparedStatementTask(PreparedStatement* stmt);
- PreparedStatementTask(PreparedStatement* stmt, PreparedQueryResultFuture result);
+ PreparedStatementTask(PreparedStatement* stmt, bool async = false);
~PreparedStatementTask();
bool Execute();
+ PreparedQueryResultFuture GetFuture() { return m_result->get_future(); }
protected:
PreparedStatement* m_stmt;
bool m_has_result;
- PreparedQueryResultFuture m_result;
+ PreparedQueryResultPromise* m_result;
};
#endif
diff --git a/src/server/shared/Database/QueryHolder.cpp b/src/server/shared/Database/QueryHolder.cpp
index 7b4105ee076..bd938561b50 100644
--- a/src/server/shared/Database/QueryHolder.cpp
+++ b/src/server/shared/Database/QueryHolder.cpp
@@ -168,9 +168,6 @@ void SQLQueryHolder::SetSize(size_t size)
bool SQLQueryHolderTask::Execute()
{
- //the result can't be ready as we are processing it right now
- ASSERT(!m_result.ready());
-
if (!m_holder)
return false;
@@ -202,6 +199,6 @@ bool SQLQueryHolderTask::Execute()
}
}
- m_result.set(m_holder);
+ m_result.set_value(m_holder);
return true;
}
diff --git a/src/server/shared/Database/QueryHolder.h b/src/server/shared/Database/QueryHolder.h
index b92b2e5327e..37e23ecd653 100644
--- a/src/server/shared/Database/QueryHolder.h
+++ b/src/server/shared/Database/QueryHolder.h
@@ -18,7 +18,7 @@
#ifndef _QUERYHOLDER_H
#define _QUERYHOLDER_H
-#include <ace/Future.h>
+#include <future>
class SQLQueryHolder
{
@@ -39,18 +39,21 @@ class SQLQueryHolder
void SetPreparedResult(size_t index, PreparedResultSet* result);
};
-typedef ACE_Future<SQLQueryHolder*> QueryResultHolderFuture;
+typedef std::future<SQLQueryHolder*> QueryResultHolderFuture;
+typedef std::promise<SQLQueryHolder*> QueryResultHolderPromise;
class SQLQueryHolderTask : public SQLOperation
{
private:
- SQLQueryHolder * m_holder;
- QueryResultHolderFuture m_result;
+ SQLQueryHolder* m_holder;
+ QueryResultHolderPromise m_result;
public:
- SQLQueryHolderTask(SQLQueryHolder *holder, QueryResultHolderFuture res)
- : m_holder(holder), m_result(res){ };
+ SQLQueryHolderTask(SQLQueryHolder* holder)
+ : m_holder(holder) { };
+
bool Execute();
+ QueryResultHolderFuture GetFuture() { return m_result.get_future(); }
};
diff --git a/src/server/shared/Database/QueryResult.cpp b/src/server/shared/Database/QueryResult.cpp
index 58ac8d37270..06b09d43168 100644
--- a/src/server/shared/Database/QueryResult.cpp
+++ b/src/server/shared/Database/QueryResult.cpp
@@ -105,10 +105,10 @@ m_length(NULL)
for (uint64 fIndex = 0; fIndex < m_fieldCount; ++fIndex)
{
if (!*m_rBind[fIndex].is_null)
- m_rows[uint32(m_rowPosition)][fIndex].SetByteValue( m_rBind[fIndex].buffer,
+ m_rows[uint32(m_rowPosition)][fIndex].SetByteValue(m_rBind[fIndex].buffer,
m_rBind[fIndex].buffer_length,
m_rBind[fIndex].buffer_type,
- *m_rBind[fIndex].length );
+ *m_rBind[fIndex].length);
else
switch (m_rBind[fIndex].buffer_type)
{
@@ -118,16 +118,16 @@ m_length(NULL)
case MYSQL_TYPE_BLOB:
case MYSQL_TYPE_STRING:
case MYSQL_TYPE_VAR_STRING:
- m_rows[uint32(m_rowPosition)][fIndex].SetByteValue( "",
+ m_rows[uint32(m_rowPosition)][fIndex].SetByteValue("",
m_rBind[fIndex].buffer_length,
m_rBind[fIndex].buffer_type,
- *m_rBind[fIndex].length );
+ *m_rBind[fIndex].length);
break;
default:
- m_rows[uint32(m_rowPosition)][fIndex].SetByteValue( 0,
+ m_rows[uint32(m_rowPosition)][fIndex].SetByteValue(0,
m_rBind[fIndex].buffer_length,
m_rBind[fIndex].buffer_type,
- *m_rBind[fIndex].length );
+ *m_rBind[fIndex].length);
}
}
m_rowPosition++;
@@ -186,15 +186,8 @@ bool PreparedResultSet::_NextRow()
if (m_rowPosition >= m_rowCount)
return false;
- int retval = mysql_stmt_fetch( m_stmt );
-
- if (!retval || retval == MYSQL_DATA_TRUNCATED)
- retval = true;
-
- if (retval == MYSQL_NO_DATA)
- retval = false;
-
- return retval;
+ int retval = mysql_stmt_fetch(m_stmt);
+ return retval == 0 || retval == MYSQL_DATA_TRUNCATED;
}
void ResultSet::CleanUp()
diff --git a/src/server/shared/Database/QueryResult.h b/src/server/shared/Database/QueryResult.h
index 4795fef4a4c..e8c277c03cf 100644
--- a/src/server/shared/Database/QueryResult.h
+++ b/src/server/shared/Database/QueryResult.h
@@ -19,9 +19,7 @@
#ifndef QUERYRESULT_H
#define QUERYRESULT_H
-#include "AutoPtr.h"
-#include <ace/Thread_Mutex.h>
-
+#include <memory>
#include "Field.h"
#ifdef _WIN32
@@ -60,7 +58,7 @@ class ResultSet
ResultSet& operator=(ResultSet const& right) = delete;
};
-typedef Trinity::AutoPtr<ResultSet, ACE_Thread_Mutex> QueryResult;
+typedef std::shared_ptr<ResultSet> QueryResult;
class PreparedResultSet
{
@@ -107,7 +105,7 @@ class PreparedResultSet
PreparedResultSet& operator=(PreparedResultSet const& right) = delete;
};
-typedef Trinity::AutoPtr<PreparedResultSet, ACE_Thread_Mutex> PreparedQueryResult;
+typedef std::shared_ptr<PreparedResultSet> PreparedQueryResult;
#endif
diff --git a/src/server/shared/Database/SQLOperation.h b/src/server/shared/Database/SQLOperation.h
index 6f933a051e3..4d6e349449d 100644
--- a/src/server/shared/Database/SQLOperation.h
+++ b/src/server/shared/Database/SQLOperation.h
@@ -18,9 +18,6 @@
#ifndef _SQLOPERATION_H
#define _SQLOPERATION_H
-#include <ace/Method_Request.h>
-#include <ace/Activation_Queue.h>
-
#include "QueryResult.h"
//- Forward declare (don't include header to prevent circular includes)
@@ -56,10 +53,12 @@ union SQLResultSetUnion
class MySQLConnection;
-class SQLOperation : public ACE_Method_Request
+class SQLOperation
{
public:
SQLOperation(): m_conn(NULL) { }
+ virtual ~SQLOperation() { }
+
virtual int call()
{
Execute();
diff --git a/src/server/shared/Database/Transaction.h b/src/server/shared/Database/Transaction.h
index cb28f0ad876..c7cbbbbe712 100644
--- a/src/server/shared/Database/Transaction.h
+++ b/src/server/shared/Database/Transaction.h
@@ -50,7 +50,7 @@ class Transaction
bool _cleanedUp;
};
-typedef Trinity::AutoPtr<Transaction, ACE_Thread_Mutex> SQLTransaction;
+typedef std::shared_ptr<Transaction> SQLTransaction;
/*! Low level class*/
class TransactionTask : public SQLOperation
diff --git a/src/server/shared/Debugging/Errors.cpp b/src/server/shared/Debugging/Errors.cpp
index d656dc3fb4a..62e97d56d42 100644
--- a/src/server/shared/Debugging/Errors.cpp
+++ b/src/server/shared/Debugging/Errors.cpp
@@ -18,17 +18,15 @@
#include "Errors.h"
-#include <ace/Stack_Trace.h>
-#include <ace/OS_NS_unistd.h>
#include <cstdlib>
+#include <thread>
namespace Trinity {
void Assert(char const* file, int line, char const* function, char const* message)
{
- ACE_Stack_Trace st;
- fprintf(stderr, "\n%s:%i in %s ASSERTION FAILED:\n %s\n%s\n",
- file, line, function, message, st.c_str());
+ fprintf(stderr, "\n%s:%i in %s ASSERTION FAILED:\n %s\n",
+ file, line, function, message);
*((volatile int*)NULL) = 0;
exit(1);
}
@@ -37,7 +35,8 @@ void Fatal(char const* file, int line, char const* function, char const* message
{
fprintf(stderr, "\n%s:%i in %s FATAL ERROR:\n %s\n",
file, line, function, message);
- ACE_OS::sleep(10);
+
+ std::this_thread::sleep_for(std::chrono::seconds(10));
*((volatile int*)NULL) = 0;
exit(1);
}
diff --git a/src/server/shared/Debugging/Errors.h b/src/server/shared/Debugging/Errors.h
index 7d521fefca0..218acfa453e 100644
--- a/src/server/shared/Debugging/Errors.h
+++ b/src/server/shared/Debugging/Errors.h
@@ -34,10 +34,18 @@ namespace Trinity
} // namespace Trinity
-#define WPAssert(cond) do { if (!(cond)) Trinity::Assert(__FILE__, __LINE__, __FUNCTION__, #cond); } while (0)
-#define WPFatal(cond, msg) do { if (!(cond)) Trinity::Fatal(__FILE__, __LINE__, __FUNCTION__, (msg)); } while (0)
-#define WPError(cond, msg) do { if (!(cond)) Trinity::Error(__FILE__, __LINE__, __FUNCTION__, (msg)); } while (0)
-#define WPWarning(cond, msg) do { if (!(cond)) Trinity::Warning(__FILE__, __LINE__, __FUNCTION__, (msg)); } while (0)
+#if COMPILER == COMPILER_MICROSOFT
+#define ASSERT_BEGIN __pragma(warning(push)) __pragma(warning(disable: 4127))
+#define ASSERT_END __pragma(warning(pop))
+#else
+#define ASSERT_BEGIN
+#define ASSERT_END
+#endif
+
+#define WPAssert(cond) ASSERT_BEGIN do { if (!(cond)) Trinity::Assert(__FILE__, __LINE__, __FUNCTION__, #cond); } while(0) ASSERT_END
+#define WPFatal(cond, msg) ASSERT_BEGIN do { if (!(cond)) Trinity::Fatal(__FILE__, __LINE__, __FUNCTION__, (msg)); } while(0) ASSERT_END
+#define WPError(cond, msg) ASSERT_BEGIN do { if (!(cond)) Trinity::Error(__FILE__, __LINE__, __FUNCTION__, (msg)); } while(0) ASSERT_END
+#define WPWarning(cond, msg) ASSERT_BEGIN do { if (!(cond)) Trinity::Warning(__FILE__, __LINE__, __FUNCTION__, (msg)); } while(0) ASSERT_END
#define ASSERT WPAssert
diff --git a/src/server/shared/Debugging/WheatyExceptionReport.cpp b/src/server/shared/Debugging/WheatyExceptionReport.cpp
index 350a258f455..2eb456ddd02 100644
--- a/src/server/shared/Debugging/WheatyExceptionReport.cpp
+++ b/src/server/shared/Debugging/WheatyExceptionReport.cpp
@@ -677,7 +677,7 @@ bool bWriteVariables, HANDLE pThreadHandle)
dwMachineType = IMAGE_FILE_MACHINE_AMD64;
#endif
- while (1)
+ for (;;)
{
// Get the next stack frame
if (! StackWalk64(dwMachineType,
diff --git a/src/server/shared/Define.h b/src/server/shared/Define.h
index 1e2a9676cd5..aa57a65167d 100644
--- a/src/server/shared/Define.h
+++ b/src/server/shared/Define.h
@@ -21,21 +21,25 @@
#include "CompilerDefs.h"
-#include <ace/Basic_Types.h>
-#include <ace/ACE_export.h>
+#if COMPILER == COMPILER_GNU
+# if !defined(__STDC_FORMAT_MACROS)
+# define __STDC_FORMAT_MACROS
+# endif
+#endif
#include <cstddef>
+#include <cinttypes>
#define TRINITY_LITTLEENDIAN 0
#define TRINITY_BIGENDIAN 1
#if !defined(TRINITY_ENDIAN)
-# if defined (ACE_BIG_ENDIAN)
+# if defined (BOOST_BIG_ENDIAN)
# define TRINITY_ENDIAN TRINITY_BIGENDIAN
-# else //ACE_BYTE_ORDER != ACE_BIG_ENDIAN
+# else
# define TRINITY_ENDIAN TRINITY_LITTLEENDIAN
-# endif //ACE_BYTE_ORDER
-#endif //TRINITY_ENDIAN
+# endif
+#endif
#if PLATFORM == PLATFORM_WINDOWS
# define TRINITY_PATH_MAX MAX_PATH
@@ -70,22 +74,20 @@
# define ATTR_DEPRECATED
#endif //COMPILER == COMPILER_GNU
-#define UI64FMTD ACE_UINT64_FORMAT_SPECIFIER
-#define UI64LIT(N) ACE_UINT64_LITERAL(N)
-
-#define SI64FMTD ACE_INT64_FORMAT_SPECIFIER
-#define SI64LIT(N) ACE_INT64_LITERAL(N)
+#define UI64FMTD "%" PRIu64
+#define UI64LIT(N) UINT64_C(N)
-#define SIZEFMTD ACE_SIZE_T_FORMAT_SPECIFIER
+#define SI64FMTD "%" PRId64
+#define SI64LIT(N) INT64_C(N)
-typedef ACE_INT64 int64;
-typedef ACE_INT32 int32;
-typedef ACE_INT16 int16;
-typedef ACE_INT8 int8;
-typedef ACE_UINT64 uint64;
-typedef ACE_UINT32 uint32;
-typedef ACE_UINT16 uint16;
-typedef ACE_UINT8 uint8;
+typedef int64_t int64;
+typedef int32_t int32;
+typedef int16_t int16;
+typedef int8_t int8;
+typedef uint64_t uint64;
+typedef uint32_t uint32;
+typedef uint16_t uint16;
+typedef uint8_t uint8;
enum DBCFormer
{
diff --git a/src/server/shared/Dynamic/FactoryHolder.h b/src/server/shared/Dynamic/FactoryHolder.h
index aee84ab151e..a009fd37a7e 100644
--- a/src/server/shared/Dynamic/FactoryHolder.h
+++ b/src/server/shared/Dynamic/FactoryHolder.h
@@ -30,15 +30,13 @@ class FactoryHolder
{
public:
typedef ObjectRegistry<FactoryHolder<T, Key >, Key > FactoryHolderRegistry;
- friend class ACE_Singleton<FactoryHolderRegistry, ACE_Null_Mutex>;
- typedef ACE_Singleton<FactoryHolderRegistry, ACE_Null_Mutex> FactoryHolderRepository;
FactoryHolder(Key k) : i_key(k) { }
virtual ~FactoryHolder() { }
inline Key key() const { return i_key; }
- void RegisterSelf(void) { FactoryHolderRepository::instance()->InsertItem(this, i_key); }
- void DeregisterSelf(void) { FactoryHolderRepository::instance()->RemoveItem(this, false); }
+ void RegisterSelf(void) { FactoryHolderRegistry::instance()->InsertItem(this, i_key); }
+ void DeregisterSelf(void) { FactoryHolderRegistry::instance()->RemoveItem(this, false); }
/// Abstract Factory create method
virtual T* Create(void *data = NULL) const = 0;
diff --git a/src/server/shared/Dynamic/ObjectRegistry.h b/src/server/shared/Dynamic/ObjectRegistry.h
index be7ce00ac05..e9e57415073 100644
--- a/src/server/shared/Dynamic/ObjectRegistry.h
+++ b/src/server/shared/Dynamic/ObjectRegistry.h
@@ -20,12 +20,10 @@
#define TRINITY_OBJECTREGISTRY_H
#include "Define.h"
-#include <ace/Singleton.h>
#include <string>
-#include <vector>
#include <map>
-#include <unordered_map>
+#include <vector>
/** ObjectRegistry holds all registry item of the same type
*/
@@ -33,7 +31,13 @@ template<class T, class Key = std::string>
class ObjectRegistry
{
public:
- typedef std::map<Key, T *> RegistryMapType;
+ typedef std::map<Key, T*> RegistryMapType;
+
+ static ObjectRegistry<T, Key>* instance()
+ {
+ static ObjectRegistry<T, Key>* instance = new ObjectRegistry<T, Key>();
+ return instance;
+ }
/// Returns a registry item
const T* GetRegistryItem(Key key) const
diff --git a/src/server/shared/Logging/Appender.cpp b/src/server/shared/Logging/Appender.cpp
index 718c3a406f1..2b38f9886c3 100644
--- a/src/server/shared/Logging/Appender.cpp
+++ b/src/server/shared/Logging/Appender.cpp
@@ -17,11 +17,12 @@
#include "Appender.h"
#include "Common.h"
+#include "Util.h"
std::string LogMessage::getTimeStr(time_t time)
{
tm aTm;
- ACE_OS::localtime_r(&time, &aTm);
+ localtime_r(&time, &aTm);
char buf[20];
snprintf(buf, 20, "%04d-%02d-%02d_%02d:%02d:%02d", aTm.tm_year+1900, aTm.tm_mon+1, aTm.tm_mday, aTm.tm_hour, aTm.tm_min, aTm.tm_sec);
return std::string(buf);
diff --git a/src/server/shared/Logging/Appender.h b/src/server/shared/Logging/Appender.h
index 84d0dc14eca..67213d0ddd0 100644
--- a/src/server/shared/Logging/Appender.h
+++ b/src/server/shared/Logging/Appender.h
@@ -18,10 +18,10 @@
#ifndef APPENDER_H
#define APPENDER_H
-#include "Define.h"
-#include <time.h>
#include <unordered_map>
#include <string>
+#include <time.h>
+#include "Define.h"
// Values assigned have their equivalent in enum ACE_Log_Priority
enum LogLevel
diff --git a/src/server/shared/Logging/AppenderConsole.cpp b/src/server/shared/Logging/AppenderConsole.cpp
index 14d434e35b8..8102d3b6021 100644
--- a/src/server/shared/Logging/AppenderConsole.cpp
+++ b/src/server/shared/Logging/AppenderConsole.cpp
@@ -15,11 +15,15 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+#include <sstream>
+#if PLATFORM == PLATFORM_WINDOWS
+ #include <windows.h>
+#endif
+
#include "AppenderConsole.h"
#include "Config.h"
#include "Util.h"
-#include <sstream>
AppenderConsole::AppenderConsole(uint8 id, std::string const& name, LogLevel level, AppenderFlags flags):
Appender(id, name, APPENDER_CONSOLE, level, flags), _colored(false)
diff --git a/src/server/shared/Logging/AppenderConsole.h b/src/server/shared/Logging/AppenderConsole.h
index 1aaa74e96ec..b8f15b4fa0f 100644
--- a/src/server/shared/Logging/AppenderConsole.h
+++ b/src/server/shared/Logging/AppenderConsole.h
@@ -18,8 +18,8 @@
#ifndef APPENDERCONSOLE_H
#define APPENDERCONSOLE_H
-#include "Appender.h"
#include <string>
+#include "Appender.h"
enum ColorTypes
{
diff --git a/src/server/shared/Logging/AppenderFile.cpp b/src/server/shared/Logging/AppenderFile.cpp
index f2532ad8bb8..3e79ac40c6f 100644
--- a/src/server/shared/Logging/AppenderFile.cpp
+++ b/src/server/shared/Logging/AppenderFile.cpp
@@ -45,7 +45,7 @@ AppenderFile::~AppenderFile()
void AppenderFile::_write(LogMessage const& message)
{
- bool exceedMaxSize = maxFileSize > 0 && (fileSize.value() + message.Size()) > maxFileSize;
+ bool exceedMaxSize = maxFileSize > 0 && (fileSize.load() + message.Size()) > maxFileSize;
if (dynamicName)
{
diff --git a/src/server/shared/Logging/AppenderFile.h b/src/server/shared/Logging/AppenderFile.h
index 1034b41f665..a600c92d152 100644
--- a/src/server/shared/Logging/AppenderFile.h
+++ b/src/server/shared/Logging/AppenderFile.h
@@ -18,8 +18,8 @@
#ifndef APPENDERFILE_H
#define APPENDERFILE_H
+#include <atomic>
#include "Appender.h"
-#include "ace/Atomic_Op.h"
class AppenderFile: public Appender
{
@@ -38,7 +38,7 @@ class AppenderFile: public Appender
bool dynamicName;
bool backup;
uint64 maxFileSize;
- ACE_Atomic_Op<ACE_Thread_Mutex, uint64> fileSize;
+ std::atomic<uint64> fileSize;
};
#endif
diff --git a/src/server/shared/Logging/Log.cpp b/src/server/shared/Logging/Log.cpp
index dc9bda62bfb..65cf930a634 100644
--- a/src/server/shared/Logging/Log.cpp
+++ b/src/server/shared/Logging/Log.cpp
@@ -29,7 +29,7 @@
#include <cstdio>
#include <sstream>
-Log::Log() : worker(NULL)
+Log::Log() : _ioService(nullptr), _strand(nullptr)
{
m_logsTimestamp = "_" + GetTimestampStr();
LoadFromConfig();
@@ -37,6 +37,7 @@ Log::Log() : worker(NULL)
Log::~Log()
{
+ delete _strand;
Close();
}
@@ -272,8 +273,13 @@ void Log::write(LogMessage* msg) const
Logger const* logger = GetLoggerByType(msg->type);
msg->text.append("\n");
- if (worker)
- worker->enqueue(new LogOperation(logger, msg));
+ if (_ioService)
+ {
+ auto logOperation = std::shared_ptr<LogOperation>(new LogOperation(logger, msg));
+
+ _ioService->post(_strand->wrap([logOperation](){ logOperation->call(); }));
+
+ }
else
{
logger->write(*msg);
@@ -283,9 +289,11 @@ void Log::write(LogMessage* msg) const
std::string Log::GetTimestampStr()
{
- time_t t = time(NULL);
- tm aTm;
- ACE_OS::localtime_r(&t, &aTm);
+ time_t tt = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
+
+ std::tm aTm;
+ localtime_r(&tt, &aTm);
+
// YYYY year
// MM month (2 digits 01-12)
// DD day (2 digits 01-31)
@@ -373,8 +381,6 @@ void Log::SetRealmId(uint32 id)
void Log::Close()
{
- delete worker;
- worker = NULL;
loggers.clear();
for (AppenderMap::iterator it = appenders.begin(); it != appenders.end(); ++it)
{
@@ -388,9 +394,6 @@ void Log::LoadFromConfig()
{
Close();
- if (sConfigMgr->GetBoolDefault("Log.Async.Enable", false))
- worker = new LogWorker();
-
AppenderId = 0;
m_logsDir = sConfigMgr->GetStringDefault("LogsDir", "");
if (!m_logsDir.empty())
diff --git a/src/server/shared/Logging/Log.h b/src/server/shared/Logging/Log.h
index a118e6e8773..e739c9eaf4e 100644
--- a/src/server/shared/Logging/Log.h
+++ b/src/server/shared/Logging/Log.h
@@ -22,18 +22,17 @@
#include "Define.h"
#include "Appender.h"
#include "Logger.h"
-#include "LogWorker.h"
+#include <stdarg.h>
+#include <boost/asio/io_service.hpp>
+#include <boost/asio/strand.hpp>
#include <unordered_map>
#include <string>
-#include <ace/Singleton.h>
#define LOGGER_ROOT "root"
class Log
{
- friend class ACE_Singleton<Log, ACE_Thread_Mutex>;
-
typedef std::unordered_map<std::string, Logger> LoggerMap;
private:
@@ -41,6 +40,20 @@ class Log
~Log();
public:
+
+ static Log* instance(boost::asio::io_service* ioService = nullptr)
+ {
+ static Log* instance = new Log();
+
+ if (ioService != nullptr)
+ {
+ instance->_ioService = ioService;
+ instance->_strand = new boost::asio::strand(*ioService);
+ }
+
+ return instance;
+ }
+
void LoadFromConfig();
void Close();
bool ShouldLog(std::string const& type, LogLevel level) const;
@@ -73,7 +86,8 @@ class Log
std::string m_logsDir;
std::string m_logsTimestamp;
- LogWorker* worker;
+ boost::asio::io_service* _ioService;
+ boost::asio::strand* _strand;
};
inline Logger const* Log::GetLoggerByType(std::string const& type) const
@@ -117,7 +131,7 @@ inline void Log::outMessage(std::string const& filter, LogLevel level, const cha
va_end(ap);
}
-#define sLog ACE_Singleton<Log, ACE_Thread_Mutex>::instance()
+#define sLog Log::instance()
#if PLATFORM != PLATFORM_WINDOWS
#define TC_LOG_MESSAGE_BODY(filterType__, level__, ...) \
diff --git a/src/server/shared/Logging/LogWorker.cpp b/src/server/shared/Logging/LogWorker.cpp
deleted file mode 100644
index b0c82b614f4..00000000000
--- a/src/server/shared/Logging/LogWorker.cpp
+++ /dev/null
@@ -1,50 +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/>.
- */
-
-#include "LogWorker.h"
-
-LogWorker::LogWorker()
- : m_queue(HIGH_WATERMARK, LOW_WATERMARK)
-{
- ACE_Task_Base::activate(THR_NEW_LWP | THR_JOINABLE | THR_INHERIT_SCHED, 1);
-}
-
-LogWorker::~LogWorker()
-{
- m_queue.deactivate();
- wait();
-}
-
-int LogWorker::enqueue(LogOperation* op)
-{
- return m_queue.enqueue(op);
-}
-
-int LogWorker::svc()
-{
- while (1)
- {
- LogOperation* request;
- if (m_queue.dequeue(request) == -1)
- break;
-
- request->call();
- delete request;
- }
-
- return 0;
-}
diff --git a/src/server/shared/Logging/LogWorker.h b/src/server/shared/Logging/LogWorker.h
deleted file mode 100644
index 25a57842e08..00000000000
--- a/src/server/shared/Logging/LogWorker.h
+++ /dev/null
@@ -1,47 +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 LOGWORKER_H
-#define LOGWORKER_H
-
-#include "LogOperation.h"
-
-#include <ace/Task.h>
-#include <ace/Activation_Queue.h>
-
-class LogWorker: protected ACE_Task_Base
-{
- public:
- LogWorker();
- ~LogWorker();
-
- typedef ACE_Message_Queue_Ex<LogOperation, ACE_MT_SYNCH> LogMessageQueueType;
-
- enum
- {
- HIGH_WATERMARK = 8 * 1024 * 1024,
- LOW_WATERMARK = 8 * 1024 * 1024
- };
-
- int enqueue(LogOperation *op);
-
- private:
- virtual int svc();
- LogMessageQueueType m_queue;
-};
-
-#endif
diff --git a/src/server/shared/Networking/AsyncAcceptor.h b/src/server/shared/Networking/AsyncAcceptor.h
new file mode 100644
index 00000000000..d056731bb79
--- /dev/null
+++ b/src/server/shared/Networking/AsyncAcceptor.h
@@ -0,0 +1,65 @@
+/*
+* 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 __ASYNCACCEPT_H_
+#define __ASYNCACCEPT_H_
+
+#include <boost/asio.hpp>
+
+using boost::asio::ip::tcp;
+
+template <class T>
+class AsyncAcceptor
+{
+public:
+ AsyncAcceptor(boost::asio::io_service& ioService, std::string bindIp, int port) :
+ _acceptor(ioService, tcp::endpoint(boost::asio::ip::address::from_string(bindIp), port)),
+ _socket(ioService)
+ {
+ AsyncAccept();
+ };
+
+ AsyncAcceptor(boost::asio::io_service& ioService, std::string bindIp, int port, bool tcpNoDelay) :
+ _acceptor(ioService, tcp::endpoint(boost::asio::ip::address::from_string(bindIp), port)),
+ _socket(ioService)
+ {
+ _acceptor.set_option(boost::asio::ip::tcp::no_delay(tcpNoDelay));
+
+ AsyncAccept();
+ };
+
+private:
+ void AsyncAccept()
+ {
+ _acceptor.async_accept(_socket, [this](boost::system::error_code error)
+ {
+ if (!error)
+ {
+ // this-> is required here to fix an segmentation fault in gcc 4.7.2 - reason is lambdas in a templated class
+ std::make_shared<T>(std::move(this->_socket))->Start();
+ }
+
+ // lets slap some more this-> on this so we can fix this bug with gcc 4.7.2 throwing internals in yo face
+ this->AsyncAccept();
+ });
+ }
+
+ tcp::acceptor _acceptor;
+ tcp::socket _socket;
+};
+
+#endif /* __ASYNCACCEPT_H_ */
diff --git a/src/server/shared/Packets/ByteBuffer.cpp b/src/server/shared/Packets/ByteBuffer.cpp
index f446592e922..0a911492f85 100644
--- a/src/server/shared/Packets/ByteBuffer.cpp
+++ b/src/server/shared/Packets/ByteBuffer.cpp
@@ -20,7 +20,6 @@
#include "Common.h"
#include "Log.h"
-#include <ace/Stack_Trace.h>
#include <sstream>
ByteBufferPositionException::ByteBufferPositionException(bool add, size_t pos,
diff --git a/src/server/shared/Packets/ByteBuffer.h b/src/server/shared/Packets/ByteBuffer.h
index 418f6677e76..ba4894fc32e 100644
--- a/src/server/shared/Packets/ByteBuffer.h
+++ b/src/server/shared/Packets/ByteBuffer.h
@@ -22,8 +22,8 @@
#include "Define.h"
#include "Errors.h"
#include "ByteConverter.h"
+#include "Util.h"
-#include <ace/OS_NS_time.h>
#include <exception>
#include <list>
#include <map>
@@ -604,7 +604,7 @@ class ByteBuffer
void AppendPackedTime(time_t time)
{
tm lt;
- ACE_OS::localtime_r(&time, &lt);
+ localtime_r(&time, &lt);
append<uint32>((lt.tm_year - 100) << 24 | lt.tm_mon << 20 | (lt.tm_mday - 1) << 14 | lt.tm_wday << 11 | lt.tm_hour << 6 | lt.tm_min);
}
diff --git a/src/server/shared/Threading/Callback.h b/src/server/shared/Threading/Callback.h
index c48546bbf5c..b462fce25d5 100644
--- a/src/server/shared/Threading/Callback.h
+++ b/src/server/shared/Threading/Callback.h
@@ -18,17 +18,14 @@
#ifndef _CALLBACK_H
#define _CALLBACK_H
-#include <ace/Future.h>
-#include <ace/Future_Set.h>
+#include <future>
#include "QueryResult.h"
-typedef ACE_Future<QueryResult> QueryResultFuture;
-typedef ACE_Future<PreparedQueryResult> PreparedQueryResultFuture;
+typedef std::future<QueryResult> QueryResultFuture;
+typedef std::promise<QueryResult> QueryResultPromise;
+typedef std::future<PreparedQueryResult> PreparedQueryResultFuture;
+typedef std::promise<PreparedQueryResult> PreparedQueryResultPromise;
-/*! A simple template using ACE_Future to manage callbacks from the thread and object that
- issued the request. <ParamType> is variable type of parameter that is used as parameter
- for the callback function.
-*/
#define CALLBACK_STAGE_INVALID uint8(-1)
template <typename Result, typename ParamType, bool chain = false>
@@ -38,29 +35,29 @@ class QueryCallback
QueryCallback() : _param(), _stage(chain ? 0 : CALLBACK_STAGE_INVALID) { }
//! The parameter of this function should be a resultset returned from either .AsyncQuery or .AsyncPQuery
- void SetFutureResult(ACE_Future<Result> value)
+ void SetFutureResult(std::future<Result> value)
{
- _result = value;
+ _result = std::move(value);
}
- ACE_Future<Result> GetFutureResult()
+ std::future<Result>& GetFutureResult()
{
return _result;
}
int IsReady()
{
- return _result.ready();
+ return _result.valid() && _result.wait_for(std::chrono::seconds(0)) == std::future_status::ready;
}
void GetResult(Result& res)
{
- _result.get(res);
+ res = _result.get();
}
void FreeResult()
{
- _result.cancel();
+ // Nothing to do here, the constructor of std::future will take care of the cleanup
}
void SetParam(ParamType value)
@@ -106,7 +103,7 @@ class QueryCallback
}
private:
- ACE_Future<Result> _result;
+ std::future<Result> _result;
ParamType _param;
uint8 _stage;
@@ -121,29 +118,29 @@ class QueryCallback_2
QueryCallback_2() : _stage(chain ? 0 : CALLBACK_STAGE_INVALID) { }
//! The parameter of this function should be a resultset returned from either .AsyncQuery or .AsyncPQuery
- void SetFutureResult(ACE_Future<Result> value)
+ void SetFutureResult(std::future<Result> value)
{
- _result = value;
+ _result = std::move(value);
}
- ACE_Future<Result> GetFutureResult()
+ std::future<Result>& GetFutureResult()
{
return _result;
}
int IsReady()
{
- return _result.ready();
+ return _result.valid() && _result.wait_for(std::chrono::seconds(0)) == std::future_status::ready;
}
void GetResult(Result& res)
{
- _result.get(res);
+ res = _result.get();
}
void FreeResult()
{
- _result.cancel();
+ // Nothing to do here, the constructor of std::future will take care of the cleanup
}
void SetFirstParam(ParamType1 value)
@@ -200,7 +197,7 @@ class QueryCallback_2
}
private:
- ACE_Future<Result> _result;
+ std::future<Result> _result;
ParamType1 _param_1;
ParamType2 _param_2;
uint8 _stage;
@@ -209,4 +206,4 @@ class QueryCallback_2
QueryCallback_2& operator=(QueryCallback_2 const& right) = delete;
};
-#endif \ No newline at end of file
+#endif
diff --git a/src/server/shared/Threading/DelayExecutor.cpp b/src/server/shared/Threading/DelayExecutor.cpp
deleted file mode 100644
index ba8a19429b2..00000000000
--- a/src/server/shared/Threading/DelayExecutor.cpp
+++ /dev/null
@@ -1,109 +0,0 @@
-#include <ace/Singleton.h>
-#include <ace/Thread_Mutex.h>
-#include <ace/Log_Msg.h>
-
-#include "DelayExecutor.h"
-
-DelayExecutor* DelayExecutor::instance()
-{
- return ACE_Singleton<DelayExecutor, ACE_Thread_Mutex>::instance();
-}
-
-DelayExecutor::DelayExecutor()
- : pre_svc_hook_(0), post_svc_hook_(0), activated_(false) { }
-
-DelayExecutor::~DelayExecutor()
-{
- if (pre_svc_hook_)
- delete pre_svc_hook_;
-
- if (post_svc_hook_)
- delete post_svc_hook_;
-
- deactivate();
-}
-
-int DelayExecutor::deactivate()
-{
- if (!activated())
- return -1;
-
- activated(false);
- queue_.queue()->deactivate();
- wait();
-
- return 0;
-}
-
-int DelayExecutor::svc()
-{
- if (pre_svc_hook_)
- pre_svc_hook_->call();
-
- for (;;)
- {
- ACE_Method_Request* rq = queue_.dequeue();
-
- if (!rq)
- break;
-
- rq->call();
- delete rq;
- }
-
- if (post_svc_hook_)
- post_svc_hook_->call();
-
- return 0;
-}
-
-int DelayExecutor::start(int num_threads, ACE_Method_Request* pre_svc_hook, ACE_Method_Request* post_svc_hook)
-{
- if (activated())
- return -1;
-
- if (num_threads < 1)
- return -1;
-
- if (pre_svc_hook_)
- delete pre_svc_hook_;
-
- if (post_svc_hook_)
- delete post_svc_hook_;
-
- pre_svc_hook_ = pre_svc_hook;
- post_svc_hook_ = post_svc_hook;
-
- queue_.queue()->activate();
-
- if (ACE_Task_Base::activate(THR_NEW_LWP | THR_JOINABLE | THR_INHERIT_SCHED, num_threads) == -1)
- return -1;
-
- activated(true);
-
- return true;
-}
-
-int DelayExecutor::execute(ACE_Method_Request* new_req)
-{
- if (new_req == NULL)
- return -1;
-
- if (queue_.enqueue(new_req, (ACE_Time_Value*)&ACE_Time_Value::zero) == -1)
- {
- delete new_req;
- ACE_ERROR_RETURN((LM_ERROR, ACE_TEXT("(%t) %p\n"), ACE_TEXT("DelayExecutor::execute enqueue")), -1);
- }
-
- return 0;
-}
-
-bool DelayExecutor::activated()
-{
- return activated_;
-}
-
-void DelayExecutor::activated(bool s)
-{
- activated_ = s;
-}
diff --git a/src/server/shared/Threading/DelayExecutor.h b/src/server/shared/Threading/DelayExecutor.h
deleted file mode 100644
index 5eaaacdb98b..00000000000
--- a/src/server/shared/Threading/DelayExecutor.h
+++ /dev/null
@@ -1,37 +0,0 @@
-#ifndef _M_DELAY_EXECUTOR_H
-#define _M_DELAY_EXECUTOR_H
-
-#include <ace/Task.h>
-#include <ace/Activation_Queue.h>
-#include <ace/Method_Request.h>
-
-class DelayExecutor : protected ACE_Task_Base
-{
- public:
-
- DelayExecutor();
- virtual ~DelayExecutor();
-
- static DelayExecutor* instance();
-
- int execute(ACE_Method_Request* new_req);
-
- int start(int num_threads = 1, ACE_Method_Request* pre_svc_hook = NULL, ACE_Method_Request* post_svc_hook = NULL);
-
- int deactivate();
-
- bool activated();
-
- virtual int svc();
-
- private:
-
- ACE_Activation_Queue queue_;
- ACE_Method_Request* pre_svc_hook_;
- ACE_Method_Request* post_svc_hook_;
- bool activated_;
-
- void activated(bool s);
-};
-
-#endif // _M_DELAY_EXECUTOR_H
diff --git a/src/server/shared/Threading/LockedQueue.h b/src/server/shared/Threading/LockedQueue.h
index 5709724c9a2..bbd60cb7760 100644
--- a/src/server/shared/Threading/LockedQueue.h
+++ b/src/server/shared/Threading/LockedQueue.h
@@ -19,140 +19,126 @@
#ifndef LOCKEDQUEUE_H
#define LOCKEDQUEUE_H
-#include <ace/Guard_T.h>
-#include <ace/Thread_Mutex.h>
#include <deque>
-#include <assert.h>
-#include "Debugging/Errors.h"
+#include <mutex>
-namespace ACE_Based
+template <class T, typename StorageType = std::deque<T> >
+class LockedQueue
{
- template <class T, class LockType, typename StorageType=std::deque<T> >
- class LockedQueue
+ //! Lock access to the queue.
+ std::mutex _lock;
+
+ //! Storage backing the queue.
+ StorageType _queue;
+
+ //! Cancellation flag.
+ volatile bool _canceled;
+
+public:
+
+ //! Create a LockedQueue.
+ LockedQueue()
+ : _canceled(false)
{
- //! Lock access to the queue.
- LockType _lock;
+ }
- //! Storage backing the queue.
- StorageType _queue;
+ //! Destroy a LockedQueue.
+ virtual ~LockedQueue()
+ {
+ }
- //! Cancellation flag.
- volatile bool _canceled;
+ //! Adds an item to the queue.
+ void add(const T& item)
+ {
+ lock();
+
+ _queue.push_back(item);
- public:
+ unlock();
+ }
+
+ //! Gets the next result in the queue, if any.
+ bool next(T& result)
+ {
+ std::lock_guard<std::mutex> lock(_lock);
- //! Create a LockedQueue.
- LockedQueue()
- : _canceled(false)
- {
- }
+ if (_queue.empty())
+ return false;
- //! Destroy a LockedQueue.
- virtual ~LockedQueue()
- {
- }
-
- //! Adds an item to the queue.
- void add(const T& item)
- {
- lock();
-
- //ASSERT(!this->_canceled);
- // throw Cancellation_Exception();
-
- _queue.push_back(item);
-
- unlock();
- }
-
- //! Gets the next result in the queue, if any.
- bool next(T& result)
- {
- // ACE_Guard<LockType> g(this->_lock);
- ACE_GUARD_RETURN (LockType, g, this->_lock, false);
-
- if (_queue.empty())
- return false;
-
- //ASSERT (!_queue.empty() || !this->_canceled);
- // throw Cancellation_Exception();
- result = _queue.front();
- _queue.pop_front();
-
- return true;
- }
-
- template<class Checker>
- bool next(T& result, Checker& check)
- {
- ACE_Guard<LockType> g(this->_lock);
-
- if (_queue.empty())
- return false;
-
- result = _queue.front();
- if (!check.Process(result))
- return false;
-
- _queue.pop_front();
- return true;
- }
-
- //! Peeks at the top of the queue. Check if the queue is empty before calling! Remember to unlock after use if autoUnlock == false.
- T& peek(bool autoUnlock = false)
- {
- lock();
-
- T& result = _queue.front();
-
- if (autoUnlock)
- unlock();
-
- return result;
- }
-
- //! Cancels the queue.
- void cancel()
- {
- lock();
-
- _canceled = true;
-
- unlock();
- }
-
- //! Checks if the queue is cancelled.
- bool cancelled()
- {
- ACE_Guard<LockType> g(this->_lock);
- return _canceled;
- }
-
- //! Locks the queue for access.
- void lock()
- {
- this->_lock.acquire();
- }
-
- //! Unlocks the queue.
- void unlock()
- {
- this->_lock.release();
- }
-
- ///! Calls pop_front of the queue
- void pop_front()
- {
- ACE_GUARD (LockType, g, this->_lock);
- _queue.pop_front();
- }
-
- ///! Checks if we're empty or not with locks held
- bool empty()
- {
- ACE_GUARD_RETURN (LockType, g, this->_lock, false);
- return _queue.empty();
- }
- };
-}
+ result = _queue.front();
+ _queue.pop_front();
+
+ return true;
+ }
+
+ template<class Checker>
+ bool next(T& result, Checker& check)
+ {
+ std::lock_guard<std::mutex> lock(_lock);
+
+ if (_queue.empty())
+ return false;
+
+ result = _queue.front();
+ if (!check.Process(result))
+ return false;
+
+ _queue.pop_front();
+ return true;
+ }
+
+ //! Peeks at the top of the queue. Check if the queue is empty before calling! Remember to unlock after use if autoUnlock == false.
+ T& peek(bool autoUnlock = false)
+ {
+ lock();
+
+ T& result = _queue.front();
+
+ if (autoUnlock)
+ unlock();
+
+ return result;
+ }
+
+ //! Cancels the queue.
+ void cancel()
+ {
+ std::lock_guard<std::mutex> lock(_lock);
+
+ _canceled = true;
+ }
+
+ //! Checks if the queue is cancelled.
+ bool cancelled()
+ {
+ std::lock_guard<std::mutex> lock(_lock);
+ return _canceled;
+ }
+
+ //! Locks the queue for access.
+ void lock()
+ {
+ this->_lock.lock();
+ }
+
+ //! Unlocks the queue.
+ void unlock()
+ {
+ this->_lock.unlock();
+ }
+
+ ///! Calls pop_front of the queue
+ void pop_front()
+ {
+ std::lock_guard<std::mutex> lock(_lock);
+ _queue.pop_front();
+ }
+
+ ///! Checks if we're empty or not with locks held
+ bool empty()
+ {
+ std::lock_guard<std::mutex> lock(_lock);
+ return _queue.empty();
+ }
+};
#endif
diff --git a/src/server/shared/Threading/ProcessPriority.h b/src/server/shared/Threading/ProcessPriority.h
new file mode 100644
index 00000000000..cd116ccbbc8
--- /dev/null
+++ b/src/server/shared/Threading/ProcessPriority.h
@@ -0,0 +1,100 @@
+/*
+* 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 _PROCESSPRIO_H
+#define _PROCESSPRIO_H
+
+#include "Configuration/Config.h"
+
+#ifdef __linux__
+#include <sched.h>
+#include <sys/resource.h>
+#define PROCESS_HIGH_PRIORITY -15 // [-20, 19], default is 0
+#endif
+
+void SetProcessPriority(const std::string logChannel)
+{
+#if defined(_WIN32) || defined(__linux__)
+
+ ///- Handle affinity for multiple processors and process priority
+ uint32 affinity = sConfigMgr->GetIntDefault("UseProcessors", 0);
+ bool highPriority = sConfigMgr->GetBoolDefault("ProcessPriority", false);
+
+#ifdef _WIN32 // Windows
+
+ HANDLE hProcess = GetCurrentProcess();
+ if (affinity > 0)
+ {
+ ULONG_PTR appAff;
+ ULONG_PTR sysAff;
+
+ if (GetProcessAffinityMask(hProcess, &appAff, &sysAff))
+ {
+ // remove non accessible processors
+ ULONG_PTR currentAffinity = affinity & appAff;
+
+ if (!currentAffinity)
+ TC_LOG_ERROR(logChannel, "Processors marked in UseProcessors bitmask (hex) %x are not accessible. Accessible processors bitmask (hex): %x", affinity, appAff);
+ else if (SetProcessAffinityMask(hProcess, currentAffinity))
+ TC_LOG_INFO(logChannel, "Using processors (bitmask, hex): %x", currentAffinity);
+ else
+ TC_LOG_ERROR(logChannel, "Can't set used processors (hex): %x", currentAffinity);
+ }
+ }
+
+ if (highPriority)
+ {
+ if (SetPriorityClass(hProcess, HIGH_PRIORITY_CLASS))
+ TC_LOG_INFO(logChannel, "Process priority class set to HIGH");
+ else
+ TC_LOG_ERROR(logChannel, "Can't set process priority class.");
+ }
+
+#else // Linux
+
+ if (affinity > 0)
+ {
+ cpu_set_t mask;
+ CPU_ZERO(&mask);
+
+ for (unsigned int i = 0; i < sizeof(affinity) * 8; ++i)
+ if (affinity & (1 << i))
+ CPU_SET(i, &mask);
+
+ if (sched_setaffinity(0, sizeof(mask), &mask))
+ TC_LOG_ERROR(logChannel, "Can't set used processors (hex): %x, error: %s", affinity, strerror(errno));
+ else
+ {
+ CPU_ZERO(&mask);
+ sched_getaffinity(0, sizeof(mask), &mask);
+ TC_LOG_INFO(logChannel, "Using processors (bitmask, hex): %lx", *(__cpu_mask*)(&mask));
+ }
+ }
+
+ if (highPriority)
+ {
+ if (setpriority(PRIO_PROCESS, 0, PROCESS_HIGH_PRIORITY))
+ TC_LOG_ERROR(logChannel, "Can't set process priority class, error: %s", strerror(errno));
+ else
+ TC_LOG_INFO(logChannel, "Process priority class set to %i", getpriority(PRIO_PROCESS, 0));
+ }
+
+#endif
+#endif
+}
+
+#endif
diff --git a/src/server/shared/Threading/ProducerConsumerQueue.h b/src/server/shared/Threading/ProducerConsumerQueue.h
new file mode 100644
index 00000000000..3fefd27ba6e
--- /dev/null
+++ b/src/server/shared/Threading/ProducerConsumerQueue.h
@@ -0,0 +1,111 @@
+/*
+* 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 _PCQ_H
+#define _PCQ_H
+
+#include <condition_variable>
+#include <mutex>
+#include <queue>
+#include <atomic>
+
+template <typename T>
+class ProducerConsumerQueue
+{
+private:
+ std::mutex _queueLock;
+ std::queue<T> _queue;
+ std::condition_variable _condition;
+ std::atomic<bool> _shutdown;
+
+public:
+
+ ProducerConsumerQueue<T>() : _shutdown(false) { }
+
+ void Push(const T& value)
+ {
+ _queueLock.lock();
+
+ _queue.push(std::move(value));
+
+ _queueLock.unlock();
+
+ _condition.notify_one();
+ }
+
+ bool Empty()
+ {
+ std::lock_guard<std::mutex> lock(_queueLock);
+
+ return _queue.empty();
+ }
+
+ bool Pop(T& value)
+ {
+ std::lock_guard<std::mutex> lock(_queueLock);
+
+ if (_queue.empty())
+ return false;
+
+ value = _queue.front();
+
+ _queue.pop();
+
+ return true;
+ }
+
+ void WaitAndPop(T& value)
+ {
+ std::unique_lock<std::mutex> lock(_queueLock);
+
+ while (_queue.empty() && !_shutdown)
+ {
+ _condition.wait(lock);
+ }
+
+ if (_queue.empty())
+ return;
+
+ value = _queue.front();
+
+ _queue.pop();
+ }
+
+ void Cancel()
+ {
+ _queueLock.lock();
+
+ while (!_queue.empty())
+ {
+ T& value = _queue.front();
+
+ delete &value;
+
+ _queue.pop();
+ }
+
+ _shutdown = true;
+
+ _queueLock.unlock();
+
+ _condition.notify_all();
+ }
+};
+
+#endif
+
+
diff --git a/src/server/shared/Threading/Threading.cpp b/src/server/shared/Threading/Threading.cpp
deleted file mode 100644
index f67a985943a..00000000000
--- a/src/server/shared/Threading/Threading.cpp
+++ /dev/null
@@ -1,235 +0,0 @@
-/*
- * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
- * Copyright (C) 2005-2008 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 "Threading.h"
-#include "Errors.h"
-#include <ace/OS_NS_unistd.h>
-#include <ace/Sched_Params.h>
-#include <vector>
-
-using namespace ACE_Based;
-
-ThreadPriority::ThreadPriority()
-{
- for (int i = Idle; i < MAXPRIORITYNUM; ++i)
- m_priority[i] = ACE_THR_PRI_OTHER_DEF;
-
- m_priority[Idle] = ACE_Sched_Params::priority_min(ACE_SCHED_OTHER);
- m_priority[Realtime] = ACE_Sched_Params::priority_max(ACE_SCHED_OTHER);
-
- std::vector<int> _tmp;
-
- ACE_Sched_Params::Policy _policy = ACE_SCHED_OTHER;
- ACE_Sched_Priority_Iterator pr_iter(_policy);
-
- while (pr_iter.more())
- {
- _tmp.push_back(pr_iter.priority());
- pr_iter.next();
- }
-
- ASSERT (!_tmp.empty());
-
- if (_tmp.size() >= MAXPRIORITYNUM)
- {
- const size_t max_pos = _tmp.size();
- size_t min_pos = 1;
- size_t norm_pos = 0;
- for (size_t i = 0; i < max_pos; ++i)
- {
- if (_tmp[i] == ACE_THR_PRI_OTHER_DEF)
- {
- norm_pos = i + 1;
- break;
- }
- }
-
- // since we have only 7(seven) values in enum Priority
- // and 3 we know already (Idle, Normal, Realtime) so
- // we need to split each list [Idle...Normal] and [Normal...Realtime]
- // into pieces
- const size_t _divider = 4;
- size_t _div = (norm_pos - min_pos) / _divider;
- if (_div == 0)
- _div = 1;
-
- min_pos = (norm_pos - 1);
-
- m_priority[Low] = _tmp[min_pos -= _div];
- m_priority[Lowest] = _tmp[min_pos -= _div ];
-
- _div = (max_pos - norm_pos) / _divider;
- if (_div == 0)
- _div = 1;
-
- min_pos = norm_pos - 1;
-
- m_priority[High] = _tmp[min_pos += _div];
- m_priority[Highest] = _tmp[min_pos += _div];
- }
-}
-
-int ThreadPriority::getPriority(Priority p) const
-{
- if (p < Idle)
- p = Idle;
-
- if (p > Realtime)
- p = Realtime;
-
- return m_priority[p];
-}
-
-#define THREADFLAG (THR_NEW_LWP | THR_SCHED_DEFAULT| THR_JOINABLE)
-
-Thread::Thread(): m_iThreadId(0), m_hThreadHandle(0), m_task(0)
-{
-
-}
-
-Thread::Thread(Runnable* instance): m_iThreadId(0), m_hThreadHandle(0), m_task(instance)
-{
- // register reference to m_task to prevent it deeltion until destructor
- if (m_task)
- m_task->incReference();
-
- bool _start = start();
- ASSERT (_start);
-}
-
-Thread::~Thread()
-{
- //Wait();
-
- // deleted runnable object (if no other references)
- if (m_task)
- m_task->decReference();
-}
-
-//initialize Thread's class static member
-Thread::ThreadStorage Thread::m_ThreadStorage;
-ThreadPriority Thread::m_TpEnum;
-
-bool Thread::start()
-{
- if (m_task == 0 || m_iThreadId != 0)
- return false;
-
- // incRef before spawing the thread, otherwise Thread::ThreadTask() might call decRef and delete m_task
- m_task->incReference();
-
- bool res = (ACE_Thread::spawn(&Thread::ThreadTask, (void*)m_task, THREADFLAG, &m_iThreadId, &m_hThreadHandle) == 0);
-
- if (!res)
- m_task->decReference();
-
- return res;
-}
-
-bool Thread::wait()
-{
- if (!m_hThreadHandle || !m_task)
- return false;
-
- ACE_THR_FUNC_RETURN _value = ACE_THR_FUNC_RETURN(-1);
- int _res = ACE_Thread::join(m_hThreadHandle, &_value);
-
- m_iThreadId = 0;
- m_hThreadHandle = 0;
-
- return (_res == 0);
-}
-
-void Thread::destroy()
-{
- if (!m_iThreadId || !m_task)
- return;
-
- if (ACE_Thread::kill(m_iThreadId, -1) != 0)
- return;
-
- m_iThreadId = 0;
- m_hThreadHandle = 0;
-
- // reference set at ACE_Thread::spawn
- m_task->decReference();
-}
-
-void Thread::suspend()
-{
- ACE_Thread::suspend(m_hThreadHandle);
-}
-
-void Thread::resume()
-{
- ACE_Thread::resume(m_hThreadHandle);
-}
-
-ACE_THR_FUNC_RETURN Thread::ThreadTask(void * param)
-{
- Runnable* _task = (Runnable*)param;
- _task->run();
-
- // task execution complete, free referecne added at
- _task->decReference();
-
- return (ACE_THR_FUNC_RETURN)0;
-}
-
-ACE_thread_t Thread::currentId()
-{
- return ACE_Thread::self();
-}
-
-ACE_hthread_t Thread::currentHandle()
-{
- ACE_hthread_t _handle;
- ACE_Thread::self(_handle);
-
- return _handle;
-}
-
-Thread * Thread::current()
-{
- Thread * _thread = m_ThreadStorage.ts_object();
- if (!_thread)
- {
- _thread = new Thread();
- _thread->m_iThreadId = Thread::currentId();
- _thread->m_hThreadHandle = Thread::currentHandle();
-
- Thread * _oldValue = m_ThreadStorage.ts_object(_thread);
- if (_oldValue)
- delete _oldValue;
- }
-
- return _thread;
-}
-
-void Thread::setPriority(Priority type)
-{
- int _priority = m_TpEnum.getPriority(type);
- int _ok = ACE_Thread::setprio(m_hThreadHandle, _priority);
- //remove this ASSERT in case you don't want to know is thread priority change was successful or not
- ASSERT (_ok == 0);
-}
-
-void Thread::Sleep(unsigned long msecs)
-{
- ACE_OS::sleep(ACE_Time_Value(0, 1000 * msecs));
-}
diff --git a/src/server/shared/Threading/Threading.h b/src/server/shared/Threading/Threading.h
deleted file mode 100644
index 9d416109e9f..00000000000
--- a/src/server/shared/Threading/Threading.h
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
- * Copyright (C) 2005-2008 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 THREADING_H
-#define THREADING_H
-
-#include <ace/Thread.h>
-#include <ace/TSS_T.h>
-#include <ace/Atomic_Op.h>
-#include <assert.h>
-
-namespace ACE_Based
-{
-
- class Runnable
- {
- public:
- virtual ~Runnable() { }
- virtual void run() = 0;
-
- void incReference() { ++m_refs; }
- void decReference()
- {
- if (!--m_refs)
- delete this;
- }
- private:
- ACE_Atomic_Op<ACE_Thread_Mutex, long> m_refs;
- };
-
- enum Priority
- {
- Idle,
- Lowest,
- Low,
- Normal,
- High,
- Highest,
- Realtime
- };
-
-#define MAXPRIORITYNUM (Realtime + 1)
-
- class ThreadPriority
- {
- public:
- ThreadPriority();
- int getPriority(Priority p) const;
-
- private:
- int m_priority[MAXPRIORITYNUM];
- };
-
- class Thread
- {
- public:
- Thread();
- explicit Thread(Runnable* instance);
- ~Thread();
-
- bool start();
- bool wait();
- void destroy();
-
- void suspend();
- void resume();
-
- void setPriority(Priority type);
-
- static void Sleep(unsigned long msecs);
- static ACE_thread_t currentId();
- static ACE_hthread_t currentHandle();
- static Thread * current();
-
- private:
- Thread(const Thread&);
- Thread& operator=(const Thread&);
-
- static ACE_THR_FUNC_RETURN ThreadTask(void * param);
-
- ACE_thread_t m_iThreadId;
- ACE_hthread_t m_hThreadHandle;
- Runnable* m_task;
-
- typedef ACE_TSS<Thread> ThreadStorage;
- //global object - container for Thread class representation of every thread
- static ThreadStorage m_ThreadStorage;
- //use this object to determine current OS thread priority values mapped to enum Priority{ }
- static ThreadPriority m_TpEnum;
- };
-
-}
-#endif
diff --git a/src/server/shared/Utilities/ServiceWin32.cpp b/src/server/shared/Utilities/ServiceWin32.cpp
index ec472b33f40..f4a0339d9e6 100644
--- a/src/server/shared/Utilities/ServiceWin32.cpp
+++ b/src/server/shared/Utilities/ServiceWin32.cpp
@@ -60,7 +60,7 @@ bool WinServiceInstall()
if (GetModuleFileName( 0, path, sizeof(path)/sizeof(path[0]) ) > 0)
{
SC_HANDLE service;
- std::strcat(path, " --service");
+ std::strcat(path, " --service run");
service = CreateService(serviceControlManager,
serviceName, // name of service
serviceLongName, // service name to display
@@ -119,6 +119,8 @@ bool WinServiceInstall()
}
CloseServiceHandle(serviceControlManager);
}
+
+ printf("Service installed\n");
return true;
}
@@ -143,6 +145,8 @@ bool WinServiceUninstall()
CloseServiceHandle(serviceControlManager);
}
+
+ printf("Service uninstalled\n");
return true;
}
diff --git a/src/server/shared/Utilities/SignalHandler.h b/src/server/shared/Utilities/SignalHandler.h
deleted file mode 100644
index 41e867c3d1a..00000000000
--- a/src/server/shared/Utilities/SignalHandler.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
- * Copyright (C) 2005-2010 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 __SIGNAL_HANDLER_H__
-#define __SIGNAL_HANDLER_H__
-
-#include <ace/Event_Handler.h>
-
-namespace Trinity
-{
-
-/// Handle termination signals
-class SignalHandler : public ACE_Event_Handler
-{
- public:
- int handle_signal(int SigNum, siginfo_t* = NULL, ucontext_t* = NULL)
- {
- HandleSignal(SigNum);
- return 0;
- }
- virtual void HandleSignal(int /*SigNum*/) { };
-};
-
-}
-
-#endif /* __SIGNAL_HANDLER_H__ */
diff --git a/src/server/shared/Utilities/Timer.h b/src/server/shared/Utilities/Timer.h
index c809a59c20f..7c62de5f5ed 100644
--- a/src/server/shared/Utilities/Timer.h
+++ b/src/server/shared/Utilities/Timer.h
@@ -19,13 +19,15 @@
#ifndef TRINITY_TIMER_H
#define TRINITY_TIMER_H
-#include "ace/OS_NS_sys_time.h"
-#include "Common.h"
+#include <chrono>
+
+using namespace std::chrono;
inline uint32 getMSTime()
{
- static const ACE_Time_Value ApplicationStartTime = ACE_OS::gettimeofday();
- return (ACE_OS::gettimeofday() - ApplicationStartTime).msec();
+ static const system_clock::time_point ApplicationStartTime = system_clock::now();
+
+ return duration_cast<milliseconds>(system_clock::now() - ApplicationStartTime).count();
}
inline uint32 getMSTimeDiff(uint32 oldMSTime, uint32 newMSTime)
@@ -44,158 +46,158 @@ inline uint32 GetMSTimeDiffToNow(uint32 oldMSTime)
struct IntervalTimer
{
- public:
-
- IntervalTimer()
- : _interval(0), _current(0)
- {
- }
-
- void Update(time_t diff)
- {
- _current += diff;
- if (_current < 0)
- _current = 0;
- }
-
- bool Passed()
- {
- return _current >= _interval;
- }
-
- void Reset()
- {
- if (_current >= _interval)
- _current %= _interval;
- }
-
- void SetCurrent(time_t current)
- {
- _current = current;
- }
-
- void SetInterval(time_t interval)
- {
- _interval = interval;
- }
-
- time_t GetInterval() const
- {
- return _interval;
- }
-
- time_t GetCurrent() const
- {
- return _current;
- }
-
- private:
-
- time_t _interval;
- time_t _current;
+public:
+
+ IntervalTimer()
+ : _interval(0), _current(0)
+ {
+ }
+
+ void Update(time_t diff)
+ {
+ _current += diff;
+ if (_current < 0)
+ _current = 0;
+ }
+
+ bool Passed()
+ {
+ return _current >= _interval;
+ }
+
+ void Reset()
+ {
+ if (_current >= _interval)
+ _current %= _interval;
+ }
+
+ void SetCurrent(time_t current)
+ {
+ _current = current;
+ }
+
+ void SetInterval(time_t interval)
+ {
+ _interval = interval;
+ }
+
+ time_t GetInterval() const
+ {
+ return _interval;
+ }
+
+ time_t GetCurrent() const
+ {
+ return _current;
+ }
+
+private:
+
+ time_t _interval;
+ time_t _current;
};
struct TimeTracker
{
- public:
+public:
- TimeTracker(time_t expiry)
- : i_expiryTime(expiry)
- {
- }
+ TimeTracker(time_t expiry)
+ : i_expiryTime(expiry)
+ {
+ }
- void Update(time_t diff)
- {
- i_expiryTime -= diff;
- }
+ void Update(time_t diff)
+ {
+ i_expiryTime -= diff;
+ }
- bool Passed() const
- {
- return i_expiryTime <= 0;
- }
+ bool Passed() const
+ {
+ return i_expiryTime <= 0;
+ }
- void Reset(time_t interval)
- {
- i_expiryTime = interval;
- }
+ void Reset(time_t interval)
+ {
+ i_expiryTime = interval;
+ }
- time_t GetExpiry() const
- {
- return i_expiryTime;
- }
+ time_t GetExpiry() const
+ {
+ return i_expiryTime;
+ }
- private:
+private:
- time_t i_expiryTime;
+ time_t i_expiryTime;
};
struct TimeTrackerSmall
{
- public:
+public:
- TimeTrackerSmall(uint32 expiry = 0)
- : i_expiryTime(expiry)
- {
- }
+ TimeTrackerSmall(uint32 expiry = 0)
+ : i_expiryTime(expiry)
+ {
+ }
- void Update(int32 diff)
- {
- i_expiryTime -= diff;
- }
+ void Update(int32 diff)
+ {
+ i_expiryTime -= diff;
+ }
- bool Passed() const
- {
- return i_expiryTime <= 0;
- }
+ bool Passed() const
+ {
+ return i_expiryTime <= 0;
+ }
- void Reset(uint32 interval)
- {
- i_expiryTime = interval;
- }
+ void Reset(uint32 interval)
+ {
+ i_expiryTime = interval;
+ }
- int32 GetExpiry() const
- {
- return i_expiryTime;
- }
+ int32 GetExpiry() const
+ {
+ return i_expiryTime;
+ }
- private:
+private:
- int32 i_expiryTime;
+ int32 i_expiryTime;
};
struct PeriodicTimer
{
- public:
+public:
- PeriodicTimer(int32 period, int32 start_time)
- : i_period(period), i_expireTime(start_time)
- {
- }
+ PeriodicTimer(int32 period, int32 start_time)
+ : i_period(period), i_expireTime(start_time)
+ {
+ }
- bool Update(const uint32 diff)
- {
- if ((i_expireTime -= diff) > 0)
- return false;
+ bool Update(const uint32 diff)
+ {
+ if ((i_expireTime -= diff) > 0)
+ return false;
- i_expireTime += i_period > int32(diff) ? i_period : diff;
- return true;
- }
+ i_expireTime += i_period > int32(diff) ? i_period : diff;
+ return true;
+ }
- void SetPeriodic(int32 period, int32 start_time)
- {
- i_expireTime = start_time;
- i_period = period;
- }
+ void SetPeriodic(int32 period, int32 start_time)
+ {
+ i_expireTime = start_time;
+ i_period = period;
+ }
- // Tracker interface
- void TUpdate(int32 diff) { i_expireTime -= diff; }
- bool TPassed() const { return i_expireTime <= 0; }
- void TReset(int32 diff, int32 period) { i_expireTime += period > diff ? period : diff; }
+ // Tracker interface
+ void TUpdate(int32 diff) { i_expireTime -= diff; }
+ bool TPassed() const { return i_expireTime <= 0; }
+ void TReset(int32 diff, int32 period) { i_expireTime += period > diff ? period : diff; }
- private:
+private:
- int32 i_period;
- int32 i_expireTime;
+ int32 i_period;
+ int32 i_expireTime;
};
#endif
diff --git a/src/server/shared/Utilities/Util.cpp b/src/server/shared/Utilities/Util.cpp
index 4c54492f5ad..a68d836252d 100644
--- a/src/server/shared/Utilities/Util.cpp
+++ b/src/server/shared/Utilities/Util.cpp
@@ -21,42 +21,54 @@
#include "utf8.h"
#include "SFMT.h"
#include "Errors.h" // for ASSERT
-#include <ace/TSS_T.h>
+#include <boost/thread/tss.hpp>
-typedef ACE_TSS<SFMTRand> SFMTRandTSS;
-static SFMTRandTSS sfmtRand;
+static boost::thread_specific_ptr<SFMTRand> sfmtRand;
+
+static SFMTRand* GetRng()
+{
+ SFMTRand* rand = sfmtRand.get();
+
+ if (!rand)
+ {
+ rand = new SFMTRand();
+ sfmtRand.reset(rand);
+ }
+
+ return rand;
+}
int32 irand(int32 min, int32 max)
{
ASSERT(max >= min);
- return int32(sfmtRand->IRandom(min, max));
+ return int32(GetRng()->IRandom(min, max));
}
uint32 urand(uint32 min, uint32 max)
{
ASSERT(max >= min);
- return sfmtRand->URandom(min, max);
+ return GetRng()->URandom(min, max);
}
float frand(float min, float max)
{
ASSERT(max >= min);
- return float(sfmtRand->Random() * (max - min) + min);
+ return float(GetRng()->Random() * (max - min) + min);
}
int32 rand32()
{
- return int32(sfmtRand->BRandom());
+ return int32(GetRng()->BRandom());
}
double rand_norm(void)
{
- return sfmtRand->Random();
+ return GetRng()->Random();
}
double rand_chance(void)
{
- return sfmtRand->Random() * 100.0;
+ return GetRng()->Random() * 100.0;
}
Tokenizer::Tokenizer(const std::string &src, const char sep, uint32 vectorReserve)
@@ -127,6 +139,14 @@ void stripLineInvisibleChars(std::string &str)
}
+#if (defined(WIN32) || defined(_WIN32) || defined(__WIN32__))
+struct tm* localtime_r(const time_t* time, struct tm *result)
+{
+ localtime_s(result, time);
+ return result;
+}
+#endif
+
std::string secsToTimeString(uint64 timeInSecs, bool shortText, bool hoursOnly)
{
uint64 secs = timeInSecs % MINUTE;
@@ -216,7 +236,7 @@ uint32 TimeStringToSecs(const std::string& timestring)
std::string TimeToTimestampStr(time_t t)
{
tm aTm;
- ACE_OS::localtime_r(&t, &aTm);
+ localtime_r(&t, &aTm);
// YYYY year
// MM month (2 digits 01-12)
// DD day (2 digits 01-31)
@@ -239,21 +259,6 @@ bool IsIPAddress(char const* ipaddress)
return inet_addr(ipaddress) != INADDR_NONE;
}
-std::string GetAddressString(ACE_INET_Addr const& addr)
-{
- char buf[ACE_MAX_FULLY_QUALIFIED_NAME_LEN + 16];
- addr.addr_to_string(buf, ACE_MAX_FULLY_QUALIFIED_NAME_LEN + 16);
- return buf;
-}
-
-bool IsIPAddrInNetwork(ACE_INET_Addr const& net, ACE_INET_Addr const& addr, ACE_INET_Addr const& subnetMask)
-{
- uint32 mask = subnetMask.get_ip_address();
- if ((net.get_ip_address() & mask) == (addr.get_ip_address() & mask))
- return true;
- return false;
-}
-
/// create PID file
uint32 CreatePIDFile(const std::string& filename)
{
diff --git a/src/server/shared/Utilities/Util.h b/src/server/shared/Utilities/Util.h
index 538264c9cfe..6fc5dcfdc2b 100644
--- a/src/server/shared/Utilities/Util.h
+++ b/src/server/shared/Utilities/Util.h
@@ -27,7 +27,6 @@
#include <vector>
#include <list>
#include <map>
-#include <ace/INET_Addr.h>
// Searcher for map of structs
template<typename T, class S> struct Finder
@@ -71,6 +70,8 @@ void stripLineInvisibleChars(std::string &src);
int64 MoneyStringToMoney(const std::string& moneyString);
+struct tm* localtime_r(const time_t* time, struct tm *result);
+
std::string secsToTimeString(uint64 timeInSecs, bool shortText = false, bool hoursOnly = false);
uint32 TimeStringToSecs(const std::string& timestring);
std::string TimeToTimestampStr(time_t t);
@@ -348,12 +349,6 @@ bool Utf8ToUpperOnlyLatin(std::string& utf8String);
bool IsIPAddress(char const* ipaddress);
-/// Checks if address belongs to the a network with specified submask
-bool IsIPAddrInNetwork(ACE_INET_Addr const& net, ACE_INET_Addr const& addr, ACE_INET_Addr const& subnetMask);
-
-/// Transforms ACE_INET_Addr address into string format "dotted_ip:port"
-std::string GetAddressString(ACE_INET_Addr const& addr);
-
uint32 CreatePIDFile(const std::string& filename);
std::string ByteArrayToHexStr(uint8 const* bytes, uint32 length, bool reverse = false);
diff --git a/src/server/worldserver/CMakeLists.txt b/src/server/worldserver/CMakeLists.txt
index 2f4d557fec0..e48cbc9c7c7 100644
--- a/src/server/worldserver/CMakeLists.txt
+++ b/src/server/worldserver/CMakeLists.txt
@@ -11,7 +11,6 @@
file(GLOB_RECURSE sources_CommandLine CommandLine/*.cpp CommandLine/*.h)
file(GLOB_RECURSE sources_RemoteAccess RemoteAccess/*.cpp RemoteAccess/*.h)
file(GLOB_RECURSE sources_TCSoap TCSoap/*.cpp TCSoap/*.h)
-file(GLOB_RECURSE sources_WorldThread WorldThread/*.cpp WorldThread/*.h)
file(GLOB sources_localdir *.cpp *.h)
if (USE_COREPCH)
@@ -24,7 +23,6 @@ set(worldserver_SRCS
${sources_CommandLine}
${sources_RemoteAccess}
${sources_TCSoap}
- ${sources_WorldThread}
${sources_localdir}
)
@@ -62,6 +60,7 @@ include_directories(
${CMAKE_SOURCE_DIR}/src/server/shared/Dynamic/LinkedReference
${CMAKE_SOURCE_DIR}/src/server/shared/Dynamic
${CMAKE_SOURCE_DIR}/src/server/shared/Logging
+ ${CMAKE_SOURCE_DIR}/src/server/shared/Networking
${CMAKE_SOURCE_DIR}/src/server/shared/Packets
${CMAKE_SOURCE_DIR}/src/server/shared/Threading
${CMAKE_SOURCE_DIR}/src/server/shared/Utilities
@@ -139,8 +138,6 @@ include_directories(
${CMAKE_CURRENT_SOURCE_DIR}/CommandLine
${CMAKE_CURRENT_SOURCE_DIR}/RemoteAccess
${CMAKE_CURRENT_SOURCE_DIR}/TCSoap
- ${CMAKE_CURRENT_SOURCE_DIR}/WorldThread
- ${ACE_INCLUDE_DIR}
${MYSQL_INCLUDE_DIR}
${OPENSSL_INCLUDE_DIR}
)
@@ -175,11 +172,11 @@ target_link_libraries(worldserver
${JEMALLOC_LIBRARY}
${READLINE_LIBRARY}
${TERMCAP_LIBRARY}
- ${ACE_LIBRARY}
${MYSQL_LIBRARY}
${OPENSSL_LIBRARIES}
${ZLIB_LIBRARIES}
${CMAKE_THREAD_LIBS_INIT}
+ ${Boost_LIBRARIES}
)
if( WIN32 )
diff --git a/src/server/worldserver/CommandLine/CliRunnable.cpp b/src/server/worldserver/CommandLine/CliRunnable.cpp
index ac46b218305..295e63c696b 100644
--- a/src/server/worldserver/CommandLine/CliRunnable.cpp
+++ b/src/server/worldserver/CommandLine/CliRunnable.cpp
@@ -131,7 +131,7 @@ int kb_hit_return()
#endif
/// %Thread start
-void CliRunnable::run()
+void CliThread()
{
///- Display the list of available CLI functions then beep
//TC_LOG_INFO("server.worldserver", "");
diff --git a/src/server/worldserver/CommandLine/CliRunnable.h b/src/server/worldserver/CommandLine/CliRunnable.h
index 5510173973e..7ed3a44995f 100644
--- a/src/server/worldserver/CommandLine/CliRunnable.h
+++ b/src/server/worldserver/CommandLine/CliRunnable.h
@@ -23,12 +23,7 @@
#ifndef __CLIRUNNABLE_H
#define __CLIRUNNABLE_H
-/// Command Line Interface handling thread
-class CliRunnable : public ACE_Based::Runnable
-{
- public:
- void run() override;
-};
+void CliThread();
#endif
diff --git a/src/server/worldserver/Main.cpp b/src/server/worldserver/Main.cpp
index 75d9ca5145d..0c051eae37a 100644
--- a/src/server/worldserver/Main.cpp
+++ b/src/server/worldserver/Main.cpp
@@ -22,19 +22,38 @@
#include <openssl/opensslv.h>
#include <openssl/crypto.h>
-#include <ace/Version.h>
+#include <boost/asio/io_service.hpp>
+#include <boost/asio/deadline_timer.hpp>
+#include <boost/program_options.hpp>
#include "Common.h"
-#include "Database/DatabaseEnv.h"
+#include "DatabaseEnv.h"
+#include "AsyncAcceptor.h"
+#include "RASession.h"
#include "Configuration/Config.h"
+#include "OpenSSLCrypto.h"
+#include "ProcessPriority.h"
+#include "BigNumber.h"
+#include "RealmList.h"
+#include "World.h"
+#include "MapManager.h"
+#include "ObjectAccessor.h"
+#include "ScriptMgr.h"
+#include "OutdoorPvP/OutdoorPvPMgr.h"
+#include "BattlegroundMgr.h"
+#include "TCSoap.h"
+#include "CliRunnable.h"
+#include "SystemConfig.h"
+#include "WorldSocket.h"
-#include "Log.h"
-#include "Master.h"
+using namespace boost::program_options;
#ifndef _TRINITY_CORE_CONFIG
-# define _TRINITY_CORE_CONFIG "worldserver.conf"
+ #define _TRINITY_CORE_CONFIG "worldserver.conf"
#endif
+#define WORLD_SLEEP_CONST 50
+
#ifdef _WIN32
#include "ServiceWin32.h"
char serviceName[] = "worldserver";
@@ -49,104 +68,504 @@ char serviceDescription[] = "TrinityCore World of Warcraft emulator world servic
int m_ServiceStatus = -1;
#endif
+boost::asio::io_service _ioService;
+boost::asio::deadline_timer _freezeCheckTimer(_ioService);
+uint32 _worldLoopCounter(0);
+uint32 _lastChangeMsTime(0);
+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
-/// Print out the usage string for this program on the console.
-void usage(const char* prog)
+void SignalHandler(const boost::system::error_code& error, int signalNumber);
+void FreezeDetectorHandler(const boost::system::error_code& error);
+AsyncAcceptor<RASession>* StartRaSocketAcceptor(boost::asio::io_service& ioService);
+bool StartDB();
+void StopDB();
+void WorldUpdateLoop();
+void ClearOnlineAccounts();
+variables_map GetConsoleArguments(int argc, char** argv, std::string& cfg_file, std::string& cfg_service);
+
+/// Launch the Trinity server
+extern int main(int argc, char** argv)
{
- printf("Usage:\n");
- printf(" %s [<options>]\n", prog);
- printf(" -c config_file use config_file as configuration file\n");
+ std::string configFile = _TRINITY_CORE_CONFIG;
+ std::string configService;
+
+ auto vm = GetConsoleArguments(argc, argv, configFile, configService);
+ // exit if help is enabled
+ if (vm.count("help"))
+ return 0;
+
+#ifdef _WIN32
+ if (configService.compare("install") == 0)
+ return WinServiceInstall() == true ? 0 : 1;
+ else if (configService.compare("uninstall") == 0)
+ return WinServiceUninstall() == true ? 0 : 1;
+ else if (configService.compare("run") == 0)
+ WinServiceRun();
+#endif
+
+ if (!sConfigMgr->LoadInitial(configFile))
+ {
+ printf("Invalid or missing configuration file : %s\n", configFile.c_str());
+ printf("Verify that the file exists and has \'[worldserver]' written in the top of the file!\n");
+ return 1;
+ }
+
+ if (sConfigMgr->GetBoolDefault("Log.Async.Enable", false))
+ {
+ // If logs are supposed to be handled async then we need to pass the io_service into the Log singleton
+ Log::instance(&_ioService);
+ }
+
+ TC_LOG_INFO("server.worldserver", "%s (worldserver-daemon)", _FULLVERSION);
+ TC_LOG_INFO("server.worldserver", "<Ctrl-C> to stop.\n");
+ TC_LOG_INFO("server.worldserver", " ______ __");
+ TC_LOG_INFO("server.worldserver", "/\\__ _\\ __ __/\\ \\__");
+ TC_LOG_INFO("server.worldserver", "\\/_/\\ \\/ _ __ /\\_\\ ___ /\\_\\ \\, _\\ __ __");
+ TC_LOG_INFO("server.worldserver", " \\ \\ \\/\\`'__\\/\\ \\ /' _ `\\/\\ \\ \\ \\/ /\\ \\/\\ \\");
+ TC_LOG_INFO("server.worldserver", " \\ \\ \\ \\ \\/ \\ \\ \\/\\ \\/\\ \\ \\ \\ \\ \\_\\ \\ \\_\\ \\");
+ TC_LOG_INFO("server.worldserver", " \\ \\_\\ \\_\\ \\ \\_\\ \\_\\ \\_\\ \\_\\ \\__\\\\/`____ \\");
+ TC_LOG_INFO("server.worldserver", " \\/_/\\/_/ \\/_/\\/_/\\/_/\\/_/\\/__/ `/___/> \\");
+ TC_LOG_INFO("server.worldserver", " C O R E /\\___/");
+ TC_LOG_INFO("server.worldserver", "http://TrinityCore.org \\/__/\n");
+ TC_LOG_INFO("server.worldserver", "Using configuration file %s.", configFile.c_str());
+ TC_LOG_INFO("server.worldserver", "Using SSL version: %s (library: %s)", OPENSSL_VERSION_TEXT, SSLeay_version(SSLEAY_VERSION));
+ TC_LOG_INFO("server.worldserver", "Using Boost version: %i.%i.%i", BOOST_VERSION / 100000, BOOST_VERSION / 100 % 1000, BOOST_VERSION % 100);
+
+ OpenSSLCrypto::threadsSetup();
+
+ // Seed the OpenSSL's PRNG here.
+ // That way it won't auto-seed when calling BigNumber::SetRand and slow down the first world login
+ BigNumber seed;
+ seed.SetRand(16 * 8);
+
+ /// worldserver PID file creation
+ std::string pidFile = sConfigMgr->GetStringDefault("PidFile", "");
+ if (!pidFile.empty())
+ {
+ if (uint32 pid = CreatePIDFile(pidFile))
+ TC_LOG_INFO("server.worldserver", "Daemon PID: %u\n", pid);
+ else
+ {
+ TC_LOG_ERROR("server.worldserver", "Cannot create PID file %s.\n", pidFile.c_str());
+ return 1;
+ }
+ }
+
+ // Set signal handlers (this must be done before starting io_service threads, because otherwise they would unblock and exit)
+ boost::asio::signal_set signals(_ioService, SIGINT, SIGTERM);
+ signals.async_wait(SignalHandler);
+
+ // Start the Boost based thread pool
+ int numThreads = sConfigMgr->GetIntDefault("ThreadPool", 1);
+ std::vector<std::thread> threadPool;
+
+ if (numThreads < 1)
+ numThreads = 1;
+
+ for (int i = 0; i < numThreads; ++i)
+ threadPool.push_back(std::thread(boost::bind(&boost::asio::io_service::run, &_ioService)));
+
+ // Set process priority according to configuration settings
+ SetProcessPriority("server.worldserver");
+
+ // Start the databases
+ if (!StartDB())
+ return 1;
+
+ // Set server offline (not connectable)
+ LoginDatabase.DirectPExecute("UPDATE realmlist SET flag = (flag & ~%u) | %u WHERE id = '%d'", REALM_FLAG_OFFLINE, REALM_FLAG_INVALID, realmID);
+
+ // Initialize the World
+ sWorld->SetInitialWorldSettings();
+
+ // Launch CliRunnable thread
+ std::thread* cliThread = nullptr;
#ifdef _WIN32
- printf(" Running as service functions:\n");
- printf(" --service run as service\n");
- printf(" -s install install service\n");
- printf(" -s uninstall uninstall service\n");
+ if (sConfigMgr->GetBoolDefault("Console.Enable", true) && (m_ServiceStatus == -1)/* need disable console in service mode*/)
+#else
+ if (sConfigMgr->GetBoolDefault("Console.Enable", true))
#endif
+ {
+ cliThread = new std::thread(CliThread);
+ }
+
+ // Start the Remote Access port (acceptor) if enabled
+ AsyncAcceptor<RASession>* raAcceptor = nullptr;
+ if (sConfigMgr->GetBoolDefault("Ra.Enable", false))
+ raAcceptor = StartRaSocketAcceptor(_ioService);
+
+ // Start soap serving thread if enabled
+ std::thread* soapThread = nullptr;
+ if (sConfigMgr->GetBoolDefault("SOAP.Enabled", false))
+ {
+ soapThread = new std::thread(TCSoapThread, sConfigMgr->GetStringDefault("SOAP.IP", "127.0.0.1"), uint16(sConfigMgr->GetIntDefault("SOAP.Port", 7878)));
+ }
+
+ // Launch the worldserver listener socket
+ uint16 worldPort = uint16(sWorld->getIntConfig(CONFIG_PORT_WORLD));
+ std::string worldListener = sConfigMgr->GetStringDefault("BindIP", "0.0.0.0");
+ bool tcpNoDelay = sConfigMgr->GetBoolDefault("Network.TcpNodelay", true);
+
+ AsyncAcceptor<WorldSocket> worldAcceptor(_ioService, worldListener, worldPort, tcpNoDelay);
+
+ sScriptMgr->OnStartup();
+
+ // Set server online (allow connecting now)
+ LoginDatabase.DirectPExecute("UPDATE realmlist SET flag = flag & ~%u, population = 0 WHERE id = '%u'", REALM_FLAG_INVALID, realmID);
+
+ // Start the freeze check callback cycle in 5 seconds (cycle itself is 1 sec)
+ if (int coreStuckTime = sConfigMgr->GetIntDefault("MaxCoreStuckTime", 0))
+ {
+ _maxCoreStuckTimeInMs = coreStuckTime * 1000;
+ _freezeCheckTimer.expires_from_now(boost::posix_time::seconds(5));
+ _freezeCheckTimer.async_wait(FreezeDetectorHandler);
+ TC_LOG_INFO("server.worldserver", "Starting up anti-freeze thread (%u seconds max stuck time)...", coreStuckTime);
+ }
+
+ TC_LOG_INFO("server.worldserver", "%s (worldserver-daemon) ready...", _FULLVERSION);
+
+ WorldUpdateLoop();
+
+ // Shutdown starts here
+
+ _ioService.stop();
+
+ for (auto& thread : threadPool)
+ {
+ thread.join();
+ }
+
+ sScriptMgr->OnShutdown();
+
+ sWorld->KickAll(); // save and kick all players
+ sWorld->UpdateSessions(1); // real players unload required UpdateSessions call
+
+ // unload battleground templates before different singletons destroyed
+ sBattlegroundMgr->DeleteAllBattlegrounds();
+
+ sMapMgr->UnloadAll(); // unload all grids (including locked in memory)
+ sObjectAccessor->UnloadAll(); // unload 'i_player2corpse' storage and remove from world
+ sScriptMgr->Unload();
+ sOutdoorPvPMgr->Die();
+
+ // set server offline
+ LoginDatabase.DirectPExecute("UPDATE realmlist SET flag = flag | %u WHERE id = '%d'", REALM_FLAG_OFFLINE, realmID);
+
+ // Clean up threads if any
+ if (soapThread != nullptr)
+ {
+ soapThread->join();
+ delete soapThread;
+ }
+
+ if (raAcceptor != nullptr)
+ delete raAcceptor;
+
+ ///- Clean database before leaving
+ ClearOnlineAccounts();
+
+ StopDB();
+
+ TC_LOG_INFO("server.worldserver", "Halting process...");
+
+ if (cliThread != nullptr)
+ {
+#ifdef _WIN32
+
+ // this only way to terminate CLI thread exist at Win32 (alt. way exist only in Windows Vista API)
+ //_exit(1);
+ // send keyboard input to safely unblock the CLI thread
+ INPUT_RECORD b[4];
+ HANDLE hStdIn = GetStdHandle(STD_INPUT_HANDLE);
+ b[0].EventType = KEY_EVENT;
+ b[0].Event.KeyEvent.bKeyDown = TRUE;
+ b[0].Event.KeyEvent.uChar.AsciiChar = 'X';
+ b[0].Event.KeyEvent.wVirtualKeyCode = 'X';
+ b[0].Event.KeyEvent.wRepeatCount = 1;
+
+ b[1].EventType = KEY_EVENT;
+ b[1].Event.KeyEvent.bKeyDown = FALSE;
+ b[1].Event.KeyEvent.uChar.AsciiChar = 'X';
+ b[1].Event.KeyEvent.wVirtualKeyCode = 'X';
+ b[1].Event.KeyEvent.wRepeatCount = 1;
+
+ b[2].EventType = KEY_EVENT;
+ b[2].Event.KeyEvent.bKeyDown = TRUE;
+ b[2].Event.KeyEvent.dwControlKeyState = 0;
+ b[2].Event.KeyEvent.uChar.AsciiChar = '\r';
+ b[2].Event.KeyEvent.wVirtualKeyCode = VK_RETURN;
+ b[2].Event.KeyEvent.wRepeatCount = 1;
+ b[2].Event.KeyEvent.wVirtualScanCode = 0x1c;
+
+ b[3].EventType = KEY_EVENT;
+ b[3].Event.KeyEvent.bKeyDown = FALSE;
+ b[3].Event.KeyEvent.dwControlKeyState = 0;
+ b[3].Event.KeyEvent.uChar.AsciiChar = '\r';
+ b[3].Event.KeyEvent.wVirtualKeyCode = VK_RETURN;
+ b[3].Event.KeyEvent.wVirtualScanCode = 0x1c;
+ b[3].Event.KeyEvent.wRepeatCount = 1;
+ DWORD numb;
+ WriteConsoleInput(hStdIn, b, 4, &numb);
+#endif
+ cliThread->join();
+ delete cliThread;
+ }
+
+ OpenSSLCrypto::threadsCleanup();
+
+ // 0 - normal shutdown
+ // 1 - shutdown at error
+ // 2 - restart command used, this code can be used by restarter for restart Trinityd
+
+ return World::GetExitCode();
}
-/// Launch the Trinity server
-extern int main(int argc, char** argv)
+
+void WorldUpdateLoop()
{
- ///- Command line parsing to get the configuration file name
- char const* cfg_file = _TRINITY_CORE_CONFIG;
- int c = 1;
- while (c < argc)
+ uint32 realCurrTime = 0;
+ uint32 realPrevTime = getMSTime();
+
+ uint32 prevSleepTime = 0; // used for balanced full tick time length near WORLD_SLEEP_CONST
+
+ ///- While we have not World::m_stopEvent, update the world
+ while (!World::IsStopped())
{
- if (!strcmp(argv[c], "-c"))
+ ++World::m_worldLoopCounter;
+ realCurrTime = getMSTime();
+
+ uint32 diff = getMSTimeDiff(realPrevTime, realCurrTime);
+
+ sWorld->Update(diff);
+ realPrevTime = realCurrTime;
+
+ // diff (D0) include time of previous sleep (d0) + tick time (t0)
+ // we want that next d1 + t1 == WORLD_SLEEP_CONST
+ // we can't know next t1 and then can use (t0 + d1) == WORLD_SLEEP_CONST requirement
+ // d1 = WORLD_SLEEP_CONST - t0 = WORLD_SLEEP_CONST - (D0 - d0) = WORLD_SLEEP_CONST + d0 - D0
+ if (diff <= WORLD_SLEEP_CONST + prevSleepTime)
{
- if (++c >= argc)
- {
- printf("Runtime-Error: -c option requires an input argument");
- usage(argv[0]);
- return 1;
- }
- else
- cfg_file = argv[c];
+ prevSleepTime = WORLD_SLEEP_CONST + prevSleepTime - diff;
+
+ std::this_thread::sleep_for(std::chrono::milliseconds(prevSleepTime));
}
+ else
+ prevSleepTime = 0;
+
+#ifdef _WIN32
+ if (m_ServiceStatus == 0)
+ World::StopNow(SHUTDOWN_EXIT_CODE);
+
+ while (m_ServiceStatus == 2)
+ Sleep(1000);
+#endif
+ }
+}
- #ifdef _WIN32
- if (strcmp(argv[c], "-s") == 0) // Services
+void SignalHandler(const boost::system::error_code& error, int signalNumber)
+{
+ if (!error)
+ {
+ switch (signalNumber)
{
- if (++c >= argc)
- {
- printf("Runtime-Error: -s option requires an input argument");
- usage(argv[0]);
- return 1;
- }
-
- if (strcmp(argv[c], "install") == 0)
- {
- if (WinServiceInstall())
- printf("Installing service\n");
- return 1;
- }
- else if (strcmp(argv[c], "uninstall") == 0)
- {
- if (WinServiceUninstall())
- printf("Uninstalling service\n");
- return 1;
- }
- else
- {
- printf("Runtime-Error: unsupported option %s", argv[c]);
- usage(argv[0]);
- return 1;
- }
+ case SIGINT:
+ case SIGTERM:
+ World::StopNow(SHUTDOWN_EXIT_CODE);
+ break;
}
+ }
+}
- if (strcmp(argv[c], "--service") == 0)
- WinServiceRun();
- #endif
- ++c;
+void FreezeDetectorHandler(const boost::system::error_code& error)
+{
+ if (!error)
+ {
+ uint32 curtime = getMSTime();
+
+ uint32 worldLoopCounter = World::m_worldLoopCounter;
+ if (_worldLoopCounter != worldLoopCounter)
+ {
+ _lastChangeMsTime = curtime;
+ _worldLoopCounter = worldLoopCounter;
+ }
+ // possible freeze
+ else if (getMSTimeDiff(_lastChangeMsTime, curtime) > _maxCoreStuckTimeInMs)
+ {
+ TC_LOG_ERROR("server.worldserver", "World Thread hangs, kicking out server!");
+ ASSERT(false);
+ }
+
+ _freezeCheckTimer.expires_from_now(boost::posix_time::seconds(1));
+ _freezeCheckTimer.async_wait(FreezeDetectorHandler);
}
+}
- if (!sConfigMgr->LoadInitial(cfg_file))
+AsyncAcceptor<RASession>* StartRaSocketAcceptor(boost::asio::io_service& ioService)
+{
+ uint16 raPort = uint16(sConfigMgr->GetIntDefault("Ra.Port", 3443));
+ std::string raListener = sConfigMgr->GetStringDefault("Ra.IP", "0.0.0.0");
+
+ return new AsyncAcceptor<RASession>(ioService, raListener, raPort);
+}
+
+/// Initialize connection to the databases
+bool StartDB()
+{
+ MySQL::Library_Init();
+
+ std::string dbString;
+ uint8 asyncThreads, synchThreads;
+
+ dbString = sConfigMgr->GetStringDefault("WorldDatabaseInfo", "");
+ if (dbString.empty())
{
- printf("Invalid or missing configuration file : %s\n", cfg_file);
- printf("Verify that the file exists and has \'[worldserver]' written in the top of the file!\n");
- return 1;
+ TC_LOG_ERROR("server.worldserver", "World database not specified in configuration file");
+ return false;
}
- TC_LOG_INFO("server.worldserver", "Using configuration file %s.", cfg_file);
+ asyncThreads = uint8(sConfigMgr->GetIntDefault("WorldDatabase.WorkerThreads", 1));
+ if (asyncThreads < 1 || asyncThreads > 32)
+ {
+ TC_LOG_ERROR("server.worldserver", "World database: invalid number of worker threads specified. "
+ "Please pick a value between 1 and 32.");
+ return false;
+ }
- TC_LOG_INFO("server.worldserver", "Using SSL version: %s (library: %s)", OPENSSL_VERSION_TEXT, SSLeay_version(SSLEAY_VERSION));
- TC_LOG_INFO("server.worldserver", "Using ACE version: %s", ACE_VERSION);
+ synchThreads = uint8(sConfigMgr->GetIntDefault("WorldDatabase.SynchThreads", 1));
+ ///- Initialize the world database
+ if (!WorldDatabase.Open(dbString, asyncThreads, synchThreads))
+ {
+ TC_LOG_ERROR("server.worldserver", "Cannot connect to world database %s", dbString.c_str());
+ return false;
+ }
- ///- and run the 'Master'
- /// @todo Why do we need this 'Master'? Can't all of this be in the Main as for Realmd?
- int ret = sMaster->Run();
+ ///- Get character database info from configuration file
+ dbString = sConfigMgr->GetStringDefault("CharacterDatabaseInfo", "");
+ if (dbString.empty())
+ {
+ TC_LOG_ERROR("server.worldserver", "Character database not specified in configuration file");
+ return false;
+ }
- // at sMaster return function exist with codes
- // 0 - normal shutdown
- // 1 - shutdown at error
- // 2 - restart command used, this code can be used by restarter for restart Trinityd
+ asyncThreads = uint8(sConfigMgr->GetIntDefault("CharacterDatabase.WorkerThreads", 1));
+ if (asyncThreads < 1 || asyncThreads > 32)
+ {
+ TC_LOG_ERROR("server.worldserver", "Character database: invalid number of worker threads specified. "
+ "Please pick a value between 1 and 32.");
+ return false;
+ }
+
+ synchThreads = uint8(sConfigMgr->GetIntDefault("CharacterDatabase.SynchThreads", 2));
+
+ ///- Initialize the Character database
+ if (!CharacterDatabase.Open(dbString, asyncThreads, synchThreads))
+ {
+ TC_LOG_ERROR("server.worldserver", "Cannot connect to Character database %s", dbString.c_str());
+ return false;
+ }
+
+ ///- Get login database info from configuration file
+ dbString = sConfigMgr->GetStringDefault("LoginDatabaseInfo", "");
+ if (dbString.empty())
+ {
+ TC_LOG_ERROR("server.worldserver", "Login database not specified in configuration file");
+ return false;
+ }
+
+ asyncThreads = uint8(sConfigMgr->GetIntDefault("LoginDatabase.WorkerThreads", 1));
+ if (asyncThreads < 1 || asyncThreads > 32)
+ {
+ TC_LOG_ERROR("server.worldserver", "Login database: invalid number of worker threads specified. "
+ "Please pick a value between 1 and 32.");
+ return false;
+ }
+
+ synchThreads = uint8(sConfigMgr->GetIntDefault("LoginDatabase.SynchThreads", 1));
+ ///- Initialise the login database
+ if (!LoginDatabase.Open(dbString, asyncThreads, synchThreads))
+ {
+ TC_LOG_ERROR("server.worldserver", "Cannot connect to login database %s", dbString.c_str());
+ return false;
+ }
+
+ ///- Get the realm Id from the configuration file
+ realmID = sConfigMgr->GetIntDefault("RealmID", 0);
+ if (!realmID)
+ {
+ 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);
+
+ ///- Clean the database before starting
+ ClearOnlineAccounts();
+
+ ///- Insert version info into DB
+ WorldDatabase.PExecute("UPDATE version SET core_version = '%s', core_revision = '%s'", _FULLVERSION, _HASH); // One-time query
+
+ sWorld->LoadDBVersion();
- return ret;
+ TC_LOG_INFO("server.worldserver", "Using World DB: %s", sWorld->GetDBVersion());
+ return true;
+}
+
+void StopDB()
+{
+ CharacterDatabase.Close();
+ WorldDatabase.Close();
+ LoginDatabase.Close();
+
+ MySQL::Library_End();
+}
+
+/// Clear 'online' status for all accounts with characters in this realm
+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);
+
+ // Reset online status for all characters
+ CharacterDatabase.DirectExecute("UPDATE characters SET online = 0 WHERE online <> 0");
+
+ // Battleground instance ids reset at server restart
+ CharacterDatabase.DirectExecute("UPDATE character_battleground_data SET instanceId = 0");
}
/// @}
+
+variables_map GetConsoleArguments(int argc, char** argv, std::string& configFile, std::string& configService)
+{
+ options_description all("Allowed options");
+ all.add_options()
+ ("help,h", "print usage message")
+ ("config,c", value<std::string>(&configFile)->default_value(_TRINITY_CORE_CONFIG), "use <arg> as configuration file")
+ ;
+#ifdef _WIN32
+ options_description win("Windows platform specific options");
+ win.add_options()
+ ("service,s", value<std::string>(&configService)->default_value(""), "Windows service options: [install | uninstall]")
+ ;
+
+ all.add(win);
+#endif
+ variables_map vm;
+ try
+ {
+ store(command_line_parser(argc, argv).options(all).allow_unregistered().run(), vm);
+ notify(vm);
+ }
+ catch (std::exception& e) {
+ std::cerr << e.what() << "\n";
+ }
+
+ if (vm.count("help")) {
+ std::cout << all << "\n";
+ }
+
+ return vm;
+}
diff --git a/src/server/worldserver/Master.cpp b/src/server/worldserver/Master.cpp
deleted file mode 100644
index 6e4214603cb..00000000000
--- a/src/server/worldserver/Master.cpp
+++ /dev/null
@@ -1,508 +0,0 @@
-/*
- * 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
- \ingroup Trinityd
-*/
-
-#include <ace/Sig_Handler.h>
-
-#include "Common.h"
-#include "SystemConfig.h"
-#include "SignalHandler.h"
-#include "World.h"
-#include "WorldRunnable.h"
-#include "WorldSocket.h"
-#include "WorldSocketMgr.h"
-#include "Configuration/Config.h"
-#include "Database/DatabaseEnv.h"
-#include "Database/DatabaseWorkerPool.h"
-
-#include "CliRunnable.h"
-#include "Log.h"
-#include "Master.h"
-#include "RARunnable.h"
-#include "TCSoap.h"
-#include "Timer.h"
-#include "Util.h"
-#include "AuthSocket.h"
-#include "RealmList.h"
-
-#include "BigNumber.h"
-#include "OpenSSLCrypto.h"
-
-#ifdef _WIN32
-#include "ServiceWin32.h"
-extern int m_ServiceStatus;
-#endif
-
-#ifdef __linux__
-#include <sched.h>
-#include <sys/resource.h>
-#define PROCESS_HIGH_PRIORITY -15 // [-20, 19], default is 0
-#endif
-
-/// Handle worldservers's termination signals
-class WorldServerSignalHandler : public Trinity::SignalHandler
-{
- public:
- virtual void HandleSignal(int sigNum)
- {
- switch (sigNum)
- {
- case SIGINT:
- World::StopNow(RESTART_EXIT_CODE);
- break;
- case SIGTERM:
-#ifdef _WIN32
- case SIGBREAK:
- if (m_ServiceStatus != 1)
-#endif
- World::StopNow(SHUTDOWN_EXIT_CODE);
- break;
- }
- }
-};
-
-class FreezeDetectorRunnable : public ACE_Based::Runnable
-{
-private:
- uint32 _loops;
- uint32 _lastChange;
- uint32 _delaytime;
-public:
- FreezeDetectorRunnable()
- {
- _loops = 0;
- _lastChange = 0;
- _delaytime = 0;
- }
-
- void SetDelayTime(uint32 t) { _delaytime = t; }
-
- void run() override
- {
- if (!_delaytime)
- return;
-
- TC_LOG_INFO("server.worldserver", "Starting up anti-freeze thread (%u seconds max stuck time)...", _delaytime/1000);
- _loops = 0;
- _lastChange = 0;
- while (!World::IsStopped())
- {
- ACE_Based::Thread::Sleep(1000);
- uint32 curtime = getMSTime();
- // normal work
- uint32 worldLoopCounter = World::m_worldLoopCounter.value();
- if (_loops != worldLoopCounter)
- {
- _lastChange = curtime;
- _loops = worldLoopCounter;
- }
- // possible freeze
- else if (getMSTimeDiff(_lastChange, curtime) > _delaytime)
- {
- TC_LOG_ERROR("server.worldserver", "World Thread hangs, kicking out server!");
- ASSERT(false);
- }
- }
- TC_LOG_INFO("server.worldserver", "Anti-freeze thread exiting without problems.");
- }
-};
-
-/// Main function
-int Master::Run()
-{
- OpenSSLCrypto::threadsSetup();
- BigNumber seed1;
- seed1.SetRand(16 * 8);
-
- TC_LOG_INFO("server.worldserver", "%s (worldserver-daemon)", _FULLVERSION);
- TC_LOG_INFO("server.worldserver", "<Ctrl-C> to stop.\n");
-
- TC_LOG_INFO("server.worldserver", " ______ __");
- TC_LOG_INFO("server.worldserver", "/\\__ _\\ __ __/\\ \\__");
- TC_LOG_INFO("server.worldserver", "\\/_/\\ \\/ _ __ /\\_\\ ___ /\\_\\ \\, _\\ __ __");
- TC_LOG_INFO("server.worldserver", " \\ \\ \\/\\`'__\\/\\ \\ /' _ `\\/\\ \\ \\ \\/ /\\ \\/\\ \\");
- TC_LOG_INFO("server.worldserver", " \\ \\ \\ \\ \\/ \\ \\ \\/\\ \\/\\ \\ \\ \\ \\ \\_\\ \\ \\_\\ \\");
- TC_LOG_INFO("server.worldserver", " \\ \\_\\ \\_\\ \\ \\_\\ \\_\\ \\_\\ \\_\\ \\__\\\\/`____ \\");
- TC_LOG_INFO("server.worldserver", " \\/_/\\/_/ \\/_/\\/_/\\/_/\\/_/\\/__/ `/___/> \\");
- TC_LOG_INFO("server.worldserver", " C O R E /\\___/");
- TC_LOG_INFO("server.worldserver", "http://TrinityCore.org \\/__/\n");
-
- /// worldserver PID file creation
- std::string pidFile = sConfigMgr->GetStringDefault("PidFile", "");
- if (!pidFile.empty())
- {
- if (uint32 pid = CreatePIDFile(pidFile))
- TC_LOG_INFO("server.worldserver", "Daemon PID: %u\n", pid);
- else
- {
- TC_LOG_ERROR("server.worldserver", "Cannot create PID file %s.\n", pidFile.c_str());
- return 1;
- }
- }
-
- ///- Start the databases
- if (!_StartDB())
- return 1;
-
- // set server offline (not connectable)
- LoginDatabase.DirectPExecute("UPDATE realmlist SET flag = (flag & ~%u) | %u WHERE id = '%d'", REALM_FLAG_OFFLINE, REALM_FLAG_INVALID, realmID);
-
- ///- Initialize the World
- sWorld->SetInitialWorldSettings();
-
- ///- Initialize the signal handlers
- WorldServerSignalHandler signalINT, signalTERM;
- #ifdef _WIN32
- WorldServerSignalHandler signalBREAK;
- #endif /* _WIN32 */
-
- ///- Register worldserver's signal handlers
- ACE_Sig_Handler handle;
- handle.register_handler(SIGINT, &signalINT);
- handle.register_handler(SIGTERM, &signalTERM);
-#ifdef _WIN32
- handle.register_handler(SIGBREAK, &signalBREAK);
-#endif
-
- ///- Launch WorldRunnable thread
- ACE_Based::Thread worldThread(new WorldRunnable);
- worldThread.setPriority(ACE_Based::Highest);
-
- ACE_Based::Thread* cliThread = NULL;
-
-#ifdef _WIN32
- if (sConfigMgr->GetBoolDefault("Console.Enable", true) && (m_ServiceStatus == -1)/* need disable console in service mode*/)
-#else
- if (sConfigMgr->GetBoolDefault("Console.Enable", true))
-#endif
- {
- ///- Launch CliRunnable thread
- cliThread = new ACE_Based::Thread(new CliRunnable);
- }
-
- ACE_Based::Thread rarThread(new RARunnable);
-
-#if defined(_WIN32) || defined(__linux__)
-
- ///- Handle affinity for multiple processors and process priority
- uint32 affinity = sConfigMgr->GetIntDefault("UseProcessors", 0);
- bool highPriority = sConfigMgr->GetBoolDefault("ProcessPriority", false);
-
-#ifdef _WIN32 // Windows
-
- HANDLE hProcess = GetCurrentProcess();
-
- if (affinity > 0)
- {
- ULONG_PTR appAff;
- ULONG_PTR sysAff;
-
- if (GetProcessAffinityMask(hProcess, &appAff, &sysAff))
- {
- ULONG_PTR currentAffinity = affinity & appAff; // remove non accessible processors
-
- if (!currentAffinity)
- TC_LOG_ERROR("server.worldserver", "Processors marked in UseProcessors bitmask (hex) %x are not accessible for the worldserver. Accessible processors bitmask (hex): %x", affinity, appAff);
- else if (SetProcessAffinityMask(hProcess, currentAffinity))
- TC_LOG_INFO("server.worldserver", "Using processors (bitmask, hex): %x", currentAffinity);
- else
- TC_LOG_ERROR("server.worldserver", "Can't set used processors (hex): %x", currentAffinity);
- }
- }
-
- if (highPriority)
- {
- if (SetPriorityClass(hProcess, HIGH_PRIORITY_CLASS))
- TC_LOG_INFO("server.worldserver", "worldserver process priority class set to HIGH");
- else
- TC_LOG_ERROR("server.worldserver", "Can't set worldserver process priority class.");
- }
-
-#else // Linux
-
- if (affinity > 0)
- {
- cpu_set_t mask;
- CPU_ZERO(&mask);
-
- for (unsigned int i = 0; i < sizeof(affinity) * 8; ++i)
- if (affinity & (1 << i))
- CPU_SET(i, &mask);
-
- if (sched_setaffinity(0, sizeof(mask), &mask))
- TC_LOG_ERROR("server.worldserver", "Can't set used processors (hex): %x, error: %s", affinity, strerror(errno));
- else
- {
- CPU_ZERO(&mask);
- sched_getaffinity(0, sizeof(mask), &mask);
- TC_LOG_INFO("server.worldserver", "Using processors (bitmask, hex): %lx", *(__cpu_mask*)(&mask));
- }
- }
-
- if (highPriority)
- {
- if (setpriority(PRIO_PROCESS, 0, PROCESS_HIGH_PRIORITY))
- TC_LOG_ERROR("server.worldserver", "Can't set worldserver process priority class, error: %s", strerror(errno));
- else
- TC_LOG_INFO("server.worldserver", "worldserver process priority class set to %i", getpriority(PRIO_PROCESS, 0));
- }
-
-#endif
-#endif
-
- //Start soap serving thread
- ACE_Based::Thread* soapThread = NULL;
-
- if (sConfigMgr->GetBoolDefault("SOAP.Enabled", false))
- {
- TCSoapRunnable* runnable = new TCSoapRunnable();
- runnable->SetListenArguments(sConfigMgr->GetStringDefault("SOAP.IP", "127.0.0.1"), uint16(sConfigMgr->GetIntDefault("SOAP.Port", 7878)));
- soapThread = new ACE_Based::Thread(runnable);
- }
-
- ///- Start up freeze catcher thread
- if (uint32 freezeDelay = sConfigMgr->GetIntDefault("MaxCoreStuckTime", 0))
- {
- FreezeDetectorRunnable* fdr = new FreezeDetectorRunnable();
- fdr->SetDelayTime(freezeDelay * 1000);
- ACE_Based::Thread freezeThread(fdr);
- freezeThread.setPriority(ACE_Based::Highest);
- }
-
- ///- Launch the world listener socket
- uint16 worldPort = uint16(sWorld->getIntConfig(CONFIG_PORT_WORLD));
- std::string bindIp = sConfigMgr->GetStringDefault("BindIP", "0.0.0.0");
-
- if (sWorldSocketMgr->StartNetwork(worldPort, bindIp.c_str()) == -1)
- {
- TC_LOG_ERROR("server.worldserver", "Failed to start network");
- World::StopNow(ERROR_EXIT_CODE);
- // go down and shutdown the server
- }
-
- // set server online (allow connecting now)
- LoginDatabase.DirectPExecute("UPDATE realmlist SET flag = flag & ~%u, population = 0 WHERE id = '%u'", REALM_FLAG_INVALID, realmID);
-
- TC_LOG_INFO("server.worldserver", "%s (worldserver-daemon) ready...", _FULLVERSION);
-
- // when the main thread closes the singletons get unloaded
- // since worldrunnable uses them, it will crash if unloaded after master
- worldThread.wait();
- rarThread.wait();
-
- if (soapThread)
- {
- soapThread->wait();
- soapThread->destroy();
- delete soapThread;
- }
-
- // set server offline
- LoginDatabase.DirectPExecute("UPDATE realmlist SET flag = flag | %u WHERE id = '%d'", REALM_FLAG_OFFLINE, realmID);
-
- ///- Clean database before leaving
- ClearOnlineAccounts();
-
- _StopDB();
-
- TC_LOG_INFO("server.worldserver", "Halting process...");
-
- if (cliThread)
- {
- #ifdef _WIN32
-
- // this only way to terminate CLI thread exist at Win32 (alt. way exist only in Windows Vista API)
- //_exit(1);
- // send keyboard input to safely unblock the CLI thread
- INPUT_RECORD b[4];
- HANDLE hStdIn = GetStdHandle(STD_INPUT_HANDLE);
- b[0].EventType = KEY_EVENT;
- b[0].Event.KeyEvent.bKeyDown = TRUE;
- b[0].Event.KeyEvent.uChar.AsciiChar = 'X';
- b[0].Event.KeyEvent.wVirtualKeyCode = 'X';
- b[0].Event.KeyEvent.wRepeatCount = 1;
-
- b[1].EventType = KEY_EVENT;
- b[1].Event.KeyEvent.bKeyDown = FALSE;
- b[1].Event.KeyEvent.uChar.AsciiChar = 'X';
- b[1].Event.KeyEvent.wVirtualKeyCode = 'X';
- b[1].Event.KeyEvent.wRepeatCount = 1;
-
- b[2].EventType = KEY_EVENT;
- b[2].Event.KeyEvent.bKeyDown = TRUE;
- b[2].Event.KeyEvent.dwControlKeyState = 0;
- b[2].Event.KeyEvent.uChar.AsciiChar = '\r';
- b[2].Event.KeyEvent.wVirtualKeyCode = VK_RETURN;
- b[2].Event.KeyEvent.wRepeatCount = 1;
- b[2].Event.KeyEvent.wVirtualScanCode = 0x1c;
-
- b[3].EventType = KEY_EVENT;
- b[3].Event.KeyEvent.bKeyDown = FALSE;
- b[3].Event.KeyEvent.dwControlKeyState = 0;
- b[3].Event.KeyEvent.uChar.AsciiChar = '\r';
- b[3].Event.KeyEvent.wVirtualKeyCode = VK_RETURN;
- b[3].Event.KeyEvent.wVirtualScanCode = 0x1c;
- b[3].Event.KeyEvent.wRepeatCount = 1;
- DWORD numb;
- WriteConsoleInput(hStdIn, b, 4, &numb);
-
- cliThread->wait();
-
- #else
-
- cliThread->destroy();
-
- #endif
-
- delete cliThread;
- }
-
- // for some unknown reason, unloading scripts here and not in worldrunnable
- // fixes a memory leak related to detaching threads from the module
- //UnloadScriptingModule();
-
- OpenSSLCrypto::threadsCleanup();
- // Exit the process with specified return value
- return World::GetExitCode();
-}
-
-/// Initialize connection to the databases
-bool Master::_StartDB()
-{
- MySQL::Library_Init();
-
- std::string dbString;
- uint8 asyncThreads, synchThreads;
-
- dbString = sConfigMgr->GetStringDefault("WorldDatabaseInfo", "");
- if (dbString.empty())
- {
- TC_LOG_ERROR("server.worldserver", "World database not specified in configuration file");
- return false;
- }
-
- asyncThreads = uint8(sConfigMgr->GetIntDefault("WorldDatabase.WorkerThreads", 1));
- if (asyncThreads < 1 || asyncThreads > 32)
- {
- TC_LOG_ERROR("server.worldserver", "World database: invalid number of worker threads specified. "
- "Please pick a value between 1 and 32.");
- return false;
- }
-
- synchThreads = uint8(sConfigMgr->GetIntDefault("WorldDatabase.SynchThreads", 1));
- ///- Initialize the world database
- if (!WorldDatabase.Open(dbString, asyncThreads, synchThreads))
- {
- TC_LOG_ERROR("server.worldserver", "Cannot connect to world database %s", dbString.c_str());
- return false;
- }
-
- ///- Get character database info from configuration file
- dbString = sConfigMgr->GetStringDefault("CharacterDatabaseInfo", "");
- if (dbString.empty())
- {
- TC_LOG_ERROR("server.worldserver", "Character database not specified in configuration file");
- return false;
- }
-
- asyncThreads = uint8(sConfigMgr->GetIntDefault("CharacterDatabase.WorkerThreads", 1));
- if (asyncThreads < 1 || asyncThreads > 32)
- {
- TC_LOG_ERROR("server.worldserver", "Character database: invalid number of worker threads specified. "
- "Please pick a value between 1 and 32.");
- return false;
- }
-
- synchThreads = uint8(sConfigMgr->GetIntDefault("CharacterDatabase.SynchThreads", 2));
-
- ///- Initialize the Character database
- if (!CharacterDatabase.Open(dbString, asyncThreads, synchThreads))
- {
- TC_LOG_ERROR("server.worldserver", "Cannot connect to Character database %s", dbString.c_str());
- return false;
- }
-
- ///- Get login database info from configuration file
- dbString = sConfigMgr->GetStringDefault("LoginDatabaseInfo", "");
- if (dbString.empty())
- {
- TC_LOG_ERROR("server.worldserver", "Login database not specified in configuration file");
- return false;
- }
-
- asyncThreads = uint8(sConfigMgr->GetIntDefault("LoginDatabase.WorkerThreads", 1));
- if (asyncThreads < 1 || asyncThreads > 32)
- {
- TC_LOG_ERROR("server.worldserver", "Login database: invalid number of worker threads specified. "
- "Please pick a value between 1 and 32.");
- return false;
- }
-
- synchThreads = uint8(sConfigMgr->GetIntDefault("LoginDatabase.SynchThreads", 1));
- ///- Initialise the login database
- if (!LoginDatabase.Open(dbString, asyncThreads, synchThreads))
- {
- TC_LOG_ERROR("server.worldserver", "Cannot connect to login database %s", dbString.c_str());
- return false;
- }
-
- ///- Get the realm Id from the configuration file
- realmID = sConfigMgr->GetIntDefault("RealmID", 0);
- if (!realmID)
- {
- 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);
-
- ///- Clean the database before starting
- ClearOnlineAccounts();
-
- ///- Insert version info into DB
- WorldDatabase.PExecute("UPDATE version SET core_version = '%s', core_revision = '%s'", _FULLVERSION, _HASH); // One-time query
-
- sWorld->LoadDBVersion();
-
- TC_LOG_INFO("server.worldserver", "Using World DB: %s", sWorld->GetDBVersion());
- return true;
-}
-
-void Master::_StopDB()
-{
- CharacterDatabase.Close();
- WorldDatabase.Close();
- LoginDatabase.Close();
-
- MySQL::Library_End();
-}
-
-/// Clear 'online' status for all accounts with characters in this realm
-void Master::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);
-
- // Reset online status for all characters
- CharacterDatabase.DirectExecute("UPDATE characters SET online = 0 WHERE online <> 0");
-
- // Battleground instance ids reset at server restart
- CharacterDatabase.DirectExecute("UPDATE character_battleground_data SET instanceId = 0");
-}
diff --git a/src/server/worldserver/Master.h b/src/server/worldserver/Master.h
deleted file mode 100644
index 9ee94a44acb..00000000000
--- a/src/server/worldserver/Master.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * 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/>.
- */
-
-/// \addtogroup Trinityd
-/// @{
-/// \file
-
-#ifndef _MASTER_H
-#define _MASTER_H
-
-#include "Common.h"
-
-/// Start the server
-class Master
-{
- public:
- int Run();
-
- private:
- bool _StartDB();
- void _StopDB();
-
- void ClearOnlineAccounts();
-};
-
-#define sMaster ACE_Singleton<Master, ACE_Null_Mutex>::instance()
-
-#endif
-
-/// @}
diff --git a/src/server/worldserver/PrecompiledHeaders/worldPCH.h b/src/server/worldserver/PrecompiledHeaders/worldPCH.h
index f94dd953bba..6407485f70b 100644
--- a/src/server/worldserver/PrecompiledHeaders/worldPCH.h
+++ b/src/server/worldserver/PrecompiledHeaders/worldPCH.h
@@ -1,5 +1,3 @@
-#include "WorldSocket.h" // must be first to make ACE happy with ACE includes in it
-
#include "Common.h"
#include "World.h"
#include "Log.h"
diff --git a/src/server/worldserver/RemoteAccess/RARunnable.cpp b/src/server/worldserver/RemoteAccess/RARunnable.cpp
deleted file mode 100644
index 44b07163294..00000000000
--- a/src/server/worldserver/RemoteAccess/RARunnable.cpp
+++ /dev/null
@@ -1,84 +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/>.
- */
-
-/** \file
- \ingroup Trinityd
- */
-
-#include "Common.h"
-#include "Config.h"
-#include "Log.h"
-#include "RARunnable.h"
-#include "World.h"
-
-#include <ace/Reactor_Impl.h>
-#include <ace/TP_Reactor.h>
-#include <ace/Dev_Poll_Reactor.h>
-#include <ace/Acceptor.h>
-#include <ace/SOCK_Acceptor.h>
-
-#include "RASocket.h"
-
-RARunnable::RARunnable()
-{
- ACE_Reactor_Impl* imp;
-
-#if defined (ACE_HAS_EVENT_POLL) || defined (ACE_HAS_DEV_POLL)
- imp = new ACE_Dev_Poll_Reactor();
- imp->max_notify_iterations (128);
- imp->restart (1);
-#else
- imp = new ACE_TP_Reactor();
- imp->max_notify_iterations (128);
-#endif
-
- m_Reactor = new ACE_Reactor (imp, 1);
-}
-
-RARunnable::~RARunnable()
-{
- delete m_Reactor;
-}
-
-void RARunnable::run()
-{
- if (!sConfigMgr->GetBoolDefault("Ra.Enable", false))
- return;
-
- ACE_Acceptor<RASocket, ACE_SOCK_ACCEPTOR> acceptor;
-
- uint16 raPort = uint16(sConfigMgr->GetIntDefault("Ra.Port", 3443));
- std::string stringIp = sConfigMgr->GetStringDefault("Ra.IP", "0.0.0.0");
- ACE_INET_Addr listenAddress(raPort, stringIp.c_str());
-
- if (acceptor.open(listenAddress, m_Reactor) == -1)
- {
- TC_LOG_ERROR("server.worldserver", "Trinity RA can not bind to port %d on %s", raPort, stringIp.c_str());
- return;
- }
-
- TC_LOG_INFO("server.worldserver", "Starting Trinity RA on port %d on %s", raPort, stringIp.c_str());
-
- while (!World::IsStopped())
- {
- ACE_Time_Value interval(0, 100000);
- if (m_Reactor->run_reactor_event_loop(interval) == -1)
- break;
- }
-
- TC_LOG_DEBUG("server.worldserver", "Trinity RA thread exiting");
-}
diff --git a/src/server/worldserver/RemoteAccess/RARunnable.h b/src/server/worldserver/RemoteAccess/RARunnable.h
deleted file mode 100644
index 540ac762f30..00000000000
--- a/src/server/worldserver/RemoteAccess/RARunnable.h
+++ /dev/null
@@ -1,43 +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/>.
- */
-
-/// \addtogroup Trinityd
-/// @{
-/// \file
-
-#ifndef _TRINITY_RARUNNABLE_H_
-#define _TRINITY_RARUNNABLE_H_
-
-#include "Common.h"
-
-#include <ace/Reactor.h>
-
-class RARunnable : public ACE_Based::Runnable
-{
-public:
- RARunnable();
- virtual ~RARunnable();
- void run() override;
-
-private:
- ACE_Reactor* m_Reactor;
-
-};
-
-#endif /* _TRINITY_RARUNNABLE_H_ */
-
-/// @}
diff --git a/src/server/worldserver/RemoteAccess/RASession.cpp b/src/server/worldserver/RemoteAccess/RASession.cpp
new file mode 100644
index 00000000000..846a4eb39e3
--- /dev/null
+++ b/src/server/worldserver/RemoteAccess/RASession.cpp
@@ -0,0 +1,222 @@
+/*
+* 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 <memory>
+#include <boost/asio/write.hpp>
+#include <boost/asio/read_until.hpp>
+#include <boost/array.hpp>
+#include "RASession.h"
+#include "AccountMgr.h"
+#include "Log.h"
+#include "DatabaseEnv.h"
+#include "World.h"
+#include "Config.h"
+
+using boost::asio::ip::tcp;
+
+void RASession::Start()
+{
+ boost::asio::socket_base::bytes_readable command(true);
+ _socket.io_control(command);
+ std::size_t bytes_readable = command.get();
+
+ // Check if there are bytes available, if they are, then the client is requesting the negotiation
+ if (bytes_readable > 0)
+ {
+ // Handle subnegotiation
+ boost::array<char, 1024> buf;
+ _socket.read_some(boost::asio::buffer(buf));
+
+ // Send the end-of-negotiation packet
+ uint8 const reply[2] = { 0xFF, 0xF0 };
+ _socket.write_some(boost::asio::buffer(reply));
+ }
+
+ Send("Authentication Required\r\n");
+ Send("Username: ");
+
+ std::string username = ReadString();
+
+ if (username.empty())
+ return;
+
+ TC_LOG_INFO("commands.ra", "Accepting RA connection from user %s (IP: %s)", username.c_str(), GetRemoteIpAddress().c_str());
+
+ Send("Password: ");
+
+ std::string password = ReadString();
+ if (password.empty())
+ return;
+
+ if (!CheckAccessLevel(username) || !CheckPassword(username, password))
+ {
+ Send("Authentication failed\r\n");
+ _socket.close();
+ return;
+ }
+
+ TC_LOG_INFO("commands.ra", "User %s (IP: %s) authenticated correctly to RA", username.c_str(), GetRemoteIpAddress().c_str());
+
+ // Authentication successful, send the motd
+ Send(std::string(std::string(sWorld->GetMotd()) + "\r\n").c_str());
+
+ // Read commands
+ for (;;)
+ {
+ Send("TC>");
+ std::string command = ReadString();
+
+ if (ProcessCommand(command))
+ break;
+ }
+
+ _socket.close();
+}
+
+int RASession::Send(const char* data)
+{
+ std::ostream os(&_writeBuffer);
+ os << data;
+ size_t written = _socket.send(_writeBuffer.data());
+ _writeBuffer.consume(written);
+ return written;
+}
+
+std::string RASession::ReadString()
+{
+ boost::system::error_code error;
+ size_t read = boost::asio::read_until(_socket, _readBuffer, "\r\n", error);
+ if (!read)
+ {
+ _socket.close();
+ return "";
+ }
+
+ std::string line;
+ std::istream is(&_readBuffer);
+ std::getline(is, line);
+
+ if (*line.rbegin() == '\r')
+ line.erase(line.length() - 1);
+
+ return line;
+}
+
+bool RASession::CheckAccessLevel(const std::string& user)
+{
+ std::string safeUser = user;
+
+ AccountMgr::normalizeString(safeUser);
+
+ PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_ACCOUNT_ACCESS);
+ stmt->setString(0, safeUser);
+ PreparedQueryResult result = LoginDatabase.Query(stmt);
+
+ if (!result)
+ {
+ TC_LOG_INFO("commands.ra", "User %s does not exist in database", user.c_str());
+ return false;
+ }
+
+ Field* fields = result->Fetch();
+
+ if (fields[1].GetUInt8() < sConfigMgr->GetIntDefault("RA.MinLevel", 3))
+ {
+ TC_LOG_INFO("commands.ra", "User %s has no privilege to login", user.c_str());
+ return false;
+ }
+ else if (fields[2].GetInt32() != -1)
+ {
+ TC_LOG_INFO("commands.ra", "User %s has to be assigned on all realms (with RealmID = '-1')", user.c_str());
+ return false;
+ }
+
+ return true;
+}
+
+bool RASession::CheckPassword(const std::string& user, const std::string& pass)
+{
+ std::string safe_user = user;
+ std::transform(safe_user.begin(), safe_user.end(), safe_user.begin(), ::toupper);
+ AccountMgr::normalizeString(safe_user);
+
+ std::string safe_pass = pass;
+ AccountMgr::normalizeString(safe_pass);
+ std::transform(safe_pass.begin(), safe_pass.end(), safe_pass.begin(), ::toupper);
+
+ std::string hash = AccountMgr::CalculateShaPassHash(safe_user, safe_pass);
+
+ PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_CHECK_PASSWORD_BY_NAME);
+
+ stmt->setString(0, safe_user);
+ stmt->setString(1, hash);
+
+ PreparedQueryResult result = LoginDatabase.Query(stmt);
+
+ if (!result)
+ {
+ TC_LOG_INFO("commands.ra", "Wrong password for user: %s", user.c_str());
+ return false;
+ }
+
+ return true;
+}
+
+bool RASession::ProcessCommand(std::string& command)
+{
+ if (command.length() == 0)
+ return true;
+
+ TC_LOG_INFO("commands.ra", "Received command: %s", command.c_str());
+
+ // handle quit, exit and logout commands to terminate connection
+ if (command == "quit" || command == "exit" || command == "logout")
+ {
+ Send("Bye\r\n");
+ return true;
+ }
+
+ // Obtain a new promise per command
+ if (_commandExecuting != nullptr)
+ delete _commandExecuting;
+
+ _commandExecuting = new std::promise<void>();
+
+ CliCommandHolder* cmd = new CliCommandHolder(this, command.c_str(), &RASession::CommandPrint, &RASession::CommandFinished);
+ sWorld->QueueCliCommand(cmd);
+
+ // Wait for the command to finish
+ _commandExecuting->get_future().wait();
+
+ return false;
+}
+
+void RASession::CommandPrint(void* callbackArg, const char* text)
+{
+ if (!text || !*text)
+ return;
+
+ RASession* session = static_cast<RASession*>(callbackArg);
+ session->Send(text);
+}
+
+void RASession::CommandFinished(void* callbackArg, bool /*success*/)
+{
+ RASession* session = static_cast<RASession*>(callbackArg);
+ session->_commandExecuting->set_value();
+}
diff --git a/src/server/worldserver/RemoteAccess/RASession.h b/src/server/worldserver/RemoteAccess/RASession.h
new file mode 100644
index 00000000000..61156a0fa53
--- /dev/null
+++ b/src/server/worldserver/RemoteAccess/RASession.h
@@ -0,0 +1,63 @@
+/*
+* 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 __RASESSION_H__
+#define __RASESSION_H__
+
+#include <memory>
+#include <boost/asio/ip/tcp.hpp>
+#include <boost/asio/streambuf.hpp>
+#include "Common.h"
+
+#include <future>
+
+using boost::asio::ip::tcp;
+
+const size_t bufferSize = 4096;
+
+#define BUFFER_SIZE 4096
+
+class RASession : public std::enable_shared_from_this <RASession>
+{
+public:
+ RASession(tcp::socket&& socket) : _socket(std::move(socket)), _commandExecuting(nullptr)
+ {
+ }
+
+ void Start();
+
+ const std::string GetRemoteIpAddress() const { return _socket.remote_endpoint().address().to_string(); }
+ unsigned short GetRemotePort() const { return _socket.remote_endpoint().port(); }
+
+private:
+ int Send(const char* data);
+ std::string ReadString();
+ bool CheckAccessLevel(const std::string& user);
+ bool CheckPassword(const std::string& user, const std::string& pass);
+ bool ProcessCommand(std::string& command);
+
+ static void CommandPrint(void* callbackArg, const char* text);
+ static void CommandFinished(void* callbackArg, bool);
+
+ tcp::socket _socket;
+ boost::asio::streambuf _readBuffer;
+ boost::asio::streambuf _writeBuffer;
+ std::promise<void>* _commandExecuting;
+};
+
+#endif
diff --git a/src/server/worldserver/RemoteAccess/RASocket.cpp b/src/server/worldserver/RemoteAccess/RASocket.cpp
deleted file mode 100644
index f2c7a8e0f02..00000000000
--- a/src/server/worldserver/RemoteAccess/RASocket.cpp
+++ /dev/null
@@ -1,424 +0,0 @@
-/*
- * 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
- \ingroup Trinityd
-*/
-
-#include "Common.h"
-#include "Configuration/Config.h"
-#include "Database/DatabaseEnv.h"
-#include "AccountMgr.h"
-#include "Log.h"
-#include "RASocket.h"
-#include "Util.h"
-#include "World.h"
-#include "SHA1.h"
-
-RASocket::RASocket()
-{
- _minLevel = uint8(sConfigMgr->GetIntDefault("RA.MinLevel", 3));
- _commandExecuting = false;
-}
-
-int RASocket::open(void *)
-{
- ACE_INET_Addr remoteAddress;
-
- if (peer().get_remote_addr(remoteAddress) == -1)
- {
- TC_LOG_ERROR("server.worldserver", "RASocket::open: peer().get_remote_addr error is %s", ACE_OS::strerror(errno));
- return -1;
- }
-
- TC_LOG_INFO("commands.ra", "Incoming connection from %s", remoteAddress.get_host_addr());
-
- return activate();
-}
-
-int RASocket::handle_close(ACE_HANDLE /*handle*/, ACE_Reactor_Mask /*mask*/)
-{
- TC_LOG_INFO("commands.ra", "Closing connection");
- peer().close_reader();
- wait();
- // While the above wait() will wait for the ::svc() to finish, it will not wait for the async event
- // RASocket::commandfinished to be completed. Calling destroy() before the latter function ends
- // will lead to using a freed pointer -> crash.
- while (_commandExecuting.value())
- ACE_OS::sleep(1);
-
- destroy();
- return 0;
-}
-
-int RASocket::send(const std::string& line)
-{
-#ifdef MSG_NOSIGNAL
- ssize_t n = peer().send(line.c_str(), line.length(), MSG_NOSIGNAL);
-#else
- ssize_t n = peer().send(line.c_str(), line.length());
-#endif // MSG_NOSIGNAL
-
- return n == ssize_t(line.length()) ? 0 : -1;
-}
-
-int RASocket::recv_line(ACE_Message_Block& buffer)
-{
- char byte;
- for (;;)
- {
- ssize_t n = peer().recv(&byte, sizeof(byte));
-
- if (n < 0)
- return -1;
-
- if (n == 0)
- {
- // EOF, connection was closed
- errno = ECONNRESET;
- return -1;
- }
-
- ACE_ASSERT(n == sizeof(byte));
-
- if (byte == '\n')
- break;
- else if (byte == '\r') /* Ignore CR */
- continue;
- else if (buffer.copy(&byte, sizeof(byte)) == -1)
- return -1;
- }
-
- const char nullTerm = '\0';
- if (buffer.copy(&nullTerm, sizeof(nullTerm)) == -1)
- return -1;
-
- return 0;
-}
-
-int RASocket::recv_line(std::string& out_line)
-{
- char buf[4096];
-
- ACE_Data_Block db(sizeof (buf),
- ACE_Message_Block::MB_DATA,
- buf,
- 0,
- 0,
- ACE_Message_Block::DONT_DELETE,
- 0);
-
- ACE_Message_Block message_block(&db,
- ACE_Message_Block::DONT_DELETE,
- 0);
-
- if (recv_line(message_block) == -1)
- {
- TC_LOG_DEBUG("commands.ra", "Recv error %s", ACE_OS::strerror(errno));
- return -1;
- }
-
- out_line = message_block.rd_ptr();
-
- return 0;
-}
-
-int RASocket::process_command(const std::string& command)
-{
- if (command.length() == 0)
- return 0;
-
- TC_LOG_INFO("commands.ra", "Received command: %s", command.c_str());
-
- // handle quit, exit and logout commands to terminate connection
- if (command == "quit" || command == "exit" || command == "logout") {
- (void) send("Bye\r\n");
- return -1;
- }
-
- _commandExecuting = true;
- CliCommandHolder* cmd = new CliCommandHolder(this, command.c_str(), &RASocket::zprint, &RASocket::commandFinished);
- sWorld->QueueCliCommand(cmd);
-
- // wait for result
- ACE_Message_Block* mb;
- for (;;)
- {
- if (getq(mb) == -1)
- return -1;
-
- if (mb->msg_type() == ACE_Message_Block::MB_BREAK)
- {
- mb->release();
- break;
- }
-
- if (send(std::string(mb->rd_ptr(), mb->length())) == -1)
- {
- mb->release();
- return -1;
- }
-
- mb->release();
- }
-
- return 0;
-}
-
-int RASocket::check_access_level(const std::string& user)
-{
- std::string safeUser = user;
-
- Utf8ToUpperOnlyLatin(safeUser);
-
- PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_ACCOUNT_ACCESS);
- stmt->setString(0, safeUser);
- PreparedQueryResult result = LoginDatabase.Query(stmt);
-
- if (!result)
- {
- TC_LOG_INFO("commands.ra", "User %s does not exist in database", user.c_str());
- return -1;
- }
-
- Field* fields = result->Fetch();
-
- if (fields[1].GetUInt8() < _minLevel)
- {
- TC_LOG_INFO("commands.ra", "User %s has no privilege to login", user.c_str());
- return -1;
- }
- else if (fields[2].GetInt32() != -1)
- {
- TC_LOG_INFO("commands.ra", "User %s has to be assigned on all realms (with RealmID = '-1')", user.c_str());
- return -1;
- }
-
- return 0;
-}
-
-int RASocket::check_password(const std::string& user, const std::string& pass)
-{
- std::string safe_user = user;
- Utf8ToUpperOnlyLatin(safe_user);
-
- std::string safe_pass = pass;
- Utf8ToUpperOnlyLatin(safe_pass);
-
- std::string hash = AccountMgr::CalculateShaPassHash(safe_user, safe_pass);
-
- PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_CHECK_PASSWORD_BY_NAME);
-
- stmt->setString(0, safe_user);
- stmt->setString(1, hash);
-
- PreparedQueryResult result = LoginDatabase.Query(stmt);
-
- if (!result)
- {
- TC_LOG_INFO("commands.ra", "Wrong password for user: %s", user.c_str());
- return -1;
- }
-
- return 0;
-}
-
-int RASocket::authenticate()
-{
- if (send(std::string("Username: ")) == -1)
- return -1;
-
- std::string user;
- if (recv_line(user) == -1)
- return -1;
-
- if (send(std::string("Password: ")) == -1)
- return -1;
-
- std::string pass;
- if (recv_line(pass) == -1)
- return -1;
-
- TC_LOG_INFO("commands.ra", "Login attempt for user: %s", user.c_str());
-
- if (check_access_level(user) == -1)
- return -1;
-
- if (check_password(user, pass) == -1)
- return -1;
-
- TC_LOG_INFO("commands.ra", "User login: %s", user.c_str());
-
- return 0;
-}
-
-
-int RASocket::subnegotiate()
-{
- char buf[1024];
-
- ACE_Data_Block db(sizeof (buf),
- ACE_Message_Block::MB_DATA,
- buf,
- 0,
- 0,
- ACE_Message_Block::DONT_DELETE,
- 0);
-
- ACE_Message_Block message_block(&db,
- ACE_Message_Block::DONT_DELETE,
- 0);
-
- const size_t recv_size = message_block.space();
-
- // Wait a maximum of 1000ms for negotiation packet - not all telnet clients may send it
- ACE_Time_Value waitTime = ACE_Time_Value(1);
- const ssize_t n = peer().recv(message_block.wr_ptr(),
- recv_size, &waitTime);
-
- if (n <= 0)
- return int(n);
-
- if (n >= 1024)
- {
- TC_LOG_DEBUG("commands.ra", "RASocket::subnegotiate: allocated buffer 1024 bytes was too small for negotiation packet, size: %u", uint32(n));
- return -1;
- }
-
- buf[n] = '\0';
-
- #ifdef _DEBUG
- for (uint8 i = 0; i < n; )
- {
- uint8 iac = buf[i];
- if (iac == 0xFF) // "Interpret as Command" (IAC)
- {
- uint8 command = buf[++i];
- std::stringstream ss;
- switch (command)
- {
- case 0xFB: // WILL
- ss << "WILL ";
- break;
- case 0xFC: // WON'T
- ss << "WON'T ";
- break;
- case 0xFD: // DO
- ss << "DO ";
- break;
- case 0xFE: // DON'T
- ss << "DON'T ";
- break;
- default:
- return -1; // not allowed
- }
-
- uint8 param = buf[++i];
- ss << uint32(param);
- TC_LOG_DEBUG("commands.ra", ss.str().c_str());
- }
- ++i;
- }
- #endif
-
- //! Just send back end of subnegotiation packet
- uint8 const reply[2] = {0xFF, 0xF0};
-
-#ifdef MSG_NOSIGNAL
- return int(peer().send(reply, 2, MSG_NOSIGNAL));
-#else
- return int(peer().send(reply, 2));
-#endif // MSG_NOSIGNAL
-}
-
-int RASocket::svc(void)
-{
- //! Subnegotiation may differ per client - do not react on it
- subnegotiate();
-
- if (send("Authentication required\r\n") == -1)
- return -1;
-
- if (authenticate() == -1)
- {
- (void) send("Authentication failed\r\n");
- return -1;
- }
-
- // send motd
- if (send(std::string(sWorld->GetMotd()) + "\r\n") == -1)
- return -1;
-
- for (;;)
- {
- // show prompt
- if (send("TC> ") == -1)
- return -1;
-
- std::string line;
-
- if (recv_line(line) == -1)
- return -1;
-
- if (process_command(line) == -1)
- return -1;
- }
-
- return 0;
-}
-
-void RASocket::zprint(void* callbackArg, const char * szText)
-{
- if (!szText || !callbackArg)
- return;
-
- RASocket* socket = static_cast<RASocket*>(callbackArg);
- size_t sz = strlen(szText);
-
- ACE_Message_Block* mb = new ACE_Message_Block(sz);
- mb->copy(szText, sz);
-
- ACE_Time_Value tv = ACE_Time_Value::zero;
- if (socket->putq(mb, &tv) == -1)
- {
- TC_LOG_DEBUG("commands.ra", "Failed to enqueue message, queue is full or closed. Error is %s", ACE_OS::strerror(errno));
- mb->release();
- }
-}
-
-void RASocket::commandFinished(void* callbackArg, bool /*success*/)
-{
- if (!callbackArg)
- return;
-
- RASocket* socket = static_cast<RASocket*>(callbackArg);
-
- ACE_Message_Block* mb = new ACE_Message_Block();
-
- mb->msg_type(ACE_Message_Block::MB_BREAK);
-
- // the message is 0 size control message to tell that command output is finished
- // hence we don't put timeout, because it shouldn't increase queue size and shouldn't block
- if (socket->putq(mb->duplicate()) == -1)
- // getting here is bad, command can't be marked as complete
- TC_LOG_DEBUG("commands.ra", "Failed to enqueue command end message. Error is %s", ACE_OS::strerror(errno));
-
- mb->release();
-
- socket->_commandExecuting = false;
-}
diff --git a/src/server/worldserver/RemoteAccess/RASocket.h b/src/server/worldserver/RemoteAccess/RASocket.h
deleted file mode 100644
index 2cbb14b3578..00000000000
--- a/src/server/worldserver/RemoteAccess/RASocket.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * 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/>.
- */
-
-/// \addtogroup Trinityd
-/// @{
-/// \file
-
-#ifndef _RASOCKET_H
-#define _RASOCKET_H
-
-#include "Common.h"
-
-#include <ace/Synch_Traits.h>
-#include <ace/Svc_Handler.h>
-#include <ace/SOCK_Stream.h>
-#include <ace/SOCK_Acceptor.h>
-
-/// Remote Administration socket
-class RASocket : public ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_MT_SYNCH>
-{
- public:
- RASocket();
- virtual ~RASocket() { }
-
- virtual int svc() override;
- virtual int open(void* = 0) override;
- virtual int handle_close(ACE_HANDLE = ACE_INVALID_HANDLE, ACE_Reactor_Mask = ACE_Event_Handler::ALL_EVENTS_MASK) override;
-
- private:
- int recv_line(std::string& outLine);
- int recv_line(ACE_Message_Block& buffer);
- int process_command(const std::string& command);
- int authenticate();
- int subnegotiate(); ///< Used by telnet protocol RFC 854 / 855
- int check_access_level(const std::string& user);
- int check_password(const std::string& user, const std::string& pass);
- int send(const std::string& line);
-
- static void zprint(void* callbackArg, const char* szText);
- static void commandFinished(void* callbackArg, bool success);
-
- private:
- uint8 _minLevel; ///< Minimum security level required to connect
- ACE_Atomic_Op<ACE_Thread_Mutex, bool> _commandExecuting;
-};
-
-#endif
-
-/// @}
diff --git a/src/server/worldserver/TCSoap/TCSoap.cpp b/src/server/worldserver/TCSoap/TCSoap.cpp
index 1549019352d..5122752f3a4 100644
--- a/src/server/worldserver/TCSoap/TCSoap.cpp
+++ b/src/server/worldserver/TCSoap/TCSoap.cpp
@@ -22,7 +22,7 @@
#include "AccountMgr.h"
#include "Log.h"
-void TCSoapRunnable::run()
+void TCSoapThread(const std::string& host, uint16 port)
{
struct soap soap;
soap_init(&soap);
@@ -33,13 +33,13 @@ void TCSoapRunnable::run()
soap.accept_timeout = 3;
soap.recv_timeout = 5;
soap.send_timeout = 5;
- if (!soap_valid_socket(soap_bind(&soap, _host.c_str(), _port, 100)))
+ if (!soap_valid_socket(soap_bind(&soap, host.c_str(), port, 100)))
{
- TC_LOG_ERROR("network.soap", "Couldn't bind to %s:%d", _host.c_str(), _port);
+ TC_LOG_ERROR("network.soap", "Couldn't bind to %s:%d", host.c_str(), port);
exit(-1);
}
- TC_LOG_INFO("network.soap", "Bound to http://%s:%d", _host.c_str(), _port);
+ TC_LOG_INFO("network.soap", "Bound to http://%s:%d", host.c_str(), port);
while (!World::IsStopped())
{
@@ -48,28 +48,21 @@ void TCSoapRunnable::run()
TC_LOG_DEBUG("network.soap", "Accepted connection from IP=%d.%d.%d.%d", (int)(soap.ip>>24)&0xFF, (int)(soap.ip>>16)&0xFF, (int)(soap.ip>>8)&0xFF, (int)soap.ip&0xFF);
struct soap* thread_soap = soap_copy(&soap);// make a safe copy
-
- ACE_Message_Block* mb = new ACE_Message_Block(sizeof(struct soap*));
- ACE_OS::memcpy(mb->wr_ptr(), &thread_soap, sizeof(struct soap*));
- process_message(mb);
+ process_message(thread_soap);
}
soap_done(&soap);
}
-void TCSoapRunnable::process_message(ACE_Message_Block* mb)
+void process_message(struct soap* soap_message)
{
- ACE_TRACE (ACE_TEXT ("SOAPWorkingThread::process_message"));
-
- struct soap* soap;
- ACE_OS::memcpy(&soap, mb->rd_ptr (), sizeof(struct soap*));
- mb->release();
+ TC_LOG_TRACE("network.soap", "SOAPWorkingThread::process_message");
- soap_serve(soap);
- soap_destroy(soap); // dealloc C++ data
- soap_end(soap); // dealloc data and clean up
- soap_done(soap); // detach soap struct
- free(soap);
+ soap_serve(soap_message);
+ soap_destroy(soap_message); // dealloc C++ data
+ soap_end(soap_message); // dealloc data and clean up
+ soap_done(soap_message); // detach soap struct
+ free(soap_message);
}
/*
Code used for generating stubs:
@@ -112,19 +105,15 @@ int ns1__executeCommand(soap* soap, char* command, char** result)
// commands are executed in the world thread. We have to wait for them to be completed
{
- // CliCommandHolder will be deleted from world, accessing after queueing is NOT save
+ // CliCommandHolder will be deleted from world, accessing after queueing is NOT safe
CliCommandHolder* cmd = new CliCommandHolder(&connection, command, &SOAPCommand::print, &SOAPCommand::commandFinished);
sWorld->QueueCliCommand(cmd);
}
- // wait for callback to complete command
-
- int acc = connection.pendingCommands.acquire();
- if (acc)
- TC_LOG_ERROR("network.soap", "Error while acquiring lock, acc = %i, errno = %u", acc, errno);
-
- // alright, command finished
+ // Wait until the command has finished executing
+ connection.finishedPromise.get_future().wait();
+ // The command has finished executing already
char* printBuffer = soap_strdup(soap, connection.m_printBuffer.c_str());
if (connection.hasCommandSucceeded())
{
@@ -139,7 +128,6 @@ void SOAPCommand::commandFinished(void* soapconnection, bool success)
{
SOAPCommand* con = (SOAPCommand*)soapconnection;
con->setCommandSuccess(success);
- con->pendingCommands.release();
}
////////////////////////////////////////////////////////////////////////////////
diff --git a/src/server/worldserver/TCSoap/TCSoap.h b/src/server/worldserver/TCSoap/TCSoap.h
index 427d37ef0cc..999a03a9009 100644
--- a/src/server/worldserver/TCSoap/TCSoap.h
+++ b/src/server/worldserver/TCSoap/TCSoap.h
@@ -19,36 +19,17 @@
#define _TCSOAP_H
#include "Define.h"
+#include <mutex>
+#include <future>
-#include <ace/Semaphore.h>
-#include <ace/Task.h>
-#include <Threading.h>
-
-class TCSoapRunnable : public ACE_Based::Runnable
-{
- public:
- TCSoapRunnable() : _port(0) { }
-
- void run() override;
-
- void SetListenArguments(const std::string& host, uint16 port)
- {
- _host = host;
- _port = port;
- }
-
- private:
- void process_message(ACE_Message_Block* mb);
-
- std::string _host;
- uint16 _port;
-};
+void process_message(struct soap* soap_message);
+void TCSoapThread(const std::string& host, uint16 port);
class SOAPCommand
{
public:
SOAPCommand():
- pendingCommands(0, USYNC_THREAD, "pendingCommands"), m_success(false)
+ m_success(false)
{
}
@@ -61,11 +42,10 @@ class SOAPCommand
m_printBuffer += msg;
}
- ACE_Semaphore pendingCommands;
-
void setCommandSuccess(bool val)
{
m_success = val;
+ finishedPromise.set_value();
}
bool hasCommandSucceeded() const
@@ -82,6 +62,7 @@ class SOAPCommand
bool m_success;
std::string m_printBuffer;
+ std::promise<void> finishedPromise;
};
#endif
diff --git a/src/server/worldserver/WorldThread/WorldRunnable.cpp b/src/server/worldserver/WorldThread/WorldRunnable.cpp
deleted file mode 100644
index 476007f6ea0..00000000000
--- a/src/server/worldserver/WorldThread/WorldRunnable.cpp
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * 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
- \ingroup Trinityd
-*/
-
-#include "Common.h"
-#include "ObjectAccessor.h"
-#include "World.h"
-#include "WorldSocketMgr.h"
-#include "Database/DatabaseEnv.h"
-#include "ScriptMgr.h"
-#include "BattlegroundMgr.h"
-#include "MapManager.h"
-#include "Timer.h"
-#include "WorldRunnable.h"
-#include "OutdoorPvPMgr.h"
-
-#define WORLD_SLEEP_CONST 50
-
-#ifdef _WIN32
-#include "ServiceWin32.h"
-extern int m_ServiceStatus;
-#endif
-
-/// Heartbeat for the World
-void WorldRunnable::run()
-{
- uint32 realCurrTime = 0;
- uint32 realPrevTime = getMSTime();
-
- uint32 prevSleepTime = 0; // used for balanced full tick time length near WORLD_SLEEP_CONST
-
- sScriptMgr->OnStartup();
-
- ///- While we have not World::m_stopEvent, update the world
- while (!World::IsStopped())
- {
- ++World::m_worldLoopCounter;
- realCurrTime = getMSTime();
-
- uint32 diff = getMSTimeDiff(realPrevTime, realCurrTime);
-
- sWorld->Update( diff );
- realPrevTime = realCurrTime;
-
- // diff (D0) include time of previous sleep (d0) + tick time (t0)
- // we want that next d1 + t1 == WORLD_SLEEP_CONST
- // we can't know next t1 and then can use (t0 + d1) == WORLD_SLEEP_CONST requirement
- // d1 = WORLD_SLEEP_CONST - t0 = WORLD_SLEEP_CONST - (D0 - d0) = WORLD_SLEEP_CONST + d0 - D0
- if (diff <= WORLD_SLEEP_CONST+prevSleepTime)
- {
- prevSleepTime = WORLD_SLEEP_CONST+prevSleepTime-diff;
- ACE_Based::Thread::Sleep(prevSleepTime);
- }
- else
- prevSleepTime = 0;
-
- #ifdef _WIN32
- if (m_ServiceStatus == 0)
- World::StopNow(SHUTDOWN_EXIT_CODE);
-
- while (m_ServiceStatus == 2)
- Sleep(1000);
- #endif
- }
-
- sScriptMgr->OnShutdown();
-
- sWorld->KickAll(); // save and kick all players
- sWorld->UpdateSessions( 1 ); // real players unload required UpdateSessions call
-
- // unload battleground templates before different singletons destroyed
- sBattlegroundMgr->DeleteAllBattlegrounds();
-
- sWorldSocketMgr->StopNetwork();
-
- sMapMgr->UnloadAll(); // unload all grids (including locked in memory)
- sObjectAccessor->UnloadAll(); // unload 'i_player2corpse' storage and remove from world
- sScriptMgr->Unload();
- sOutdoorPvPMgr->Die();
-}
diff --git a/src/server/worldserver/WorldThread/WorldRunnable.h b/src/server/worldserver/WorldThread/WorldRunnable.h
deleted file mode 100644
index dfc74dd1e3a..00000000000
--- a/src/server/worldserver/WorldThread/WorldRunnable.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * 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/>.
- */
-
-/// \addtogroup Trinityd
-/// @{
-/// \file
-
-#ifndef __WORLDRUNNABLE_H
-#define __WORLDRUNNABLE_H
-
-/// Heartbeat thread for the World
-class WorldRunnable : public ACE_Based::Runnable
-{
- public:
- void run() override;
-};
-
-#endif
-
-/// @}
diff --git a/src/server/worldserver/worldserver.conf.dist b/src/server/worldserver/worldserver.conf.dist
index 18c4d63b879..f9c88e0dcef 100644
--- a/src/server/worldserver/worldserver.conf.dist
+++ b/src/server/worldserver/worldserver.conf.dist
@@ -145,6 +145,14 @@ WorldServerPort = 8085
BindIP = "0.0.0.0"
#
+# ThreadPool
+# Description: Number of threads to be used for the global thread pool
+# The thread pool is currently used for the signal handler and remote access
+# Default: 1
+
+ThreadPool = 1
+
+#
###################################################################################################
###################################################################################################
@@ -162,7 +170,8 @@ 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.
+# 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)
@@ -1042,6 +1051,16 @@ AccountInstancesPerHour = 5
Account.PasswordChangeSecurity = 0
#
+# BirthdayTime
+# Description: Set to date of project's birth in UNIX time. By default the date when
+# TrinityCore was started (Thu Oct 2, 2008)
+# Default: 1222964635
+#
+#
+
+BirthdayTime = 1222964635
+
+#
###################################################################################################
###################################################################################################
@@ -2586,8 +2605,10 @@ UI.ShowQuestLevelsInDialogs = 0
# 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)
+# 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"
@@ -2703,7 +2724,8 @@ Log.Async.Enable = 0
#
# Allow.IP.Based.Action.Logging
-# Description: Logs actions, e.g. account login and logout to name a few, based on IP of current session.
+# Description: Logs actions, e.g. account login and logout to name a few, based on IP of
+# current session.
# Default: 0 - (Disabled)
# 1 - (Enabled)