aboutsummaryrefslogtreecommitdiff
path: root/src/common
diff options
context:
space:
mode:
Diffstat (limited to 'src/common')
-rw-r--r--src/common/CMakeLists.txt115
-rw-r--r--src/common/Collision/BoundingIntervalHierarchy.h2
-rw-r--r--src/common/Collision/DynamicTree.h2
-rw-r--r--src/common/Collision/Management/IVMapManager.h2
-rw-r--r--src/common/Collision/Management/MMapFactory.h2
-rw-r--r--src/common/Collision/Management/MMapManager.h4
-rw-r--r--src/common/Collision/Management/VMapFactory.h2
-rw-r--r--src/common/Collision/Management/VMapManager2.h4
-rw-r--r--src/common/Collision/Maps/MapTree.h6
-rw-r--r--src/common/Collision/Maps/TileAssembler.h10
-rw-r--r--src/common/Collision/Models/GameObjectModel.h6
-rw-r--r--src/common/Collision/Models/ModelInstance.h4
-rw-r--r--src/common/Collision/Models/WorldModel.h8
-rw-r--r--src/common/Collision/RegularGrid.h2
-rw-r--r--src/common/Common.h43
-rw-r--r--src/common/Configuration/BuiltInConfig.cpp52
-rw-r--r--src/common/Configuration/BuiltInConfig.h43
-rw-r--r--src/common/Configuration/Config.cpp76
-rw-r--r--src/common/Configuration/Config.h34
-rw-r--r--src/common/Cryptography/ARC4.h2
-rw-r--r--src/common/Cryptography/Authentication/AuthCrypt.h2
-rw-r--r--src/common/Cryptography/BigNumber.h2
-rw-r--r--src/common/Cryptography/HMACSHA1.h2
-rw-r--r--src/common/Cryptography/OpenSSLCrypto.h8
-rw-r--r--src/common/Cryptography/SHA1.cpp8
-rw-r--r--src/common/Cryptography/SHA1.h7
-rw-r--r--src/common/Debugging/Errors.cpp7
-rw-r--r--src/common/Debugging/Errors.h14
-rw-r--r--src/common/Define.h45
-rw-r--r--src/common/GitRevision.cpp21
-rw-r--r--src/common/GitRevision.h27
-rw-r--r--src/common/Logging/Appender.h8
-rw-r--r--src/common/Logging/AppenderConsole.h2
-rw-r--r--src/common/Logging/AppenderFile.h2
-rw-r--r--src/common/Logging/Log.cpp25
-rw-r--r--src/common/Logging/Log.h9
-rw-r--r--src/common/Logging/LogOperation.h3
-rw-r--r--src/common/Logging/Logger.h2
-rw-r--r--src/common/Platform/ServiceWin32.cpp263
-rw-r--r--src/common/Platform/ServiceWin32.h28
-rw-r--r--src/common/Threading/LockedQueue.h8
-rw-r--r--src/common/Threading/MPSCQueue.h83
-rw-r--r--src/common/Utilities/Containers.h179
-rw-r--r--src/common/Utilities/EventMap.h14
-rw-r--r--src/common/Utilities/EventProcessor.h4
-rw-r--r--src/common/Utilities/MessageBuffer.h139
-rw-r--r--src/common/Utilities/Random.cpp91
-rw-r--r--src/common/Utilities/Random.h99
-rw-r--r--src/common/Utilities/StartProcess.cpp267
-rw-r--r--src/common/Utilities/StartProcess.h67
-rw-r--r--src/common/Utilities/StringFormat.h2
-rw-r--r--src/common/Utilities/TaskScheduler.h8
-rw-r--r--src/common/Utilities/Util.cpp133
-rw-r--r--src/common/Utilities/Util.h83
54 files changed, 1754 insertions, 327 deletions
diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt
index 8dee99c65e7..0428738f2dd 100644
--- a/src/common/CMakeLists.txt
+++ b/src/common/CMakeLists.txt
@@ -8,42 +8,33 @@
# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-if( USE_COREPCH )
- include_directories(${CMAKE_CURRENT_BINARY_DIR})
-endif()
-
-file(GLOB_RECURSE sources_Common Common.cpp Common.h)
-file(GLOB_RECURSE sources_Collision Collision/*.cpp Collision/*.h)
-file(GLOB_RECURSE sources_Threading Threading/*.cpp Threading/*.h)
-file(GLOB_RECURSE sources_Utilities Utilities/*.cpp Utilities/*.h)
-file(GLOB_RECURSE sources_Configuration Configuration/*.cpp Configuration/*.h)
-file(GLOB_RECURSE sources_Logging Logging/*.cpp Logging/*.h)
-if (SERVERS)
- file(GLOB_RECURSE sources_Cryptography Cryptography/*.cpp Cryptography/*.h)
-endif (SERVERS)
+CollectSourceFiles(
+ ${CMAKE_CURRENT_SOURCE_DIR}
+ PRIVATE_SOURCES
+ # Exclude
+ ${CMAKE_CURRENT_SOURCE_DIR}/Debugging
+ ${CMAKE_CURRENT_SOURCE_DIR}/Platform
+ ${CMAKE_CURRENT_SOURCE_DIR}/PrecompiledHeaders)
# Manually set sources for Debugging directory as we don't want to include WheatyExceptionReport in common project
# It needs to be included both in authserver and worldserver for the static global variable to be properly initialized
# and to handle crash logs on windows
-set(sources_Debugging Debugging/Errors.cpp Debugging/Errors.h)
-file(GLOB sources_localdir *.cpp *.h)
+list(APPEND PRIVATE_SOURCES
+ ${CMAKE_CURRENT_SOURCE_DIR}/Debugging/Errors.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/Debugging/Errors.h)
if (USE_COREPCH)
- set(common_STAT_PCH_HDR PrecompiledHeaders/commonPCH.h)
- set(common_STAT_PCH_SRC PrecompiledHeaders/commonPCH.cpp)
+ set(PRIVATE_PCH_HEADER PrecompiledHeaders/commonPCH.h)
+ set(PRIVATE_PCH_SOURCE PrecompiledHeaders/commonPCH.cpp)
endif (USE_COREPCH)
-set(common_STAT_SRCS
- ${common_STAT_SRCS}
- ${sources_Common}
- ${sources_Collision}
- ${sources_Threading}
- ${sources_Utilities}
- ${sources_Debugging}
- ${sources_Configuration}
- ${sources_Logging}
- ${sources_Cryptography}
- ${sources_localdir}
+GroupSources(${CMAKE_CURRENT_SOURCE_DIR})
+
+add_definitions(-DTRINITY_API_EXPORT_COMMON)
+
+add_library(common
+ ${PRIVATE_PCH_SOURCE}
+ ${PRIVATE_SOURCES}
)
# Do NOT add any extra include directory here, as we don't want the common
@@ -55,37 +46,55 @@ set(common_STAT_SRCS
# linkage (enums, defines...) it is discouraged to do so unless necessary, as it will pullute
# include_directories leading to further unnoticed dependency aditions
# Linker Depencency requirements: none
-include_directories(
- ${CMAKE_BINARY_DIR}
+CollectIncludeDirectories(
${CMAKE_CURRENT_SOURCE_DIR}
- ${CMAKE_CURRENT_SOURCE_DIR}/Collision
- ${CMAKE_CURRENT_SOURCE_DIR}/Collision/Management
- ${CMAKE_CURRENT_SOURCE_DIR}/Collision/Maps
- ${CMAKE_CURRENT_SOURCE_DIR}/Collision/Models
- ${CMAKE_CURRENT_SOURCE_DIR}/Configuration
- ${CMAKE_CURRENT_SOURCE_DIR}/Cryptography
- ${CMAKE_CURRENT_SOURCE_DIR}/Debugging
- ${CMAKE_CURRENT_SOURCE_DIR}/Logging
- ${CMAKE_CURRENT_SOURCE_DIR}/Utilities
- ${CMAKE_SOURCE_DIR}/dep/cppformat
- ${CMAKE_SOURCE_DIR}/dep/g3dlite/include
- ${CMAKE_SOURCE_DIR}/dep/recastnavigation/Detour/Include
- ${CMAKE_SOURCE_DIR}/dep/SFMT
- ${CMAKE_SOURCE_DIR}/dep/utf8cpp
- ${OPENSSL_INCLUDE_DIR}
- ${VALGRIND_INCLUDE_DIR}
-)
+ PUBLIC_INCLUDES
+ # Exclude
+ ${CMAKE_CURRENT_SOURCE_DIR}/PrecompiledHeaders)
-GroupSources(${CMAKE_CURRENT_SOURCE_DIR})
+target_include_directories(common
+ PUBLIC
+ # Provide the binary dir for all child targets
+ ${CMAKE_BINARY_DIR}
+ ${PUBLIC_INCLUDES}
+ PRIVATE
+ ${CMAKE_CURRENT_BINARY_DIR})
-add_library(common STATIC
- ${common_STAT_SRCS}
- ${common_STAT_PCH_SRC}
-)
+target_link_libraries(common
+ PUBLIC
+ boost
+ cppformat
+ g3dlib
+ Detour
+ sfmt
+ utf8cpp
+ openssl
+ valgrind
+ threads
+ jemalloc
+ PRIVATE
+ process)
add_dependencies(common revision_data.h)
+set_target_properties(common
+ PROPERTIES
+ FOLDER
+ "server")
+
+if( BUILD_SHARED_LIBS )
+ if( UNIX )
+ install(TARGETS common
+ LIBRARY
+ DESTINATION lib)
+ elseif( WIN32 )
+ install(TARGETS common
+ RUNTIME
+ DESTINATION "${CMAKE_INSTALL_PREFIX}")
+ endif()
+endif()
+
# Generate precompiled header
if (USE_COREPCH)
- add_cxx_pch(common ${common_STAT_PCH_HDR} ${common_STAT_PCH_SRC})
+ add_cxx_pch(common ${PRIVATE_PCH_HEADER} ${PRIVATE_PCH_SOURCE})
endif ()
diff --git a/src/common/Collision/BoundingIntervalHierarchy.h b/src/common/Collision/BoundingIntervalHierarchy.h
index 0b15bd2d92f..eb0a102806f 100644
--- a/src/common/Collision/BoundingIntervalHierarchy.h
+++ b/src/common/Collision/BoundingIntervalHierarchy.h
@@ -67,7 +67,7 @@ struct AABound
Copyright (c) 2003-2007 Christopher Kulla
*/
-class BIH
+class TC_COMMON_API BIH
{
private:
void init_empty()
diff --git a/src/common/Collision/DynamicTree.h b/src/common/Collision/DynamicTree.h
index 0f18bb265f8..85707efebd2 100644
--- a/src/common/Collision/DynamicTree.h
+++ b/src/common/Collision/DynamicTree.h
@@ -31,7 +31,7 @@ namespace G3D
class GameObjectModel;
struct DynTreeImpl;
-class DynamicMapTree
+class TC_COMMON_API DynamicMapTree
{
DynTreeImpl *impl;
diff --git a/src/common/Collision/Management/IVMapManager.h b/src/common/Collision/Management/IVMapManager.h
index 1e64551956c..35437b7b816 100644
--- a/src/common/Collision/Management/IVMapManager.h
+++ b/src/common/Collision/Management/IVMapManager.h
@@ -42,7 +42,7 @@ namespace VMAP
#define VMAP_INVALID_HEIGHT_VALUE -200000.0f // real assigned value in unknown height case
//===========================================================
- class IVMapManager
+ class TC_COMMON_API IVMapManager
{
private:
bool iEnableLineOfSightCalc;
diff --git a/src/common/Collision/Management/MMapFactory.h b/src/common/Collision/Management/MMapFactory.h
index edd074fc93d..6dda7a40a22 100644
--- a/src/common/Collision/Management/MMapFactory.h
+++ b/src/common/Collision/Management/MMapFactory.h
@@ -38,7 +38,7 @@ namespace MMAP
// static class
// holds all mmap global data
// access point to MMapManager singleton
- class MMapFactory
+ class TC_COMMON_API MMapFactory
{
public:
static MMapManager* createOrGetMMapManager();
diff --git a/src/common/Collision/Management/MMapManager.h b/src/common/Collision/Management/MMapManager.h
index 1a502a916dd..a8d792296bb 100644
--- a/src/common/Collision/Management/MMapManager.h
+++ b/src/common/Collision/Management/MMapManager.h
@@ -58,7 +58,7 @@ namespace MMAP
// singleton class
// holds all all access to mmap loading unloading and meshes
- class MMapManager
+ class TC_COMMON_API MMapManager
{
public:
MMapManager() : loadedTiles(0), thread_safe_environment(true) {}
@@ -75,7 +75,7 @@ namespace MMAP
dtNavMesh const* GetNavMesh(uint32 mapId);
uint32 getLoadedTilesCount() const { return loadedTiles; }
- uint32 getLoadedMapsCount() const { return loadedMMaps.size(); }
+ uint32 getLoadedMapsCount() const { return uint32(loadedMMaps.size()); }
private:
bool loadMapData(uint32 mapId);
uint32 packTileID(int32 x, int32 y);
diff --git a/src/common/Collision/Management/VMapFactory.h b/src/common/Collision/Management/VMapFactory.h
index 1a45bd5094b..a730fa12ef2 100644
--- a/src/common/Collision/Management/VMapFactory.h
+++ b/src/common/Collision/Management/VMapFactory.h
@@ -29,7 +29,7 @@ namespace VMAP
{
//===========================================================
- class VMapFactory
+ class TC_COMMON_API VMapFactory
{
public:
static IVMapManager* createOrGetVMapManager();
diff --git a/src/common/Collision/Management/VMapManager2.h b/src/common/Collision/Management/VMapManager2.h
index 722ac4935c6..61c5025e41f 100644
--- a/src/common/Collision/Management/VMapManager2.h
+++ b/src/common/Collision/Management/VMapManager2.h
@@ -51,7 +51,7 @@ namespace VMAP
class StaticMapTree;
class WorldModel;
- class ManagedModel
+ class TC_COMMON_API ManagedModel
{
public:
ManagedModel() : iModel(nullptr), iRefCount(0) { }
@@ -75,7 +75,7 @@ namespace VMAP
VMAP_DISABLE_LIQUIDSTATUS = 0x8
};
- class VMapManager2 : public IVMapManager
+ class TC_COMMON_API VMapManager2 : public IVMapManager
{
protected:
// Tree to check collision
diff --git a/src/common/Collision/Maps/MapTree.h b/src/common/Collision/Maps/MapTree.h
index 63d542754c1..c6a283cac4d 100644
--- a/src/common/Collision/Maps/MapTree.h
+++ b/src/common/Collision/Maps/MapTree.h
@@ -29,7 +29,7 @@ namespace VMAP
class GroupModel;
class VMapManager2;
- struct LocationInfo
+ struct TC_COMMON_API LocationInfo
{
LocationInfo(): hitInstance(nullptr), hitModel(nullptr), ground_Z(-G3D::finf()) { }
const ModelInstance* hitInstance;
@@ -37,7 +37,7 @@ namespace VMAP
float ground_Z;
};
- class StaticMapTree
+ class TC_COMMON_API StaticMapTree
{
typedef std::unordered_map<uint32, bool> loadedTileMap;
typedef std::unordered_map<uint32, uint32> loadedSpawnMap;
@@ -87,7 +87,7 @@ namespace VMAP
StaticMapTree& operator=(StaticMapTree const& right) = delete;
};
- struct AreaInfo
+ struct TC_COMMON_API AreaInfo
{
AreaInfo(): result(false), ground_Z(-G3D::finf()), flags(0), adtId(0),
rootId(0), groupId(0) { }
diff --git a/src/common/Collision/Maps/TileAssembler.h b/src/common/Collision/Maps/TileAssembler.h
index 1e2dc1924f1..74111f69910 100644
--- a/src/common/Collision/Maps/TileAssembler.h
+++ b/src/common/Collision/Maps/TileAssembler.h
@@ -35,7 +35,7 @@ namespace VMAP
*/
//===============================================
- class ModelPosition
+ class TC_COMMON_API ModelPosition
{
private:
G3D::Matrix3 iRotation;
@@ -55,7 +55,7 @@ namespace VMAP
typedef std::map<uint32, ModelSpawn> UniqueEntryMap;
typedef std::multimap<uint32, uint32> TileMap;
- struct MapSpawns
+ struct TC_COMMON_API MapSpawns
{
UniqueEntryMap UniqueEntries;
TileMap TileEntries;
@@ -64,7 +64,7 @@ namespace VMAP
typedef std::map<uint32, MapSpawns*> MapData;
//===============================================
- struct GroupModel_Raw
+ struct TC_COMMON_API GroupModel_Raw
{
uint32 mogpflags;
uint32 GroupWMOID;
@@ -82,7 +82,7 @@ namespace VMAP
bool Read(FILE* f);
};
- struct WorldModel_Raw
+ struct TC_COMMON_API WorldModel_Raw
{
uint32 RootWMOID;
std::vector<GroupModel_Raw> groupsArray;
@@ -90,7 +90,7 @@ namespace VMAP
bool Read(const char * path);
};
- class TileAssembler
+ class TC_COMMON_API TileAssembler
{
private:
std::string iDestDir;
diff --git a/src/common/Collision/Models/GameObjectModel.h b/src/common/Collision/Models/GameObjectModel.h
index 9d8687233c1..37f11af20ac 100644
--- a/src/common/Collision/Models/GameObjectModel.h
+++ b/src/common/Collision/Models/GameObjectModel.h
@@ -35,7 +35,7 @@ namespace VMAP
class GameObject;
struct GameObjectDisplayInfoEntry;
-class GameObjectModelOwnerBase
+class TC_COMMON_API GameObjectModelOwnerBase
{
public:
virtual bool IsSpawned() const { return false; }
@@ -47,7 +47,7 @@ public:
virtual void DebugVisualizeCorner(G3D::Vector3 const& /*corner*/) const { }
};
-class GameObjectModel /*, public Intersectable*/
+class TC_COMMON_API GameObjectModel /*, public Intersectable*/
{
GameObjectModel() : phasemask(0), iInvScale(0), iScale(0), iModel(NULL) { }
public:
@@ -84,4 +84,6 @@ private:
std::unique_ptr<GameObjectModelOwnerBase> owner;
};
+TC_COMMON_API void LoadGameObjectModelList(std::string const& dataPath);
+
#endif // _GAMEOBJECT_MODEL_H
diff --git a/src/common/Collision/Models/ModelInstance.h b/src/common/Collision/Models/ModelInstance.h
index d101630d1e9..84a41b15ce6 100644
--- a/src/common/Collision/Models/ModelInstance.h
+++ b/src/common/Collision/Models/ModelInstance.h
@@ -39,7 +39,7 @@ namespace VMAP
MOD_HAS_BOUND = 1<<2
};
- class ModelSpawn
+ class TC_COMMON_API ModelSpawn
{
public:
//mapID, tileX, tileY, Flags, ID, Pos, Rot, Scale, Bound_lo, Bound_hi, name
@@ -60,7 +60,7 @@ namespace VMAP
static bool writeToFile(FILE* rw, const ModelSpawn &spawn);
};
- class ModelInstance: public ModelSpawn
+ class TC_COMMON_API ModelInstance: public ModelSpawn
{
public:
ModelInstance(): iInvScale(0.0f), iModel(nullptr) { }
diff --git a/src/common/Collision/Models/WorldModel.h b/src/common/Collision/Models/WorldModel.h
index 39787f6c664..bfc0367627f 100644
--- a/src/common/Collision/Models/WorldModel.h
+++ b/src/common/Collision/Models/WorldModel.h
@@ -33,7 +33,7 @@ namespace VMAP
struct AreaInfo;
struct LocationInfo;
- class MeshTriangle
+ class TC_COMMON_API MeshTriangle
{
public:
MeshTriangle() : idx0(0), idx1(0), idx2(0) { }
@@ -44,7 +44,7 @@ namespace VMAP
uint32 idx2;
};
- class WmoLiquid
+ class TC_COMMON_API WmoLiquid
{
public:
WmoLiquid(uint32 width, uint32 height, const G3D::Vector3 &corner, uint32 type);
@@ -70,7 +70,7 @@ namespace VMAP
};
/*! holding additional info for WMO group files */
- class GroupModel
+ class TC_COMMON_API GroupModel
{
public:
GroupModel() : iBound(), iMogpFlags(0), iGroupWMOID(0), iLiquid(NULL) { }
@@ -103,7 +103,7 @@ namespace VMAP
};
/*! Holds a model (converted M2 or WMO) in its original coordinate space */
- class WorldModel
+ class TC_COMMON_API WorldModel
{
public:
WorldModel(): RootWMOID(0) { }
diff --git a/src/common/Collision/RegularGrid.h b/src/common/Collision/RegularGrid.h
index 6a2a07968ad..563cf516406 100644
--- a/src/common/Collision/RegularGrid.h
+++ b/src/common/Collision/RegularGrid.h
@@ -20,7 +20,7 @@ class NodeCreatorFunc = NodeCreator<Node>,
/*class BoundsFunc = BoundsTrait<T>,*/
class PositionFunc = PositionTrait<T>
>
-class RegularGrid2D
+class TC_COMMON_API RegularGrid2D
{
public:
diff --git a/src/common/Common.h b/src/common/Common.h
index e8adc55d20d..aa04abacd30 100644
--- a/src/common/Common.h
+++ b/src/common/Common.h
@@ -21,28 +21,31 @@
#include "Define.h"
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-#include <cmath>
-#include <errno.h>
-#include <signal.h>
-#include <assert.h>
-
-#include <set>
-#include <unordered_set>
+#include <algorithm>
+#include <array>
+#include <exception>
#include <list>
-#include <string>
#include <map>
-#include <unordered_map>
+#include <memory>
#include <queue>
+#include <set>
#include <sstream>
-#include <algorithm>
-#include <memory>
+#include <string>
+#include <type_traits>
+#include <unordered_map>
+#include <unordered_set>
#include <vector>
-#include <array>
+#include <cmath>
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+#include <ctime>
+#include <cerrno>
+#include <csignal>
+
+#include <boost/optional.hpp>
+#include <boost/utility/in_place_factory.hpp>
#include <boost/functional/hash.hpp>
#include "Debugging/Errors.h"
@@ -130,9 +133,9 @@ enum LocaleConstant
#define MAX_LOCALES 8
#define MAX_ACCOUNT_TUTORIAL_VALUES 8
-extern char const* localeNames[TOTAL_LOCALES];
+TC_COMMON_API extern char const* localeNames[TOTAL_LOCALES];
-LocaleConstant GetLocaleByName(const std::string& name);
+TC_COMMON_API LocaleConstant GetLocaleByName(const std::string& name);
typedef std::vector<std::string> StringVector;
@@ -151,6 +154,10 @@ typedef std::vector<std::string> StringVector;
#define MAX_QUERY_LEN 32*1024
+//! Optional helper class to wrap optional values within.
+template <typename T>
+using Optional = boost::optional<T>;
+
namespace Trinity
{
//! std::make_unique implementation (TODO: remove this once C++14 is supported)
diff --git a/src/common/Configuration/BuiltInConfig.cpp b/src/common/Configuration/BuiltInConfig.cpp
new file mode 100644
index 00000000000..c2fc3b91766
--- /dev/null
+++ b/src/common/Configuration/BuiltInConfig.cpp
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2008-2016 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 "BuiltInConfig.h"
+#include "Config.h"
+#include "GitRevision.h"
+
+template<typename Fn>
+static std::string GetStringWithDefaultValueFromFunction(
+ std::string const& key, Fn getter)
+{
+ std::string const value = sConfigMgr->GetStringDefault(key, "");
+ return value.empty() ? getter() : value;
+}
+
+std::string BuiltInConfig::GetCMakeCommand()
+{
+ return GetStringWithDefaultValueFromFunction(
+ "CMakeCommand", GitRevision::GetCMakeCommand);
+}
+
+std::string BuiltInConfig::GetBuildDirectory()
+{
+ return GetStringWithDefaultValueFromFunction(
+ "BuildDirectory", GitRevision::GetBuildDirectory);
+}
+
+std::string BuiltInConfig::GetSourceDirectory()
+{
+ return GetStringWithDefaultValueFromFunction(
+ "SourceDirectory", GitRevision::GetSourceDirectory);
+}
+
+std::string BuiltInConfig::GetMySQLExecutable()
+{
+ return GetStringWithDefaultValueFromFunction(
+ "MySQLExecutable", GitRevision::GetMySQLExecutable);
+}
diff --git a/src/common/Configuration/BuiltInConfig.h b/src/common/Configuration/BuiltInConfig.h
new file mode 100644
index 00000000000..0ffa059bc41
--- /dev/null
+++ b/src/common/Configuration/BuiltInConfig.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2008-2016 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 BUILT_IN_CONFIG_H
+#define BUILT_IN_CONFIG_H
+
+#include <string>
+#include "Define.h"
+
+/// Provides helper functions to access built-in values
+/// which can be overwritten in config
+namespace BuiltInConfig
+{
+ /// Returns the CMake command when any is specified in the config,
+ /// returns the built-in path otherwise
+ TC_COMMON_API std::string GetCMakeCommand();
+ /// Returns the build directory path when any is specified in the config,
+ /// returns the built-in one otherwise
+ TC_COMMON_API std::string GetBuildDirectory();
+ /// Returns the source directory path when any is specified in the config,
+ /// returns the built-in one otherwise
+ TC_COMMON_API std::string GetSourceDirectory();
+ /// Returns the path to the mysql executable (`mysql`) when any is specified
+ /// in the config, returns the built-in one otherwise
+ TC_COMMON_API std::string GetMySQLExecutable();
+
+} // namespace BuiltInConfig
+
+#endif // BUILT_IN_CONFIG_H
diff --git a/src/common/Configuration/Config.cpp b/src/common/Configuration/Config.cpp
index 6ac04615315..888aa6ecef3 100644
--- a/src/common/Configuration/Config.cpp
+++ b/src/common/Configuration/Config.cpp
@@ -21,14 +21,17 @@
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/ini_parser.hpp>
#include "Config.h"
+#include "Log.h"
using namespace boost::property_tree;
-bool ConfigMgr::LoadInitial(std::string const& file, std::string& error)
+bool ConfigMgr::LoadInitial(std::string const& file, std::vector<std::string> args,
+ std::string& error)
{
std::lock_guard<std::mutex> lock(_configLock);
_filename = file;
+ _args = args;
try
{
@@ -56,42 +59,81 @@ bool ConfigMgr::LoadInitial(std::string const& file, std::string& error)
return true;
}
-bool ConfigMgr::Reload(std::string& error)
+ConfigMgr* ConfigMgr::instance()
{
- return LoadInitial(_filename, error);
+ static ConfigMgr instance;
+ return &instance;
}
-std::string ConfigMgr::GetStringDefault(std::string const& name, const std::string& def)
+bool ConfigMgr::Reload(std::string& error)
{
- std::string value = _config.get<std::string>(ptree::path_type(name, '/'), def);
+ return LoadInitial(_filename, std::move(_args), error);
+}
- value.erase(std::remove(value.begin(), value.end(), '"'), value.end());
+template<class T>
+T ConfigMgr::GetValueDefault(std::string const& name, T def) const
+{
+ try
+ {
+ return _config.get<T>(ptree::path_type(name, '/'));
+ }
+ catch (boost::property_tree::ptree_bad_path)
+ {
+ TC_LOG_WARN("server.loading", "Missing name %s in config file %s, add \"%s = %s\" to this file",
+ name.c_str(), _filename.c_str(), name.c_str(), std::to_string(def).c_str());
+ }
+ catch (boost::property_tree::ptree_bad_data)
+ {
+ TC_LOG_ERROR("server.loading", "Bad value defined for name %s in config file %s, going to use %s instead",
+ name.c_str(), _filename.c_str(), std::to_string(def).c_str());
+ }
- return value;
+ return def;
}
-bool ConfigMgr::GetBoolDefault(std::string const& name, bool def)
+template<>
+std::string ConfigMgr::GetValueDefault<std::string>(std::string const& name, std::string def) const
{
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");
+ return _config.get<std::string>(ptree::path_type(name, '/'));
+ }
+ catch (boost::property_tree::ptree_bad_path)
+ {
+ TC_LOG_WARN("server.loading", "Missing name %s in config file %s, add \"%s = %s\" to this file",
+ name.c_str(), _filename.c_str(), name.c_str(), def.c_str());
}
- catch (std::exception const& /*ex*/)
+ catch (boost::property_tree::ptree_bad_data)
{
- return def;
+ TC_LOG_ERROR("server.loading", "Bad value defined for name %s in config file %s, going to use %s instead",
+ name.c_str(), _filename.c_str(), def.c_str());
}
+
+ return def;
+}
+
+std::string ConfigMgr::GetStringDefault(std::string const& name, const std::string& def) const
+{
+ std::string val = GetValueDefault(name, def);
+ val.erase(std::remove(val.begin(), val.end(), '"'), val.end());
+ return val;
+}
+
+bool ConfigMgr::GetBoolDefault(std::string const& name, bool def) const
+{
+ std::string val = GetValueDefault(name, std::string(def ? "1" : "0"));
+ val.erase(std::remove(val.begin(), val.end(), '"'), val.end());
+ return (val == "1" || val == "true" || val == "TRUE" || val == "yes" || val == "YES");
}
-int ConfigMgr::GetIntDefault(std::string const& name, int def)
+int ConfigMgr::GetIntDefault(std::string const& name, int def) const
{
- return _config.get<int>(ptree::path_type(name, '/'), def);
+ return GetValueDefault(name, def);
}
-float ConfigMgr::GetFloatDefault(std::string const& name, float def)
+float ConfigMgr::GetFloatDefault(std::string const& name, float def) const
{
- return _config.get<float>(ptree::path_type(name, '/'), def);
+ return GetValueDefault(name, def);
}
std::string const& ConfigMgr::GetFilename()
diff --git a/src/common/Configuration/Config.h b/src/common/Configuration/Config.h
index 5b04212ed7c..573bc7b4a15 100644
--- a/src/common/Configuration/Config.h
+++ b/src/common/Configuration/Config.h
@@ -19,43 +19,47 @@
#ifndef CONFIG_H
#define CONFIG_H
+#include "Define.h"
+
#include <string>
#include <list>
+#include <vector>
#include <mutex>
#include <boost/property_tree/ptree.hpp>
-class ConfigMgr
+class TC_COMMON_API ConfigMgr
{
- ConfigMgr() { }
- ~ConfigMgr() { }
+ ConfigMgr() = default;
+ ConfigMgr(ConfigMgr const&) = delete;
+ ConfigMgr& operator=(ConfigMgr const&) = delete;
+ ~ConfigMgr() = default;
public:
/// Method used only for loading main configuration files (authserver.conf and worldserver.conf)
- bool LoadInitial(std::string const& file, std::string& error);
+ bool LoadInitial(std::string const& file, std::vector<std::string> args,
+ std::string& error);
- static ConfigMgr* instance()
- {
- static ConfigMgr instance;
- return &instance;
- }
+ static ConfigMgr* instance();
bool Reload(std::string& error);
- 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 GetStringDefault(std::string const& name, const std::string& def) const;
+ bool GetBoolDefault(std::string const& name, bool def) const;
+ int GetIntDefault(std::string const& name, int def) const;
+ float GetFloatDefault(std::string const& name, float def) const;
std::string const& GetFilename();
+ std::vector<std::string> const& GetArguments() const { return _args; }
std::list<std::string> GetKeysByString(std::string const& name);
private:
std::string _filename;
+ std::vector<std::string> _args;
boost::property_tree::ptree _config;
std::mutex _configLock;
- ConfigMgr(ConfigMgr const&);
- ConfigMgr& operator=(ConfigMgr const&);
+ template<class T>
+ T GetValueDefault(std::string const& name, T def) const;
};
#define sConfigMgr ConfigMgr::instance()
diff --git a/src/common/Cryptography/ARC4.h b/src/common/Cryptography/ARC4.h
index f39e662e295..7e680176836 100644
--- a/src/common/Cryptography/ARC4.h
+++ b/src/common/Cryptography/ARC4.h
@@ -22,7 +22,7 @@
#include <openssl/evp.h>
#include "Define.h"
-class ARC4
+class TC_COMMON_API ARC4
{
public:
ARC4(uint8 len);
diff --git a/src/common/Cryptography/Authentication/AuthCrypt.h b/src/common/Cryptography/Authentication/AuthCrypt.h
index 878391e3ce8..db4de8a7bd1 100644
--- a/src/common/Cryptography/Authentication/AuthCrypt.h
+++ b/src/common/Cryptography/Authentication/AuthCrypt.h
@@ -23,7 +23,7 @@
class BigNumber;
-class AuthCrypt
+class TC_COMMON_API AuthCrypt
{
public:
AuthCrypt();
diff --git a/src/common/Cryptography/BigNumber.h b/src/common/Cryptography/BigNumber.h
index a5bda50dc72..1d21be1b431 100644
--- a/src/common/Cryptography/BigNumber.h
+++ b/src/common/Cryptography/BigNumber.h
@@ -24,7 +24,7 @@
struct bignum_st;
-class BigNumber
+class TC_COMMON_API BigNumber
{
public:
BigNumber();
diff --git a/src/common/Cryptography/HMACSHA1.h b/src/common/Cryptography/HMACSHA1.h
index 29a926d5b16..049847489a6 100644
--- a/src/common/Cryptography/HMACSHA1.h
+++ b/src/common/Cryptography/HMACSHA1.h
@@ -28,7 +28,7 @@ class BigNumber;
#define SEED_KEY_SIZE 16
-class HmacHash
+class TC_COMMON_API HmacHash
{
public:
HmacHash(uint32 len, uint8 *seed);
diff --git a/src/common/Cryptography/OpenSSLCrypto.h b/src/common/Cryptography/OpenSSLCrypto.h
index df1b14b5eda..65155df9af8 100644
--- a/src/common/Cryptography/OpenSSLCrypto.h
+++ b/src/common/Cryptography/OpenSSLCrypto.h
@@ -18,6 +18,8 @@
#ifndef OPENSSL_CRYPTO_H
#define OPENSSL_CRYPTO_H
+#include "Define.h"
+
/**
* A group of functions which setup openssl crypto module to work properly in multithreaded enviroment
* If not setup properly - it will crash
@@ -25,9 +27,9 @@
namespace OpenSSLCrypto
{
/// Needs to be called before threads using openssl are spawned
- void threadsSetup();
+ TC_COMMON_API void threadsSetup();
/// Needs to be called after threads using openssl are despawned
- void threadsCleanup();
+ TC_COMMON_API void threadsCleanup();
}
-#endif \ No newline at end of file
+#endif
diff --git a/src/common/Cryptography/SHA1.cpp b/src/common/Cryptography/SHA1.cpp
index a01bd7844ee..aed4a069827 100644
--- a/src/common/Cryptography/SHA1.cpp
+++ b/src/common/Cryptography/SHA1.cpp
@@ -18,6 +18,7 @@
#include "SHA1.h"
#include "BigNumber.h"
+#include "Util.h"
#include <cstring>
#include <stdarg.h>
@@ -67,3 +68,10 @@ void SHA1Hash::Finalize(void)
SHA1_Final(mDigest, &mC);
}
+std::string CalculateSHA1Hash(std::string const& content)
+{
+ unsigned char digest[SHA_DIGEST_LENGTH];
+ SHA1((unsigned char*)content.c_str(), content.length(), (unsigned char*)&digest);
+
+ return ByteArrayToHexStr(digest, SHA_DIGEST_LENGTH);
+}
diff --git a/src/common/Cryptography/SHA1.h b/src/common/Cryptography/SHA1.h
index ffa02176a2d..37ac2cc0166 100644
--- a/src/common/Cryptography/SHA1.h
+++ b/src/common/Cryptography/SHA1.h
@@ -25,7 +25,7 @@
class BigNumber;
-class SHA1Hash
+class TC_COMMON_API SHA1Hash
{
public:
SHA1Hash();
@@ -46,5 +46,8 @@ class SHA1Hash
SHA_CTX mC;
uint8 mDigest[SHA_DIGEST_LENGTH];
};
-#endif
+/// Returns the SHA1 hash of the given content as hex string.
+TC_COMMON_API std::string CalculateSHA1Hash(std::string const& content);
+
+#endif
diff --git a/src/common/Debugging/Errors.cpp b/src/common/Debugging/Errors.cpp
index 1ec66ff6d59..2ce00229e53 100644
--- a/src/common/Debugging/Errors.cpp
+++ b/src/common/Debugging/Errors.cpp
@@ -96,4 +96,11 @@ void Abort(char const* file, int line, char const* function)
exit(1);
}
+void AbortHandler(int /*sigval*/)
+{
+ // nothing useful to log here, no way to pass args
+ *((volatile int*)NULL) = 0;
+ exit(1);
+}
+
} // namespace Trinity
diff --git a/src/common/Debugging/Errors.h b/src/common/Debugging/Errors.h
index 38e311a6b13..e4b3563ca96 100644
--- a/src/common/Debugging/Errors.h
+++ b/src/common/Debugging/Errors.h
@@ -23,16 +23,18 @@
namespace Trinity
{
- DECLSPEC_NORETURN void Assert(char const* file, int line, char const* function, char const* message) ATTR_NORETURN;
- DECLSPEC_NORETURN void Assert(char const* file, int line, char const* function, char const* message, char const* format, ...) ATTR_NORETURN ATTR_PRINTF(5, 6);
+ DECLSPEC_NORETURN TC_COMMON_API void Assert(char const* file, int line, char const* function, char const* message) ATTR_NORETURN;
+ DECLSPEC_NORETURN TC_COMMON_API void Assert(char const* file, int line, char const* function, char const* message, char const* format, ...) ATTR_NORETURN ATTR_PRINTF(5, 6);
- DECLSPEC_NORETURN void Fatal(char const* file, int line, char const* function, char const* message, ...) ATTR_NORETURN ATTR_PRINTF(4, 5);
+ DECLSPEC_NORETURN TC_COMMON_API void Fatal(char const* file, int line, char const* function, char const* message, ...) ATTR_NORETURN ATTR_PRINTF(4, 5);
- DECLSPEC_NORETURN void Error(char const* file, int line, char const* function, char const* message) ATTR_NORETURN;
+ DECLSPEC_NORETURN TC_COMMON_API void Error(char const* file, int line, char const* function, char const* message) ATTR_NORETURN;
- DECLSPEC_NORETURN void Abort(char const* file, int line, char const* function) ATTR_NORETURN;
+ DECLSPEC_NORETURN TC_COMMON_API void Abort(char const* file, int line, char const* function) ATTR_NORETURN;
- void Warning(char const* file, int line, char const* function, char const* message);
+ TC_COMMON_API void Warning(char const* file, int line, char const* function, char const* message);
+
+ DECLSPEC_NORETURN TC_COMMON_API void AbortHandler(int sigval) ATTR_NORETURN;
} // namespace Trinity
diff --git a/src/common/Define.h b/src/common/Define.h
index df3dd37b503..d03d26ad780 100644
--- a/src/common/Define.h
+++ b/src/common/Define.h
@@ -83,12 +83,57 @@
# define ATTR_NORETURN __attribute__((__noreturn__))
# define ATTR_PRINTF(F, V) __attribute__ ((__format__ (__printf__, F, V)))
# define ATTR_DEPRECATED __attribute__((__deprecated__))
+# define TRINITY_CONSTEXPR constexpr
#else //COMPILER != COMPILER_GNU
# define ATTR_NORETURN
# define ATTR_PRINTF(F, V)
# define ATTR_DEPRECATED
+#if _MSC_VER >= 1900
+# define TRINITY_CONSTEXPR constexpr
+#else
+# define TRINITY_CONSTEXPR
+#endif
#endif //COMPILER == COMPILER_GNU
+#ifdef TRINITY_API_USE_DYNAMIC_LINKING
+# if COMPILER == COMPILER_MICROSOFT
+# define TC_API_EXPORT __declspec(dllexport)
+# define TC_API_IMPORT __declspec(dllimport)
+# elif COMPILER == COMPILER_GNU
+# define TC_API_EXPORT __attribute__((visibility("default")))
+# define TC_API_IMPORT
+# else
+# error compiler not supported!
+# endif
+#else
+# define TC_API_EXPORT
+# define TC_API_IMPORT
+#endif
+
+#ifdef TRINITY_API_EXPORT_COMMON
+# define TC_COMMON_API TC_API_EXPORT
+#else
+# define TC_COMMON_API TC_API_IMPORT
+#endif
+
+#ifdef TRINITY_API_EXPORT_DATABASE
+# define TC_DATABASE_API TC_API_EXPORT
+#else
+# define TC_DATABASE_API TC_API_IMPORT
+#endif
+
+#ifdef TRINITY_API_EXPORT_SHARED
+# define TC_SHARED_API TC_API_EXPORT
+#else
+# define TC_SHARED_API TC_API_IMPORT
+#endif
+
+#ifdef TRINITY_API_EXPORT_GAME
+# define TC_GAME_API TC_API_EXPORT
+#else
+# define TC_GAME_API TC_API_IMPORT
+#endif
+
#define UI64FMTD "%" PRIu64
#define UI64LIT(N) UINT64_C(N)
diff --git a/src/common/GitRevision.cpp b/src/common/GitRevision.cpp
index d0719c09959..2162e36847f 100644
--- a/src/common/GitRevision.cpp
+++ b/src/common/GitRevision.cpp
@@ -1,5 +1,4 @@
#include "GitRevision.h"
-#include "CompilerDefs.h"
#include "revision_data.h"
char const* GitRevision::GetHash()
@@ -17,6 +16,16 @@ char const* GitRevision::GetBranch()
return _BRANCH;
}
+char const* GitRevision::GetCMakeCommand()
+{
+ return _CMAKE_COMMAND;
+}
+
+char const* GitRevision::GetBuildDirectory()
+{
+ return _BUILD_DIRECTORY;
+}
+
char const* GitRevision::GetSourceDirectory()
{
return _SOURCE_DIRECTORY;
@@ -66,13 +75,3 @@ char const* GitRevision::GetProductVersionStr()
{
return VER_PRODUCTVERSION_STR;
}
-
-char const* GitRevision::GetCompilerCFlags()
-{
- return COMPILER_C_FLAGS;
-}
-
-char const* GitRevision::GetCompilerCXXFlags()
-{
- return COMPILER_CXX_FLAGS;
-}
diff --git a/src/common/GitRevision.h b/src/common/GitRevision.h
index 8d2764ba861..aace8ad2076 100644
--- a/src/common/GitRevision.h
+++ b/src/common/GitRevision.h
@@ -19,22 +19,23 @@
#define __GITREVISION_H__
#include <string>
+#include "Define.h"
namespace GitRevision
{
- char const* GetHash();
- char const* GetDate();
- char const* GetBranch();
- char const* GetSourceDirectory();
- char const* GetMySQLExecutable();
- char const* GetFullDatabase();
- char const* GetFullVersion();
- char const* GetCompanyNameStr();
- char const* GetLegalCopyrightStr();
- char const* GetFileVersionStr();
- char const* GetProductVersionStr();
- char const* GetCompilerCFlags();
- char const* GetCompilerCXXFlags();
+ TC_COMMON_API char const* GetHash();
+ TC_COMMON_API char const* GetDate();
+ TC_COMMON_API char const* GetBranch();
+ TC_COMMON_API char const* GetCMakeCommand();
+ TC_COMMON_API char const* GetBuildDirectory();
+ TC_COMMON_API char const* GetSourceDirectory();
+ TC_COMMON_API char const* GetMySQLExecutable();
+ TC_COMMON_API char const* GetFullDatabase();
+ TC_COMMON_API char const* GetFullVersion();
+ TC_COMMON_API char const* GetCompanyNameStr();
+ TC_COMMON_API char const* GetLegalCopyrightStr();
+ TC_COMMON_API char const* GetFileVersionStr();
+ TC_COMMON_API char const* GetProductVersionStr();
}
#endif
diff --git a/src/common/Logging/Appender.h b/src/common/Logging/Appender.h
index f0bfe423a66..d24daa2b60d 100644
--- a/src/common/Logging/Appender.h
+++ b/src/common/Logging/Appender.h
@@ -41,7 +41,7 @@ enum LogLevel
const uint8 MaxLogLevels = 6;
-enum AppenderType
+enum AppenderType : uint8
{
APPENDER_NONE,
APPENDER_CONSOLE,
@@ -59,7 +59,7 @@ enum AppenderFlags
APPENDER_FLAGS_MAKE_FILE_BACKUP = 0x10 // only used by FileAppender
};
-struct LogMessage
+struct TC_COMMON_API LogMessage
{
LogMessage(LogLevel _level, std::string const& _type, std::string&& _text)
: level(_level), type(_type), text(std::forward<std::string>(_text)), mtime(time(NULL))
@@ -85,7 +85,7 @@ struct LogMessage
}
};
-class Appender
+class TC_COMMON_API Appender
{
public:
Appender(uint8 _id, std::string const& name, LogLevel level = LOG_LEVEL_DISABLED, AppenderFlags flags = APPENDER_FLAGS_NONE);
@@ -123,7 +123,7 @@ Appender* CreateAppender(uint8 id, std::string const& name, LogLevel level, Appe
return new AppenderImpl(id, name, level, flags, std::forward<ExtraAppenderArgs>(extraArgs));
}
-class InvalidAppenderArgsException : public std::length_error
+class TC_COMMON_API InvalidAppenderArgsException : public std::length_error
{
public:
explicit InvalidAppenderArgsException(std::string const& message) : std::length_error(message) { }
diff --git a/src/common/Logging/AppenderConsole.h b/src/common/Logging/AppenderConsole.h
index 5d7eae36b40..96d17207158 100644
--- a/src/common/Logging/AppenderConsole.h
+++ b/src/common/Logging/AppenderConsole.h
@@ -42,7 +42,7 @@ enum ColorTypes
const uint8 MaxColors = uint8(WHITE) + 1;
-class AppenderConsole : public Appender
+class TC_COMMON_API AppenderConsole : public Appender
{
public:
typedef std::integral_constant<AppenderType, APPENDER_CONSOLE>::type TypeIndex;
diff --git a/src/common/Logging/AppenderFile.h b/src/common/Logging/AppenderFile.h
index 9ba5d59259c..956b7a70b93 100644
--- a/src/common/Logging/AppenderFile.h
+++ b/src/common/Logging/AppenderFile.h
@@ -21,7 +21,7 @@
#include <atomic>
#include "Appender.h"
-class AppenderFile : public Appender
+class TC_COMMON_API AppenderFile : public Appender
{
public:
typedef std::integral_constant<AppenderType, APPENDER_FILE>::type TypeIndex;
diff --git a/src/common/Logging/Log.cpp b/src/common/Logging/Log.cpp
index 4bd0487343d..f7a84fb8b47 100644
--- a/src/common/Logging/Log.cpp
+++ b/src/common/Logging/Log.cpp
@@ -214,13 +214,13 @@ void Log::ReadLoggersFromConfig()
AppenderConsole* appender = new AppenderConsole(NextAppenderId(), "Console", LOG_LEVEL_DEBUG, APPENDER_FLAGS_NONE, ExtraAppenderArgs());
appenders[appender->getId()] = appender;
- Logger& logger = loggers[LOGGER_ROOT];
- logger.Create(LOGGER_ROOT, LOG_LEVEL_ERROR);
- logger.addAppender(appender->getId(), appender);
+ Logger& rootLogger = loggers[LOGGER_ROOT];
+ rootLogger.Create(LOGGER_ROOT, LOG_LEVEL_ERROR);
+ rootLogger.addAppender(appender->getId(), appender);
- logger = loggers["server"];
- logger.Create("server", LOG_LEVEL_ERROR);
- logger.addAppender(appender->getId(), appender);
+ Logger& serverLogger = loggers["server"];
+ serverLogger.Create("server", LOG_LEVEL_INFO);
+ serverLogger.addAppender(appender->getId(), appender);
}
}
@@ -320,6 +320,12 @@ void Log::Close()
appenders.clear();
}
+Log* Log::instance()
+{
+ static Log instance;
+ return &instance;
+}
+
void Log::Initialize(boost::asio::io_service* ioService)
{
if (ioService)
@@ -331,6 +337,13 @@ void Log::Initialize(boost::asio::io_service* ioService)
LoadFromConfig();
}
+void Log::SetSynchronous()
+{
+ delete _strand;
+ _strand = nullptr;
+ _ioService = nullptr;
+}
+
void Log::LoadFromConfig()
{
Close();
diff --git a/src/common/Logging/Log.h b/src/common/Logging/Log.h
index a90481ad5d2..6460e404c90 100644
--- a/src/common/Logging/Log.h
+++ b/src/common/Logging/Log.h
@@ -34,7 +34,7 @@
#define LOGGER_ROOT "root"
-class Log
+class TC_COMMON_API Log
{
typedef std::unordered_map<std::string, Logger> LoggerMap;
@@ -44,13 +44,10 @@ class Log
public:
- static Log* instance()
- {
- static Log instance;
- return &instance;
- }
+ static Log* instance();
void Initialize(boost::asio::io_service* ioService);
+ void SetSynchronous(); // Not threadsafe - should only be called from main() after all threads are joined
void LoadFromConfig();
void Close();
bool ShouldLog(std::string const& type, LogLevel level) const;
diff --git a/src/common/Logging/LogOperation.h b/src/common/Logging/LogOperation.h
index 618629b5423..56e2307d492 100644
--- a/src/common/Logging/LogOperation.h
+++ b/src/common/Logging/LogOperation.h
@@ -19,11 +19,12 @@
#define LOGOPERATION_H
#include <memory>
+#include "Define.h"
class Logger;
struct LogMessage;
-class LogOperation
+class TC_COMMON_API LogOperation
{
public:
LogOperation(Logger const* _logger, std::unique_ptr<LogMessage>&& _msg)
diff --git a/src/common/Logging/Logger.h b/src/common/Logging/Logger.h
index 67eab4295a4..4ac2e4494cc 100644
--- a/src/common/Logging/Logger.h
+++ b/src/common/Logging/Logger.h
@@ -20,7 +20,7 @@
#include "Appender.h"
-class Logger
+class TC_COMMON_API Logger
{
public:
Logger();
diff --git a/src/common/Platform/ServiceWin32.cpp b/src/common/Platform/ServiceWin32.cpp
new file mode 100644
index 00000000000..3c34f3e322c
--- /dev/null
+++ b/src/common/Platform/ServiceWin32.cpp
@@ -0,0 +1,263 @@
+/*
+ * Copyright (C) 2008-2016 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/>.
+ */
+
+#ifdef _WIN32
+
+#include "Common.h"
+#include "Log.h"
+#include <cstring>
+#include <windows.h>
+#include <winsvc.h>
+
+#if !defined(WINADVAPI)
+#if !defined(_ADVAPI32_)
+#define WINADVAPI DECLSPEC_IMPORT
+#else
+#define WINADVAPI
+#endif
+#endif
+
+extern int main(int argc, char ** argv);
+extern char serviceLongName[];
+extern char serviceName[];
+extern char serviceDescription[];
+
+extern int m_ServiceStatus;
+
+SERVICE_STATUS serviceStatus;
+
+SERVICE_STATUS_HANDLE serviceStatusHandle = 0;
+
+typedef WINADVAPI BOOL (WINAPI *CSD_T)(SC_HANDLE, DWORD, LPCVOID);
+
+bool WinServiceInstall()
+{
+ SC_HANDLE serviceControlManager = OpenSCManager(0, 0, SC_MANAGER_CREATE_SERVICE);
+
+ if (serviceControlManager)
+ {
+ char path[_MAX_PATH + 10];
+ if (GetModuleFileName( 0, path, sizeof(path)/sizeof(path[0]) ) > 0)
+ {
+ SC_HANDLE service;
+ std::strcat(path, " --service run");
+ service = CreateService(serviceControlManager,
+ serviceName, // name of service
+ serviceLongName, // service name to display
+ SERVICE_ALL_ACCESS, // desired access
+ // service type
+ SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS,
+ SERVICE_AUTO_START, // start type
+ SERVICE_ERROR_IGNORE, // error control type
+ path, // service's binary
+ 0, // no load ordering group
+ 0, // no tag identifier
+ 0, // no dependencies
+ 0, // LocalSystem account
+ 0); // no password
+ if (service)
+ {
+ HMODULE advapi32 = GetModuleHandle("ADVAPI32.DLL");
+ if (!advapi32)
+ {
+ CloseServiceHandle(service);
+ CloseServiceHandle(serviceControlManager);
+ return false;
+ }
+
+ CSD_T ChangeService_Config2 = (CSD_T) GetProcAddress(advapi32, "ChangeServiceConfig2A");
+ if (!ChangeService_Config2)
+ {
+ CloseServiceHandle(service);
+ CloseServiceHandle(serviceControlManager);
+ return false;
+ }
+
+ SERVICE_DESCRIPTION sdBuf;
+ sdBuf.lpDescription = serviceDescription;
+ ChangeService_Config2(
+ service, // handle to service
+ SERVICE_CONFIG_DESCRIPTION, // change: description
+ &sdBuf); // new data
+
+ SC_ACTION _action[1];
+ _action[0].Type = SC_ACTION_RESTART;
+ _action[0].Delay = 10000;
+ SERVICE_FAILURE_ACTIONS sfa;
+ ZeroMemory(&sfa, sizeof(SERVICE_FAILURE_ACTIONS));
+ sfa.lpsaActions = _action;
+ sfa.cActions = 1;
+ sfa.dwResetPeriod =INFINITE;
+ ChangeService_Config2(
+ service, // handle to service
+ SERVICE_CONFIG_FAILURE_ACTIONS, // information level
+ &sfa); // new data
+
+ CloseServiceHandle(service);
+
+ }
+ }
+ CloseServiceHandle(serviceControlManager);
+ }
+
+ printf("Service installed\n");
+ return true;
+}
+
+bool WinServiceUninstall()
+{
+ SC_HANDLE serviceControlManager = OpenSCManager(0, 0, SC_MANAGER_CONNECT);
+
+ if (serviceControlManager)
+ {
+ SC_HANDLE service = OpenService(serviceControlManager,
+ serviceName, SERVICE_QUERY_STATUS | DELETE);
+ if (service)
+ {
+ SERVICE_STATUS serviceStatus2;
+ if (QueryServiceStatus(service, &serviceStatus2))
+ {
+ if (serviceStatus2.dwCurrentState == SERVICE_STOPPED)
+ DeleteService(service);
+ }
+ CloseServiceHandle(service);
+ }
+
+ CloseServiceHandle(serviceControlManager);
+ }
+
+ printf("Service uninstalled\n");
+ return true;
+}
+
+void WINAPI ServiceControlHandler(DWORD controlCode)
+{
+ switch (controlCode)
+ {
+ case SERVICE_CONTROL_INTERROGATE:
+ break;
+
+ case SERVICE_CONTROL_SHUTDOWN:
+ case SERVICE_CONTROL_STOP:
+ serviceStatus.dwCurrentState = SERVICE_STOP_PENDING;
+ SetServiceStatus(serviceStatusHandle, &serviceStatus);
+
+ m_ServiceStatus = 0;
+ return;
+
+ case SERVICE_CONTROL_PAUSE:
+ m_ServiceStatus = 2;
+ serviceStatus.dwCurrentState = SERVICE_PAUSED;
+ SetServiceStatus(serviceStatusHandle, &serviceStatus);
+ break;
+
+ case SERVICE_CONTROL_CONTINUE:
+ serviceStatus.dwCurrentState = SERVICE_RUNNING;
+ SetServiceStatus(serviceStatusHandle, &serviceStatus);
+ m_ServiceStatus = 1;
+ break;
+
+ default:
+ if ( controlCode >= 128 && controlCode <= 255 )
+ // user defined control code
+ break;
+ else
+ // unrecognized control code
+ break;
+ }
+
+ SetServiceStatus(serviceStatusHandle, &serviceStatus);
+}
+
+void WINAPI ServiceMain(DWORD argc, char *argv[])
+{
+ // initialise service status
+ serviceStatus.dwServiceType = SERVICE_WIN32;
+ serviceStatus.dwCurrentState = SERVICE_START_PENDING;
+ serviceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_PAUSE_CONTINUE;
+ serviceStatus.dwWin32ExitCode = NO_ERROR;
+ serviceStatus.dwServiceSpecificExitCode = NO_ERROR;
+ serviceStatus.dwCheckPoint = 0;
+ serviceStatus.dwWaitHint = 0;
+
+ serviceStatusHandle = RegisterServiceCtrlHandler(serviceName, ServiceControlHandler);
+
+ if ( serviceStatusHandle )
+ {
+ char path[_MAX_PATH + 1];
+ unsigned int i, last_slash = 0;
+
+ GetModuleFileName(0, path, sizeof(path)/sizeof(path[0]));
+
+ size_t pathLen = std::strlen(path);
+ for (i = 0; i < pathLen; i++)
+ {
+ if (path[i] == '\\') last_slash = i;
+ }
+
+ path[last_slash] = 0;
+
+ // service is starting
+ serviceStatus.dwCurrentState = SERVICE_START_PENDING;
+ SetServiceStatus(serviceStatusHandle, &serviceStatus);
+
+ // do initialisation here
+ SetCurrentDirectory(path);
+
+ // running
+ serviceStatus.dwControlsAccepted |= (SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN);
+ serviceStatus.dwCurrentState = SERVICE_RUNNING;
+ SetServiceStatus( serviceStatusHandle, &serviceStatus );
+
+ ////////////////////////
+ // service main cycle //
+ ////////////////////////
+
+ m_ServiceStatus = 1;
+ argc = 1;
+ main(argc, argv);
+
+ // service was stopped
+ serviceStatus.dwCurrentState = SERVICE_STOP_PENDING;
+ SetServiceStatus(serviceStatusHandle, &serviceStatus);
+
+ // do cleanup here
+
+ // service is now stopped
+ serviceStatus.dwControlsAccepted &= ~(SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN);
+ serviceStatus.dwCurrentState = SERVICE_STOPPED;
+ SetServiceStatus(serviceStatusHandle, &serviceStatus);
+ }
+}
+
+bool WinServiceRun()
+{
+ SERVICE_TABLE_ENTRY serviceTable[] =
+ {
+ { serviceName, ServiceMain },
+ { 0, 0 }
+ };
+
+ if (!StartServiceCtrlDispatcher(serviceTable))
+ {
+ TC_LOG_ERROR("server.worldserver", "StartService Failed. Error [%u]", uint32(::GetLastError()));
+ return false;
+ }
+ return true;
+}
+#endif
diff --git a/src/common/Platform/ServiceWin32.h b/src/common/Platform/ServiceWin32.h
new file mode 100644
index 00000000000..b892ba4e3b6
--- /dev/null
+++ b/src/common/Platform/ServiceWin32.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2008-2016 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/>.
+ */
+
+#ifdef _WIN32
+#ifndef _WIN32_SERVICE_
+#define _WIN32_SERVICE_
+
+bool WinServiceInstall();
+bool WinServiceUninstall();
+bool WinServiceRun();
+
+#endif // _WIN32_SERVICE_
+#endif // _WIN32
diff --git a/src/common/Threading/LockedQueue.h b/src/common/Threading/LockedQueue.h
index c6faaaf81ca..21a29d7e53b 100644
--- a/src/common/Threading/LockedQueue.h
+++ b/src/common/Threading/LockedQueue.h
@@ -57,6 +57,14 @@ public:
unlock();
}
+ //! Adds items back to front of the queue
+ template<class Iterator>
+ void readd(Iterator begin, Iterator end)
+ {
+ std::lock_guard<std::mutex> lock(_lock);
+ _queue.insert(_queue.begin(), begin, end);
+ }
+
//! Gets the next result in the queue, if any.
bool next(T& result)
{
diff --git a/src/common/Threading/MPSCQueue.h b/src/common/Threading/MPSCQueue.h
new file mode 100644
index 00000000000..09648b844be
--- /dev/null
+++ b/src/common/Threading/MPSCQueue.h
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2008-2016 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 MPSCQueue_h__
+#define MPSCQueue_h__
+
+#include <atomic>
+#include <utility>
+
+// C++ implementation of Dmitry Vyukov's lock free MPSC queue
+// http://www.1024cores.net/home/lock-free-algorithms/queues/non-intrusive-mpsc-node-based-queue
+template<typename T>
+class MPSCQueue
+{
+public:
+ MPSCQueue() : _head(new Node()), _tail(_head.load(std::memory_order_relaxed))
+ {
+ Node* front = _head.load(std::memory_order_relaxed);
+ front->Next.store(nullptr, std::memory_order_relaxed);
+ }
+
+ ~MPSCQueue()
+ {
+ T* output;
+ while (this->Dequeue(output))
+ ;
+
+ Node* front = _head.load(std::memory_order_relaxed);
+ delete front;
+ }
+
+ void Enqueue(T* input)
+ {
+ Node* node = new Node(input);
+ Node* prevHead = _head.exchange(node, std::memory_order_acq_rel);
+ prevHead->Next.store(node, std::memory_order_release);
+ }
+
+ bool Dequeue(T*& result)
+ {
+ Node* tail = _tail.load(std::memory_order_relaxed);
+ Node* next = tail->Next.load(std::memory_order_acquire);
+ if (!next)
+ return false;
+
+ result = next->Data;
+ _tail.store(next, std::memory_order_release);
+ delete tail;
+ return true;
+ }
+
+private:
+ struct Node
+ {
+ Node() = default;
+ explicit Node(T* data) : Data(data) { Next.store(nullptr, std::memory_order_relaxed); }
+
+ T* Data;
+ std::atomic<Node*> Next;
+ };
+
+ std::atomic<Node*> _head;
+ std::atomic<Node*> _tail;
+
+ MPSCQueue(MPSCQueue const&) = delete;
+ MPSCQueue& operator=(MPSCQueue const&) = delete;
+};
+
+#endif // MPSCQueue_h__
diff --git a/src/common/Utilities/Containers.h b/src/common/Utilities/Containers.h
new file mode 100644
index 00000000000..0f83b52f9d0
--- /dev/null
+++ b/src/common/Utilities/Containers.h
@@ -0,0 +1,179 @@
+/*
+ * Copyright (C) 2008-2016 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_CONTAINERS_H
+#define TRINITY_CONTAINERS_H
+
+#include "Define.h"
+#include "Random.h"
+#include "Util.h"
+#include <algorithm>
+#include <functional>
+#include <list>
+#include <vector>
+
+namespace Trinity
+{
+ namespace Containers
+ {
+ template<class T>
+ void RandomResizeList(std::list<T> &list, uint32 size)
+ {
+ size_t list_size = list.size();
+
+ while (list_size > size)
+ {
+ typename std::list<T>::iterator itr = list.begin();
+ std::advance(itr, urand(0, list_size - 1));
+ list.erase(itr);
+ --list_size;
+ }
+ }
+
+ template<class T, class Predicate>
+ void RandomResizeList(std::list<T> &list, Predicate& predicate, uint32 size)
+ {
+ //! First use predicate filter
+ std::list<T> listCopy;
+ for (typename std::list<T>::iterator itr = list.begin(); itr != list.end(); ++itr)
+ if (predicate(*itr))
+ listCopy.push_back(*itr);
+
+ if (size)
+ RandomResizeList(listCopy, size);
+
+ list = listCopy;
+ }
+
+ /*
+ * Select a random element from a container.
+ *
+ * Note: container cannot be empty
+ */
+ template <class C>
+ typename C::value_type const& SelectRandomContainerElement(C const& container)
+ {
+ typename C::const_iterator it = container.begin();
+ std::advance(it, urand(0, container.size() - 1));
+ return *it;
+ }
+
+ /*
+ * Select a random element from a container where each element has a different chance to be selected.
+ *
+ * @param container Container to select an element from
+ * @param weights Chances of each element to be selected, must be in the same order as elements in container.
+ * Caller is responsible for checking that sum of all weights is greater than 0.
+ *
+ * Note: container cannot be empty
+ */
+ template <class C>
+ typename C::const_iterator SelectRandomWeightedContainerElement(C const& container, std::vector<double> weights)
+ {
+ Trinity::discrete_distribution_param<uint32> ddParam(weights.begin(), weights.end());
+ std::discrete_distribution<uint32> dd(ddParam);
+ typename C::const_iterator it = container.begin();
+ std::advance(it, dd(SFMTEngine::Instance()));
+ return it;
+ }
+
+ /*
+ * Select a random element from a container where each element has a different chance to be selected.
+ *
+ * @param container Container to select an element from
+ * @param weightExtractor Function retrieving chance of each element in container, expected to take an element of the container and returning a double
+ *
+ * Note: container cannot be empty
+ */
+ template <class C, class Fn>
+ typename C::const_iterator SelectRandomWeightedContainerElement(C const& container, Fn weightExtractor)
+ {
+ std::vector<double> weights;
+ weights.reserve(container.size());
+ double weightSum = 0.0;
+ for (auto itr = container.begin(); itr != container.end(); ++itr)
+ {
+ double weight = weightExtractor(*itr);
+ weights.push_back(weight);
+ weightSum += weight;
+ }
+ if (weightSum <= 0.0)
+ weights.assign(container.size(), 1.0);
+
+ return SelectRandomWeightedContainerElement(container, weights);
+ }
+
+ /**
+ * @fn void Trinity::Containers::RandomShuffle(C& container)
+ *
+ * @brief Reorder the elements of the container randomly.
+ *
+ * @param container Container to reorder
+ */
+ template <class C>
+ void RandomShuffle(C& container)
+ {
+ std::shuffle(container.begin(), container.end(), SFMTEngine::Instance());
+ }
+
+ /**
+ * @fn bool Trinity::Containers::Intersects(Iterator first1, Iterator last1, Iterator first2, Iterator last2)
+ *
+ * @brief Checks if two SORTED containers have a common element
+ *
+ * @param first1 Iterator pointing to start of the first container
+ * @param last1 Iterator pointing to end of the first container
+ * @param first2 Iterator pointing to start of the second container
+ * @param last2 Iterator pointing to end of the second container
+ *
+ * @return true if containers have a common element, false otherwise.
+ */
+ template<class Iterator1, class Iterator2>
+ bool Intersects(Iterator1 first1, Iterator1 last1, Iterator2 first2, Iterator2 last2)
+ {
+ while (first1 != last1 && first2 != last2)
+ {
+ if (*first1 < *first2)
+ ++first1;
+ else if (*first2 < *first1)
+ ++first2;
+ else
+ return true;
+ }
+
+ return false;
+ }
+
+ template<class K, class V, template<class, class, class...> class M, class... Rest>
+ void MultimapErasePair(M<K, V, Rest...>& multimap, K const& key, V const& value)
+ {
+ auto range = multimap.equal_range(key);
+ for (auto itr = range.first; itr != range.second;)
+ {
+ if (itr->second == value)
+ itr = multimap.erase(itr);
+ else
+ ++itr;
+ }
+ }
+
+ }
+ //! namespace Containers
+}
+//! namespace Trinity
+
+#endif //! #ifdef TRINITY_CONTAINERS_H
diff --git a/src/common/Utilities/EventMap.h b/src/common/Utilities/EventMap.h
index a1aaa9af269..6a314a9e633 100644
--- a/src/common/Utilities/EventMap.h
+++ b/src/common/Utilities/EventMap.h
@@ -22,7 +22,7 @@
#include "Duration.h"
#include "Util.h"
-class EventMap
+class TC_COMMON_API EventMap
{
/**
* Internal storage type.
@@ -122,7 +122,7 @@ public:
*/
void ScheduleEvent(uint32 eventId, Milliseconds const& time, uint32 group = 0, uint8 phase = 0)
{
- ScheduleEvent(eventId, time.count(), group, phase);
+ ScheduleEvent(eventId, uint32(time.count()), group, phase);
}
/**
@@ -145,7 +145,7 @@ public:
*/
void RescheduleEvent(uint32 eventId, Milliseconds const& time, uint32 group = 0, uint8 phase = 0)
{
- RescheduleEvent(eventId, time.count(), group, phase);
+ RescheduleEvent(eventId, uint32(time.count()), group, phase);
}
/**
@@ -169,7 +169,7 @@ public:
*/
void Repeat(Milliseconds const& time)
{
- Repeat(time.count());
+ Repeat(uint32(time.count()));
}
/**
@@ -190,7 +190,7 @@ public:
*/
void Repeat(Milliseconds const& minTime, Milliseconds const& maxTime)
{
- Repeat(minTime.count(), maxTime.count());
+ Repeat(uint32(minTime.count()), uint32(maxTime.count()));
}
/**
@@ -218,7 +218,7 @@ public:
*/
void DelayEvents(Milliseconds const& delay)
{
- DelayEvents(delay.count());
+ DelayEvents(uint32(delay.count()));
}
/**
@@ -239,7 +239,7 @@ public:
*/
void DelayEvents(Milliseconds const& delay, uint32 group)
{
- DelayEvents(delay.count(), group);
+ DelayEvents(uint32(delay.count()), group);
}
/**
diff --git a/src/common/Utilities/EventProcessor.h b/src/common/Utilities/EventProcessor.h
index e5eafed79b9..e10558e6a21 100644
--- a/src/common/Utilities/EventProcessor.h
+++ b/src/common/Utilities/EventProcessor.h
@@ -25,7 +25,7 @@
// Note. All times are in milliseconds here.
-class BasicEvent
+class TC_COMMON_API BasicEvent
{
public:
BasicEvent()
@@ -55,7 +55,7 @@ class BasicEvent
typedef std::multimap<uint64, BasicEvent*> EventList;
-class EventProcessor
+class TC_COMMON_API EventProcessor
{
public:
EventProcessor();
diff --git a/src/common/Utilities/MessageBuffer.h b/src/common/Utilities/MessageBuffer.h
new file mode 100644
index 00000000000..d08c4b25bab
--- /dev/null
+++ b/src/common/Utilities/MessageBuffer.h
@@ -0,0 +1,139 @@
+/*
+* Copyright (C) 2008-2016 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 __MESSAGEBUFFER_H_
+#define __MESSAGEBUFFER_H_
+
+#include "Define.h"
+#include <vector>
+#include <cstring>
+
+class MessageBuffer
+{
+ typedef std::vector<uint8>::size_type size_type;
+
+public:
+ MessageBuffer() : _wpos(0), _rpos(0), _storage()
+ {
+ _storage.resize(4096);
+ }
+
+ explicit MessageBuffer(std::size_t initialSize) : _wpos(0), _rpos(0), _storage()
+ {
+ _storage.resize(initialSize);
+ }
+
+ MessageBuffer(MessageBuffer const& right) : _wpos(right._wpos), _rpos(right._rpos), _storage(right._storage)
+ {
+ }
+
+ MessageBuffer(MessageBuffer&& right) : _wpos(right._wpos), _rpos(right._rpos), _storage(right.Move()) { }
+
+ void Reset()
+ {
+ _wpos = 0;
+ _rpos = 0;
+ }
+
+ void Resize(size_type bytes)
+ {
+ _storage.resize(bytes);
+ }
+
+ uint8* GetBasePointer() { return _storage.data(); }
+
+ uint8* GetReadPointer() { return GetBasePointer() + _rpos; }
+
+ uint8* GetWritePointer() { return GetBasePointer() + _wpos; }
+
+ void ReadCompleted(size_type bytes) { _rpos += bytes; }
+
+ void WriteCompleted(size_type bytes) { _wpos += bytes; }
+
+ size_type GetActiveSize() const { return _wpos - _rpos; }
+
+ size_type GetRemainingSpace() const { return _storage.size() - _wpos; }
+
+ size_type GetBufferSize() const { return _storage.size(); }
+
+ // Discards inactive data
+ void Normalize()
+ {
+ if (_rpos)
+ {
+ if (_rpos != _wpos)
+ memmove(GetBasePointer(), GetReadPointer(), GetActiveSize());
+ _wpos -= _rpos;
+ _rpos = 0;
+ }
+ }
+
+ // Ensures there's "some" free space, make sure to call Normalize() before this
+ void EnsureFreeSpace()
+ {
+ // resize buffer if it's already full
+ if (GetRemainingSpace() == 0)
+ _storage.resize(_storage.size() * 3 / 2);
+ }
+
+ void Write(void const* data, std::size_t size)
+ {
+ if (size)
+ {
+ memcpy(GetWritePointer(), data, size);
+ WriteCompleted(size);
+ }
+ }
+
+ std::vector<uint8>&& Move()
+ {
+ _wpos = 0;
+ _rpos = 0;
+ return std::move(_storage);
+ }
+
+ MessageBuffer& operator=(MessageBuffer const& right)
+ {
+ if (this != &right)
+ {
+ _wpos = right._wpos;
+ _rpos = right._rpos;
+ _storage = right._storage;
+ }
+
+ return *this;
+ }
+
+ MessageBuffer& operator=(MessageBuffer&& right)
+ {
+ if (this != &right)
+ {
+ _wpos = right._wpos;
+ _rpos = right._rpos;
+ _storage = right.Move();
+ }
+
+ return *this;
+ }
+
+private:
+ size_type _wpos;
+ size_type _rpos;
+ std::vector<uint8> _storage;
+};
+
+#endif /* __MESSAGEBUFFER_H_ */
diff --git a/src/common/Utilities/Random.cpp b/src/common/Utilities/Random.cpp
new file mode 100644
index 00000000000..31318e8f52d
--- /dev/null
+++ b/src/common/Utilities/Random.cpp
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "Random.h"
+#include "Common.h"
+#include "Errors.h"
+#include "SFMT.h"
+#include <boost/thread/tss.hpp>
+
+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(GetRng()->IRandom(min, max));
+}
+
+uint32 urand(uint32 min, uint32 max)
+{
+ ASSERT(max >= min);
+ return GetRng()->URandom(min, max);
+}
+
+uint32 urandms(uint32 min, uint32 max)
+{
+ ASSERT(max >= min);
+ ASSERT(INT_MAX / IN_MILLISECONDS >= max);
+ return GetRng()->URandom(min * IN_MILLISECONDS, max * IN_MILLISECONDS);
+}
+
+float frand(float min, float max)
+{
+ ASSERT(max >= min);
+ return float(GetRng()->Random() * (max - min) + min);
+}
+
+Milliseconds randtime(Milliseconds const& min, Milliseconds const& max)
+{
+ long long diff = max.count() - min.count();
+ ASSERT(diff >= 0);
+ ASSERT(diff <= (uint32)-1);
+ return min + Milliseconds(urand(0, diff));
+}
+
+uint32 rand32()
+{
+ return GetRng()->BRandom();
+}
+
+double rand_norm()
+{
+ return GetRng()->Random();
+}
+
+double rand_chance()
+{
+ return GetRng()->Random() * 100.0;
+}
+
+SFMTEngine& SFMTEngine::Instance()
+{
+ static SFMTEngine engine;
+ return engine;
+}
diff --git a/src/common/Utilities/Random.h b/src/common/Utilities/Random.h
new file mode 100644
index 00000000000..b3ca00219ef
--- /dev/null
+++ b/src/common/Utilities/Random.h
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef Random_h__
+#define Random_h__
+
+#include "Define.h"
+#include "Duration.h"
+#include <limits>
+#include <random>
+
+/* Return a random number in the range min..max. */
+TC_COMMON_API int32 irand(int32 min, int32 max);
+
+/* Return a random number in the range min..max (inclusive). */
+TC_COMMON_API uint32 urand(uint32 min, uint32 max);
+
+/* Return a random millisecond value between min and max seconds. Functionally equivalent to urand(min*IN_MILLISECONDS, max*IN_MILLISECONDS). */
+TC_COMMON_API uint32 urandms(uint32 min, uint32 max);
+
+/* Return a random number in the range 0 .. UINT32_MAX. */
+TC_COMMON_API uint32 rand32();
+
+/* Return a random time in the range min..max (up to millisecond precision). Only works for values where millisecond difference is a valid uint32. */
+TC_COMMON_API Milliseconds randtime(Milliseconds const& min, Milliseconds const& max);
+
+/* Return a random number in the range min..max */
+TC_COMMON_API float frand(float min, float max);
+
+/* Return a random double from 0.0 to 1.0 (exclusive). */
+TC_COMMON_API double rand_norm();
+
+/* Return a random double from 0.0 to 100.0 (exclusive). */
+TC_COMMON_API double rand_chance();
+
+/* Return true if a random roll fits in the specified chance (range 0-100). */
+inline bool roll_chance_f(float chance)
+{
+ return chance > rand_chance();
+}
+
+/* Return true if a random roll fits in the specified chance (range 0-100). */
+inline bool roll_chance_i(int chance)
+{
+ return chance > irand(0, 99);
+}
+
+/*
+* SFMT wrapper satisfying UniformRandomNumberGenerator concept for use in <random> algorithms
+*/
+class TC_COMMON_API SFMTEngine
+{
+public:
+ typedef uint32 result_type;
+
+ static TRINITY_CONSTEXPR result_type min() { return std::numeric_limits<result_type>::min(); }
+ static TRINITY_CONSTEXPR result_type max() { return std::numeric_limits<result_type>::max(); }
+ result_type operator()() const { return rand32(); }
+
+ static SFMTEngine& Instance();
+};
+
+// Ugly, horrible, i don't even..., hack for VS2013 to work around missing discrete_distribution(iterator, iterator) constructor
+namespace Trinity
+{
+#if COMPILER == COMPILER_MICROSOFT && _MSC_VER <= 1800
+ template<typename T>
+ struct discrete_distribution_param : public std::discrete_distribution<T>::param_type
+ {
+ typedef typename std::discrete_distribution<T>::param_type base;
+
+ template<typename InIt>
+ discrete_distribution_param(InIt begin, InIt end) : base(_Noinit())
+ {
+ this->_Pvec.assign(begin, end);
+ this->_Init();
+ }
+ };
+#else
+ template<typename T>
+ using discrete_distribution_param = typename std::discrete_distribution<T>::param_type;
+#endif
+}
+
+#endif // Random_h__
diff --git a/src/common/Utilities/StartProcess.cpp b/src/common/Utilities/StartProcess.cpp
new file mode 100644
index 00000000000..29feeaa2714
--- /dev/null
+++ b/src/common/Utilities/StartProcess.cpp
@@ -0,0 +1,267 @@
+/*
+ * Copyright (C) 2008-2016 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 "StartProcess.h"
+
+#include <atomic>
+#include <thread>
+#include <functional>
+
+#include <boost/algorithm/string/join.hpp>
+#include <boost/iostreams/stream.hpp>
+#include <boost/iostreams/copy.hpp>
+#include <boost/iostreams/concepts.hpp>
+#include <boost/iostreams/device/file_descriptor.hpp>
+#include <boost/process.hpp>
+#include <boost/system/system_error.hpp>
+
+#include "Common.h"
+#include "Log.h"
+
+using namespace boost::process;
+using namespace boost::process::initializers;
+using namespace boost::iostreams;
+
+namespace Trinity {
+
+template<typename T>
+class TCLogSink
+{
+ T callback_;
+
+public:
+ typedef char char_type;
+ typedef sink_tag category;
+
+ // Requires a callback type which has a void(std::string) signature
+ TCLogSink(T callback)
+ : callback_(std::move(callback)) { }
+
+ std::streamsize write(const char* str, std::streamsize size)
+ {
+ callback_(std::string(str, size));
+ return size;
+ }
+};
+
+template<typename T>
+auto MakeTCLogSink(T&& callback)
+ -> TCLogSink<typename std::decay<T>::type>
+{
+ return { std::forward<T>(callback) };
+}
+
+template<typename T>
+static int CreateChildProcess(T waiter, std::string const& executable,
+ std::vector<std::string> const& args,
+ std::string const& logger, std::string const& input,
+ bool secure)
+{
+ auto outPipe = create_pipe();
+ auto errPipe = create_pipe();
+
+ Optional<file_descriptor_source> inputSource;
+
+ if (!secure)
+ {
+ TC_LOG_TRACE(logger, "Starting process \"%s\" with arguments: \"%s\".",
+ executable.c_str(), boost::algorithm::join(args, " ").c_str());
+ }
+
+ // Start the child process
+ child c = [&]
+ {
+ if (!input.empty())
+ {
+ inputSource = file_descriptor_source(input);
+
+ // With binding stdin
+ return execute(run_exe(boost::filesystem::absolute(executable)),
+ set_args(args),
+ bind_stdin(*inputSource),
+ bind_stdout(file_descriptor_sink(outPipe.sink, close_handle)),
+ bind_stderr(file_descriptor_sink(errPipe.sink, close_handle)));
+ }
+ else
+ {
+ // Without binding stdin
+ return execute(run_exe(boost::filesystem::absolute(executable)),
+ set_args(args),
+ bind_stdout(file_descriptor_sink(outPipe.sink, close_handle)),
+ bind_stderr(file_descriptor_sink(errPipe.sink, close_handle)));
+ }
+ }();
+
+ file_descriptor_source outFd(outPipe.source, close_handle);
+ file_descriptor_source errFd(errPipe.source, close_handle);
+
+ auto outInfo = MakeTCLogSink([&](std::string msg)
+ {
+ TC_LOG_INFO(logger, "%s", msg.c_str());
+ });
+
+ auto outError = MakeTCLogSink([&](std::string msg)
+ {
+ TC_LOG_ERROR(logger, "%s", msg.c_str());
+ });
+
+ copy(outFd, outInfo);
+ copy(errFd, outError);
+
+ // Call the waiter in the current scope to prevent
+ // the streams from closing too early on leaving the scope.
+ int const result = waiter(c);
+
+ if (!secure)
+ {
+ TC_LOG_TRACE(logger, ">> Process \"%s\" finished with return value %i.",
+ executable.c_str(), result);
+ }
+
+ if (inputSource)
+ inputSource->close();
+
+ return result;
+}
+
+int StartProcess(std::string const& executable, std::vector<std::string> const& args,
+ std::string const& logger, std::string input_file, bool secure)
+{
+ return CreateChildProcess([](child& c) -> int
+ {
+ try
+ {
+ return wait_for_exit(c);
+ }
+ catch (...)
+ {
+ return EXIT_FAILURE;
+ }
+ }, executable, args, logger, input_file, secure);
+}
+
+class AsyncProcessResultImplementation
+ : public AsyncProcessResult
+{
+ std::string const executable;
+ std::vector<std::string> const args;
+ std::string const logger;
+ std::string const input_file;
+ bool const is_secure;
+
+ std::atomic<bool> was_terminated;
+
+ // Workaround for missing move support in boost < 1.57
+ Optional<std::shared_ptr<std::future<int>>> result;
+ Optional<std::reference_wrapper<child>> my_child;
+
+public:
+ explicit AsyncProcessResultImplementation(std::string executable_, std::vector<std::string> args_,
+ std::string logger_, std::string input_file_,
+ bool secure)
+ : executable(std::move(executable_)), args(std::move(args_)),
+ logger(std::move(logger_)), input_file(input_file_),
+ is_secure(secure), was_terminated(false) { }
+
+ AsyncProcessResultImplementation(AsyncProcessResultImplementation const&) = delete;
+ AsyncProcessResultImplementation& operator= (AsyncProcessResultImplementation const&) = delete;
+ AsyncProcessResultImplementation(AsyncProcessResultImplementation&&) = delete;
+ AsyncProcessResultImplementation& operator= (AsyncProcessResultImplementation&&) = delete;
+
+ int StartProcess()
+ {
+ ASSERT(!my_child, "Process started already!");
+
+ return CreateChildProcess([&](child& c) -> int
+ {
+ int result;
+ my_child = std::reference_wrapper<child>(c);
+
+ try
+ {
+ result = wait_for_exit(c);
+ }
+ catch (...)
+ {
+ result = EXIT_FAILURE;
+ }
+
+ my_child.reset();
+ return was_terminated ? EXIT_FAILURE : result;
+
+ }, executable, args, logger, input_file, is_secure);
+ }
+
+ void SetFuture(std::future<int> result_)
+ {
+ result = std::make_shared<std::future<int>>(std::move(result_));
+ }
+
+ /// Returns the future which contains the result of the process
+ /// as soon it is finished.
+ std::future<int>& GetFutureResult() override
+ {
+ ASSERT(*result, "The process wasn't started!");
+ return **result;
+ }
+
+ /// Tries to terminate the process
+ void Terminate() override
+ {
+ if (!my_child)
+ {
+ was_terminated = true;
+ try
+ {
+ terminate(my_child->get());
+ }
+ catch(...)
+ {
+ // Do nothing
+ }
+ }
+ }
+};
+
+TC_COMMON_API std::shared_ptr<AsyncProcessResult>
+ StartAsyncProcess(std::string executable, std::vector<std::string> args,
+ std::string logger, std::string input_file, bool secure)
+{
+ auto handle = std::make_shared<AsyncProcessResultImplementation>(
+ std::move(executable), std::move(args), std::move(logger), std::move(input_file), secure);
+
+ handle->SetFuture(std::async(std::launch::async, [handle] { return handle->StartProcess(); }));
+ return handle;
+}
+
+Optional<std::string> SearchExecutableInPath(std::string const& filename)
+{
+ try
+ {
+ auto result = search_path(filename);
+ if (result.empty())
+ return boost::none;
+ else
+ return result;
+ }
+ catch (...)
+ {
+ return boost::none;
+ }
+}
+
+} // namespace Trinity
diff --git a/src/common/Utilities/StartProcess.h b/src/common/Utilities/StartProcess.h
new file mode 100644
index 00000000000..3b380bd4f4e
--- /dev/null
+++ b/src/common/Utilities/StartProcess.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2008-2016 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 Process_h__
+#define Process_h__
+
+#include <future>
+#include <memory>
+#include "Common.h"
+
+namespace Trinity {
+
+/// Starts a process with the given arguments and parameters and will block
+/// until the process is finished.
+/// When an input path is given, the file will be routed to the processes stdin.
+/// When the process is marked as secure no arguments are leaked to logs.
+/// Note that most executables expect it's name as the first argument.
+TC_COMMON_API int StartProcess(std::string const& executable, std::vector<std::string> const& args,
+ std::string const& logger, std::string input_file = "",
+ bool secure = false);
+
+/// Platform and library independent representation
+/// of asynchronous process results
+class AsyncProcessResult
+{
+public:
+ virtual ~AsyncProcessResult() { }
+
+ /// Returns the future which contains the result of the process
+ /// as soon it is finished.
+ virtual std::future<int>& GetFutureResult() = 0;
+
+ /// Tries to terminate the process
+ virtual void Terminate() = 0;
+};
+
+/// Starts a process asynchronously with the given arguments and parameters and
+/// returns an AsyncProcessResult immediately which is set, when the process exits.
+/// When an input path is given, the file will be routed to the processes stdin.
+/// When the process is marked as secure no arguments are leaked to logs.
+/// Note that most executables expect it's name as the first argument.
+TC_COMMON_API std::shared_ptr<AsyncProcessResult>
+ StartAsyncProcess(std::string executable, std::vector<std::string> args,
+ std::string logger, std::string input_file = "",
+ bool secure = false);
+
+/// Searches for the given executable in the PATH variable
+/// and returns a present optional when it was found.
+TC_COMMON_API Optional<std::string> SearchExecutableInPath(std::string const& filename);
+
+} // namespace Trinity
+
+#endif // Process_h__
diff --git a/src/common/Utilities/StringFormat.h b/src/common/Utilities/StringFormat.h
index d85523bc11f..e21b1024e87 100644
--- a/src/common/Utilities/StringFormat.h
+++ b/src/common/Utilities/StringFormat.h
@@ -19,7 +19,7 @@
#ifndef TRINITYCORE_STRING_FORMAT_H
#define TRINITYCORE_STRING_FORMAT_H
-#include "format.h"
+#include "cppformat/format.h"
namespace Trinity
{
diff --git a/src/common/Utilities/TaskScheduler.h b/src/common/Utilities/TaskScheduler.h
index 8cf5d914128..6784c968683 100644
--- a/src/common/Utilities/TaskScheduler.h
+++ b/src/common/Utilities/TaskScheduler.h
@@ -46,7 +46,7 @@ class TaskContext;
/// with the same duration or a new one.
/// It also provides access to the repeat counter which is useful for task that repeat itself often
/// but behave different every time (spoken event dialogs for example).
-class TaskScheduler
+class TC_COMMON_API TaskScheduler
{
friend class TaskContext;
@@ -131,7 +131,7 @@ class TaskScheduler
};
};
- class TaskQueue
+ class TC_COMMON_API TaskQueue
{
std::multiset<TaskContainer, Compare> container;
@@ -401,14 +401,14 @@ private:
auto const milli_max = std::chrono::duration_cast<std::chrono::milliseconds>(max);
// TC specific: use SFMT URandom
- return std::chrono::milliseconds(urand(milli_min.count(), milli_max.count()));
+ return std::chrono::milliseconds(urand(uint32(milli_min.count()), uint32(milli_max.count())));
}
/// Dispatch remaining tasks
void Dispatch(success_t const& callback);
};
-class TaskContext
+class TC_COMMON_API TaskContext
{
friend class TaskScheduler;
diff --git a/src/common/Utilities/Util.cpp b/src/common/Utilities/Util.cpp
index 3eb901ca35d..3d8cda66d48 100644
--- a/src/common/Utilities/Util.cpp
+++ b/src/common/Utilities/Util.cpp
@@ -20,10 +20,9 @@
#include "Common.h"
#include "CompilerDefs.h"
#include "utf8.h"
-#include "SFMT.h"
#include "Errors.h" // for ASSERT
#include <stdarg.h>
-#include <boost/thread/tss.hpp>
+#include <boost/algorithm/string/case_conv.hpp>
#if COMPILER == COMPILER_GNU
#include <sys/socket.h>
@@ -31,61 +30,6 @@
#include <arpa/inet.h>
#endif
-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(GetRng()->IRandom(min, max));
-}
-
-uint32 urand(uint32 min, uint32 max)
-{
- ASSERT(max >= min);
- return GetRng()->URandom(min, max);
-}
-
-uint32 urandms(uint32 min, uint32 max)
-{
- ASSERT(max >= min);
- ASSERT(INT_MAX/IN_MILLISECONDS >= max);
- return GetRng()->URandom(min * IN_MILLISECONDS, max * IN_MILLISECONDS);
-}
-
-float frand(float min, float max)
-{
- ASSERT(max >= min);
- return float(GetRng()->Random() * (max - min) + min);
-}
-
-uint32 rand32()
-{
- return GetRng()->BRandom();
-}
-
-double rand_norm()
-{
- return GetRng()->Random();
-}
-
-double rand_chance()
-{
- return GetRng()->Random() * 100.0;
-}
-
Tokenizer::Tokenizer(const std::string &src, const char sep, uint32 vectorReserve)
{
m_str = new char[src.length() + 1];
@@ -275,22 +219,29 @@ bool IsIPAddress(char const* ipaddress)
}
/// create PID file
-uint32 CreatePIDFile(const std::string& filename)
+uint32 CreatePIDFile(std::string const& filename)
{
- FILE* pid_file = fopen (filename.c_str(), "w" );
+ FILE* pid_file = fopen(filename.c_str(), "w");
if (pid_file == NULL)
return 0;
+ uint32 pid = GetPID();
+
+ fprintf(pid_file, "%u", pid);
+ fclose(pid_file);
+
+ return pid;
+}
+
+uint32 GetPID()
+{
#ifdef _WIN32
DWORD pid = GetCurrentProcessId();
#else
pid_t pid = getpid();
#endif
- fprintf(pid_file, "%u", pid );
- fclose(pid_file);
-
- return (uint32)pid;
+ return uint32(pid);
}
size_t utf8length(std::string& utf8str)
@@ -475,7 +426,7 @@ bool utf8ToConsole(const std::string& utf8str, std::string& conStr)
return false;
conStr.resize(wstr.size());
- CharToOemBuffW(&wstr[0], &conStr[0], wstr.size());
+ CharToOemBuffW(&wstr[0], &conStr[0], uint32(wstr.size()));
#else
// not implemented yet
conStr = utf8str;
@@ -489,7 +440,7 @@ bool consoleToUtf8(const std::string& conStr, std::string& utf8str)
#if PLATFORM == PLATFORM_WINDOWS
std::wstring wstr;
wstr.resize(conStr.size());
- OemToCharBuffW(&conStr[0], &wstr[0], conStr.size());
+ OemToCharBuffW(&conStr[0], &wstr[0], uint32(conStr.size()));
return WStrToUtf8(wstr, utf8str);
#else
@@ -507,7 +458,7 @@ bool Utf8FitTo(const std::string& str, std::wstring const& search)
return false;
// converting to lower case
- wstrToLower( temp );
+ wstrToLower(temp);
if (temp.find(search) == std::wstring::npos)
return false;
@@ -526,10 +477,10 @@ void utf8printf(FILE* out, const char *str, ...)
void vutf8printf(FILE* out, const char *str, va_list* ap)
{
#if PLATFORM == PLATFORM_WINDOWS
- char temp_buf[32*1024];
- wchar_t wtemp_buf[32*1024];
+ char temp_buf[32 * 1024];
+ wchar_t wtemp_buf[32 * 1024];
- size_t temp_len = vsnprintf(temp_buf, 32*1024, str, *ap);
+ size_t temp_len = vsnprintf(temp_buf, 32 * 1024, str, *ap);
//vsnprintf returns -1 if the buffer is too small
if (temp_len == size_t(-1))
temp_len = 32*1024-1;
@@ -537,13 +488,24 @@ void vutf8printf(FILE* out, const char *str, va_list* ap)
size_t wtemp_len = 32*1024-1;
Utf8toWStr(temp_buf, temp_len, wtemp_buf, wtemp_len);
- CharToOemBuffW(&wtemp_buf[0], &temp_buf[0], wtemp_len+1);
+ CharToOemBuffW(&wtemp_buf[0], &temp_buf[0], uint32(wtemp_len + 1));
fprintf(out, "%s", temp_buf);
#else
vfprintf(out, str, *ap);
#endif
}
+bool Utf8ToUpperOnlyLatin(std::string& utf8String)
+{
+ std::wstring wstr;
+ if (!Utf8toWStr(utf8String, wstr))
+ return false;
+
+ std::transform(wstr.begin(), wstr.end(), wstr.begin(), wcharToUpperOnlyLatin);
+
+ return WStrToUtf8(wstr, utf8String);
+}
+
std::string ByteArrayToHexStr(uint8 const* bytes, uint32 arrayLen, bool reverse /* = false */)
{
int32 init = 0;
@@ -567,3 +529,34 @@ std::string ByteArrayToHexStr(uint8 const* bytes, uint32 arrayLen, bool reverse
return ss.str();
}
+
+void HexStrToByteArray(std::string const& str, uint8* out, bool reverse /*= false*/)
+{
+ // string must have even number of characters
+ if (str.length() & 1)
+ return;
+
+ int32 init = 0;
+ int32 end = int32(str.length());
+ int8 op = 1;
+
+ if (reverse)
+ {
+ init = int32(str.length() - 2);
+ end = -2;
+ op = -1;
+ }
+
+ uint32 j = 0;
+ for (int32 i = init; i != end; i += 2 * op)
+ {
+ char buffer[3] = { str[i], str[i + 1], '\0' };
+ out[j++] = uint8(strtoul(buffer, NULL, 16));
+ }
+}
+
+bool StringToBool(std::string const& str)
+{
+ std::string lowerStr = boost::algorithm::to_lower_copy(str);
+ return lowerStr == "1" || lowerStr == "true" || lowerStr == "yes";
+}
diff --git a/src/common/Utilities/Util.h b/src/common/Utilities/Util.h
index 1f3b78a8d56..cc68f3b2237 100644
--- a/src/common/Utilities/Util.h
+++ b/src/common/Utilities/Util.h
@@ -21,6 +21,7 @@
#include "Define.h"
#include "Errors.h"
+#include "Random.h"
#include <algorithm>
#include <string>
@@ -39,7 +40,7 @@ template<typename T, class S> struct Finder
bool operator()(const std::pair<int, S> &obj) { return obj.second.*idMember_ == val_; }
};
-class Tokenizer
+class TC_COMMON_API Tokenizer
{
public:
typedef std::vector<char const*> StorageType;
@@ -67,48 +68,15 @@ private:
StorageType m_storage;
};
-void stripLineInvisibleChars(std::string &src);
+TC_COMMON_API void stripLineInvisibleChars(std::string &src);
-int32 MoneyStringToMoney(const std::string& moneyString);
+TC_COMMON_API int32 MoneyStringToMoney(const std::string& moneyString);
-struct tm* localtime_r(const time_t* time, struct tm *result);
+TC_COMMON_API 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);
-
-/* Return a random number in the range min..max. */
-int32 irand(int32 min, int32 max);
-
-/* Return a random number in the range min..max (inclusive). */
-uint32 urand(uint32 min, uint32 max);
-
-/* Return a random millisecond value between min and max seconds. Functionally equivalent to urand(min*IN_MILLISECONDS, max*IN_MILLISECONDS). */
-uint32 urandms(uint32 min, uint32 max);
-
-/* Return a random number in the range 0 .. UINT32_MAX. */
-uint32 rand32();
-
-/* Return a random number in the range min..max */
-float frand(float min, float max);
-
-/* Return a random double from 0.0 to 1.0 (exclusive). */
-double rand_norm();
-
-/* Return a random double from 0.0 to 100.0 (exclusive). */
-double rand_chance();
-
-/* Return true if a random roll fits in the specified chance (range 0-100). */
-inline bool roll_chance_f(float chance)
-{
- return chance > rand_chance();
-}
-
-/* Return true if a random roll fits in the specified chance (range 0-100). */
-inline bool roll_chance_i(int chance)
-{
- return chance > irand(0, 99);
-}
+TC_COMMON_API std::string secsToTimeString(uint64 timeInSecs, bool shortText = false, bool hoursOnly = false);
+TC_COMMON_API uint32 TimeStringToSecs(const std::string& timestring);
+TC_COMMON_API std::string TimeToTimestampStr(time_t t);
inline void ApplyPercentModFloatVar(float& var, float val, bool apply)
{
@@ -143,20 +111,20 @@ inline T RoundToInterval(T& num, T floor, T ceil)
}
// UTF8 handling
-bool Utf8toWStr(const std::string& utf8str, std::wstring& wstr);
+TC_COMMON_API bool Utf8toWStr(const std::string& utf8str, std::wstring& wstr);
// in wsize==max size of buffer, out wsize==real string size
-bool Utf8toWStr(char const* utf8str, size_t csize, wchar_t* wstr, size_t& wsize);
+TC_COMMON_API bool Utf8toWStr(char const* utf8str, size_t csize, wchar_t* wstr, size_t& wsize);
inline bool Utf8toWStr(const std::string& utf8str, wchar_t* wstr, size_t& wsize)
{
return Utf8toWStr(utf8str.c_str(), utf8str.size(), wstr, wsize);
}
-bool WStrToUtf8(std::wstring const& wstr, std::string& utf8str);
+TC_COMMON_API bool WStrToUtf8(std::wstring const& wstr, std::string& utf8str);
// size==real string size
-bool WStrToUtf8(wchar_t* wstr, size_t size, std::string& utf8str);
+TC_COMMON_API bool WStrToUtf8(wchar_t* wstr, size_t size, std::string& utf8str);
-size_t utf8length(std::string& utf8str); // set string to "" if invalid utf8 sequence
-void utf8truncate(std::string& utf8str, size_t len);
+TC_COMMON_API size_t utf8length(std::string& utf8str); // set string to "" if invalid utf8 sequence
+TC_COMMON_API void utf8truncate(std::string& utf8str, size_t len);
inline bool isBasicLatinCharacter(wchar_t wchar)
{
@@ -335,19 +303,24 @@ inline void wstrToLower(std::wstring& str)
std::transform( str.begin(), str.end(), str.begin(), wcharToLower );
}
-std::wstring GetMainPartOfName(std::wstring const& wname, uint32 declension);
+TC_COMMON_API std::wstring GetMainPartOfName(std::wstring const& wname, uint32 declension);
+
+TC_COMMON_API bool utf8ToConsole(const std::string& utf8str, std::string& conStr);
+TC_COMMON_API bool consoleToUtf8(const std::string& conStr, std::string& utf8str);
+TC_COMMON_API bool Utf8FitTo(const std::string& str, std::wstring const& search);
+TC_COMMON_API void utf8printf(FILE* out, const char *str, ...);
+TC_COMMON_API void vutf8printf(FILE* out, const char *str, va_list* ap);
+TC_COMMON_API bool Utf8ToUpperOnlyLatin(std::string& utf8String);
-bool utf8ToConsole(const std::string& utf8str, std::string& conStr);
-bool consoleToUtf8(const std::string& conStr, std::string& utf8str);
-bool Utf8FitTo(const std::string& str, std::wstring const& search);
-void utf8printf(FILE* out, const char *str, ...);
-void vutf8printf(FILE* out, const char *str, va_list* ap);
+TC_COMMON_API bool IsIPAddress(char const* ipaddress);
-bool IsIPAddress(char const* ipaddress);
+TC_COMMON_API uint32 CreatePIDFile(std::string const& filename);
+TC_COMMON_API uint32 GetPID();
-uint32 CreatePIDFile(const std::string& filename);
+TC_COMMON_API std::string ByteArrayToHexStr(uint8 const* bytes, uint32 length, bool reverse = false);
+TC_COMMON_API void HexStrToByteArray(std::string const& str, uint8* out, bool reverse = false);
-std::string ByteArrayToHexStr(uint8 const* bytes, uint32 length, bool reverse = false);
+TC_COMMON_API bool StringToBool(std::string const& str);
// simple class for not-modifyable list
template <typename T>