mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-19 00:48:56 +01:00
Core/Game: Add a dynamic script reloader which reloads scripts modules on changes.
* is responsible for registering plain modules. * requires compilation with the `WITH_DYNAMIC_LINKING` flag. * requires further support of the ScriptMgr.
This commit is contained in:
@@ -263,12 +263,19 @@ void ScriptMgr::Initialize()
|
||||
|
||||
FillSpellSummary();
|
||||
|
||||
// Load core script systems
|
||||
// SmartAI
|
||||
BeginScriptContext("core scripts");
|
||||
AddSC_SmartScripts();
|
||||
FinishScriptContext();
|
||||
|
||||
// Load all static linked scripts through the script loader function.
|
||||
BeginScriptContext("static scripts");
|
||||
ASSERT(_script_loader_callback,
|
||||
"Script loader callback wasn't registered!");
|
||||
|
||||
_script_loader_callback();
|
||||
FinishScriptContext();
|
||||
|
||||
#ifdef SCRIPTS
|
||||
for (std::string const& scriptName : UnusedScriptNames)
|
||||
@@ -280,6 +287,21 @@ void ScriptMgr::Initialize()
|
||||
TC_LOG_INFO("server.loading", ">> Loaded %u C++ scripts in %u ms", GetScriptCount(), GetMSTimeDiffToNow(oldMSTime));
|
||||
}
|
||||
|
||||
void ScriptMgr::BeginScriptContext(std::string const& context)
|
||||
{
|
||||
_currentContext = context;
|
||||
}
|
||||
|
||||
void ScriptMgr::FinishScriptContext()
|
||||
{
|
||||
_currentContext.clear();
|
||||
}
|
||||
|
||||
void ScriptMgr::ReleaseScriptContext(std::string const& /*context*/)
|
||||
{
|
||||
// ToDo
|
||||
}
|
||||
|
||||
void ScriptMgr::Unload()
|
||||
{
|
||||
#define SCR_CLEAR(T) \
|
||||
|
||||
@@ -837,9 +837,6 @@ class TC_GAME_API GroupScript : public ScriptObject
|
||||
virtual void OnDisband(Group* /*group*/) { }
|
||||
};
|
||||
|
||||
// Placed here due to ScriptRegistry::AddScript dependency.
|
||||
#define sScriptMgr ScriptMgr::instance()
|
||||
|
||||
// namespace
|
||||
// {
|
||||
typedef std::list<std::string> UnusedScriptNamesContainer;
|
||||
@@ -855,12 +852,13 @@ class TC_GAME_API ScriptMgr
|
||||
ScriptMgr();
|
||||
virtual ~ScriptMgr();
|
||||
|
||||
void FillSpellSummary();
|
||||
void LoadDatabase();
|
||||
|
||||
public: /* Initialization */
|
||||
static ScriptMgr* instance();
|
||||
|
||||
void Initialize();
|
||||
void LoadDatabase();
|
||||
void FillSpellSummary();
|
||||
|
||||
const char* ScriptsVersion() const { return "Integrated Trinity Scripts"; }
|
||||
|
||||
@@ -876,6 +874,12 @@ class TC_GAME_API ScriptMgr
|
||||
_script_loader_callback = script_loader_callback;
|
||||
}
|
||||
|
||||
public: /* Script contexts */
|
||||
void BeginScriptContext(std::string const& context);
|
||||
void FinishScriptContext();
|
||||
|
||||
void ReleaseScriptContext(std::string const& context);
|
||||
|
||||
public: /* Unloading */
|
||||
|
||||
void Unload();
|
||||
@@ -1106,13 +1110,16 @@ class TC_GAME_API ScriptMgr
|
||||
bool IsScriptScheduled() const { return _scheduledScripts > 0; }
|
||||
|
||||
private:
|
||||
|
||||
uint32 _scriptCount;
|
||||
|
||||
//atomic op counter for active scripts amount
|
||||
std::atomic<uint32> _scheduledScripts;
|
||||
|
||||
ScriptLoaderCallbackType _script_loader_callback;
|
||||
|
||||
std::string _currentContext;
|
||||
};
|
||||
|
||||
#define sScriptMgr ScriptMgr::instance()
|
||||
|
||||
#endif
|
||||
|
||||
1449
src/server/game/Scripting/ScriptReloadMgr.cpp
Normal file
1449
src/server/game/Scripting/ScriptReloadMgr.cpp
Normal file
File diff suppressed because it is too large
Load Diff
82
src/server/game/Scripting/ScriptReloadMgr.h
Normal file
82
src/server/game/Scripting/ScriptReloadMgr.h
Normal file
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* 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 SCRIPT_RELOADER_H
|
||||
#define SCRIPT_RELOADER_H
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include "Define.h"
|
||||
#include <boost/filesystem/path.hpp>
|
||||
|
||||
/// Represents a strong reference to a dynamic library which
|
||||
/// provides C++ scripts. As long as one reference to the library exists
|
||||
/// the library is kept loaded in the server, which makes it possible to lazy
|
||||
/// unload several script types on demand (like SpellScripts), and to
|
||||
/// provide multiple versions of the same script to the script factories.
|
||||
///
|
||||
/// Acquire a new reference through using:
|
||||
/// `ScriptReloadMgr::AcquireModuleReferenceOfContext`
|
||||
class ModuleReference
|
||||
{
|
||||
public:
|
||||
virtual ~ModuleReference() { }
|
||||
|
||||
/// Returns the git revision hash of the referenced script module
|
||||
virtual char const* GetScriptModuleRevisionHash() const = 0;
|
||||
/// Returns the name of the referenced script module
|
||||
virtual char const* GetScriptModule() const = 0;
|
||||
/// Returns the path to the script module
|
||||
virtual boost::filesystem::path const& GetModulePath() const = 0;
|
||||
};
|
||||
|
||||
/// Provides the whole physical dynamic library unloading capability.
|
||||
/// Loads, Reloads and Unloads dynamic libraries on changes and
|
||||
/// informs the ScriptMgr about changes which were made.
|
||||
/// The ScriptReloadMgr is also responsible for watching the source directory
|
||||
/// and to invoke a build on changes.
|
||||
class TC_GAME_API ScriptReloadMgr
|
||||
{
|
||||
protected:
|
||||
ScriptReloadMgr() { }
|
||||
|
||||
public:
|
||||
virtual ~ScriptReloadMgr() { }
|
||||
|
||||
/// Initializes the ScriptReloadMgr
|
||||
virtual void Initialize() { }
|
||||
|
||||
/// Needs to be called periodically to check for updates on script modules.
|
||||
/// Expects to be invoked in a thread safe way which means it's required that
|
||||
/// the current thread is the only one which accesses the world data.
|
||||
virtual void Update() { }
|
||||
|
||||
/// Unloads the ScriptReloadMgr
|
||||
virtual void Unload() { }
|
||||
|
||||
/// Returns an owning reference to the current module of the given context
|
||||
static std::shared_ptr<ModuleReference> AcquireModuleReferenceOfContext(
|
||||
std::string const& context);
|
||||
|
||||
/// Returns the unique ScriptReloadMgr singleton instance
|
||||
static ScriptReloadMgr* instance();
|
||||
};
|
||||
|
||||
#define sScriptReloadMgr ScriptReloadMgr::instance()
|
||||
|
||||
#endif // SCRIPT_RELOADER_H
|
||||
|
||||
@@ -54,6 +54,7 @@
|
||||
#include "PoolMgr.h"
|
||||
#include "GitRevision.h"
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptReloadMgr.h"
|
||||
#include "SkillDiscovery.h"
|
||||
#include "SkillExtraItems.h"
|
||||
#include "SmartAI.h"
|
||||
@@ -1385,9 +1386,18 @@ void World::LoadConfigSettings(bool reload)
|
||||
m_bool_configs[CONFIG_CALCULATE_CREATURE_ZONE_AREA_DATA] = sConfigMgr->GetBoolDefault("Calculate.Creature.Zone.Area.Data", false);
|
||||
m_bool_configs[CONFIG_CALCULATE_GAMEOBJECT_ZONE_AREA_DATA] = sConfigMgr->GetBoolDefault("Calculate.Gameoject.Zone.Area.Data", false);
|
||||
|
||||
|
||||
// prevent character rename on character customization
|
||||
m_bool_configs[CONFIG_PREVENT_RENAME_CUSTOMIZATION] = sConfigMgr->GetBoolDefault("PreventRenameCharacterOnCustomization", false);
|
||||
|
||||
// HotSwap
|
||||
m_bool_configs[CONFIG_HOTSWAP_ENABLED] = sConfigMgr->GetBoolDefault("HotSwap.Enabled", true);
|
||||
m_bool_configs[CONFIG_HOTSWAP_RECOMPILER_ENABLED] = sConfigMgr->GetBoolDefault("HotSwap.EnableReCompiler", true);
|
||||
m_bool_configs[CONFIG_HOTSWAP_EARLY_TERMINATION_ENABLED] = sConfigMgr->GetBoolDefault("HotSwap.EnableEarlyTermination", true);
|
||||
m_bool_configs[CONFIG_HOTSWAP_BUILD_FILE_RECREATION_ENABLED] = sConfigMgr->GetBoolDefault("HotSwap.EnableBuildFileRecreation", true);
|
||||
m_bool_configs[CONFIG_HOTSWAP_INSTALL_ENABLED] = sConfigMgr->GetBoolDefault("HotSwap.EnableInstall", true);
|
||||
m_bool_configs[CONFIG_HOTSWAP_PREFIX_CORRECTION_ENABLED] = sConfigMgr->GetBoolDefault("HotSwap.EnablePrefixCorrection", true);
|
||||
|
||||
// call ScriptMgr if we're reloading the configuration
|
||||
if (reload)
|
||||
sScriptMgr->OnConfigLoad(reload);
|
||||
@@ -1891,6 +1901,7 @@ void World::SetInitialWorldSettings()
|
||||
TC_LOG_INFO("server.loading", "Initializing Scripts...");
|
||||
sScriptMgr->Initialize();
|
||||
sScriptMgr->OnConfigLoad(false); // must be done after the ScriptMgr has been properly initialized
|
||||
sScriptReloadMgr->Initialize();
|
||||
|
||||
TC_LOG_INFO("server.loading", "Validating spell scripts...");
|
||||
sObjectMgr->ValidateSpellScripts();
|
||||
@@ -1926,6 +1937,8 @@ void World::SetInitialWorldSettings()
|
||||
|
||||
m_timers[WUPDATE_PINGDB].SetInterval(getIntConfig(CONFIG_DB_PING_INTERVAL)*MINUTE*IN_MILLISECONDS); // Mysql ping time in minutes
|
||||
|
||||
m_timers[WUPDATE_CHECK_FILECHANGES].SetInterval(500);
|
||||
|
||||
m_timers[WUPDATE_GUILDSAVE].SetInterval(getIntConfig(CONFIG_GUILD_SAVE_INTERVAL) * MINUTE * IN_MILLISECONDS);
|
||||
|
||||
//to set mailtimer to return mails every day between 4 and 5 am
|
||||
@@ -2182,6 +2195,13 @@ void World::Update(uint32 diff)
|
||||
m_timers[WUPDATE_AHBOT].Reset();
|
||||
}
|
||||
|
||||
/// <li> Handle file changes
|
||||
if (m_timers[WUPDATE_CHECK_FILECHANGES].Passed())
|
||||
{
|
||||
sScriptReloadMgr->Update();
|
||||
m_timers[WUPDATE_CHECK_FILECHANGES].Reset();
|
||||
}
|
||||
|
||||
/// <li> Handle session updates when the timer has passed
|
||||
ResetTimeDiffRecord();
|
||||
UpdateSessions(diff);
|
||||
|
||||
@@ -91,6 +91,7 @@ enum WorldTimers
|
||||
WUPDATE_AHBOT,
|
||||
WUPDATE_PINGDB,
|
||||
WUPDATE_GUILDSAVE,
|
||||
WUPDATE_CHECK_FILECHANGES,
|
||||
WUPDATE_COUNT
|
||||
};
|
||||
|
||||
@@ -178,6 +179,12 @@ enum WorldBoolConfigs
|
||||
CONFIG_BASEMAP_LOAD_GRIDS,
|
||||
CONFIG_INSTANCEMAP_LOAD_GRIDS,
|
||||
CONFIG_PREVENT_RENAME_CUSTOMIZATION,
|
||||
CONFIG_HOTSWAP_ENABLED,
|
||||
CONFIG_HOTSWAP_RECOMPILER_ENABLED,
|
||||
CONFIG_HOTSWAP_EARLY_TERMINATION_ENABLED,
|
||||
CONFIG_HOTSWAP_BUILD_FILE_RECREATION_ENABLED,
|
||||
CONFIG_HOTSWAP_INSTALL_ENABLED,
|
||||
CONFIG_HOTSWAP_PREFIX_CORRECTION_ENABLED,
|
||||
BOOL_CONFIG_VALUE_COUNT
|
||||
};
|
||||
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
#include "InstanceSaveMgr.h"
|
||||
#include "ObjectAccessor.h"
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptReloadMgr.h"
|
||||
#include "ScriptLoader.h"
|
||||
#include "OutdoorPvP/OutdoorPvPMgr.h"
|
||||
#include "BattlegroundMgr.h"
|
||||
@@ -280,6 +281,7 @@ extern int main(int argc, char** argv)
|
||||
sOutdoorPvPMgr->Die();
|
||||
sMapMgr->UnloadAll(); // unload all grids (including locked in memory)
|
||||
sScriptMgr->Unload();
|
||||
sScriptReloadMgr->Unload();
|
||||
|
||||
// set server offline
|
||||
LoginDatabase.DirectPExecute("UPDATE realmlist SET flag = flag | %u WHERE id = '%d'", REALM_FLAG_OFFLINE, realm.Id.Realm);
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
# SERVER LOGGING
|
||||
# SERVER SETTINGS
|
||||
# UPDATE SETTINGS
|
||||
# HOTSWAP SETTINGS
|
||||
# WARDEN SETTINGS
|
||||
# PLAYER INTERACTION
|
||||
# CREATURE SETTINGS
|
||||
@@ -1261,6 +1262,78 @@ Updates.CleanDeadRefMaxCount = 3
|
||||
#
|
||||
###################################################################################################
|
||||
|
||||
###################################################################################################
|
||||
# HOTSWAP SETTINGS
|
||||
#
|
||||
# HotSwap.Enabled (Requires compilation with DYNAMIC_LINKING=1)
|
||||
# Description: Enables dynamic script hotswapping.
|
||||
# Reloads scripts on changes.
|
||||
# Default: 1 - (Enabled)
|
||||
# 0 - (Disabled)
|
||||
|
||||
HotSwap.Enabled = 1
|
||||
|
||||
#
|
||||
# HotSwap.ScriptDir
|
||||
# Description: Directory containing the script shared libraries (.dll/.so).
|
||||
# Example: "/usr/local/scripts"
|
||||
# Default: "scripts"
|
||||
|
||||
HotSwap.ScriptDir = "scripts"
|
||||
|
||||
# HotSwap.EnableReCompiler
|
||||
# Description: Enables the dynamic script recompiler.
|
||||
# Watches your script source directories and recompiles the
|
||||
# script modules on changes.
|
||||
# Default: 0 - (Disabled)
|
||||
# 1 - (Enabled)
|
||||
|
||||
HotSwap.EnableReCompiler = 1
|
||||
|
||||
# HotSwap.EnableEarlyTermination
|
||||
# Description: Terminate the build of a module when an associated
|
||||
# source file was changed meanwhile.
|
||||
# Default: 1 - (Enabled)
|
||||
# 0 - (Disabled)
|
||||
|
||||
HotSwap.EnableEarlyTermination = 1
|
||||
|
||||
# HotSwap.EnableBuildFileRecreation
|
||||
# Description: Recreate build files when sources to a module
|
||||
# were added or removed.
|
||||
# Default: 1 - (Enabled)
|
||||
# 0 - (Disabled)
|
||||
|
||||
HotSwap.EnableBuildFileRecreation = 1
|
||||
|
||||
#
|
||||
# HotSwap.EnableInstall
|
||||
# Description: Enables cmake install after automatic builds have finished
|
||||
# Default: 1 - (Enabled)
|
||||
# 0 - (Disabled)
|
||||
|
||||
HotSwap.EnableInstall = 1
|
||||
|
||||
#
|
||||
# HotSwap.EnablePrefixCorrection
|
||||
# Description: Allows the core to automatic set the CMAKE_INSTALL_PREFIX
|
||||
# to it's current location in the filesystem.
|
||||
# Default: 1 - (Enabled)
|
||||
# 0 - (Disabled)
|
||||
|
||||
HotSwap.EnablePrefixCorrection = 1
|
||||
|
||||
# HotSwap.ReCompilerBuildType
|
||||
# Description: Defines the build type of the builds invoked by the recompiler.
|
||||
# Default: "" - Built-in build type of the module is used.
|
||||
# "Release" - Release builds only
|
||||
# "Debug" - Debug builds only
|
||||
|
||||
HotSwap.ReCompilerBuildType = ""
|
||||
|
||||
#
|
||||
###################################################################################################
|
||||
|
||||
###################################################################################################
|
||||
# WARDEN SETTINGS
|
||||
#
|
||||
@@ -3622,6 +3695,7 @@ Logger.sql.updates=3,Console Server
|
||||
#Logger.rbac=3,Console Server
|
||||
#Logger.scripts=3,Console Server
|
||||
#Logger.scripts.ai=3,Console Server
|
||||
#Logger.scripts.hotswap=3,Console Server
|
||||
#Logger.server.authserver=3,Console Server
|
||||
#Logger.spells=3,Console Server
|
||||
#Logger.spells.periodic=3,Console Server
|
||||
|
||||
Reference in New Issue
Block a user