diff --git a/config.lua.dist b/config.lua.dist index 3ba98113b19..6662140ecde 100644 --- a/config.lua.dist +++ b/config.lua.dist @@ -277,9 +277,11 @@ maxAllowedOnADummy = 1 -- Save interval per time -- NOTE: toggleSaveInterval: true = enable the save interval, false = disable the save interval +-- NOTE: toggleSaveAsync = true, will enable save async (experimental), not recommended for use in production -- NOTE: saveIntervalType: "minute", "second" or "hour" -- NOTE: toggleSaveIntervalCleanMap: true = enable the clean map, false = disable the clean map -- NOTE: saveIntervalTime: time based on what was set in "saveIntervalType" +toggleSaveAsync = false toggleSaveInterval = true saveIntervalType = "hour" toggleSaveIntervalCleanMap = true diff --git a/data-canary/scripts/globalevents/save_interval.lua b/data-canary/scripts/globalevents/save_interval.lua deleted file mode 100644 index 3e1c16326e4..00000000000 --- a/data-canary/scripts/globalevents/save_interval.lua +++ /dev/null @@ -1,40 +0,0 @@ -local function serverSave(interval) - if configManager.getBoolean(configKeys.TOGGLE_SAVE_INTERVAL_CLEAN_MAP) then - cleanMap() - end - - saveServer() - local message = "Server save complete. Next save in %d %ss!" - local messageSingle = "Server save complete. Next save in %d %s!" - Webhook.sendMessage("Server save", message, WEBHOOK_COLOR_WARNING) - if SAVE_INTERVAL_CONFIG_TIME > 1 then - Game.broadcastMessage(string.format(message, SAVE_INTERVAL_CONFIG_TIME, SAVE_INTERVAL_TYPE), MESSAGE_GAME_HIGHLIGHT) - logger.info(string.format(message, SAVE_INTERVAL_CONFIG_TIME, SAVE_INTERVAL_TYPE)) - else - Game.broadcastMessage(string.format(messageSingle, SAVE_INTERVAL_CONFIG_TIME, SAVE_INTERVAL_TYPE), MESSAGE_GAME_HIGHLIGHT) - logger.info(string.format(messageSingle, SAVE_INTERVAL_CONFIG_TIME, SAVE_INTERVAL_TYPE)) - end -end - -local save = GlobalEvent("save") - -function save.onTime(interval) - local remainingTime = 60 * 1000 - if configManager.getBoolean(configKeys.TOGGLE_SAVE_INTERVAL) then - local message = "The server will save all accounts within " .. (remainingTime / 1000) .. " seconds. \z - You might lag or freeze for 5 seconds, please find a safe place." - Game.broadcastMessage(message, MESSAGE_GAME_HIGHLIGHT) - logger.info(string.format(message, SAVE_INTERVAL_CONFIG_TIME, SAVE_INTERVAL_TYPE)) - addEvent(serverSave, remainingTime, interval) - return true - end - return not configManager.getBoolean(configKeys.TOGGLE_SAVE_INTERVAL) -end - -if SAVE_INTERVAL_TIME ~= 0 then - save:interval(SAVE_INTERVAL_CONFIG_TIME * SAVE_INTERVAL_TIME) -else - return logger.error("[save.onTime] - Save interval type '{}' is not valid, use 'second', 'minute' or 'hour'", SAVE_INTERVAL_TYPE) -end - -save:register() diff --git a/data-otservbr-global/scripts/globalevents/customs/save_interval.lua b/data/scripts/globalevents/save_interval.lua similarity index 100% rename from data-otservbr-global/scripts/globalevents/customs/save_interval.lua rename to data/scripts/globalevents/save_interval.lua diff --git a/src/config/config_enums.hpp b/src/config/config_enums.hpp index 8c21bdfe1ac..7b51bd0d778 100644 --- a/src/config/config_enums.hpp +++ b/src/config/config_enums.hpp @@ -284,6 +284,7 @@ enum ConfigKey_t : uint16_t { TOGGLE_MAP_CUSTOM, TOGGLE_MOUNT_IN_PZ, TOGGLE_RECEIVE_REWARD, + TOGGLE_SAVE_ASYNC, TOGGLE_SAVE_INTERVAL_CLEAN_MAP, TOGGLE_SAVE_INTERVAL, TOGGLE_SERVER_IS_RETRO, diff --git a/src/config/configmanager.cpp b/src/config/configmanager.cpp index 96c48ae2f69..4b626b9aa63 100644 --- a/src/config/configmanager.cpp +++ b/src/config/configmanager.cpp @@ -149,6 +149,7 @@ bool ConfigManager::load() { loadBoolConfig(L, TOGGLE_IMBUEMENT_SHRINE_STORAGE, "toggleImbuementShrineStorage", true); loadBoolConfig(L, TOGGLE_MOUNT_IN_PZ, "toggleMountInProtectionZone", false); loadBoolConfig(L, TOGGLE_RECEIVE_REWARD, "toggleReceiveReward", false); + loadBoolConfig(L, TOGGLE_SAVE_ASYNC, "toggleSaveAsync", false); loadBoolConfig(L, TOGGLE_SAVE_INTERVAL_CLEAN_MAP, "toggleSaveIntervalCleanMap", false); loadBoolConfig(L, TOGGLE_SAVE_INTERVAL, "toggleSaveInterval", false); loadBoolConfig(L, TOGGLE_SERVER_IS_RETRO, "toggleServerIsRetroPVP", false); diff --git a/src/game/scheduling/save_manager.cpp b/src/game/scheduling/save_manager.cpp index dfbcd04a0c6..6e8b76050ad 100644 --- a/src/game/scheduling/save_manager.cpp +++ b/src/game/scheduling/save_manager.cpp @@ -35,6 +35,12 @@ void SaveManager::scheduleAll() { auto scheduledAt = std::chrono::steady_clock::now(); m_scheduledAt = scheduledAt; + // Disable save async if the config is set to false + if (!g_configManager().getBoolean(TOGGLE_SAVE_ASYNC, __FUNCTION__)) { + saveAll(); + return; + } + threadPool.addLoad([this, scheduledAt]() { if (m_scheduledAt.load() != scheduledAt) { logger.warn("Skipping save for server because another save has been scheduled."); @@ -50,6 +56,14 @@ void SaveManager::schedulePlayer(std::weak_ptr playerPtr) { logger.debug("Skipping save for player because player is no longer online."); return; } + + // Disable save async if the config is set to false + if (!g_configManager().getBoolean(TOGGLE_SAVE_ASYNC, __FUNCTION__)) { + logger.debug("Saving player {}.", playerToSave->getName()); + doSavePlayer(playerToSave); + return; + } + logger.debug("Scheduling player {} for saving.", playerToSave->getName()); auto scheduledAt = std::chrono::steady_clock::now(); m_playerMap[playerToSave->getGUID()] = scheduledAt;