From 30d105fe9f5ba401ba298b5318012503abf5fe04 Mon Sep 17 00:00:00 2001 From: H0zen Date: Tue, 8 May 2018 12:04:55 +0300 Subject: [PATCH] New RNG engine for MaNGOS - Based on C++11 library - Uses ACE_TSS_Singleton for thread-safety --- src/CMakeLists.txt | 10 ++--- src/game/Server/WorldSocket.cpp | 2 +- src/mangosd/mangosd.cpp | 4 -- src/shared/Utilities/RNGen.h | 79 +++++++++++++++++++++++++++++++++ src/shared/Utilities/Util.cpp | 33 +++++--------- src/shared/Utilities/Util.h | 15 +------ 6 files changed, 96 insertions(+), 47 deletions(-) create mode 100644 src/shared/Utilities/RNGen.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index e2fbcf60..8516dda3 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -31,11 +31,6 @@ add_subdirectory(framework) # Build the mangos shared library add_subdirectory(shared) -# Build the mangos realm authentication server -if(BUILD_REALMD) - add_subdirectory(realmd) -endif() - if(BUILD_MANGOSD) # Build the mangos game library add_subdirectory(game) @@ -47,6 +42,11 @@ if(BUILD_MANGOSD) add_subdirectory(modules) endif() +# Build the mangos realm authentication server +if(BUILD_REALMD) + add_subdirectory(realmd) +endif() + # If we want the tools for map/vmap/mmap extraction if(BUILD_TOOLS) add_subdirectory(tools) diff --git a/src/game/Server/WorldSocket.cpp b/src/game/Server/WorldSocket.cpp index bc03fa50..77ede485 100644 --- a/src/game/Server/WorldSocket.cpp +++ b/src/game/Server/WorldSocket.cpp @@ -89,7 +89,7 @@ WorldSocket::WorldSocket(void) : m_OutBufferLock(), m_OutBuffer(0), m_OutBufferSize(65536), - m_Seed(static_cast(rand32())) + m_Seed(rand32()) { reference_counting_policy().value(ACE_Event_Handler::Reference_Counting_Policy::ENABLED); } diff --git a/src/mangosd/mangosd.cpp b/src/mangosd/mangosd.cpp index 852863fd..808d3652 100644 --- a/src/mangosd/mangosd.cpp +++ b/src/mangosd/mangosd.cpp @@ -413,8 +413,6 @@ int main(int argc, char** argv) ///- Set Realm to Offline, if crash happens. Only used once. LoginDatabase.DirectPExecute("UPDATE realmlist SET realmflags = realmflags | %u WHERE id = '%u'", REALM_FLAG_OFFLINE, realmID); - initMTRandTSS(); - ///- Initialize the World sWorld.SetInitialWorldSettings(); @@ -547,8 +545,6 @@ int main(int argc, char** argv) WorldDatabase.HaltDelayThread(); LoginDatabase.HaltDelayThread(); - deleteMTRandTSS(); - // This is done to make sure that we cleanup our so file before it's // unloaded automatically, since the ~ScriptMgr() is called to late // as it's allocated with static storage. diff --git a/src/shared/Utilities/RNGen.h b/src/shared/Utilities/RNGen.h new file mode 100644 index 00000000..9482323f --- /dev/null +++ b/src/shared/Utilities/RNGen.h @@ -0,0 +1,79 @@ +/** + * MaNGOS is a full featured server for World of Warcraft, supporting + * the following clients: 1.12.x, 2.4.3, 3.3.5a, 4.3.4a and 5.4.8 + * + * Copyright (C) 2005-2018 MaNGOS project + * + * 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * World of Warcraft, and all World of Warcraft or Warcraft art, images, + * and lore are copyrighted by Blizzard Entertainment, Inc. + */ + +#ifndef MANGOS_RNG_H +#define MANGOS_RNG_H + +#include + +#include "ace/Singleton.h" +#include "ace/Synch_Traits.h" +#include "Platform/Define.h" + +class RNGen +{ +public: + RNGen() + { + std::random_device rd; + gen_.seed(rd()); + } + + int32 rand_i(int32 min, int32 max) + { + std::uniform_int_distribution dist{min, max}; + return dist(gen_); + } + + uint32 rand_u(uint32 min, uint32 max) + { + std::uniform_int_distribution dist{min, max}; + return dist(gen_); + } + + uint32 rand() + { + std::uniform_int_distribution dist; + return dist(gen_); + } + + float rand_f(float min, float max) + { + std::uniform_real_distribution dist{min, max}; + return dist(gen_); + } + + double rand_d(double min, double max) + { + std::uniform_real_distribution dist{min, max}; + return dist(gen_); + } + +private: + std::mt19937 gen_; +}; + +typedef ACE_TSS_Singleton RNG; + +#endif \ No newline at end of file diff --git a/src/shared/Utilities/Util.cpp b/src/shared/Utilities/Util.cpp index 5160e6d4..5fa1d24f 100644 --- a/src/shared/Utilities/Util.cpp +++ b/src/shared/Utilities/Util.cpp @@ -26,14 +26,11 @@ #include "Timer.h" #include "utf8cpp/utf8.h" -#include +#include "RNGen.h" #include #include #include "Log/Log.h" -typedef ACE_TSS MTRandTSS; -static MTRandTSS *mtRand; - static ACE_Time_Value g_SystemTickTime = ACE_OS::gettimeofday(); uint32 WorldTimer::m_iTime = 0; @@ -75,54 +72,44 @@ uint32 WorldTimer::getMSTime_internal() } ////////////////////////////////////////////////////////////////////////// -void initMTRandTSS() -{ - mtRand = new ACE_TSS(); -} - -void deleteMTRandTSS() -{ - delete mtRand; -} - int32 irand(int32 min, int32 max) { - return int32((*mtRand)->randInt(max - min)) + min; + return RNG::instance()->rand_i(min,max); } uint32 urand(uint32 min, uint32 max) { - return (*mtRand)->randInt(max - min) + min; + return RNG::instance()->rand_u(min,max); } float frand(float min, float max) { - return (*mtRand)->randExc(max - min) + min; + return RNG::instance()->rand_f(min, max); } -int32 rand32() +uint32 rand32() { - return (*mtRand)->randInt(); + return RNG::instance()->rand(); } double rand_norm(void) { - return (*mtRand)->randExc(); + return RNG::instance()->rand_d(0.0, 1.0); } float rand_norm_f(void) { - return (float)(*mtRand)->randExc(); + return RNG::instance()->rand_f(0.0, 1.0); } double rand_chance(void) { - return (*mtRand)->randExc(100.0); + return RNG::instance()->rand_d(0.0, 100.0); } float rand_chance_f(void) { - return (float)(*mtRand)->randExc(100.0); + return RNG::instance()->rand_f(0.0, 100.0); } Tokens StrSplit(const std::string& src, const std::string& sep) diff --git a/src/shared/Utilities/Util.h b/src/shared/Utilities/Util.h index a8bd164c..7208aa8d 100644 --- a/src/shared/Utilities/Util.h +++ b/src/shared/Utilities/Util.h @@ -106,19 +106,6 @@ inline uint32 secsToTimeBitFields(time_t secs) return (lt->tm_year - 100) << 24 | lt->tm_mon << 20 | (lt->tm_mday - 1) << 14 | lt->tm_wday << 11 | lt->tm_hour << 6 | lt->tm_min; } -/** - * @brief Initializes the TSS for MersenneTwister - * - * - */ -void initMTRandTSS(); - -/** - * @brief Cleanups the TSS for MersenneTwister - * - * - */ -void deleteMTRandTSS(); /** * @brief Return a random number in the range min..max; (max-min) must be smaller than 32768. @@ -155,7 +142,7 @@ void deleteMTRandTSS(); * * @return int32 */ - int32 rand32(); +uint32 rand32(); /** * @brief Return a random double from 0.0 to 1.0 (exclusive).