diff --git a/.github/build.sh b/.github/build.sh index 452034477..405e2577e 100755 --- a/.github/build.sh +++ b/.github/build.sh @@ -87,18 +87,6 @@ function inplace_sed() { fi } -function subst_version() { - local path=$1 - if [[ $BSH_HOST_PLATFORM == darwin ]]; then - inplace_sed "s|SUBST_MACOS_MIN_VER|$macos_min_ver|g" $path - else - inplace_sed "s|SUBST_DATE|$(date --iso-8601)|g" $path - fi - inplace_sed "s|SUBST_SAVE_VERSION|$save_version|g" $path - inplace_sed "s|SUBST_MINOR_VERSION|$minor_version|g" $path - inplace_sed "s|SUBST_BUILD_NUM|$build_num|g" $path -} - if [[ $BSH_HOST_PLATFORM == android ]]; then android_platform=android-30 if [[ -z "${JAVA_HOME_8_X64-}" ]]; then @@ -189,6 +177,11 @@ meson_configure=meson$'\t'setup if [[ $BSH_DEBUG_RELEASE == release ]]; then meson_configure+=$'\t'-Dbuildtype=debugoptimized fi +if [[ $BSH_HOST_PLATFORM == darwin ]]; then + meson_configure+=$'\t'-Dmanifest_macos_min_ver=$macos_min_ver +else + meson_configure+=$'\t'-Dmanifest_date=$(date --iso-8601) +fi meson_configure+=$'\t'-Dapp_name=$APP_NAME meson_configure+=$'\t'-Dapp_comment=$APP_COMMENT meson_configure+=$'\t'-Dapp_exe=$APP_EXE @@ -251,19 +244,10 @@ fi if [[ $RELEASE_TYPE == stable ]]; then stable_or_beta=yes fi -set +e -save_version=$(cat src/Config.template.h | sed -n 's/constexpr int SAVE_VERSION * = \([^;]*\);/\1/p') -minor_version=$(cat src/Config.template.h | sed -n 's/constexpr int MINOR_VERSION * = \([^;]*\);/\1/p') -build_num=$(cat src/Config.template.h | sed -n 's/constexpr int BUILD_NUM * = \([^;]*\);/\1/p') -if [[ -z ${save_version-} ]] || [[ -z ${minor_version-} ]] || [[ -z ${build_num-} ]]; then - >&2 echo "failed to extract version from Config.template.h" - exit 1 -fi -set -e -if [[ $stable_or_beta == yes ]] && [[ $MOD_ID != 0 ]]; then - save_version=$(echo $RELEASE_NAME | cut -d '.' -f 1) - minor_version=$(echo $RELEASE_NAME | cut -d '.' -f 2) - build_num=$(echo $RELEASE_NAME | cut -d '.' -f 3) +if [[ $stable_or_beta == yes ]]; then + meson_configure+=$'\t'-Ddisplay_version_major=$(echo $RELEASE_NAME | cut -d '.' -f 1) + meson_configure+=$'\t'-Ddisplay_version_minor=$(echo $RELEASE_NAME | cut -d '.' -f 2) + meson_configure+=$'\t'-Dbuild_num=$(echo $RELEASE_NAME | cut -d '.' -f 3) fi if [[ $RELEASE_TYPE == snapshot ]]; then meson_configure+=$'\t'-Dsnapshot=true @@ -426,7 +410,6 @@ if [[ $PACKAGE_MODE == dmg ]]; then mkdir $appdir mkdir $appdir/Contents cp resources/Info.plist $appdir/Contents/Info.plist - subst_version $appdir/Contents/Info.plist mkdir $appdir/Contents/MacOS cp $APP_EXE $appdir/Contents/MacOS/$APP_EXE mkdir $appdir/Contents/Resources @@ -471,7 +454,6 @@ elif [[ $PACKAGE_MODE == appimage ]]; then cp ../resources/icon_exe.svg $appdir/$APP_VENDOR-$APP_EXE.svg cp resources/powder.desktop $appdir/$APP_ID.desktop cp resources/appdata.xml $appdir/usr/share/metainfo/$APP_ID.appdata.xml - subst_version $appdir/usr/share/metainfo/$APP_ID.appdata.xml cp $appdir/$APP_VENDOR-$APP_EXE.svg $appdir/usr/share/icons/$APP_VENDOR-$APP_EXE.svg cp $appdir/$APP_ID.desktop $appdir/usr/share/applications/$APP_ID.desktop ./appimagetool $appdir $ASSET_PATH diff --git a/android/AndroidManifest.template.xml b/android/AndroidManifest.template.xml index c84b868c1..af9ace73d 100644 --- a/android/AndroidManifest.template.xml +++ b/android/AndroidManifest.template.xml @@ -2,8 +2,8 @@ CFBundleIconFile icon_exe.icns NSHumanReadableCopyright - Copyright © 2008-2011 Stanislaw K Skowrenek, Copyright © 2011-2023 Simon Robertshaw, Copyright © 2016-2023 jacob1 + @MANIFEST_COPYRIGHT@ CFBundleDevelopmentRegion English CFBundleDocumentTypes @@ -57,13 +57,13 @@ CFBundlePackageType APPL CFBundleShortVersionString - SUBST_SAVE_VERSION.SUBST_MINOR_VERSION + @DISPLAY_VERSION_MAJOR@.@DISPLAY_VERSION_MINOR@ CFBundleSignature ???? CFBundleVersion - SUBST_SAVE_VERSION.SUBST_MINOR_VERSION (build SUBST_BUILD_NUM) + @DISPLAY_VERSION_MAJOR@.@DISPLAY_VERSION_MINOR@ (build @BUILD_NUM@) LSMinimumSystemVersion - SUBST_MACOS_MIN_VER + @MANIFEST_MACOS_MIN_VER@ NSPrincipalClass NSApplication diff --git a/resources/appdata.template.xml b/resources/appdata.template.xml index 9d67bf029..824921133 100644 --- a/resources/appdata.template.xml +++ b/resources/appdata.template.xml @@ -29,6 +29,6 @@ https://github.com/The-Powder-Toy/The-Powder-Toy/issues https://powdertoy.co.uk/Wiki/W/Main_Page.html - + diff --git a/resources/meson.build b/resources/meson.build index bf8b39532..44a470ce2 100644 --- a/resources/meson.build +++ b/resources/meson.build @@ -52,8 +52,18 @@ if host_platform == 'windows' command: command, ) } endforeach + rc_conf_data = configuration_data() + rc_conf_data.merge_from(conf_data) + rc_conf_data.set('RESOUCE_H', join_paths(meson.current_source_dir(), 'resource.h')) + rc_conf_data.set('WINUTF8_XML', join_paths(meson.current_source_dir(), 'winutf8.xml')) + rc_conf_data.set('ICON_EXE_ICO', join_paths(meson.current_build_dir(), 'icon_exe.ico')) + rc_conf_data.set('ICON_CPS_ICO', join_paths(meson.current_build_dir(), 'icon_cps.ico')) powder_files += windows_mod.compile_resources( - 'powder-res.rc', + configure_file( + input: 'powder-res.template.rc', + output: 'powder-res.rc', + configuration: rc_conf_data, + ), depends: [ generated_win_icos['icon_exe'], generated_win_icos['icon_cps'], diff --git a/resources/powder-res.rc b/resources/powder-res.rc deleted file mode 100644 index 7bb0c594e..000000000 --- a/resources/powder-res.rc +++ /dev/null @@ -1,6 +0,0 @@ -#include "resource.h" -#include - -IDI_ICON ICON DISCARDABLE "icon_exe.ico" -IDI_DOC_ICON ICON DISCARDABLE "icon_cps.ico" -CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "winutf8.xml" diff --git a/resources/powder-res.template.rc b/resources/powder-res.template.rc new file mode 100644 index 000000000..71d47a6a2 --- /dev/null +++ b/resources/powder-res.template.rc @@ -0,0 +1,32 @@ +#include "@RESOUCE_H@" +#include +#include +#include + +IDI_ICON ICON DISCARDABLE "@ICON_EXE_ICO@" +IDI_DOC_ICON ICON DISCARDABLE "@ICON_CPS_ICO@" +CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "@WINUTF8_XML@" + +VS_VERSION_INFO VERSIONINFO +FILEVERSION @DISPLAY_VERSION_MAJOR@,@DISPLAY_VERSION_MINOR@,0,@BUILD_NUM@ +PRODUCTVERSION @DISPLAY_VERSION_MAJOR@,@DISPLAY_VERSION_MINOR@,0,@BUILD_NUM@ +{ + BLOCK "StringFileInfo" + { + BLOCK "040904b0" + { + VALUE "CompanyName", "https://powdertoy.co.uk/\0" + VALUE "FileDescription", "@APPCOMMENT@\0" + VALUE "FileVersion", "@DISPLAY_VERSION_MAJOR@.@DISPLAY_VERSION_MINOR@.0.@BUILD_NUM@\0" + VALUE "OriginalFilename", "@APPEXE@.exe\0" + VALUE "LegalCopyright", "@MANIFEST_COPYRIGHT@\0" + VALUE "ProductName", "@APPNAME@\0" + VALUE "ProductVersion", "@DISPLAY_VERSION_MAJOR@.@DISPLAY_VERSION_MINOR@.0.@BUILD_NUM@\0" + VALUE "InternalName", "@APPID@\0" + } + } + BLOCK "VarFileInfo" + { + VALUE "Translation", 0x409, 65001 + } +} diff --git a/src/Config.template.h b/src/Config.template.h index 41292c497..e9fce5618 100644 --- a/src/Config.template.h +++ b/src/Config.template.h @@ -1,5 +1,6 @@ #pragma once #include "VcsTag.h" +#include "common/Version.h" constexpr bool SET_WINDOW_ICON = @SET_WINDOW_ICON@; constexpr bool DEBUG = @DEBUG@; @@ -44,13 +45,18 @@ constexpr char APPID[] = "@APPID@"; constexpr char APPDATA[] = "@APPDATA@"; constexpr char APPVENDOR[] = "@APPVENDOR@"; -constexpr int SAVE_VERSION = 97; -constexpr int MINOR_VERSION = 0; -constexpr int BUILD_NUM = 352; constexpr int SNAPSHOT_ID = @SNAPSHOT_ID@; constexpr int MOD_ID = @MOD_ID@; -constexpr int FUTURE_SAVE_VERSION = 98; -constexpr int FUTURE_MINOR_VERSION = 0; + +struct DisplayVersionWithBuild +{ + Version<2> displayVersion; + size_t build; +}; +constexpr DisplayVersionWithBuild APP_VERSION = { { @DISPLAY_VERSION_MAJOR@, @DISPLAY_VERSION_MINOR@ }, @BUILD_NUM@ }; +constexpr DisplayVersionWithBuild UPSTREAM_VERSION = { { @UPSTREAM_VERSION_MAJOR@, @UPSTREAM_VERSION_MINOR@ }, @UPSTREAM_BUILD_NUM@ }; + +constexpr auto DISPLAY_VERSION = APP_VERSION.displayVersion; constexpr char IDENT_RELTYPE = SNAPSHOT ? 'S' : (BETA ? 'B' : 'R'); diff --git a/src/client/Client.cpp b/src/client/Client.cpp index 8e2b1e54c..419c87e0a 100644 --- a/src/client/Client.cpp +++ b/src/client/Client.cpp @@ -325,8 +325,8 @@ ByteString Client::AddStamp(std::unique_ptr saveData) } saveData->authors = stampInfo; - auto [ fromNewerVersion, gameData ] = saveData->Serialise(); - (void)fromNewerVersion; + std::vector gameData; + std::tie(std::ignore, gameData) = saveData->Serialise(); if (!gameData.size()) return ""; diff --git a/src/client/GameSave.cpp b/src/client/GameSave.cpp index 27196e45a..adbe30dd4 100644 --- a/src/client/GameSave.cpp +++ b/src/client/GameSave.cpp @@ -4,7 +4,6 @@ #include "simulation/Simulation.h" #include "simulation/ElementClasses.h" #include "common/tpt-compat.h" -#include "common/Version.h" #include "bson/BSON.h" #include "graphics/Renderer.h" #include "Config.h" @@ -16,6 +15,9 @@ #include #include +constexpr auto currentVersionMajor = 97; +constexpr auto nextVersionMajor = currentVersionMajor + 1; + static void ConvertJsonToBson(bson *b, Json::Value j, int depth = 0); static void ConvertBsonToJson(bson_iterator *b, Json::Value *j, int depth = 0); static void CheckBsonFieldUser(bson_iterator iter, const char *field, unsigned char **data, unsigned int *fieldLen); @@ -326,6 +328,9 @@ static void CheckBsonFieldFloat(bson_iterator iter, const char *field, float *se void GameSave::readOPS(const std::vector &data) { + constexpr auto currentVersion = Version(currentVersionMajor, 0); + constexpr auto nextVersion = Version(nextVersionMajor, 0); + Renderer::PopulateTables(); unsigned char *inputData = (unsigned char*)&data[0], *partsData = NULL, *partsPosData = NULL, *fanData = NULL, *wallData = NULL, *soapLinkData = NULL; @@ -333,9 +338,8 @@ void GameSave::readOPS(const std::vector &data) unsigned int inputDataLen = data.size(), bsonDataLen = 0, partsDataLen, partsPosDataLen, fanDataLen, wallDataLen, soapLinkDataLen; unsigned int pressDataLen, vxDataLen, vyDataLen, ambientDataLen, blockAirDataLen; unsigned partsCount = 0; - int savedVersion = inputData[4]; - majorVersion = savedVersion; - minorVersion = 0; + unsigned int savedVersion = inputData[4]; + version = { savedVersion, 0 }; bool fakeNewerVersion = false; // used for development builds only bson b; @@ -354,7 +358,7 @@ void GameSave::readOPS(const std::vector &data) auto partS = blockS * CELL; //From newer version - if (savedVersion > SAVE_VERSION) + if (savedVersion > currentVersion[0]) { fromNewerVersion = true; //throw ParseException(ParseException::WrongVersion, "Save from newer version"); @@ -470,7 +474,7 @@ void GameSave::readOPS(const std::vector &data) if (!strcmp(bson_iterator_key(&signiter), "text") && bson_iterator_type(&signiter) == BSON_STRING) { tempSign.text = format::CleanString(ByteString(bson_iterator_string(&signiter)).FromUtf8(), true, true, true).Substr(0, 45); - if (majorVersion < 94 || (majorVersion == 94 && minorVersion < 2)) + if (version < Version(94, 2)) { if (tempSign.text == "{t}") { @@ -582,7 +586,7 @@ void GameSave::readOPS(const std::vector &data) { if (!strcmp(bson_iterator_key(&subiter), "minorVersion")) { - minorVersion = bson_iterator_int(&subiter); + version[1] = bson_iterator_int(&subiter); } } } @@ -596,27 +600,30 @@ void GameSave::readOPS(const std::vector &data) { if (bson_iterator_type(&iter) == BSON_OBJECT) { - int major = INT_MAX, minor = INT_MAX; - bson_iterator subiter; - bson_iterator_subiterator(&iter, &subiter); - while (bson_iterator_next(&subiter)) + Version<2> version; { - if (bson_iterator_type(&subiter) == BSON_INT) + int major = INT_MAX, minor = INT_MAX; + bson_iterator subiter; + bson_iterator_subiterator(&iter, &subiter); + while (bson_iterator_next(&subiter)) { - if (!strcmp(bson_iterator_key(&subiter), "major")) - major = bson_iterator_int(&subiter); - else if (!strcmp(bson_iterator_key(&subiter), "minor")) - minor = bson_iterator_int(&subiter); + if (bson_iterator_type(&subiter) == BSON_INT) + { + if (!strcmp(bson_iterator_key(&subiter), "major")) + major = bson_iterator_int(&subiter); + else if (!strcmp(bson_iterator_key(&subiter), "minor")) + minor = bson_iterator_int(&subiter); + } } + version = Version(major, minor); } - auto majorToCheck = ALLOW_FAKE_NEWER_VERSION ? FUTURE_SAVE_VERSION : SAVE_VERSION; - auto minorToCheck = ALLOW_FAKE_NEWER_VERSION ? FUTURE_MINOR_VERSION : MINOR_VERSION; - if (major > majorToCheck || (major == majorToCheck && minor > minorToCheck)) + auto versionToCheck = ALLOW_FAKE_NEWER_VERSION ? nextVersion : currentVersion; + if (versionToCheck < version) { - String errorMessage = String::Build("Save from a newer version: Requires version ", major, ".", minor); + String errorMessage = String::Build("Save from a newer version: Requires version ", version[0], ".", version[1]); throw ParseException(ParseException::WrongVersion, errorMessage); } - else if (ALLOW_FAKE_NEWER_VERSION && (major > SAVE_VERSION || (major == SAVE_VERSION && minor > MINOR_VERSION))) + else if (ALLOW_FAKE_NEWER_VERSION && currentVersion < version) { fakeNewerVersion = true; } @@ -642,8 +649,8 @@ void GameSave::readOPS(const std::vector &data) } } - auto paletteRemap = [this, saveVersion = Version(majorVersion, minorVersion)](auto maxVersion, ByteString from, ByteString to) { - if (saveVersion <= maxVersion) + auto paletteRemap = [this](auto maxVersion, ByteString from, ByteString to) { + if (version <= maxVersion) { auto it = std::find_if(palette.begin(), palette.end(), [&from](auto &item) { return item.first == from; @@ -1182,7 +1189,7 @@ void GameSave::readPSv(const std::vector &dataVec) unsigned char * saveData = (unsigned char *)&dataVec[0]; auto dataLength = int(dataVec.size()); - int q,p=0, ver, pty, ty, legacy_beta=0; + int q,p=0, pty, ty, legacy_beta=0; Vec2 blockP = { 0, 0 }; int new_format = 0, ttv = 0; @@ -1202,11 +1209,10 @@ void GameSave::readPSv(const std::vector &dataVec) if (saveData[2]==0x76 && saveData[1]==0x53 && saveData[0]==0x50) { new_format = 1; } - if (saveData[4]>SAVE_VERSION) + if (saveData[4]>97) // this used to respect currentVersion but no valid PSv will ever have a version > 97 so it's ok to hardcode throw ParseException(ParseException::WrongVersion, "Save from newer version"); - ver = saveData[4]; - majorVersion = saveData[4]; - minorVersion = 0; + version = { saveData[4], 0 }; + auto ver = version[0]; if (ver<34) { @@ -1818,16 +1824,18 @@ void GameSave::readPSv(const std::vector &dataVec) std::pair> GameSave::serialiseOPS() const { + constexpr auto currentVersion = Version(currentVersionMajor, 0); + // minimum version this save is compatible with // when building, this number may be increased depending on what elements are used // or what properties are detected - int minimumMajorVersion = 90, minimumMinorVersion = 2; - auto RESTRICTVERSION = [&minimumMajorVersion, &minimumMinorVersion](int major, int minor) { + auto minimumVersion = Version(90, 2); + auto RESTRICTVERSION = [&minimumVersion](auto major, auto minor = 0) { // restrict the minimum version this save can be opened with - if (major > minimumMajorVersion || ((major == minimumMajorVersion && minor > minimumMinorVersion))) + auto version = Version(major, minor); + if (minimumVersion < version) { - minimumMajorVersion = major; - minimumMinorVersion = minor; + minimumVersion = version; } }; @@ -2295,7 +2303,7 @@ std::pair> GameSave::serialiseOPS() const } // Mark save as incompatible with latest release - bool fakeFromNewerVersion = ALLOW_FAKE_NEWER_VERSION && (minimumMajorVersion > SAVE_VERSION || (minimumMajorVersion == SAVE_VERSION && minimumMinorVersion > MINOR_VERSION)); + bool fakeFromNewerVersion = ALLOW_FAKE_NEWER_VERSION && currentVersion < minimumVersion; bson b; b.data = NULL; @@ -2306,9 +2314,9 @@ std::pair> GameSave::serialiseOPS() const set_bson_err_handler([](const char* err) { throw BuildException("BSON error when parsing save: " + ByteString(err).FromUtf8()); }); bson_init(&b); bson_append_start_object(&b, "origin"); - bson_append_int(&b, "majorVersion", SAVE_VERSION); - bson_append_int(&b, "minorVersion", MINOR_VERSION); - bson_append_int(&b, "buildNum", BUILD_NUM); + bson_append_int(&b, "majorVersion", int(currentVersion[0])); + bson_append_int(&b, "minorVersion", int(currentVersion[1])); + bson_append_int(&b, "buildNum", APP_VERSION.build); bson_append_int(&b, "snapshotId", SNAPSHOT_ID); bson_append_int(&b, "modId", MOD_ID); bson_append_string(&b, "releaseType", ByteString(1, IDENT_RELTYPE).c_str()); @@ -2322,8 +2330,8 @@ std::pair> GameSave::serialiseOPS() const RESTRICTVERSION(97, 0); } bson_append_start_object(&b, "minimumVersion"); - bson_append_int(&b, "major", minimumMajorVersion); - bson_append_int(&b, "minor", minimumMinorVersion); + bson_append_int(&b, "major", int(minimumVersion[0])); + bson_append_int(&b, "minor", int(minimumVersion[1])); bson_append_finish_object(&b); @@ -2467,7 +2475,7 @@ std::pair> GameSave::serialiseOPS() const header[1] = 'P'; header[2] = 'S'; header[3] = '1'; - header[4] = SAVE_VERSION; + header[4] = currentVersion[0]; header[5] = CELL; header[6] = blockS.X; header[7] = blockS.Y; diff --git a/src/client/GameSave.h b/src/client/GameSave.h index 2490372f0..a22d359a3 100644 --- a/src/client/GameSave.h +++ b/src/client/GameSave.h @@ -2,6 +2,7 @@ #include "common/Plane.h" #include "common/String.h" #include "common/tpt-rand.h" +#include "common/Version.h" #include "simulation/Sign.h" #include "simulation/Particle.h" #include "Misc.h" @@ -64,8 +65,7 @@ class GameSave public: Vec2 blockSize = { 0, 0 }; bool fromNewerVersion = false; - int majorVersion = 0; - int minorVersion = 0; + Version<2> version{}; bool hasPressure = false; bool hasAmbientHeat = false; bool hasBlockAirMaps = false; // only written by readOPS, never read diff --git a/src/client/http/StartupRequest.cpp b/src/client/http/StartupRequest.cpp index c3c036b88..34fda09aa 100644 --- a/src/client/http/StartupRequest.cpp +++ b/src/client/http/StartupRequest.cpp @@ -82,12 +82,12 @@ namespace http else { parseUpdate("Stable", UpdateInfo::channelStable, [](int build) -> bool { - return build > BUILD_NUM; + return size_t(build) > APP_VERSION.build; }); if (!startupInfo.updateInfo.has_value()) { parseUpdate("Beta", UpdateInfo::channelBeta, [](int build) -> bool { - return build > BUILD_NUM; + return size_t(build) > APP_VERSION.build; }); } } diff --git a/src/client/http/requestmanager/Common.cpp b/src/client/http/requestmanager/Common.cpp index a8d18c5c9..e2cde7223 100644 --- a/src/client/http/requestmanager/Common.cpp +++ b/src/client/http/requestmanager/Common.cpp @@ -10,13 +10,14 @@ namespace http capath(newCapath), disableNetwork(newDisableNetwork) { + auto apiVersion = Version(97, 0); userAgent = ByteString::Build( - "PowderToy/", SAVE_VERSION, ".", MINOR_VERSION, + "PowderToy/", DISPLAY_VERSION[0], ".", DISPLAY_VERSION[1], " (", IDENT_PLATFORM, "; NO", // Unused, used to be SSE level. "; M", MOD_ID, "; ", IDENT, - ") TPTPP/", SAVE_VERSION, ".", MINOR_VERSION, ".", BUILD_NUM, IDENT_RELTYPE, ".", SNAPSHOT_ID + ") TPTPP/", apiVersion[0], ".", apiVersion[1], ".", APP_VERSION.build, IDENT_RELTYPE, ".", SNAPSHOT_ID ); } diff --git a/src/common/Version.h b/src/common/Version.h index 11c1e2846..ae215e3f0 100644 --- a/src/common/Version.h +++ b/src/common/Version.h @@ -26,6 +26,16 @@ struct Version { return *this < other || *this == other; } + + constexpr size_t operator [](size_t index) const + { + return components[index]; + } + + size_t &operator [](size_t index) + { + return components[index]; + } }; template diff --git a/src/gui/game/GameController.cpp b/src/gui/game/GameController.cpp index a04b3c844..05e23a359 100644 --- a/src/gui/game/GameController.cpp +++ b/src/gui/game/GameController.cpp @@ -1204,10 +1204,10 @@ void GameController::OpenLocalSaveWindow(bool asCurrent) gameSave->authors = localSaveInfo; Platform::MakeDirectory(LOCAL_SAVE_DIR); - auto [ fromNewerVersion, saveData ] = gameSave->Serialise(); + std::vector saveData; + std::tie(std::ignore, saveData) = gameSave->Serialise(); tempSave->SetGameSave(std::move(gameSave)); gameModel->SetSaveFile(std::move(tempSave), gameView->ShiftBehaviour()); - (void)fromNewerVersion; if (saveData.size() == 0) new ErrorMessage("Error", "Unable to serialize game data."); else if (!Platform::WriteFile(saveData, gameModel->GetSaveFile()->GetName())) @@ -1611,11 +1611,11 @@ void GameController::NotifyUpdateAvailable(Client * sender) } else if constexpr (BETA) { - updateMessage << SAVE_VERSION << "." << MINOR_VERSION << " Beta, Build " << BUILD_NUM; + updateMessage << DISPLAY_VERSION[0] << "." << DISPLAY_VERSION[1] << " Beta, Build " << APP_VERSION.build; } else { - updateMessage << SAVE_VERSION << "." << MINOR_VERSION << " Stable, Build " << BUILD_NUM; + updateMessage << DISPLAY_VERSION[0] << "." << DISPLAY_VERSION[1] << " Stable, Build " << APP_VERSION.build; } updateMessage << "\nNew version:\n "; diff --git a/src/gui/game/IntroText.h b/src/gui/game/IntroText.h index 9ab482324..741849ec7 100644 --- a/src/gui/game/IntroText.h +++ b/src/gui/game/IntroText.h @@ -5,7 +5,7 @@ inline ByteString VersionInfo() { ByteStringBuilder sb; - sb << SAVE_VERSION << "." << MINOR_VERSION << "." << BUILD_NUM << " " << IDENT; + sb << DISPLAY_VERSION[0] << "." << DISPLAY_VERSION[1] << "." << APP_VERSION.build << " " << IDENT; if constexpr (SNAPSHOT) { sb << " SNAPSHOT " << SNAPSHOT_ID; @@ -39,7 +39,7 @@ inline ByteString VersionInfo() inline ByteString IntroText() { ByteStringBuilder sb; - sb << "\bl\bU" << APPNAME << "\bU - Version " << SAVE_VERSION << "." << MINOR_VERSION << " - https://powdertoy.co.uk, irc.libera.chat #powder, https://tpt.io/discord\n" + sb << "\bl\bU" << APPNAME << "\bU - Version " << DISPLAY_VERSION[0] << "." << DISPLAY_VERSION[1] << " - https://powdertoy.co.uk, irc.libera.chat #powder, https://tpt.io/discord\n" "\n" "\n" "\bgControl+C/V/X are Copy, Paste and cut respectively.\n" diff --git a/src/gui/save/LocalSaveActivity.cpp b/src/gui/save/LocalSaveActivity.cpp index 46ece246e..cb5e80cd5 100644 --- a/src/gui/save/LocalSaveActivity.cpp +++ b/src/gui/save/LocalSaveActivity.cpp @@ -115,8 +115,8 @@ void LocalSaveActivity::saveWrite(ByteString finalFilename) gameSave->authors = localSaveInfo; save->SetGameSave(std::move(gameSave)); } - auto [ fromNewerVersion, saveData ] = save->GetGameSave()->Serialise(); - (void)fromNewerVersion; + std::vector saveData; + std::tie(std::ignore, saveData) = save->GetGameSave()->Serialise(); if (saveData.size() == 0) new ErrorMessage("Error", "Unable to serialize game data."); else if (!Platform::WriteFile(saveData, finalFilename)) diff --git a/src/lua/LuaScriptInterface.cpp b/src/lua/LuaScriptInterface.cpp index d43c3f594..a40f74a13 100644 --- a/src/lua/LuaScriptInterface.cpp +++ b/src/lua/LuaScriptInterface.cpp @@ -403,12 +403,18 @@ LuaScriptInterface::LuaScriptInterface(GameController * c, GameModel * m): lua_newtable(l); tptPropertiesVersion = lua_gettop(l); - lua_pushinteger(l, SAVE_VERSION); + lua_pushinteger(l, DISPLAY_VERSION[0]); lua_setfield(l, tptPropertiesVersion, "major"); - lua_pushinteger(l, MINOR_VERSION); + lua_pushinteger(l, DISPLAY_VERSION[1]); lua_setfield(l, tptPropertiesVersion, "minor"); - lua_pushinteger(l, BUILD_NUM); + lua_pushinteger(l, APP_VERSION.build); lua_setfield(l, tptPropertiesVersion, "build"); + lua_pushinteger(l, UPSTREAM_VERSION.displayVersion[0]); + lua_setfield(l, tptPropertiesVersion, "upstream_major"); + lua_pushinteger(l, UPSTREAM_VERSION.displayVersion[1]); + lua_setfield(l, tptPropertiesVersion, "upstream_minor"); + lua_pushinteger(l, UPSTREAM_VERSION.build); + lua_setfield(l, tptPropertiesVersion, "upstream_build"); if constexpr (SNAPSHOT || MOD) { lua_pushinteger(l, SNAPSHOT_ID); diff --git a/src/meson.build b/src/meson.build index 96595a170..cb53f8a15 100644 --- a/src/meson.build +++ b/src/meson.build @@ -12,6 +12,15 @@ conf_data.set('DEBUG', is_debug.to_string()) conf_data.set('MOD', is_mod.to_string()) conf_data.set('SNAPSHOT', is_snapshot.to_string()) conf_data.set('SNAPSHOT_ID', get_option('snapshot_id')) +conf_data.set('DISPLAY_VERSION_MAJOR', get_option('display_version_major')) +conf_data.set('DISPLAY_VERSION_MINOR', get_option('display_version_minor')) +conf_data.set('BUILD_NUM', get_option('build_num')) +conf_data.set('UPSTREAM_VERSION_MAJOR', get_option('upstream_version_major')) +conf_data.set('UPSTREAM_VERSION_MINOR', get_option('upstream_version_minor')) +conf_data.set('UPSTREAM_BUILD_NUM', get_option('upstream_build_num')) +conf_data.set('MANIFEST_COPYRIGHT', get_option('manifest_copyright')) +conf_data.set('MANIFEST_MACOS_MIN_VER', get_option('manifest_macos_min_ver')) +conf_data.set('MANIFEST_DATE', get_option('manifest_date')) conf_data.set('ALLOW_FAKE_NEWER_VERSION', (is_snapshot or is_beta or is_debug or is_mod).to_string()) conf_data.set('IDENT_PLATFORM', ident_platform) conf_data.set('IDENT', '@0@-@1@-@2@'.format(host_arch, host_platform, host_libc).to_upper()) diff --git a/src/simulation/Simulation.cpp b/src/simulation/Simulation.cpp index fcb8e2e9e..7b76e8fbe 100644 --- a/src/simulation/Simulation.cpp +++ b/src/simulation/Simulation.cpp @@ -151,8 +151,8 @@ std::vector Simulation::Load(const GameSave *save, bool includePress player.spwn = 1; player.elem = PT_DUST; - if ((save->majorVersion < 93 && parts[i].ctype == SPC_AIR) || - (save->majorVersion < 88 && parts[i].ctype == OLD_SPC_AIR)) + if ((save->version < Version(93, 0) && parts[i].ctype == SPC_AIR) || + (save->version < Version(88, 0) && parts[i].ctype == OLD_SPC_AIR)) { player.fan = true; } @@ -165,8 +165,8 @@ std::vector Simulation::Load(const GameSave *save, bool includePress Element_STKM_init_legs(this, &player2, i); player2.spwn = 1; player2.elem = PT_DUST; - if ((save->majorVersion < 93 && parts[i].ctype == SPC_AIR) || - (save->majorVersion < 88 && parts[i].ctype == OLD_SPC_AIR)) + if ((save->version < Version(93, 0) && parts[i].ctype == SPC_AIR) || + (save->version < Version(88, 0) && parts[i].ctype == OLD_SPC_AIR)) { player2.fan = true; } @@ -189,8 +189,8 @@ std::vector Simulation::Load(const GameSave *save, bool includePress if (parts[i].tmp >= 0) { bool fan = false; - if ((save->majorVersion < 93 && parts[i].ctype == SPC_AIR) - || (save->majorVersion < 88 && parts[i].ctype == OLD_SPC_AIR)) + if ((save->version < Version(93, 0) && parts[i].ctype == SPC_AIR) + || (save->version < Version(88, 0) && parts[i].ctype == OLD_SPC_AIR)) { fan = true; parts[i].ctype = 0;