Merge pull request #17001 from IntelOrca/add-park-warnings

Warn or error if incompatible park version is loaded
This commit is contained in:
Michael Steenbeek 2022-04-25 18:21:24 +02:00 committed by GitHub
commit 87fe699b37
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 87 additions and 2 deletions

View File

@ -3677,6 +3677,11 @@ 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 :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 #

View File

@ -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"
@ -719,6 +720,14 @@ namespace OpenRCT2
start_silent_record();
}
#endif
if (result.SemiCompatibleVersion)
{
auto windowManager = _uiContext->GetWindowManager();
auto ft = Formatter();
ft.Add<uint32_t>(result.MinVersion);
ft.Add<uint32_t>(result.TargetVersion);
windowManager->ShowError(STR_WARNING_PARK_VERSION_TITLE, STR_WARNING_PARK_VERSION_MESSAGE, ft);
}
return true;
}
catch (const ObjectLoadException& e)
@ -760,6 +769,26 @@ 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;
/*if (e.TargetVersion < PARK_FILE_MIN_SUPPORTED_VERSION)
{
ft.Add<uint32_t>(e.TargetVersion);
windowManager->ShowError(STR_ERROR_PARK_VERSION_TITLE, STR_ERROR_PARK_VERSION_TOO_OLD_MESSAGE, ft);
}
else*/
{
ft.Add<uint32_t>(e.MinVersion);
ft.Add<uint32_t>(e.TargetVersion);
windowManager->ShowError(STR_ERROR_PARK_VERSION_TITLE, STR_ERROR_PARK_VERSION_TOO_NEW_MESSAGE, ft);
}
}
catch (const std::exception& e)
{
// If loading the SV6 or SV4 failed return to the title screen if requested.

View File

@ -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)
{
}
};

View File

@ -3948,6 +3948,12 @@ enum : uint16_t
STR_PEEPS_COMPLAINING_ABOUT_QUEUE_LENGTH_WARNING = 6488,
STR_ERROR_PARK_VERSION_TITLE = 6489,
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
};

View File

@ -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.TargetVersion < PARK_FILE_MIN_SUPPORTED_VERSION || */ 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<OrcaStream>(stream, OrcaStream::Mode::READING);
ThrowIfIncompatibleVersion();
RequiredObjects = {};
ReadWriteObjectsChunk(*_os);
ReadWritePackedObjectsChunk(*_os);
@ -2311,7 +2330,10 @@ public:
{
_parkFile = std::make_unique<OpenRCT2::ParkFile>();
_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<OpenRCT2::ParkFile>();
_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

View File

@ -13,6 +13,10 @@ 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.
// 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
struct IStream;