From 4ef2fa8226d4f8ef8f958d651cb76094a647d276 Mon Sep 17 00:00:00 2001 From: BenCheung0422 <74168521+BenCheung0422@users.noreply.github.com> Date: Tue, 9 Jan 2024 18:08:22 +0800 Subject: [PATCH 01/19] Add game_profile.conf and Gradle settings --- .github/workflows/autobuild.yml | 59 ++++++++++++++------------------- build.gradle | 21 +++++++++++- game_profile.conf | 2 ++ 3 files changed, 47 insertions(+), 35 deletions(-) create mode 100644 game_profile.conf diff --git a/.github/workflows/autobuild.yml b/.github/workflows/autobuild.yml index f7662bdb5..3276c3f53 100644 --- a/.github/workflows/autobuild.yml +++ b/.github/workflows/autobuild.yml @@ -3,7 +3,7 @@ on: schedule: - cron: '0 0 * * *' workflow_dispatch: - + jobs: gradle: strategy: @@ -16,18 +16,28 @@ jobs: - uses: actions/checkout@v3 with: token: ${{ secrets.LITOROMTOKEN }} - - name: Update ingame version - uses: jacobtomlinson/gha-find-replace@v3 - with: - find: "${{ vars.VERSION }}-dev${{ vars.VERSION_old }}" - replace: "${{ vars.VERSION }}-dev${{ vars.VERSION_s }}" - include: "src/client/java/minicraft/core/Game.java" - - name: Update gradle version - uses: jacobtomlinson/gha-find-replace@v3 - with: - find: "version = \"${{ vars.VERSION }}-dev${{ vars.VERSION_old }}\"" - replace: "version = \"${{ vars.VERSION }}-dev${{ vars.VERSION_s }}\"" - include: "build.gradle" + - name: Read game profile configs + run: | + source game_profile.conf + echo "GAME_VER=$version" >> $GITHUB_ENV + echo "DEV_BUILD=$devBuild" >> $GITHUB_ENV + # Do no increment game version if it is not currently in a development build state. + # Source: https://stackoverflow.com/a/75809743 + - name: Abort + if: ${{ ! env.DEV_BUILD }} + run: | + gh run cancel ${{ github.run_id }} + gh run watch ${{ github.run_id }} + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + - name: Increment game version + run: | + dev_num=$( [[ $GAME_VER = *"dev"* ]] && ( echo $GAME_VER | grep -Po "[0-9.]+-dev\K\d+" ) || ( echo 0 ) ) + ((dev_num++)) + base_ver=$( echo $GAME_VER | grep -o "^[^-]*" ) + echo "GAME_VER=$base_ver-dev$dev_num" >> $GITHUB_ENV + - name: Update game version + run: sed -E -i "/^version=.+$/ s/[0-9]+.+$/$GAME_VER/" game_profile.conf - name: Push changes uses: stefanzweifel/git-auto-commit-action@v4 with: @@ -35,34 +45,15 @@ jobs: token: ${{ secrets.LITOROMTOKEN }} repository: ${{ secrets.GITHUB_REPOSITORY }} branch: ${{ github.ref }} - + - uses: actions/setup-java@v3 with: distribution: temurin java-version: 8 - - - name: Increment old version number - uses: action-pack/increment@v2 - with: - name: 'VERSION_old' - token: ${{ secrets.LITOROMTOKEN }} - repository: ${{ secrets.GITHUB_REPOSITORY }} - owner: 'MinicraftPlus' - - - name: Increment new version number - uses: action-pack/increment@v2 - with: - name: 'VERSION_s' - token: ${{ secrets.LITOROMTOKEN }} - repository: ${{ secrets.GITHUB_REPOSITORY }} - owner: 'MinicraftPlus' - - name: Setup Gradle uses: gradle/gradle-build-action@v2.4.2 - - name: Execute Gradle build run: ./gradlew build - - uses: "dciborow/action-github-releases@v1.0.1" with: repo_token: "${{ secrets.GITHUB_TOKEN }}" @@ -74,4 +65,4 @@ jobs: LICENSE ChangeLog.md build/libs/**.jar - + diff --git a/build.gradle b/build.gradle index 8033cff4b..7805a9f20 100644 --- a/build.gradle +++ b/build.gradle @@ -1,3 +1,5 @@ +import groovy.json.JsonBuilder + plugins { id 'application' } @@ -5,7 +7,10 @@ plugins { allprojects { apply plugin: "java" - version = "2.2.0-dev6" + Properties profile = new Properties() + profile.load(new FileInputStream("game_profile.conf")) + + version = profile.getProperty("version") sourceCompatibility = 8 [compileJava, compileTestJava]*.options*.encoding = 'UTF-8' @@ -41,6 +46,20 @@ project(":common") { project(":client") { archivesBaseName = "minicraft-plus" + File genDir = new File(project.buildDir, "tmp/generatedResources/") + genDir.mkdirs() + JsonBuilder json = new JsonBuilder() + json { + version version + } + File metaFile = new File(genDir.toString(), "profile.meta.json") + metaFile.text = json.toString() + processResources { + from(genDir) { + include(metaFile.getName()) + } + } + repositories { maven { url "https://plugins.gradle.org/m2/" } maven { url "https://jitpack.io" } diff --git a/game_profile.conf b/game_profile.conf new file mode 100644 index 000000000..2cec452f1 --- /dev/null +++ b/game_profile.conf @@ -0,0 +1,2 @@ +version=2.2.0-dev6 +devBuild=true From 50dd972d5dc4e8facb28c8d484243dd208b09d16 Mon Sep 17 00:00:00 2001 From: BenCheung0422 <74168521+BenCheung0422@users.noreply.github.com> Date: Tue, 9 Jan 2024 18:22:56 +0800 Subject: [PATCH 02/19] Make Game read game_profile.conf --- build.gradle | 2 +- src/client/java/minicraft/core/Game.java | 29 +++++++++++++++++++++--- 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/build.gradle b/build.gradle index 7805a9f20..81c3c9f64 100644 --- a/build.gradle +++ b/build.gradle @@ -8,7 +8,7 @@ allprojects { apply plugin: "java" Properties profile = new Properties() - profile.load(new FileInputStream("game_profile.conf")) + profile.load(new FileInputStream(new File(rootDir, "game_profile.conf"))) version = profile.getProperty("version") diff --git a/src/client/java/minicraft/core/Game.java b/src/client/java/minicraft/core/Game.java index 449b5ad96..b0ce4ff76 100644 --- a/src/client/java/minicraft/core/Game.java +++ b/src/client/java/minicraft/core/Game.java @@ -14,10 +14,18 @@ import minicraft.screen.TitleDisplay; import minicraft.util.Logging; import org.jetbrains.annotations.Nullable; +import org.json.JSONObject; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.UncheckedIOException; import java.util.ArrayDeque; import java.util.ArrayList; import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; public class Game { protected Game() { @@ -25,7 +33,7 @@ protected Game() { public static final String NAME = "Minicraft Plus"; // This is the name on the application window. - public static final Version VERSION = new Version("2.2.0-dev6"); + public static final Version VERSION; public static InputHandler input; // Input used in Game, Player, and just about all the *Menu classes. public static Player player; @@ -91,10 +99,25 @@ public static void quit() { running = false; } - - public static void main(String[] args) { + static { Thread.setDefaultUncaughtExceptionHandler(CrashHandler::crashHandle); + InputStream is = Game.class.getResourceAsStream("/profile.meta.json"); + if (is == null) + throw new IllegalStateException("Malformed application setup"); + + JSONObject meta = new JSONObject(new BufferedReader(new InputStreamReader(is)).lines().collect(Collectors.joining("\n"))); + + VERSION = new Version(meta.getString("version")); + + try { + is.close(); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + + public static void main(String[] args) { Initializer.parseArgs(args); // Parses the command line arguments // Applying Game#debug first. From 7849996c56ecd0e90b81bfcd35ab17dc872f76d5 Mon Sep 17 00:00:00 2001 From: BenCheung0422 <74168521+BenCheung0422@users.noreply.github.com> Date: Fri, 2 Feb 2024 02:47:46 +0800 Subject: [PATCH 03/19] Separate HistoricLoad from LegacyLoad --- src/client/java/minicraft/core/World.java | 4 +- .../java/minicraft/saveload/HistoricLoad.java | 961 ++++++++++++++++++ .../java/minicraft/saveload/LegacyLoad.java | 112 +- src/client/java/minicraft/saveload/Load.java | 150 ++- .../java/minicraft/screen/LoadingDisplay.java | 15 +- .../minicraft/screen/WorldSelectDisplay.java | 6 +- 6 files changed, 1133 insertions(+), 115 deletions(-) create mode 100644 src/client/java/minicraft/saveload/HistoricLoad.java diff --git a/src/client/java/minicraft/core/World.java b/src/client/java/minicraft/core/World.java index 6aeb52452..a5202464c 100644 --- a/src/client/java/minicraft/core/World.java +++ b/src/client/java/minicraft/core/World.java @@ -103,7 +103,9 @@ public static void resetGame(boolean keepPlayer) { * This method is used to create a brand new world, or to load an existing one from a file. * For the loading screen updates to work, it it assumed that *this* is called by a thread *other* than the one rendering the current *menu*. **/ - public static void initWorld() { // This is a full reset; everything. + public static void initWorld() + throws Load.BackupCreationFailedException, Load.WorldLoadingFailedException, + Load.DungeonRegenerationCancelledException { // This is a full reset; everything. Logging.WORLD.debug("Resetting world..."); PlayerDeathDisplay.shouldRespawn = false; diff --git a/src/client/java/minicraft/saveload/HistoricLoad.java b/src/client/java/minicraft/saveload/HistoricLoad.java new file mode 100644 index 000000000..8cc77a118 --- /dev/null +++ b/src/client/java/minicraft/saveload/HistoricLoad.java @@ -0,0 +1,961 @@ +package minicraft.saveload; + +import minicraft.core.Game; +import minicraft.core.Updater; +import minicraft.core.World; +import minicraft.core.io.Settings; +import minicraft.entity.Entity; +import minicraft.entity.furniture.Bed; +import minicraft.entity.furniture.Chest; +import minicraft.entity.furniture.Crafter; +import minicraft.entity.furniture.DeathChest; +import minicraft.entity.furniture.DungeonChest; +import minicraft.entity.furniture.Lantern; +import minicraft.entity.furniture.Spawner; +import minicraft.entity.furniture.Tnt; +import minicraft.entity.mob.AirWizard; +import minicraft.entity.mob.Cow; +import minicraft.entity.mob.Creeper; +import minicraft.entity.mob.Knight; +import minicraft.entity.mob.Mob; +import minicraft.entity.mob.MobAi; +import minicraft.entity.mob.Pig; +import minicraft.entity.mob.Player; +import minicraft.entity.mob.Sheep; +import minicraft.entity.mob.Skeleton; +import minicraft.entity.mob.Slime; +import minicraft.entity.mob.Snake; +import minicraft.entity.mob.Zombie; +import minicraft.gfx.Color; +import minicraft.item.ArmorItem; +import minicraft.item.Inventory; +import minicraft.item.Item; +import minicraft.item.Items; +import minicraft.item.PotionItem; +import minicraft.item.PotionType; +import minicraft.item.StackableItem; +import minicraft.item.UnknownItem; +import minicraft.level.Level; +import minicraft.level.tile.Tiles; +import minicraft.util.Logging; +import org.jetbrains.annotations.Nullable; +import org.tinylog.Logger; + +import java.io.File; +import java.io.IOException; +import java.nio.file.FileAlreadyExistsException; +import java.nio.file.Files; +import java.nio.file.StandardCopyOption; +import java.util.Arrays; +import java.util.List; +import java.util.function.Predicate; +import java.util.regex.MatchResult; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** This is used for loading save files before 1.9.1. */ +@SuppressWarnings("SpellCheckingInspection") +public class HistoricLoad { + /* + * Save Structure Change History (UTC) + * + * Notes: + * - For indices, the indices are the new values when there are changes; old values if they are being removed. + * - Indices are still counted whatever the conditions of the save values are. + * - " (tail)" indicates that the data value is at the tail of the save file. + * - All save data files are saved in .miniplussave (CSV), all comma separated, tailing comma exists. + * - KeyPrefs.miniplussave here is saved in world save. + * - All save files here are saved by world instance, i.e. no global preferences. + * - In Level5 save files, there is an extra tailing comma. (seems like a mistake) + * - Although in some time periods, max armor is saved instead of armor point, it is still loaded as armor point. + * - Skin-On is an abandoned feature. It controls whether to render the player skin suits, + * which has already been removed now. + * + * Commit History + * (1.9.1) 1930f326 Apr 12, 2017 (23:30) # 1.9.1 has been released on the next day (01:53) + * - Game.miniplussave Versioning added + * b8766a33 Apr 11, 2017 (03:34) + * - Player.miniplussave (index: 13,14 (tail)) Armor values inserted (saved only when armor exists) + * - index: 13 - Armor damage buffer value + * - index: 14 - Current armor name + * 58c9922f Apr 2, 2017 (02:59) + * - Game.miniplussave (index: 3) Arrow count removed + * - Player.miniplussave (index: 5) Max armor value changed to armor value + * - Player.miniplussave (index: 7) Arrow count inserted + * - Player.miniplussave (index: 10) PotionEffects data save conditions changed + * - saved only non-empty -> always saved; saved as empty when empty + * - When empty: "PotionEffects[]" + * e0e2549b Mar 29, 2017 (22:12) + * - Player.miniplussave (index: 11 (tail)) Skin-On (boolean) inserted + * - Skin-On indicates whether skin should be rendered (preference). + * - It was a temporary in-game option. + * f95343bf Mar 24, 2017 (04:48) + * - Entities.miniplussave Spawner data (extradata index: 0) mob name changed ... + * - Value changed from class name (from class) to spawner mob name (hardcoded value property) + * - Availabilities of mob property for spawner changes; mob names here are only applicable in spawner class; + * non-mob data is set as zombie; previously, non-mob entities can be set for spawners + * - Mob names that differ from class names: AirWizardII + * The above mobs are not loaaded correctly (thus bug fix), loaded as AirWizard (I) + * 01d8e558 Mar 21, 2017 (23:26) + * - Entities.miniplussave Spawner data instance added + * - Extradata: entity name (extracted from entity class name), mob level + * 13507725 Mar 20, 2017 (10:18) + * - Entities.miniplussave DungeonChest data (extradata index: 1) is-locked: always false -> property saved + * - Key and dungeon locking feature are reimplemented + * - No effect to save structure + * d97784ce Mar 19, 2017 (11:48) + * - Player.miniplussave (index: 9) PotionEffects inserted (saved only data is non-empty) + * - Format: "PotionEffects[]" + * - Potion data is separated by ":", no tail separator is added + * - Potion data: ";