From 21ead2aa4b6c116ab8e967119467bd62fb34d158 Mon Sep 17 00:00:00 2001 From: Kelsi Date: Fri, 20 Mar 2026 16:17:04 -0700 Subject: [PATCH] feat: add /reload command to re-initialize addon system Add AddonManager::reload() which saves all SavedVariables, shuts down the Lua VM, re-initializes it, rescans .toc files, and reloads all addons. Wire /reload, /reloadui, /rl slash commands that call reload() and fire VARIABLES_LOADED + PLAYER_LOGIN + PLAYER_ENTERING_WORLD lifecycle events. Essential for addon development and troubleshooting. --- include/addons/addon_manager.hpp | 5 +++++ src/addons/addon_manager.cpp | 22 ++++++++++++++++++++++ src/ui/game_screen.cpp | 24 ++++++++++++++++++++++++ 3 files changed, 51 insertions(+) diff --git a/include/addons/addon_manager.hpp b/include/addons/addon_manager.hpp index be4a6a89..681d3822 100644 --- a/include/addons/addon_manager.hpp +++ b/include/addons/addon_manager.hpp @@ -27,9 +27,14 @@ public: void saveAllSavedVariables(); + /// Re-initialize the Lua VM and reload all addons (used by /reload). + bool reload(); + private: LuaEngine luaEngine_; std::vector addons_; + game::GameHandler* gameHandler_ = nullptr; + std::string addonsPath_; bool loadAddon(const TocFile& addon); std::string getSavedVariablesPath(const TocFile& addon) const; diff --git a/src/addons/addon_manager.cpp b/src/addons/addon_manager.cpp index 60593792..e826097f 100644 --- a/src/addons/addon_manager.cpp +++ b/src/addons/addon_manager.cpp @@ -11,12 +11,14 @@ AddonManager::AddonManager() = default; AddonManager::~AddonManager() { shutdown(); } bool AddonManager::initialize(game::GameHandler* gameHandler) { + gameHandler_ = gameHandler; if (!luaEngine_.initialize()) return false; luaEngine_.setGameHandler(gameHandler); return true; } void AddonManager::scanAddons(const std::string& addonsPath) { + addonsPath_ = addonsPath; addons_.clear(); std::error_code ec; @@ -121,6 +123,26 @@ void AddonManager::saveAllSavedVariables() { } } +bool AddonManager::reload() { + LOG_INFO("AddonManager: reloading all addons..."); + saveAllSavedVariables(); + addons_.clear(); + luaEngine_.shutdown(); + + if (!luaEngine_.initialize()) { + LOG_ERROR("AddonManager: failed to reinitialize Lua VM during reload"); + return false; + } + luaEngine_.setGameHandler(gameHandler_); + + if (!addonsPath_.empty()) { + scanAddons(addonsPath_); + loadAllAddons(); + } + LOG_INFO("AddonManager: reload complete"); + return true; +} + void AddonManager::shutdown() { saveAllSavedVariables(); addons_.clear(); diff --git a/src/ui/game_screen.cpp b/src/ui/game_screen.cpp index 19f50309..edad0a48 100644 --- a/src/ui/game_screen.cpp +++ b/src/ui/game_screen.cpp @@ -6035,6 +6035,30 @@ void GameScreen::sendChatMessage(game::GameHandler& gameHandler) { return; } + // /reload or /reloadui — reload all addons (save variables, re-init Lua, re-scan .toc files) + if (cmdLower == "reload" || cmdLower == "reloadui" || cmdLower == "rl") { + auto* am = core::Application::getInstance().getAddonManager(); + if (am) { + am->reload(); + am->fireEvent("VARIABLES_LOADED"); + am->fireEvent("PLAYER_LOGIN"); + am->fireEvent("PLAYER_ENTERING_WORLD"); + game::MessageChatData rlMsg; + rlMsg.type = game::ChatType::SYSTEM; + rlMsg.language = game::ChatLanguage::UNIVERSAL; + rlMsg.message = "Interface reloaded."; + gameHandler.addLocalChatMessage(rlMsg); + } else { + game::MessageChatData rlMsg; + rlMsg.type = game::ChatType::SYSTEM; + rlMsg.language = game::ChatLanguage::UNIVERSAL; + rlMsg.message = "Addon system not available."; + gameHandler.addLocalChatMessage(rlMsg); + } + chatInputBuffer[0] = '\0'; + return; + } + // /stopmacro [conditions] // Halts execution of the current macro (remaining lines are skipped). // With a condition block, only stops if the conditions evaluate to true.