From 23aacbd9147a8de57823f4974a36385dddf90a80 Mon Sep 17 00:00:00 2001 From: Evil Eye Date: Thu, 30 Nov 2023 19:20:38 +0100 Subject: [PATCH] Introduce a minimum supported save game format --- CHANGELOG.md | 1 + apps/openmw/mwstate/statemanagerimp.cpp | 29 +++++++++++++++++-------- components/esm3/formatversion.hpp | 4 ++++ files/data/l10n/OMWEngine/de.yaml | 3 +++ files/data/l10n/OMWEngine/en.yaml | 3 +++ files/data/l10n/OMWEngine/fr.yaml | 3 +++ files/data/l10n/OMWEngine/ru.yaml | 3 +++ files/data/l10n/OMWEngine/sv.yaml | 3 +++ 8 files changed, 40 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 30ad2bae6c..eb61affa40 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -106,6 +106,7 @@ Feature #6447: Add LOD support to Object Paging Feature #6491: Add support for Qt6 Feature #6556: Lua API for sounds + Feature #6624: Drop support for old saves Feature #6726: Lua API for creating new objects Feature #6864: Lua file access API Feature #6922: Improve launcher appearance diff --git a/apps/openmw/mwstate/statemanagerimp.cpp b/apps/openmw/mwstate/statemanagerimp.cpp index 826c0dbba6..c040dca8dd 100644 --- a/apps/openmw/mwstate/statemanagerimp.cpp +++ b/apps/openmw/mwstate/statemanagerimp.cpp @@ -411,10 +411,25 @@ void MWState::StateManager::loadGame(const Character* character, const std::file ESM::ESMReader reader; reader.open(filepath); - if (reader.getFormatVersion() > ESM::CurrentSaveGameFormatVersion) - throw VersionMismatchError( - "This save file was created using a newer version of OpenMW and is thus not supported. Please upgrade " - "to the newest OpenMW version to load this file."); + ESM::FormatVersion version = reader.getFormatVersion(); + if (version > ESM::CurrentSaveGameFormatVersion) + throw VersionMismatchError("#{OMWEngine:LoadingRequiresNewVersionError}"); + else if (version < ESM::MinSupportedSaveGameFormatVersion) + { + const char* release; + // Report the last version still capable of reading this save + if (version <= ESM::OpenMW0_48SaveGameFormatVersion) + release = "OpenMW 0.48.0"; + else + { + // Insert additional else if statements above to cover future releases + static_assert(ESM::MinSupportedSaveGameFormatVersion <= ESM::OpenMW0_49SaveGameFormatVersion); + release = "OpenMW 0.49.0"; + } + auto l10n = MWBase::Environment::get().getL10nManager()->getContext("OMWEngine"); + std::string message = l10n->formatMessage("LoadingRequiresOldVersionError", { "version" }, { release }); + throw VersionMismatchError(message); + } std::map contentFileMap = buildContentFileIndexMap(reader); reader.setContentFileMapping(&contentFileMap); @@ -607,11 +622,7 @@ void MWState::StateManager::loadGame(const Character* character, const std::file std::vector buttons; buttons.emplace_back("#{Interface:OK}"); - std::string error; - if (typeid(e) == typeid(VersionMismatchError)) - error = "#{OMWEngine:LoadingFailed}: #{OMWEngine:LoadingRequiresNewVersionError}"; - else - error = "#{OMWEngine:LoadingFailed}: " + std::string(e.what()); + std::string error = "#{OMWEngine:LoadingFailed}: " + std::string(e.what()); MWBase::Environment::get().getWindowManager()->interactiveMessageBox(error, buttons); } diff --git a/components/esm3/formatversion.hpp b/components/esm3/formatversion.hpp index 12a73fc12b..1b4bee0bc5 100644 --- a/components/esm3/formatversion.hpp +++ b/components/esm3/formatversion.hpp @@ -26,6 +26,10 @@ namespace ESM inline constexpr FormatVersion MaxUseEsmCellIdFormatVersion = 26; inline constexpr FormatVersion MaxActiveSpellSlotIndexFormatVersion = 27; inline constexpr FormatVersion CurrentSaveGameFormatVersion = 29; + + inline constexpr FormatVersion MinSupportedSaveGameFormatVersion = 0; + inline constexpr FormatVersion OpenMW0_48SaveGameFormatVersion = 21; + inline constexpr FormatVersion OpenMW0_49SaveGameFormatVersion = CurrentSaveGameFormatVersion; } #endif diff --git a/files/data/l10n/OMWEngine/de.yaml b/files/data/l10n/OMWEngine/de.yaml index 26838bd93c..0f729d0077 100644 --- a/files/data/l10n/OMWEngine/de.yaml +++ b/files/data/l10n/OMWEngine/de.yaml @@ -25,6 +25,9 @@ BuildingNavigationMesh: "Baue Navigationsgitter" #LoadingRequiresNewVersionError: |- # This save file was created using a newer version of OpenMW and is thus not supported. # Please upgrade to the newest OpenMW version to load this file. +# LoadingRequiresOldVersionError: |- +# This save file was created using an older version of OpenMW in a format that is no longer supported. +# Load and save this file using {version} to upgrade it. #NewGameConfirmation: "Do you want to start a new game and lose the current one?" #SaveGameDenied: "The game cannot be saved right now." #SavingInProgress: "Saving..." diff --git a/files/data/l10n/OMWEngine/en.yaml b/files/data/l10n/OMWEngine/en.yaml index ee2a33ee71..09db2b496d 100644 --- a/files/data/l10n/OMWEngine/en.yaml +++ b/files/data/l10n/OMWEngine/en.yaml @@ -22,6 +22,9 @@ LoadingInProgress: "Loading Save Game" LoadingRequiresNewVersionError: |- This save file was created using a newer version of OpenMW and is thus not supported. Please upgrade to the newest OpenMW version to load this file. +LoadingRequiresOldVersionError: |- + This save file was created using an older version of OpenMW in a format that is no longer supported. + Load and save this file using {version} to upgrade it. NewGameConfirmation: "Do you want to start a new game and lose the current one?" SaveGameDenied: "The game cannot be saved right now." SavingInProgress: "Saving..." diff --git a/files/data/l10n/OMWEngine/fr.yaml b/files/data/l10n/OMWEngine/fr.yaml index 689ccc59a5..f2772b017e 100644 --- a/files/data/l10n/OMWEngine/fr.yaml +++ b/files/data/l10n/OMWEngine/fr.yaml @@ -22,6 +22,9 @@ LoadingInProgress: "Chargement de la sauvegarde" LoadingRequiresNewVersionError: |- Ce fichier de sauvegarde provient d'une version plus récente d'OpenMW, il n'est par consequent pas supporté. Mettez à jour votre version d'OpenMW afin de pouvoir charger cette sauvegarde. +# LoadingRequiresOldVersionError: |- +# This save file was created using an older version of OpenMW in a format that is no longer supported. +# Load and save this file using {version} to upgrade it. NewGameConfirmation: "Voulez-vous démarrer une nouvelle partie ? Toute progression non sauvegardée sera perdue." SaveGameDenied: "Sauvegarde impossible" SavingInProgress: "Sauvegarde en cours..." diff --git a/files/data/l10n/OMWEngine/ru.yaml b/files/data/l10n/OMWEngine/ru.yaml index b645b681b1..cecd6fc37c 100644 --- a/files/data/l10n/OMWEngine/ru.yaml +++ b/files/data/l10n/OMWEngine/ru.yaml @@ -22,6 +22,9 @@ LoadingInProgress: "Загрузка сохранения" LoadingRequiresNewVersionError: |- Это сохранение создано более новой версией OpenMW и поэтому не может быть загружено. Обновите OpenMW до последней версии, чтобы загрузить этот файл. +# LoadingRequiresOldVersionError: |- +# This save file was created using an older version of OpenMW in a format that is no longer supported. +# Load and save this file using {version} to upgrade it. NewGameConfirmation: "Вы хотите начать новую игру? Текущая игра будет потеряна." SaveGameDenied: "В данный момент игру нельзя сохранить." SavingInProgress: "Сохранение..." diff --git a/files/data/l10n/OMWEngine/sv.yaml b/files/data/l10n/OMWEngine/sv.yaml index f4c9db031a..dc65726fdd 100644 --- a/files/data/l10n/OMWEngine/sv.yaml +++ b/files/data/l10n/OMWEngine/sv.yaml @@ -22,6 +22,9 @@ LoadingInProgress: "Laddar sparat spel" LoadingRequiresNewVersionError: |- Denna sparfil skapades i en nyare version av OpenMW och stöds därför inte. Uppgradera till den senaste versionen av OpenMW för att ladda filen. +# LoadingRequiresOldVersionError: |- +# This save file was created using an older version of OpenMW in a format that is no longer supported. +# Load and save this file using {version} to upgrade it. NewGameConfirmation: "Vill du starta ett nytt spel och förlora det pågående spelet?" SaveGameDenied: "Spelet kan inte sparas just nu." SavingInProgress: "Sparar..."