From 65878dda81854c846b5ad0472d90eefde5c91bce Mon Sep 17 00:00:00 2001 From: Ted John Date: Sat, 16 Apr 2022 23:47:15 +0100 Subject: [PATCH 1/3] Warn or error if incompatible park version is loaded --- data/language/en-GB.txt | 4 ++++ src/openrct2/Context.cpp | 20 ++++++++++++++++++ src/openrct2/ParkImporter.h | 16 +++++++++++++++ src/openrct2/localisation/StringIds.h | 5 +++++ src/openrct2/park/ParkFile.cpp | 29 +++++++++++++++++++++++++-- 5 files changed, 72 insertions(+), 2 deletions(-) diff --git a/data/language/en-GB.txt b/data/language/en-GB.txt index c777e77de6..8138ee616a 100644 --- a/data/language/en-GB.txt +++ b/data/language/en-GB.txt @@ -3677,6 +3677,10 @@ STR_6485 :See-Through vehicles toggle STR_6486 :See-Through guests toggle STR_6487 :See-Through staff toggle STR_6488 :{RED}Guests are complaining about the length of the queues in your park.{NEWLINE}Consider shortening problematic queues, or increasing the rides’ throughput. +STR_6489 :Error: Incompatible Park Version +STR_6490 :This park was saved in a later version of OpenRCT2. Park is v{INT32} and requires at least v{INT32}. +STR_6491 :Warning: Semi-compatible Park Version +STR_6492 :This park was saved in a later version of OpenRCT2, some data may be lost. Park is v{INT32} and requires at least v{INT32}. ############# # Scenarios # diff --git a/src/openrct2/Context.cpp b/src/openrct2/Context.cpp index ea50eff39e..b5a2c34766 100644 --- a/src/openrct2/Context.cpp +++ b/src/openrct2/Context.cpp @@ -719,6 +719,14 @@ namespace OpenRCT2 start_silent_record(); } #endif + if (result.SemiCompatibleVersion) + { + auto windowManager = _uiContext->GetWindowManager(); + auto ft = Formatter(); + ft.Add(result.MinVersion); + ft.Add(result.TargetVersion); + windowManager->ShowError(STR_WARNING_PARK_VERSION_TITLE, STR_WARNING_PARK_VERSION_MESSAGE, ft); + } return true; } catch (const ObjectLoadException& e) @@ -760,6 +768,18 @@ namespace OpenRCT2 auto windowManager = _uiContext->GetWindowManager(); windowManager->ShowError(STR_FILE_CONTAINS_UNSUPPORTED_RIDE_TYPES, STR_NONE, {}); } + catch (const UnsupportedVersionException& e) + { + if (loadTitleScreenFirstOnFail) + { + title_load(); + } + auto windowManager = _uiContext->GetWindowManager(); + Formatter ft; + ft.Add(e.MinVersion); + ft.Add(e.TargetVersion); + windowManager->ShowError(STR_ERROR_PARK_VERSION_TITLE, STR_ERROR_PARK_VERSION_MESSAGE, ft); + } catch (const std::exception& e) { // If loading the SV6 or SV4 failed return to the title screen if requested. diff --git a/src/openrct2/ParkImporter.h b/src/openrct2/ParkImporter.h index af3caf9fb7..031a4cf55d 100644 --- a/src/openrct2/ParkImporter.h +++ b/src/openrct2/ParkImporter.h @@ -32,6 +32,9 @@ struct ParkLoadResult final { public: ObjectList RequiredObjects; + bool SemiCompatibleVersion{}; + uint32_t MinVersion{}; + uint32_t TargetVersion{}; explicit ParkLoadResult(ObjectList&& requiredObjects) : RequiredObjects(std::move(requiredObjects)) @@ -101,3 +104,16 @@ public: { } }; + +class UnsupportedVersionException : public std::exception +{ +public: + uint32_t const MinVersion; + uint32_t const TargetVersion; + + explicit UnsupportedVersionException(uint32_t minVersion, uint32_t targetVersion) + : MinVersion(minVersion) + , TargetVersion(targetVersion) + { + } +}; diff --git a/src/openrct2/localisation/StringIds.h b/src/openrct2/localisation/StringIds.h index 77af76400a..379ff843e9 100644 --- a/src/openrct2/localisation/StringIds.h +++ b/src/openrct2/localisation/StringIds.h @@ -3948,6 +3948,11 @@ enum : uint16_t STR_PEEPS_COMPLAINING_ABOUT_QUEUE_LENGTH_WARNING = 6488, + STR_ERROR_PARK_VERSION_TITLE = 6489, + STR_ERROR_PARK_VERSION_MESSAGE = 6490, + STR_WARNING_PARK_VERSION_TITLE = 6491, + STR_WARNING_PARK_VERSION_MESSAGE = 6492, + // Have to include resource strings (from scenarios and objects) for the time being now that language is partially working /* MAX_STR_COUNT = 32768 */ // MAX_STR_COUNT - upper limit for number of strings, not the current count strings }; diff --git a/src/openrct2/park/ParkFile.cpp b/src/openrct2/park/ParkFile.cpp index 89aa1526ba..539d9e49b6 100644 --- a/src/openrct2/park/ParkFile.cpp +++ b/src/openrct2/park/ParkFile.cpp @@ -106,7 +106,24 @@ namespace OpenRCT2 ObjectEntryIndex _pathToQueueSurfaceMap[MAX_PATH_OBJECTS]; ObjectEntryIndex _pathToRailingsMap[MAX_PATH_OBJECTS]; + void ThrowIfIncompatibleVersion() + { + const auto& header = _os->GetHeader(); + if (header.MinVersion > PARK_FILE_CURRENT_VERSION) + { + throw UnsupportedVersionException(header.MinVersion, header.TargetVersion); + } + } + public: + bool IsSemiCompatibleVersion(uint32_t& minVersion, uint32_t& targetVersion) + { + const auto& header = _os->GetHeader(); + minVersion = header.MinVersion; + targetVersion = header.TargetVersion; + return targetVersion > PARK_FILE_CURRENT_VERSION; + } + void Load(const std::string_view path) { FileStream fs(path, FILE_MODE_OPEN); @@ -116,6 +133,8 @@ namespace OpenRCT2 void Load(IStream& stream) { _os = std::make_unique(stream, OrcaStream::Mode::READING); + ThrowIfIncompatibleVersion(); + RequiredObjects = {}; ReadWriteObjectsChunk(*_os); ReadWritePackedObjectsChunk(*_os); @@ -2311,7 +2330,10 @@ public: { _parkFile = std::make_unique(); _parkFile->Load(path); - return ParkLoadResult(std::move(_parkFile->RequiredObjects)); + + auto result = ParkLoadResult(std::move(_parkFile->RequiredObjects)); + result.SemiCompatibleVersion = _parkFile->IsSemiCompatibleVersion(result.MinVersion, result.TargetVersion); + return result; } ParkLoadResult LoadSavedGame(const utf8* path, bool skipObjectCheck = false) override @@ -2329,7 +2351,10 @@ public: { _parkFile = std::make_unique(); _parkFile->Load(*stream); - return ParkLoadResult(std::move(_parkFile->RequiredObjects)); + + auto result = ParkLoadResult(std::move(_parkFile->RequiredObjects)); + result.SemiCompatibleVersion = _parkFile->IsSemiCompatibleVersion(result.MinVersion, result.TargetVersion); + return result; } void Import() override From 3c09e60273b6a1e6ed0e739de56f32cc94a44a7f Mon Sep 17 00:00:00 2001 From: Ted John Date: Sat, 23 Apr 2022 14:45:15 +0100 Subject: [PATCH 2/3] Add error if park version is too old --- data/language/en-GB.txt | 7 ++++--- src/openrct2/Context.cpp | 15 ++++++++++++--- src/openrct2/localisation/StringIds.h | 7 ++++--- src/openrct2/park/ParkFile.cpp | 2 +- src/openrct2/park/ParkFile.h | 3 +++ 5 files changed, 24 insertions(+), 10 deletions(-) diff --git a/data/language/en-GB.txt b/data/language/en-GB.txt index 8138ee616a..3d7c108fc3 100644 --- a/data/language/en-GB.txt +++ b/data/language/en-GB.txt @@ -3678,9 +3678,10 @@ STR_6486 :See-Through guests toggle STR_6487 :See-Through staff toggle STR_6488 :{RED}Guests are complaining about the length of the queues in your park.{NEWLINE}Consider shortening problematic queues, or increasing the rides’ throughput. STR_6489 :Error: Incompatible Park Version -STR_6490 :This park was saved in a later version of OpenRCT2. Park is v{INT32} and requires at least v{INT32}. -STR_6491 :Warning: Semi-compatible Park Version -STR_6492 :This park was saved in a later version of OpenRCT2, some data may be lost. Park is v{INT32} and requires at least v{INT32}. +STR_6490 :Warning: Semi-compatible Park Version +STR_6491 :This park was saved in a later version of OpenRCT2. Park is v{INT32} and requires at least v{INT32}. +STR_6492 :This park was saved in an old version of OpenRCT2, and can not be opened with this version of OpenRCT2. Park is v{INT32}. +STR_6493 :This park was saved in a later version of OpenRCT2, some data may be lost. Park is v{INT32} and requires at least v{INT32}. ############# # Scenarios # diff --git a/src/openrct2/Context.cpp b/src/openrct2/Context.cpp index b5a2c34766..73b11b6770 100644 --- a/src/openrct2/Context.cpp +++ b/src/openrct2/Context.cpp @@ -56,6 +56,7 @@ #include "object/ObjectManager.h" #include "object/ObjectRepository.h" #include "paint/Painter.h" +#include "park/ParkFile.h" #include "platform/Crash.h" #include "platform/Platform.h" #include "profiling/Profiling.h" @@ -776,9 +777,17 @@ namespace OpenRCT2 } auto windowManager = _uiContext->GetWindowManager(); Formatter ft; - ft.Add(e.MinVersion); - ft.Add(e.TargetVersion); - windowManager->ShowError(STR_ERROR_PARK_VERSION_TITLE, STR_ERROR_PARK_VERSION_MESSAGE, ft); + if (e.TargetVersion < PARK_FILE_MIN_SUPPORTED_VERSION) + { + ft.Add(e.TargetVersion); + windowManager->ShowError(STR_ERROR_PARK_VERSION_TITLE, STR_ERROR_PARK_VERSION_TOO_OLD_MESSAGE, ft); + } + else + { + ft.Add(e.MinVersion); + ft.Add(e.TargetVersion); + windowManager->ShowError(STR_ERROR_PARK_VERSION_TITLE, STR_ERROR_PARK_VERSION_TOO_NEW_MESSAGE, ft); + } } catch (const std::exception& e) { diff --git a/src/openrct2/localisation/StringIds.h b/src/openrct2/localisation/StringIds.h index 379ff843e9..a7254c3466 100644 --- a/src/openrct2/localisation/StringIds.h +++ b/src/openrct2/localisation/StringIds.h @@ -3949,9 +3949,10 @@ enum : uint16_t STR_PEEPS_COMPLAINING_ABOUT_QUEUE_LENGTH_WARNING = 6488, STR_ERROR_PARK_VERSION_TITLE = 6489, - STR_ERROR_PARK_VERSION_MESSAGE = 6490, - STR_WARNING_PARK_VERSION_TITLE = 6491, - STR_WARNING_PARK_VERSION_MESSAGE = 6492, + STR_WARNING_PARK_VERSION_TITLE = 6490, + STR_ERROR_PARK_VERSION_TOO_NEW_MESSAGE = 6491, + STR_ERROR_PARK_VERSION_TOO_OLD_MESSAGE = 6492, + STR_WARNING_PARK_VERSION_MESSAGE = 6493, // Have to include resource strings (from scenarios and objects) for the time being now that language is partially working /* MAX_STR_COUNT = 32768 */ // MAX_STR_COUNT - upper limit for number of strings, not the current count strings diff --git a/src/openrct2/park/ParkFile.cpp b/src/openrct2/park/ParkFile.cpp index 539d9e49b6..50bbb0cb18 100644 --- a/src/openrct2/park/ParkFile.cpp +++ b/src/openrct2/park/ParkFile.cpp @@ -109,7 +109,7 @@ namespace OpenRCT2 void ThrowIfIncompatibleVersion() { const auto& header = _os->GetHeader(); - if (header.MinVersion > PARK_FILE_CURRENT_VERSION) + if (header.TargetVersion < PARK_FILE_MIN_SUPPORTED_VERSION || header.MinVersion > PARK_FILE_CURRENT_VERSION) { throw UnsupportedVersionException(header.MinVersion, header.TargetVersion); } diff --git a/src/openrct2/park/ParkFile.h b/src/openrct2/park/ParkFile.h index f7a2bc7b62..cb5ae329e8 100644 --- a/src/openrct2/park/ParkFile.h +++ b/src/openrct2/park/ParkFile.h @@ -13,6 +13,9 @@ namespace OpenRCT2 // The minimum version that is forwards compatible with the current version. constexpr uint32_t PARK_FILE_MIN_VERSION = 0x9; + // The minimum version that is backwards compatible with the current version. + constexpr uint32_t PARK_FILE_MIN_SUPPORTED_VERSION = 0x1; + constexpr uint32_t PARK_FILE_MAGIC = 0x4B524150; // PARK struct IStream; From fe9b211894908204174283f1168aa657e16e6744 Mon Sep 17 00:00:00 2001 From: Gymnasiast Date: Sun, 24 Apr 2022 15:51:41 +0200 Subject: [PATCH 3/3] Allow park files v0 --- src/openrct2/Context.cpp | 4 ++-- src/openrct2/park/ParkFile.cpp | 2 +- src/openrct2/park/ParkFile.h | 3 ++- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/openrct2/Context.cpp b/src/openrct2/Context.cpp index 73b11b6770..33d89379c9 100644 --- a/src/openrct2/Context.cpp +++ b/src/openrct2/Context.cpp @@ -777,12 +777,12 @@ namespace OpenRCT2 } auto windowManager = _uiContext->GetWindowManager(); Formatter ft; - if (e.TargetVersion < PARK_FILE_MIN_SUPPORTED_VERSION) + /*if (e.TargetVersion < PARK_FILE_MIN_SUPPORTED_VERSION) { ft.Add(e.TargetVersion); windowManager->ShowError(STR_ERROR_PARK_VERSION_TITLE, STR_ERROR_PARK_VERSION_TOO_OLD_MESSAGE, ft); } - else + else*/ { ft.Add(e.MinVersion); ft.Add(e.TargetVersion); diff --git a/src/openrct2/park/ParkFile.cpp b/src/openrct2/park/ParkFile.cpp index 50bbb0cb18..2c20b50b57 100644 --- a/src/openrct2/park/ParkFile.cpp +++ b/src/openrct2/park/ParkFile.cpp @@ -109,7 +109,7 @@ namespace OpenRCT2 void ThrowIfIncompatibleVersion() { const auto& header = _os->GetHeader(); - if (header.TargetVersion < PARK_FILE_MIN_SUPPORTED_VERSION || header.MinVersion > PARK_FILE_CURRENT_VERSION) + if (/*header.TargetVersion < PARK_FILE_MIN_SUPPORTED_VERSION || */ header.MinVersion > PARK_FILE_CURRENT_VERSION) { throw UnsupportedVersionException(header.MinVersion, header.TargetVersion); } diff --git a/src/openrct2/park/ParkFile.h b/src/openrct2/park/ParkFile.h index cb5ae329e8..74b47fb2df 100644 --- a/src/openrct2/park/ParkFile.h +++ b/src/openrct2/park/ParkFile.h @@ -14,7 +14,8 @@ namespace OpenRCT2 constexpr uint32_t PARK_FILE_MIN_VERSION = 0x9; // The minimum version that is backwards compatible with the current version. - constexpr uint32_t PARK_FILE_MIN_SUPPORTED_VERSION = 0x1; + // If this is increased beyond 0, uncomment the checks in ParkFile.cpp and Context.cpp! + constexpr uint32_t PARK_FILE_MIN_SUPPORTED_VERSION = 0x0; constexpr uint32_t PARK_FILE_MAGIC = 0x4B524150; // PARK