From 1a545b5423bf07ee2b1c6da47fe27a82373bc01e Mon Sep 17 00:00:00 2001 From: Jomar Milan Date: Tue, 21 May 2024 20:45:44 -0700 Subject: [PATCH 01/24] Upgrade to Java 21, Minecraft 1.20.5+ --- build.gradle | 2 +- gradle.properties | 4 ++-- src/main/resources/fabric.mod.json | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build.gradle b/build.gradle index 00b33b7..35bd2fc 100644 --- a/build.gradle +++ b/build.gradle @@ -30,7 +30,7 @@ processResources { } } -def targetJavaVersion = 17 +def targetJavaVersion = 21 tasks.withType(JavaCompile).configureEach { // ensure that the encoding is set to UTF-8, no matter what the system default is // this fixes some edge cases with special characters not displaying correctly diff --git a/gradle.properties b/gradle.properties index 79bcf5b..f333e3d 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,8 +2,8 @@ org.gradle.jvmargs=-Xmx1G # Fabric Properties # check these on https://fabricmc.net/develop/ -minecraft_version=1.20.3 -yarn_mappings=1.20.3+build.1 +minecraft_version=1.20.5 +yarn_mappings=1.20.5+build.1 loader_version=0.14.21 # Mod Properties mod_version=1.0.0 diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index b4a1e89..385eda4 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -23,6 +23,6 @@ ], "depends": { "fabricloader": ">=0.14.21", - "minecraft": ">=1.20.3 <1.20.5" + "minecraft": ">=1.20.5" } } From b1e2990ef3e2643f15a2b4025689c992218317bc Mon Sep 17 00:00:00 2001 From: Jomar Milan Date: Tue, 21 May 2024 20:59:45 -0700 Subject: [PATCH 02/24] Remove/deactivate DeepSource service --- .deepsource.toml | 7 ------- 1 file changed, 7 deletions(-) delete mode 100644 .deepsource.toml diff --git a/.deepsource.toml b/.deepsource.toml deleted file mode 100644 index 83170af..0000000 --- a/.deepsource.toml +++ /dev/null @@ -1,7 +0,0 @@ -version = 1 - -[[analyzers]] -name = "java" - - [analyzers.meta] - runtime_version = "17" \ No newline at end of file From 552fb93ae2a4462e85e76ceea55bb3385a8600ce Mon Sep 17 00:00:00 2001 From: Jomar Milan Date: Sun, 23 Jun 2024 23:22:04 -0700 Subject: [PATCH 03/24] Add multiple search paths --- .../client/DatapackInstallerClient.java | 16 +++++++++++----- .../mixin/CreateWorldScreenMixin.java | 19 +++++++++++++++---- 2 files changed, 26 insertions(+), 9 deletions(-) diff --git a/src/main/java/ml/unbreakinggold/datapackinstaller/client/DatapackInstallerClient.java b/src/main/java/ml/unbreakinggold/datapackinstaller/client/DatapackInstallerClient.java index 019c629..0bb5230 100644 --- a/src/main/java/ml/unbreakinggold/datapackinstaller/client/DatapackInstallerClient.java +++ b/src/main/java/ml/unbreakinggold/datapackinstaller/client/DatapackInstallerClient.java @@ -4,17 +4,23 @@ import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; import net.fabricmc.loader.api.FabricLoader; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import java.io.File; import java.nio.file.Path; @Environment(EnvType.CLIENT) public class DatapackInstallerClient implements ClientModInitializer { - public static Path globalDatapackPath; + private static final Logger LOGGER = LogManager.getLogger(DatapackInstallerClient.class); + private static final Path MAIN_PATH = FabricLoader.getInstance().getGameDir().resolve("datapacks"); + private static final Path LEGACY_PATH = FabricLoader.getInstance().getGameDir().resolve("installed_datapacks"); + public static Path[] SearchPaths = new Path[]{ MAIN_PATH, LEGACY_PATH }; + @Override public void onInitializeClient() { - globalDatapackPath = FabricLoader.getInstance().getGameDir().resolve("installed_datapacks"); - if (!globalDatapackPath.toFile().exists()) { - globalDatapackPath.toFile().mkdirs(); - } + File mainFile = MAIN_PATH.toFile(); + if (!mainFile.exists() && !mainFile.mkdirs()) + LOGGER.warn("User intervention recommended: default search path 'datapacks' could not be created."); } } diff --git a/src/main/java/ml/unbreakinggold/datapackinstaller/mixin/CreateWorldScreenMixin.java b/src/main/java/ml/unbreakinggold/datapackinstaller/mixin/CreateWorldScreenMixin.java index c3de671..4077c72 100644 --- a/src/main/java/ml/unbreakinggold/datapackinstaller/mixin/CreateWorldScreenMixin.java +++ b/src/main/java/ml/unbreakinggold/datapackinstaller/mixin/CreateWorldScreenMixin.java @@ -3,6 +3,8 @@ import ml.unbreakinggold.datapackinstaller.client.DatapackInstallerClient; import net.minecraft.client.gui.screen.world.CreateWorldScreen; import org.apache.commons.io.FileUtils; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import org.jetbrains.annotations.Nullable; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; @@ -10,20 +12,29 @@ import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import java.io.File; import java.io.IOException; import java.nio.file.Path; @Mixin(CreateWorldScreen.class) public abstract class CreateWorldScreenMixin { + private static final Logger LOGGER = LogManager.getLogger(CreateWorldScreenMixin.class); @Shadow @Nullable protected abstract Path getDataPackTempDir(); @Inject(at = @At("HEAD"), method = "openPackScreen") private void init(CallbackInfo info) { Path tempPath = this.getDataPackTempDir(); - try { - FileUtils.copyDirectory(DatapackInstallerClient.globalDatapackPath.toFile(), tempPath.toFile()); - } catch(IOException exception) { - exception.printStackTrace(); + File tempPathFile = tempPath.toFile(); + + for (Path searchPath : DatapackInstallerClient.SearchPaths) { + File searchPathFile = searchPath.toFile(); + if (!searchPathFile.exists()) continue; + + try { + FileUtils.copyDirectory(searchPathFile, tempPathFile); + } catch (IOException e) { + LOGGER.error("Could not copy from search path {}. Message: {}", searchPath, e.getMessage()); + } } } } From 93bfc02b997eb47e58f3841195412a9131e62b96 Mon Sep 17 00:00:00 2001 From: Jomar Milan Date: Mon, 24 Jun 2024 16:20:51 -0700 Subject: [PATCH 04/24] Attest build artifacts --- .builds/ubuntu.yml | 12 ------------ .github/workflows/build.yml | 20 ++++++++++++++++++-- 2 files changed, 18 insertions(+), 14 deletions(-) delete mode 100644 .builds/ubuntu.yml diff --git a/.builds/ubuntu.yml b/.builds/ubuntu.yml deleted file mode 100644 index 9fec5dd..0000000 --- a/.builds/ubuntu.yml +++ /dev/null @@ -1,12 +0,0 @@ -image: ubuntu/lts -arch: amd64 -packages: - - openjdk-17-jdk-headless -artifacts: - - datapack-installer/artifacts.tar.gz -shell: false -tasks: - - build: | - cd datapack-installer && chmod +x gradlew && ./gradlew build - - package: | - cd datapack-installer && tar -czf artifacts.tar.gz build/libs/* \ No newline at end of file diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index cb20006..59f8915 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -13,6 +13,12 @@ on: required: false type: string +permissions: + id-token: write + contents: read + attestations: write + actions: write + jobs: build: runs-on: ubuntu-latest @@ -36,8 +42,18 @@ jobs: run: chmod +x ./gradlew - name: Build run: ./gradlew build - - name: Upload artifacts + - name: Read gradle.properties + uses: madhead/read-java-properties@2.0.3 + id: properties + with: + file: gradle.properties + all: true + - name: Generate artifact attestation + uses: actions/attest-build-provenance@v1.3.2 + with: + subject-path: build/libs/${{ steps.properties.outputs.archives_base_name }}-${{ steps.properties.outputs.mod_version }}.jar + - name: Upload artifact uses: actions/upload-artifact@v3.0.0 with: name: Artifacts - path: build/libs + path: build/libs/${{ steps.properties.outputs.archives_base_name }}-${{ steps.properties.outputs.mod_version }}.jar From 76abc027cb47798aeb1692400f12c77bfbeb5da2 Mon Sep 17 00:00:00 2001 From: Jomar Milan Date: Mon, 24 Jun 2024 17:07:22 -0700 Subject: [PATCH 05/24] Use awk to determine artifact name --- .github/workflows/build.yml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 59f8915..58845bf 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -42,18 +42,18 @@ jobs: run: chmod +x ./gradlew - name: Build run: ./gradlew build - - name: Read gradle.properties - uses: madhead/read-java-properties@2.0.3 - id: properties - with: - file: gradle.properties - all: true + - name: Determine artifact name + id: name + run: | + BASE_NAME=$(awk -F '=' '/archives_base_name/ { print $2; }' gradle.properties) + VERSION=$(awk -F '=' '/mod_version/ { print $2; }' gradle.properties) + echo "name=$BASE_NAME-$VERSION.jar" >> $GITHUB_OUTPUT - name: Generate artifact attestation uses: actions/attest-build-provenance@v1.3.2 with: - subject-path: build/libs/${{ steps.properties.outputs.archives_base_name }}-${{ steps.properties.outputs.mod_version }}.jar + subject-path: build/libs/${{ steps.name.outputs.name }} - name: Upload artifact uses: actions/upload-artifact@v3.0.0 with: name: Artifacts - path: build/libs/${{ steps.properties.outputs.archives_base_name }}-${{ steps.properties.outputs.mod_version }}.jar + path: build/libs/${{ steps.name.outputs.name }} From cc973c7fda410cf6414d76477c80e7eed6a36303 Mon Sep 17 00:00:00 2001 From: Jomar Milan Date: Mon, 24 Jun 2024 17:32:57 -0700 Subject: [PATCH 06/24] Bump version --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index f333e3d..18e8db2 100644 --- a/gradle.properties +++ b/gradle.properties @@ -6,6 +6,6 @@ minecraft_version=1.20.5 yarn_mappings=1.20.5+build.1 loader_version=0.14.21 # Mod Properties -mod_version=1.0.0 +mod_version=1.1.0 maven_group=ml.unbreakinggold archives_base_name=DatapackInstaller \ No newline at end of file From 3c2a0fdab61b289454e028bf087f4dae44741dbd Mon Sep 17 00:00:00 2001 From: Jomar Milan Date: Wed, 31 Jul 2024 12:35:49 -0700 Subject: [PATCH 07/24] Build with JDK 21 --- .github/workflows/build.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 58845bf..e92eed0 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -32,10 +32,10 @@ jobs: with: ref: ${{ inputs.ref }} - uses: gradle/wrapper-validation-action@v1.0.4 - - name: Setup JDK 17 + - name: Setup JDK 21 uses: actions/setup-java@v3.11.0 with: - java-version: 17 + java-version: 21 distribution: temurin - name: Mark gradlew as an executable if: ${{ runner.os != 'Windows' }} From 97e59c3642c41c50b864f2dd3745a7eefc0c7e03 Mon Sep 17 00:00:00 2001 From: Jomar Milan Date: Wed, 31 Jul 2024 12:45:50 -0700 Subject: [PATCH 08/24] Update build workflow --- .github/workflows/build.yml | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index e92eed0..5d0539e 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -2,16 +2,15 @@ name: Build on: + pull_request: push: - pull_request: - push: - branches: - - "**" - workflow_call: - inputs: - ref: - required: false - type: string + branches: + - "**" + workflow_call: + inputs: + ref: + required: false + type: string permissions: id-token: write @@ -25,15 +24,15 @@ jobs: steps: - name: Checkout latest commit if: ${{ inputs.ref == '' }} - uses: actions/checkout@v3.5.2 + uses: actions/checkout@v4.1.7 - name: Checkout requested ref if: ${{ inputs.ref != '' }} - uses: actions/checkout@v3.5.2 + uses: actions/checkout@v4.1.7 with: ref: ${{ inputs.ref }} - - uses: gradle/wrapper-validation-action@v1.0.4 + - uses: gradle/actions/wrapper-validation@v3.5.0 - name: Setup JDK 21 - uses: actions/setup-java@v3.11.0 + uses: actions/setup-java@v4.2.1 with: java-version: 21 distribution: temurin @@ -53,7 +52,7 @@ jobs: with: subject-path: build/libs/${{ steps.name.outputs.name }} - name: Upload artifact - uses: actions/upload-artifact@v3.0.0 + uses: actions/upload-artifact@v4.3.4 with: name: Artifacts path: build/libs/${{ steps.name.outputs.name }} From e033918109e79f8534194a37b54f0d0e5329cf1e Mon Sep 17 00:00:00 2001 From: Jomar Milan Date: Wed, 31 Jul 2024 13:12:48 -0700 Subject: [PATCH 09/24] Update gradle wrapper --- gradle/wrapper/gradle-wrapper.properties | 2 +- gradlew | 0 gradlew.bat | 184 +++++++++++------------ 3 files changed, 93 insertions(+), 93 deletions(-) mode change 100644 => 100755 gradlew diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 37aef8d..171d876 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.1.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip networkTimeout=10000 zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew old mode 100644 new mode 100755 diff --git a/gradlew.bat b/gradlew.bat index 93e3f59..6689b85 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -1,92 +1,92 @@ -@rem -@rem Copyright 2015 the original author or authors. -@rem -@rem Licensed under the Apache License, Version 2.0 (the "License"); -@rem you may not use this file except in compliance with the License. -@rem You may obtain a copy of the License at -@rem -@rem https://www.apache.org/licenses/LICENSE-2.0 -@rem -@rem Unless required by applicable law or agreed to in writing, software -@rem distributed under the License is distributed on an "AS IS" BASIS, -@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -@rem See the License for the specific language governing permissions and -@rem limitations under the License. -@rem - -@if "%DEBUG%"=="" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -set DIRNAME=%~dp0 -if "%DIRNAME%"=="" set DIRNAME=. -@rem This is normally unused -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Resolve any "." and ".." in APP_HOME to make it shorter. -for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if %ERRORLEVEL% equ 0 goto execute - -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto execute - -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* - -:end -@rem End local scope for the variables with windows NT shell -if %ERRORLEVEL% equ 0 goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -set EXIT_CODE=%ERRORLEVEL% -if %EXIT_CODE% equ 0 set EXIT_CODE=1 -if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% -exit /b %EXIT_CODE% - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%"=="" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if %ERRORLEVEL% equ 0 goto execute + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if %ERRORLEVEL% equ 0 goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega From f1014d2654b5af93fca6d47a422adcc8d036a7bf Mon Sep 17 00:00:00 2001 From: Jomar Milan Date: Wed, 31 Jul 2024 21:03:18 -0700 Subject: [PATCH 10/24] Replace temporary directory with persistent directory --- .../client/DatapackInstallerClient.java | 6 +-- .../mixin/CreateWorldScreenMixin.java | 43 ++++++++++--------- 2 files changed, 26 insertions(+), 23 deletions(-) diff --git a/src/main/java/ml/unbreakinggold/datapackinstaller/client/DatapackInstallerClient.java b/src/main/java/ml/unbreakinggold/datapackinstaller/client/DatapackInstallerClient.java index 0bb5230..b087832 100644 --- a/src/main/java/ml/unbreakinggold/datapackinstaller/client/DatapackInstallerClient.java +++ b/src/main/java/ml/unbreakinggold/datapackinstaller/client/DatapackInstallerClient.java @@ -9,13 +9,13 @@ import java.io.File; import java.nio.file.Path; +import java.nio.file.Paths; @Environment(EnvType.CLIENT) public class DatapackInstallerClient implements ClientModInitializer { private static final Logger LOGGER = LogManager.getLogger(DatapackInstallerClient.class); - private static final Path MAIN_PATH = FabricLoader.getInstance().getGameDir().resolve("datapacks"); - private static final Path LEGACY_PATH = FabricLoader.getInstance().getGameDir().resolve("installed_datapacks"); - public static Path[] SearchPaths = new Path[]{ MAIN_PATH, LEGACY_PATH }; + public static final Path MAIN_PATH = FabricLoader.getInstance().getGameDir().resolve("datapacks"); + public static final Path LEGACY_PATH = FabricLoader.getInstance().getGameDir().resolve("installed_datapacks"); @Override public void onInitializeClient() { diff --git a/src/main/java/ml/unbreakinggold/datapackinstaller/mixin/CreateWorldScreenMixin.java b/src/main/java/ml/unbreakinggold/datapackinstaller/mixin/CreateWorldScreenMixin.java index 4077c72..c3a67e2 100644 --- a/src/main/java/ml/unbreakinggold/datapackinstaller/mixin/CreateWorldScreenMixin.java +++ b/src/main/java/ml/unbreakinggold/datapackinstaller/mixin/CreateWorldScreenMixin.java @@ -2,39 +2,42 @@ import ml.unbreakinggold.datapackinstaller.client.DatapackInstallerClient; import net.minecraft.client.gui.screen.world.CreateWorldScreen; -import org.apache.commons.io.FileUtils; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.jetbrains.annotations.Nullable; import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Overwrite; import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import org.spongepowered.asm.mixin.Unique; -import java.io.File; -import java.io.IOException; import java.nio.file.Path; @Mixin(CreateWorldScreen.class) public abstract class CreateWorldScreenMixin { + @Unique private static final Logger LOGGER = LogManager.getLogger(CreateWorldScreenMixin.class); - @Shadow @Nullable protected abstract Path getDataPackTempDir(); + @Shadow + @Nullable + private Path dataPackTempDir; - @Inject(at = @At("HEAD"), method = "openPackScreen") - private void init(CallbackInfo info) { - Path tempPath = this.getDataPackTempDir(); - File tempPathFile = tempPath.toFile(); + /** + * @author Jomar Milan - July 31st, 2024 - Minecraft 1.20.5 + * @reason Use persistent mod directory instead of vanilla temporary directory + */ + @Overwrite + @Nullable + private Path getDataPackTempDir() { + this.dataPackTempDir = DatapackInstallerClient.MAIN_PATH; - for (Path searchPath : DatapackInstallerClient.SearchPaths) { - File searchPathFile = searchPath.toFile(); - if (!searchPathFile.exists()) continue; + return this.dataPackTempDir; + } - try { - FileUtils.copyDirectory(searchPathFile, tempPathFile); - } catch (IOException e) { - LOGGER.error("Could not copy from search path {}. Message: {}", searchPath, e.getMessage()); - } - } + /** + * @author Jomar Milan - July 31st, 2024 - Minecraft 1.20.5 + * @reason Because dataPackTempDir is now persistent and not temporary, the directory should no longer be cleared. + */ + @Overwrite + private void clearDataPackTempDir() { + LOGGER.info("Suppressing attempt to clear data pack directory"); } } From c81a0ab4565a7ec5fc337d24e070aaf48a978d02 Mon Sep 17 00:00:00 2001 From: Jomar Milan Date: Wed, 31 Jul 2024 22:02:14 -0700 Subject: [PATCH 11/24] Migrate from installed_datapacks to datapacks fully --- .../client/DatapackInstallerClient.java | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/main/java/ml/unbreakinggold/datapackinstaller/client/DatapackInstallerClient.java b/src/main/java/ml/unbreakinggold/datapackinstaller/client/DatapackInstallerClient.java index b087832..10bd514 100644 --- a/src/main/java/ml/unbreakinggold/datapackinstaller/client/DatapackInstallerClient.java +++ b/src/main/java/ml/unbreakinggold/datapackinstaller/client/DatapackInstallerClient.java @@ -4,12 +4,13 @@ import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; import net.fabricmc.loader.api.FabricLoader; +import org.apache.commons.io.FileUtils; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import java.io.File; +import java.io.IOException; import java.nio.file.Path; -import java.nio.file.Paths; @Environment(EnvType.CLIENT) public class DatapackInstallerClient implements ClientModInitializer { @@ -20,7 +21,17 @@ public class DatapackInstallerClient implements ClientModInitializer { @Override public void onInitializeClient() { File mainFile = MAIN_PATH.toFile(); - if (!mainFile.exists() && !mainFile.mkdirs()) - LOGGER.warn("User intervention recommended: default search path 'datapacks' could not be created."); + File legacyFile = LEGACY_PATH.toFile(); + if (!mainFile.exists() && !legacyFile.exists() && legacyFile.isDirectory() && !mainFile.mkdirs()) + LOGGER.warn("User intervention recommended: default search path 'datapacks' could not be created. Please create it manually."); + + if (legacyFile.exists() && legacyFile.isDirectory()) { + try { + FileUtils.moveDirectory(legacyFile, mainFile); + LOGGER.info("Migrated from installed_datapacks to datapacks."); + } catch (IOException e) { + LOGGER.error("User intervention recommended: Failed to migrate from installed_datapacks to datapacks. Please move datapacks manually.", e); + } + } } } From 730be96e189b754e58602724e548c93f55a7308a Mon Sep 17 00:00:00 2001 From: Jomar Milan Date: Fri, 2 Aug 2024 13:56:30 -0700 Subject: [PATCH 12/24] Add new (non-functional) button to edit world screen --- .../mixin/EditWorldScreenMixin.java | 29 +++++++++++++++++++ .../resources/DatapackInstaller.mixins.json | 3 +- .../assets/datapackinstaller/lang/en_us.json | 3 ++ 3 files changed, 34 insertions(+), 1 deletion(-) create mode 100644 src/main/java/ml/unbreakinggold/datapackinstaller/mixin/EditWorldScreenMixin.java create mode 100644 src/main/resources/assets/datapackinstaller/lang/en_us.json diff --git a/src/main/java/ml/unbreakinggold/datapackinstaller/mixin/EditWorldScreenMixin.java b/src/main/java/ml/unbreakinggold/datapackinstaller/mixin/EditWorldScreenMixin.java new file mode 100644 index 0000000..fafeb1c --- /dev/null +++ b/src/main/java/ml/unbreakinggold/datapackinstaller/mixin/EditWorldScreenMixin.java @@ -0,0 +1,29 @@ +package ml.unbreakinggold.datapackinstaller.mixin; + +import net.minecraft.client.gui.screen.Screen; +import net.minecraft.client.gui.screen.world.EditWorldScreen; +import net.minecraft.client.gui.widget.ButtonWidget; +import net.minecraft.client.gui.widget.DirectionalLayoutWidget; +import net.minecraft.text.Text; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.Unique; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(EditWorldScreen.class) +public class EditWorldScreenMixin extends Screen { + @Shadow @Final private DirectionalLayoutWidget layout; + @Unique private static final Text SELECT_DATAPACKS_TEXT = Text.translatable("selectWorld.edit.datapacks"); + + protected EditWorldScreenMixin(Text title) { + super(title); + } + + @Inject(at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/widget/EmptyWidget;(II)V"), method = "") + private void addButton(CallbackInfo info) { + this.layout.add(ButtonWidget.builder(SELECT_DATAPACKS_TEXT, (button) -> {}).width(200).build()); + } +} diff --git a/src/main/resources/DatapackInstaller.mixins.json b/src/main/resources/DatapackInstaller.mixins.json index afa9356..7e0849f 100644 --- a/src/main/resources/DatapackInstaller.mixins.json +++ b/src/main/resources/DatapackInstaller.mixins.json @@ -6,7 +6,8 @@ "mixins": [ ], "client": [ - "CreateWorldScreenMixin" + "CreateWorldScreenMixin", + "EditWorldScreenMixin" ], "injectors": { "defaultRequire": 1 diff --git a/src/main/resources/assets/datapackinstaller/lang/en_us.json b/src/main/resources/assets/datapackinstaller/lang/en_us.json new file mode 100644 index 0000000..b754974 --- /dev/null +++ b/src/main/resources/assets/datapackinstaller/lang/en_us.json @@ -0,0 +1,3 @@ +{ + "selectWorld.edit.datapacks": "Select Datapacks" +} \ No newline at end of file From 6bce5b55367926bcf77fcfe4aa30c90b2a2411bb Mon Sep 17 00:00:00 2001 From: Jomar Milan Date: Fri, 2 Aug 2024 14:09:00 -0700 Subject: [PATCH 13/24] Make space on screen for button --- .../datapackinstaller/mixin/EditWorldScreenMixin.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/main/java/ml/unbreakinggold/datapackinstaller/mixin/EditWorldScreenMixin.java b/src/main/java/ml/unbreakinggold/datapackinstaller/mixin/EditWorldScreenMixin.java index fafeb1c..a3d9310 100644 --- a/src/main/java/ml/unbreakinggold/datapackinstaller/mixin/EditWorldScreenMixin.java +++ b/src/main/java/ml/unbreakinggold/datapackinstaller/mixin/EditWorldScreenMixin.java @@ -22,8 +22,11 @@ protected EditWorldScreenMixin(Text title) { super(title); } - @Inject(at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/widget/EmptyWidget;(II)V"), method = "") + @Inject(at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/widget/EmptyWidget;(II)V", ordinal = 1), method = "") private void addButton(CallbackInfo info) { this.layout.add(ButtonWidget.builder(SELECT_DATAPACKS_TEXT, (button) -> {}).width(200).build()); + + // Reduce spacing so vanilla buttons remain on screen. + this.layout.spacing(1); } } From 967bb7468203f7ab19ac31a57e4debb1cb12eeaf Mon Sep 17 00:00:00 2001 From: Jomar Milan Date: Fri, 2 Aug 2024 14:28:37 -0700 Subject: [PATCH 14/24] Make button open data pack selection screen --- .../mixin/EditWorldScreenMixin.java | 20 +++++++++++++++++-- .../assets/datapackinstaller/lang/en_us.json | 3 --- 2 files changed, 18 insertions(+), 5 deletions(-) delete mode 100644 src/main/resources/assets/datapackinstaller/lang/en_us.json diff --git a/src/main/java/ml/unbreakinggold/datapackinstaller/mixin/EditWorldScreenMixin.java b/src/main/java/ml/unbreakinggold/datapackinstaller/mixin/EditWorldScreenMixin.java index a3d9310..b46c41e 100644 --- a/src/main/java/ml/unbreakinggold/datapackinstaller/mixin/EditWorldScreenMixin.java +++ b/src/main/java/ml/unbreakinggold/datapackinstaller/mixin/EditWorldScreenMixin.java @@ -1,10 +1,18 @@ package ml.unbreakinggold.datapackinstaller.mixin; +import it.unimi.dsi.fastutil.booleans.BooleanConsumer; +import ml.unbreakinggold.datapackinstaller.client.DatapackInstallerClient; +import net.minecraft.client.MinecraftClient; import net.minecraft.client.gui.screen.Screen; +import net.minecraft.client.gui.screen.pack.PackScreen; import net.minecraft.client.gui.screen.world.EditWorldScreen; import net.minecraft.client.gui.widget.ButtonWidget; import net.minecraft.client.gui.widget.DirectionalLayoutWidget; +import net.minecraft.resource.ResourcePackManager; +import net.minecraft.resource.VanillaDataPackProvider; import net.minecraft.text.Text; +import net.minecraft.world.level.storage.LevelStorage; +import org.jetbrains.annotations.Nullable; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; @@ -16,7 +24,8 @@ @Mixin(EditWorldScreen.class) public class EditWorldScreenMixin extends Screen { @Shadow @Final private DirectionalLayoutWidget layout; - @Unique private static final Text SELECT_DATAPACKS_TEXT = Text.translatable("selectWorld.edit.datapacks"); + @Unique private static final Text SELECT_DATAPACKS_TEXT = Text.translatable("dataPack.title"); + @Unique @Nullable private ResourcePackManager packManager; protected EditWorldScreenMixin(Text title) { super(title); @@ -24,7 +33,14 @@ protected EditWorldScreenMixin(Text title) { @Inject(at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/widget/EmptyWidget;(II)V", ordinal = 1), method = "") private void addButton(CallbackInfo info) { - this.layout.add(ButtonWidget.builder(SELECT_DATAPACKS_TEXT, (button) -> {}).width(200).build()); + this.layout.add(ButtonWidget.builder(SELECT_DATAPACKS_TEXT, (button) -> { + if (this.packManager == null) { + this.packManager = VanillaDataPackProvider.createManager(DatapackInstallerClient.MAIN_PATH, client.getSymlinkFinder()); + this.packManager.scanPacks(); + } + + this.client.setScreen(new PackScreen((ResourcePackManager) this.packManager, (resourcePackManager) -> {}, DatapackInstallerClient.MAIN_PATH, Text.translatable("dataPack.title"))); + }).width(200).build()); // Reduce spacing so vanilla buttons remain on screen. this.layout.spacing(1); diff --git a/src/main/resources/assets/datapackinstaller/lang/en_us.json b/src/main/resources/assets/datapackinstaller/lang/en_us.json deleted file mode 100644 index b754974..0000000 --- a/src/main/resources/assets/datapackinstaller/lang/en_us.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "selectWorld.edit.datapacks": "Select Datapacks" -} \ No newline at end of file From ca47c5ae663c19f17a736f20dfcd3ed37c94e641 Mon Sep 17 00:00:00 2001 From: Jomar Milan Date: Fri, 2 Aug 2024 14:56:43 -0700 Subject: [PATCH 15/24] Enable previously enabled data packs from world data --- .../mixin/EditWorldScreenMixin.java | 25 ++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/src/main/java/ml/unbreakinggold/datapackinstaller/mixin/EditWorldScreenMixin.java b/src/main/java/ml/unbreakinggold/datapackinstaller/mixin/EditWorldScreenMixin.java index b46c41e..8b3e2b8 100644 --- a/src/main/java/ml/unbreakinggold/datapackinstaller/mixin/EditWorldScreenMixin.java +++ b/src/main/java/ml/unbreakinggold/datapackinstaller/mixin/EditWorldScreenMixin.java @@ -6,12 +6,16 @@ import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.gui.screen.pack.PackScreen; import net.minecraft.client.gui.screen.world.EditWorldScreen; +import net.minecraft.client.gui.screen.world.WorldCreator; import net.minecraft.client.gui.widget.ButtonWidget; import net.minecraft.client.gui.widget.DirectionalLayoutWidget; +import net.minecraft.resource.DataConfiguration; import net.minecraft.resource.ResourcePackManager; import net.minecraft.resource.VanillaDataPackProvider; import net.minecraft.text.Text; import net.minecraft.world.level.storage.LevelStorage; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import org.jetbrains.annotations.Nullable; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; @@ -21,11 +25,16 @@ import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import java.io.IOException; + @Mixin(EditWorldScreen.class) public class EditWorldScreenMixin extends Screen { @Shadow @Final private DirectionalLayoutWidget layout; + @Shadow @Final private LevelStorage.Session storageSession; + @Unique private final Logger LOGGER = LogManager.getLogger(EditWorldScreenMixin.class); @Unique private static final Text SELECT_DATAPACKS_TEXT = Text.translatable("dataPack.title"); @Unique @Nullable private ResourcePackManager packManager; + @Unique @Nullable private DataConfiguration dataConfiguration; protected EditWorldScreenMixin(Text title) { super(title); @@ -34,12 +43,26 @@ protected EditWorldScreenMixin(Text title) { @Inject(at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/widget/EmptyWidget;(II)V", ordinal = 1), method = "") private void addButton(CallbackInfo info) { this.layout.add(ButtonWidget.builder(SELECT_DATAPACKS_TEXT, (button) -> { + try { + this.dataConfiguration = this.storageSession.getLevelSummary(this.storageSession.readLevelProperties()).getLevelInfo().getDataConfiguration(); + } catch (IOException primaryException) { + LOGGER.warn("Failed to load world data from main level.dat. Attempting to load from fallback.", primaryException); + + try { + this.dataConfiguration = this.storageSession.getLevelSummary(this.storageSession.readOldLevelProperties()).getLevelInfo().getDataConfiguration(); + } catch (IOException fallbackException) { + LOGGER.error("Failed to load world data from fallback level.dat.", fallbackException); + } + } + if (this.packManager == null) { this.packManager = VanillaDataPackProvider.createManager(DatapackInstallerClient.MAIN_PATH, client.getSymlinkFinder()); this.packManager.scanPacks(); } - this.client.setScreen(new PackScreen((ResourcePackManager) this.packManager, (resourcePackManager) -> {}, DatapackInstallerClient.MAIN_PATH, Text.translatable("dataPack.title"))); + this.packManager.setEnabledProfiles(this.dataConfiguration.dataPacks().getEnabled()); + + this.client.setScreen(new PackScreen(this.packManager, (resourcePackManager) -> {}, DatapackInstallerClient.MAIN_PATH, Text.translatable("dataPack.title"))); }).width(200).build()); // Reduce spacing so vanilla buttons remain on screen. From 6670a9d0d1990368affd3f03a7505a12b7eeeea5 Mon Sep 17 00:00:00 2001 From: Jomar Milan Date: Fri, 2 Aug 2024 19:19:00 -0700 Subject: [PATCH 16/24] Get enabled data packs settings --- .../mixin/EditWorldScreenMixin.java | 25 ++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/src/main/java/ml/unbreakinggold/datapackinstaller/mixin/EditWorldScreenMixin.java b/src/main/java/ml/unbreakinggold/datapackinstaller/mixin/EditWorldScreenMixin.java index 8b3e2b8..bd4fa5d 100644 --- a/src/main/java/ml/unbreakinggold/datapackinstaller/mixin/EditWorldScreenMixin.java +++ b/src/main/java/ml/unbreakinggold/datapackinstaller/mixin/EditWorldScreenMixin.java @@ -1,5 +1,7 @@ package ml.unbreakinggold.datapackinstaller.mixin; +import com.google.common.collect.ImmutableList; +import com.mojang.datafixers.util.Pair; import it.unimi.dsi.fastutil.booleans.BooleanConsumer; import ml.unbreakinggold.datapackinstaller.client.DatapackInstallerClient; import net.minecraft.client.MinecraftClient; @@ -9,11 +11,18 @@ import net.minecraft.client.gui.screen.world.WorldCreator; import net.minecraft.client.gui.widget.ButtonWidget; import net.minecraft.client.gui.widget.DirectionalLayoutWidget; +import net.minecraft.client.world.GeneratorOptionsHolder; import net.minecraft.resource.DataConfiguration; +import net.minecraft.resource.DataPackSettings; import net.minecraft.resource.ResourcePackManager; import net.minecraft.resource.VanillaDataPackProvider; +import net.minecraft.server.SaveLoading; +import net.minecraft.server.command.CommandManager; import net.minecraft.text.Text; +import net.minecraft.world.level.LevelInfo; +import net.minecraft.world.level.LevelProperties; import net.minecraft.world.level.storage.LevelStorage; +import net.minecraft.world.level.storage.LevelSummary; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.jetbrains.annotations.Nullable; @@ -26,6 +35,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import java.io.IOException; +import java.util.List; @Mixin(EditWorldScreen.class) public class EditWorldScreenMixin extends Screen { @@ -35,6 +45,7 @@ public class EditWorldScreenMixin extends Screen { @Unique private static final Text SELECT_DATAPACKS_TEXT = Text.translatable("dataPack.title"); @Unique @Nullable private ResourcePackManager packManager; @Unique @Nullable private DataConfiguration dataConfiguration; + @Unique @Nullable private LevelSummary levelSummary; protected EditWorldScreenMixin(Text title) { super(title); @@ -44,17 +55,20 @@ protected EditWorldScreenMixin(Text title) { private void addButton(CallbackInfo info) { this.layout.add(ButtonWidget.builder(SELECT_DATAPACKS_TEXT, (button) -> { try { - this.dataConfiguration = this.storageSession.getLevelSummary(this.storageSession.readLevelProperties()).getLevelInfo().getDataConfiguration(); + this.levelSummary = this.storageSession.getLevelSummary(this.storageSession.readLevelProperties()); } catch (IOException primaryException) { LOGGER.warn("Failed to load world data from main level.dat. Attempting to load from fallback.", primaryException); try { - this.dataConfiguration = this.storageSession.getLevelSummary(this.storageSession.readOldLevelProperties()).getLevelInfo().getDataConfiguration(); + this.levelSummary = this.storageSession.getLevelSummary(this.storageSession.readOldLevelProperties()); } catch (IOException fallbackException) { LOGGER.error("Failed to load world data from fallback level.dat.", fallbackException); + return; } } + this.dataConfiguration = this.levelSummary.getLevelInfo().getDataConfiguration(); + if (this.packManager == null) { this.packManager = VanillaDataPackProvider.createManager(DatapackInstallerClient.MAIN_PATH, client.getSymlinkFinder()); this.packManager.scanPacks(); @@ -62,7 +76,12 @@ private void addButton(CallbackInfo info) { this.packManager.setEnabledProfiles(this.dataConfiguration.dataPacks().getEnabled()); - this.client.setScreen(new PackScreen(this.packManager, (resourcePackManager) -> {}, DatapackInstallerClient.MAIN_PATH, Text.translatable("dataPack.title"))); + this.client.setScreen(new PackScreen(this.packManager, (resourcePackManager) -> { + List enabledIds = ImmutableList.copyOf(resourcePackManager.getEnabledIds()); + List disabledIds = resourcePackManager.getIds().stream().filter((name) -> !enabledIds.contains(name)).collect(ImmutableList.toImmutableList()); + + this.dataConfiguration = new DataConfiguration(new DataPackSettings(enabledIds, disabledIds), this.dataConfiguration.enabledFeatures()); + }, DatapackInstallerClient.MAIN_PATH, Text.translatable("dataPack.title"))); }).width(200).build()); // Reduce spacing so vanilla buttons remain on screen. From 2801ad024a8b29f87a50a21be6278293ab0b07c7 Mon Sep 17 00:00:00 2001 From: Jomar Milan Date: Fri, 2 Aug 2024 19:46:29 -0700 Subject: [PATCH 17/24] Data pack configuration while loaded in world --- .../mixin/EditWorldScreenMixin.java | 90 ------------------- .../mixin/GameMenuScreenMixin.java | 40 +++++++++ .../resources/DatapackInstaller.mixins.json | 2 +- 3 files changed, 41 insertions(+), 91 deletions(-) delete mode 100644 src/main/java/ml/unbreakinggold/datapackinstaller/mixin/EditWorldScreenMixin.java create mode 100644 src/main/java/ml/unbreakinggold/datapackinstaller/mixin/GameMenuScreenMixin.java diff --git a/src/main/java/ml/unbreakinggold/datapackinstaller/mixin/EditWorldScreenMixin.java b/src/main/java/ml/unbreakinggold/datapackinstaller/mixin/EditWorldScreenMixin.java deleted file mode 100644 index bd4fa5d..0000000 --- a/src/main/java/ml/unbreakinggold/datapackinstaller/mixin/EditWorldScreenMixin.java +++ /dev/null @@ -1,90 +0,0 @@ -package ml.unbreakinggold.datapackinstaller.mixin; - -import com.google.common.collect.ImmutableList; -import com.mojang.datafixers.util.Pair; -import it.unimi.dsi.fastutil.booleans.BooleanConsumer; -import ml.unbreakinggold.datapackinstaller.client.DatapackInstallerClient; -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.gui.screen.Screen; -import net.minecraft.client.gui.screen.pack.PackScreen; -import net.minecraft.client.gui.screen.world.EditWorldScreen; -import net.minecraft.client.gui.screen.world.WorldCreator; -import net.minecraft.client.gui.widget.ButtonWidget; -import net.minecraft.client.gui.widget.DirectionalLayoutWidget; -import net.minecraft.client.world.GeneratorOptionsHolder; -import net.minecraft.resource.DataConfiguration; -import net.minecraft.resource.DataPackSettings; -import net.minecraft.resource.ResourcePackManager; -import net.minecraft.resource.VanillaDataPackProvider; -import net.minecraft.server.SaveLoading; -import net.minecraft.server.command.CommandManager; -import net.minecraft.text.Text; -import net.minecraft.world.level.LevelInfo; -import net.minecraft.world.level.LevelProperties; -import net.minecraft.world.level.storage.LevelStorage; -import net.minecraft.world.level.storage.LevelSummary; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.jetbrains.annotations.Nullable; -import org.spongepowered.asm.mixin.Final; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.Unique; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -import java.io.IOException; -import java.util.List; - -@Mixin(EditWorldScreen.class) -public class EditWorldScreenMixin extends Screen { - @Shadow @Final private DirectionalLayoutWidget layout; - @Shadow @Final private LevelStorage.Session storageSession; - @Unique private final Logger LOGGER = LogManager.getLogger(EditWorldScreenMixin.class); - @Unique private static final Text SELECT_DATAPACKS_TEXT = Text.translatable("dataPack.title"); - @Unique @Nullable private ResourcePackManager packManager; - @Unique @Nullable private DataConfiguration dataConfiguration; - @Unique @Nullable private LevelSummary levelSummary; - - protected EditWorldScreenMixin(Text title) { - super(title); - } - - @Inject(at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/widget/EmptyWidget;(II)V", ordinal = 1), method = "") - private void addButton(CallbackInfo info) { - this.layout.add(ButtonWidget.builder(SELECT_DATAPACKS_TEXT, (button) -> { - try { - this.levelSummary = this.storageSession.getLevelSummary(this.storageSession.readLevelProperties()); - } catch (IOException primaryException) { - LOGGER.warn("Failed to load world data from main level.dat. Attempting to load from fallback.", primaryException); - - try { - this.levelSummary = this.storageSession.getLevelSummary(this.storageSession.readOldLevelProperties()); - } catch (IOException fallbackException) { - LOGGER.error("Failed to load world data from fallback level.dat.", fallbackException); - return; - } - } - - this.dataConfiguration = this.levelSummary.getLevelInfo().getDataConfiguration(); - - if (this.packManager == null) { - this.packManager = VanillaDataPackProvider.createManager(DatapackInstallerClient.MAIN_PATH, client.getSymlinkFinder()); - this.packManager.scanPacks(); - } - - this.packManager.setEnabledProfiles(this.dataConfiguration.dataPacks().getEnabled()); - - this.client.setScreen(new PackScreen(this.packManager, (resourcePackManager) -> { - List enabledIds = ImmutableList.copyOf(resourcePackManager.getEnabledIds()); - List disabledIds = resourcePackManager.getIds().stream().filter((name) -> !enabledIds.contains(name)).collect(ImmutableList.toImmutableList()); - - this.dataConfiguration = new DataConfiguration(new DataPackSettings(enabledIds, disabledIds), this.dataConfiguration.enabledFeatures()); - }, DatapackInstallerClient.MAIN_PATH, Text.translatable("dataPack.title"))); - }).width(200).build()); - - // Reduce spacing so vanilla buttons remain on screen. - this.layout.spacing(1); - } -} diff --git a/src/main/java/ml/unbreakinggold/datapackinstaller/mixin/GameMenuScreenMixin.java b/src/main/java/ml/unbreakinggold/datapackinstaller/mixin/GameMenuScreenMixin.java new file mode 100644 index 0000000..10ebcb5 --- /dev/null +++ b/src/main/java/ml/unbreakinggold/datapackinstaller/mixin/GameMenuScreenMixin.java @@ -0,0 +1,40 @@ +package ml.unbreakinggold.datapackinstaller.mixin; + +import ml.unbreakinggold.datapackinstaller.client.DatapackInstallerClient; +import net.minecraft.client.gui.screen.GameMenuScreen; +import net.minecraft.client.gui.screen.Screen; +import net.minecraft.client.gui.screen.pack.PackScreen; +import net.minecraft.client.gui.widget.ButtonWidget; +import net.minecraft.client.gui.widget.GridWidget; +import net.minecraft.resource.ResourcePackManager; +import net.minecraft.text.Text; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.Unique; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import org.spongepowered.asm.mixin.injection.callback.LocalCapture; + +import java.util.function.Supplier; + +@Mixin(GameMenuScreen.class) +public abstract class GameMenuScreenMixin extends Screen { + @Shadow private ButtonWidget createButton(Text text, Supplier screenSupplier) { return null; }; + @Unique private static final Text DATA_PACK_TEXT = Text.translatable("dataPack.title"); + + private GameMenuScreenMixin(Text title) { + super(title); + } + + @Inject(at = @At(value = "INVOKE", target = "Lnet/minecraft/client/MinecraftClient;isInSingleplayer()Z"), method = "initWidgets", locals = LocalCapture.CAPTURE_FAILHARD) + private void onInitWidgets(CallbackInfo ci, GridWidget gridWidget, GridWidget.Adder adder) { + if (!this.client.isIntegratedServerRunning() || this.client.getServer().isRemote()) return; + + adder.add(this.createButton(DATA_PACK_TEXT, () -> { + ResourcePackManager dataPackManager = this.client.getServer().getDataPackManager(); + + return new PackScreen(dataPackManager, (manager) -> {}, DatapackInstallerClient.MAIN_PATH, DATA_PACK_TEXT); + })); + } +} diff --git a/src/main/resources/DatapackInstaller.mixins.json b/src/main/resources/DatapackInstaller.mixins.json index 7e0849f..57636c4 100644 --- a/src/main/resources/DatapackInstaller.mixins.json +++ b/src/main/resources/DatapackInstaller.mixins.json @@ -7,7 +7,7 @@ ], "client": [ "CreateWorldScreenMixin", - "EditWorldScreenMixin" + "GameMenuScreenMixin" ], "injectors": { "defaultRequire": 1 From 250d5492863482d31f7290636acfedcb3664c713 Mon Sep 17 00:00:00 2001 From: Jomar Milan Date: Fri, 2 Aug 2024 20:24:49 -0700 Subject: [PATCH 18/24] Implement enable and disable data packs in world --- .../datapackinstaller/mixin/GameMenuScreenMixin.java | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/main/java/ml/unbreakinggold/datapackinstaller/mixin/GameMenuScreenMixin.java b/src/main/java/ml/unbreakinggold/datapackinstaller/mixin/GameMenuScreenMixin.java index 10ebcb5..db40f9b 100644 --- a/src/main/java/ml/unbreakinggold/datapackinstaller/mixin/GameMenuScreenMixin.java +++ b/src/main/java/ml/unbreakinggold/datapackinstaller/mixin/GameMenuScreenMixin.java @@ -6,7 +6,6 @@ import net.minecraft.client.gui.screen.pack.PackScreen; import net.minecraft.client.gui.widget.ButtonWidget; import net.minecraft.client.gui.widget.GridWidget; -import net.minecraft.resource.ResourcePackManager; import net.minecraft.text.Text; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; @@ -16,6 +15,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.LocalCapture; +import java.util.Collection; import java.util.function.Supplier; @Mixin(GameMenuScreen.class) @@ -32,9 +32,13 @@ private void onInitWidgets(CallbackInfo ci, GridWidget gridWidget, GridWidget.Ad if (!this.client.isIntegratedServerRunning() || this.client.getServer().isRemote()) return; adder.add(this.createButton(DATA_PACK_TEXT, () -> { - ResourcePackManager dataPackManager = this.client.getServer().getDataPackManager(); + return new PackScreen(this.client.getServer().getDataPackManager(), (dataPackManager) -> { + Collection enabledProfiles = dataPackManager.getEnabledIds(); - return new PackScreen(dataPackManager, (manager) -> {}, DatapackInstallerClient.MAIN_PATH, DATA_PACK_TEXT); + this.client.getServer().reloadResources(enabledProfiles); + + this.client.setScreen(this); + }, DatapackInstallerClient.MAIN_PATH, DATA_PACK_TEXT); })); } } From 1131a60651215c94476bbc998f27025f6ab0bddf Mon Sep 17 00:00:00 2001 From: Jomar Milan Date: Fri, 2 Aug 2024 20:48:51 -0700 Subject: [PATCH 19/24] Include data packs from mod in in-world selector --- .../mixin/GameMenuScreenMixin.java | 20 ++++++++++++++++++- .../mixin/MinecraftServerAccessor.java | 12 +++++++++++ .../resources/DatapackInstaller.mixins.json | 1 + 3 files changed, 32 insertions(+), 1 deletion(-) create mode 100644 src/main/java/ml/unbreakinggold/datapackinstaller/mixin/MinecraftServerAccessor.java diff --git a/src/main/java/ml/unbreakinggold/datapackinstaller/mixin/GameMenuScreenMixin.java b/src/main/java/ml/unbreakinggold/datapackinstaller/mixin/GameMenuScreenMixin.java index db40f9b..f3c88ea 100644 --- a/src/main/java/ml/unbreakinggold/datapackinstaller/mixin/GameMenuScreenMixin.java +++ b/src/main/java/ml/unbreakinggold/datapackinstaller/mixin/GameMenuScreenMixin.java @@ -7,6 +7,10 @@ import net.minecraft.client.gui.widget.ButtonWidget; import net.minecraft.client.gui.widget.GridWidget; import net.minecraft.text.Text; +import net.minecraft.util.WorldSavePath; +import org.apache.commons.io.FileUtils; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Unique; @@ -15,14 +19,19 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.LocalCapture; +import java.io.File; +import java.io.IOException; +import java.nio.file.Path; import java.util.Collection; import java.util.function.Supplier; @Mixin(GameMenuScreen.class) public abstract class GameMenuScreenMixin extends Screen { - @Shadow private ButtonWidget createButton(Text text, Supplier screenSupplier) { return null; }; + @Unique private final Logger LOGGER = LogManager.getLogger(GameMenuScreenMixin.class); @Unique private static final Text DATA_PACK_TEXT = Text.translatable("dataPack.title"); + @Shadow private ButtonWidget createButton(Text text, Supplier screenSupplier) { return null; }; + private GameMenuScreenMixin(Text title) { super(title); } @@ -32,6 +41,15 @@ private void onInitWidgets(CallbackInfo ci, GridWidget gridWidget, GridWidget.Ad if (!this.client.isIntegratedServerRunning() || this.client.getServer().isRemote()) return; adder.add(this.createButton(DATA_PACK_TEXT, () -> { + Path worldDataPackPath = ((MinecraftServerAccessor)this.client.getServer()).getSession().getDirectory(WorldSavePath.DATAPACKS); + File modDatapackDir = DatapackInstallerClient.MAIN_PATH.toFile(); + File worldDataPackDir = worldDataPackPath.toFile(); + try { + FileUtils.copyDirectory(modDatapackDir, worldDataPackDir); + } catch(IOException exception) { + LOGGER.error("Unable to install new data packs to world. Data packs not yet seen by this world may be missing.", exception); + } + return new PackScreen(this.client.getServer().getDataPackManager(), (dataPackManager) -> { Collection enabledProfiles = dataPackManager.getEnabledIds(); diff --git a/src/main/java/ml/unbreakinggold/datapackinstaller/mixin/MinecraftServerAccessor.java b/src/main/java/ml/unbreakinggold/datapackinstaller/mixin/MinecraftServerAccessor.java new file mode 100644 index 0000000..d662416 --- /dev/null +++ b/src/main/java/ml/unbreakinggold/datapackinstaller/mixin/MinecraftServerAccessor.java @@ -0,0 +1,12 @@ +package ml.unbreakinggold.datapackinstaller.mixin; + +import net.minecraft.server.MinecraftServer; +import net.minecraft.world.level.storage.LevelStorage; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; + +@Mixin(MinecraftServer.class) +public interface MinecraftServerAccessor { + @Accessor + LevelStorage.Session getSession(); +} diff --git a/src/main/resources/DatapackInstaller.mixins.json b/src/main/resources/DatapackInstaller.mixins.json index 57636c4..d6e4a48 100644 --- a/src/main/resources/DatapackInstaller.mixins.json +++ b/src/main/resources/DatapackInstaller.mixins.json @@ -4,6 +4,7 @@ "package": "ml.unbreakinggold.datapackinstaller.mixin", "compatibilityLevel": "JAVA_17", "mixins": [ + "MinecraftServerAccessor" ], "client": [ "CreateWorldScreenMixin", From c1671d213d9899c5a2ce3bef2e080d9e322cb9ae Mon Sep 17 00:00:00 2001 From: Jomar Milan Date: Sun, 4 Aug 2024 15:17:12 -0700 Subject: [PATCH 20/24] Update Loom version and reconfigure run locations --- build.gradle | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 35bd2fc..13d67a9 100644 --- a/build.gradle +++ b/build.gradle @@ -1,5 +1,5 @@ plugins { - id 'fabric-loom' version '1.2-SNAPSHOT' + id 'fabric-loom' version '1.7-SNAPSHOT' id 'maven-publish' } @@ -76,3 +76,19 @@ publishing { // retrieving dependencies. } } + +loom { + runs { + client { + client() + + runDir = "run/client" + } + + server { + server() + + runDir = "run/server" + } + } +} \ No newline at end of file From 1c72eed22103aceb82077573f01ea4d5a1f918c5 Mon Sep 17 00:00:00 2001 From: Jomar Milan Date: Sun, 4 Aug 2024 15:18:01 -0700 Subject: [PATCH 21/24] Add server environment --- .../mixin/{ => client}/CreateWorldScreenMixin.java | 2 +- .../mixin/{ => client}/GameMenuScreenMixin.java | 3 ++- .../mixin/server/ServerMainMixin.java | 11 +++++++++++ .../server/DatapackInstallerServer.java | 12 ++++++++++++ src/main/resources/DatapackInstaller.mixins.json | 9 ++++++--- src/main/resources/fabric.mod.json | 3 +++ 6 files changed, 35 insertions(+), 5 deletions(-) rename src/main/java/ml/unbreakinggold/datapackinstaller/mixin/{ => client}/CreateWorldScreenMixin.java (96%) rename src/main/java/ml/unbreakinggold/datapackinstaller/mixin/{ => client}/GameMenuScreenMixin.java (95%) create mode 100644 src/main/java/ml/unbreakinggold/datapackinstaller/mixin/server/ServerMainMixin.java create mode 100644 src/main/java/ml/unbreakinggold/datapackinstaller/server/DatapackInstallerServer.java diff --git a/src/main/java/ml/unbreakinggold/datapackinstaller/mixin/CreateWorldScreenMixin.java b/src/main/java/ml/unbreakinggold/datapackinstaller/mixin/client/CreateWorldScreenMixin.java similarity index 96% rename from src/main/java/ml/unbreakinggold/datapackinstaller/mixin/CreateWorldScreenMixin.java rename to src/main/java/ml/unbreakinggold/datapackinstaller/mixin/client/CreateWorldScreenMixin.java index c3a67e2..fff1a2c 100644 --- a/src/main/java/ml/unbreakinggold/datapackinstaller/mixin/CreateWorldScreenMixin.java +++ b/src/main/java/ml/unbreakinggold/datapackinstaller/mixin/client/CreateWorldScreenMixin.java @@ -1,4 +1,4 @@ -package ml.unbreakinggold.datapackinstaller.mixin; +package ml.unbreakinggold.datapackinstaller.mixin.client; import ml.unbreakinggold.datapackinstaller.client.DatapackInstallerClient; import net.minecraft.client.gui.screen.world.CreateWorldScreen; diff --git a/src/main/java/ml/unbreakinggold/datapackinstaller/mixin/GameMenuScreenMixin.java b/src/main/java/ml/unbreakinggold/datapackinstaller/mixin/client/GameMenuScreenMixin.java similarity index 95% rename from src/main/java/ml/unbreakinggold/datapackinstaller/mixin/GameMenuScreenMixin.java rename to src/main/java/ml/unbreakinggold/datapackinstaller/mixin/client/GameMenuScreenMixin.java index f3c88ea..b13cda3 100644 --- a/src/main/java/ml/unbreakinggold/datapackinstaller/mixin/GameMenuScreenMixin.java +++ b/src/main/java/ml/unbreakinggold/datapackinstaller/mixin/client/GameMenuScreenMixin.java @@ -1,6 +1,7 @@ -package ml.unbreakinggold.datapackinstaller.mixin; +package ml.unbreakinggold.datapackinstaller.mixin.client; import ml.unbreakinggold.datapackinstaller.client.DatapackInstallerClient; +import ml.unbreakinggold.datapackinstaller.mixin.MinecraftServerAccessor; import net.minecraft.client.gui.screen.GameMenuScreen; import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.gui.screen.pack.PackScreen; diff --git a/src/main/java/ml/unbreakinggold/datapackinstaller/mixin/server/ServerMainMixin.java b/src/main/java/ml/unbreakinggold/datapackinstaller/mixin/server/ServerMainMixin.java new file mode 100644 index 0000000..6166f42 --- /dev/null +++ b/src/main/java/ml/unbreakinggold/datapackinstaller/mixin/server/ServerMainMixin.java @@ -0,0 +1,11 @@ +package ml.unbreakinggold.datapackinstaller.mixin.server; + +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; +import net.minecraft.server.Main; +import org.spongepowered.asm.mixin.Mixin; + +@Mixin(Main.class) +@Environment(EnvType.SERVER) +public class ServerMainMixin { +} diff --git a/src/main/java/ml/unbreakinggold/datapackinstaller/server/DatapackInstallerServer.java b/src/main/java/ml/unbreakinggold/datapackinstaller/server/DatapackInstallerServer.java new file mode 100644 index 0000000..987eced --- /dev/null +++ b/src/main/java/ml/unbreakinggold/datapackinstaller/server/DatapackInstallerServer.java @@ -0,0 +1,12 @@ +package ml.unbreakinggold.datapackinstaller.server; + +import net.fabricmc.api.DedicatedServerModInitializer; +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; + +@Environment(EnvType.SERVER) +public class DatapackInstallerServer implements DedicatedServerModInitializer { + @Override + public void onInitializeServer() { + } +} diff --git a/src/main/resources/DatapackInstaller.mixins.json b/src/main/resources/DatapackInstaller.mixins.json index d6e4a48..52ea4e7 100644 --- a/src/main/resources/DatapackInstaller.mixins.json +++ b/src/main/resources/DatapackInstaller.mixins.json @@ -7,10 +7,13 @@ "MinecraftServerAccessor" ], "client": [ - "CreateWorldScreenMixin", - "GameMenuScreenMixin" + "client.CreateWorldScreenMixin", + "client.GameMenuScreenMixin" ], "injectors": { "defaultRequire": 1 - } + }, + "server": [ + "server.ServerMainMixin" + ] } diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index 385eda4..54e7a42 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -16,6 +16,9 @@ "entrypoints": { "client": [ "ml.unbreakinggold.datapackinstaller.client.DatapackInstallerClient" + ], + "server": [ + "ml.unbreakinggold.datapackinstaller.server.DatapackInstallerServer" ] }, "mixins": [ From 85d7490d326d4e52aaf3f6193cdde7a19807fbd9 Mon Sep 17 00:00:00 2001 From: Jomar Milan Date: Sun, 4 Aug 2024 21:44:14 -0700 Subject: [PATCH 22/24] Implement server data pack installing --- gradle.properties | 2 +- .../mixin/server/ServerMainMixin.java | 29 +++++++++++++++++++ .../server/DatapackInstallerServer.java | 9 ++++++ src/main/resources/fabric.mod.json | 4 +-- 4 files changed, 41 insertions(+), 3 deletions(-) diff --git a/gradle.properties b/gradle.properties index 18e8db2..53448e1 100644 --- a/gradle.properties +++ b/gradle.properties @@ -4,7 +4,7 @@ org.gradle.jvmargs=-Xmx1G # check these on https://fabricmc.net/develop/ minecraft_version=1.20.5 yarn_mappings=1.20.5+build.1 -loader_version=0.14.21 +loader_version=0.15.0 # Mod Properties mod_version=1.1.0 maven_group=ml.unbreakinggold diff --git a/src/main/java/ml/unbreakinggold/datapackinstaller/mixin/server/ServerMainMixin.java b/src/main/java/ml/unbreakinggold/datapackinstaller/mixin/server/ServerMainMixin.java index 6166f42..cc6e90e 100644 --- a/src/main/java/ml/unbreakinggold/datapackinstaller/mixin/server/ServerMainMixin.java +++ b/src/main/java/ml/unbreakinggold/datapackinstaller/mixin/server/ServerMainMixin.java @@ -1,11 +1,40 @@ package ml.unbreakinggold.datapackinstaller.mixin.server; +import com.llamalad7.mixinextras.sugar.Local; +import ml.unbreakinggold.datapackinstaller.server.DatapackInstallerServer; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; import net.minecraft.server.Main; +import net.minecraft.util.WorldSavePath; +import net.minecraft.world.level.storage.LevelStorage; +import org.apache.commons.io.FileUtils; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Unique; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Path; @Mixin(Main.class) @Environment(EnvType.SERVER) public class ServerMainMixin { + @Unique + private static final Logger LOGGER = LogManager.getLogger(ServerMainMixin.class); + + @Inject(at = @At(value = "INVOKE", target = "Lnet/minecraft/resource/VanillaDataPackProvider;createManager(Lnet/minecraft/world/level/storage/LevelStorage$Session;)Lnet/minecraft/resource/ResourcePackManager;"), method = "main") + private static void onMain(CallbackInfo ci, @Local LevelStorage.Session session) { + Path worldDataPackPath = session.getDirectory(WorldSavePath.DATAPACKS); + File worldDataPackDir = worldDataPackPath.toFile(); + File modDataPackDir = DatapackInstallerServer.MAIN_PATH.toFile(); + try { + FileUtils.copyDirectory(modDataPackDir, worldDataPackDir); + } catch(IOException exception) { + LOGGER.error("Failed to copy data packs to the world.", exception); + } + } } diff --git a/src/main/java/ml/unbreakinggold/datapackinstaller/server/DatapackInstallerServer.java b/src/main/java/ml/unbreakinggold/datapackinstaller/server/DatapackInstallerServer.java index 987eced..a29dd94 100644 --- a/src/main/java/ml/unbreakinggold/datapackinstaller/server/DatapackInstallerServer.java +++ b/src/main/java/ml/unbreakinggold/datapackinstaller/server/DatapackInstallerServer.java @@ -3,10 +3,19 @@ import net.fabricmc.api.DedicatedServerModInitializer; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; +import net.fabricmc.loader.api.FabricLoader; + +import java.io.File; +import java.nio.file.Path; @Environment(EnvType.SERVER) public class DatapackInstallerServer implements DedicatedServerModInitializer { + public static final Path MAIN_PATH = FabricLoader.getInstance().getGameDir().resolve("datapacks"); + @Override public void onInitializeServer() { + File mainFile = MAIN_PATH.toFile(); + + if (!mainFile.exists()) mainFile.mkdirs(); } } diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index 54e7a42..204a1d1 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -12,7 +12,7 @@ }, "license": "MIT", "icon": "assets/DatapackInstaller/icon.png", - "environment": "client", + "environment": "*", "entrypoints": { "client": [ "ml.unbreakinggold.datapackinstaller.client.DatapackInstallerClient" @@ -25,7 +25,7 @@ "DatapackInstaller.mixins.json" ], "depends": { - "fabricloader": ">=0.14.21", + "fabricloader": ">=0.15.0", "minecraft": ">=1.20.5" } } From c5073431059ba06dd37fcd791a99e033606a4727 Mon Sep 17 00:00:00 2001 From: Jomar Milan Date: Sun, 4 Aug 2024 21:57:43 -0700 Subject: [PATCH 23/24] Bump major version --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 53448e1..d8248e1 100644 --- a/gradle.properties +++ b/gradle.properties @@ -6,6 +6,6 @@ minecraft_version=1.20.5 yarn_mappings=1.20.5+build.1 loader_version=0.15.0 # Mod Properties -mod_version=1.1.0 +mod_version=2.0.0 maven_group=ml.unbreakinggold archives_base_name=DatapackInstaller \ No newline at end of file From f9571ad0507f1ae5cf1c082719d2b1557e9f91ce Mon Sep 17 00:00:00 2001 From: Jomar Milan Date: Sun, 4 Aug 2024 22:13:16 -0700 Subject: [PATCH 24/24] Update README --- README.md | 55 +++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 35 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index 3998021..010c72b 100644 --- a/README.md +++ b/README.md @@ -1,27 +1,42 @@ # Datapack Installer -A Minecraft (Fabric) mod that allows you to put your datapacks in a folder and -be able to apply them at world creation without copying them to the temporary -folder or the world folder. -The mod should be installed on the client. +A Minecraft (Fabric) mod. When installed on the client, data packs put into the +data pack folder will be available for selection during world creation as well +as while paused in Singleplayer. When installed on the server, data packs put +into the data pack folder will be copied to the active world when the server +starts. -### How does it work? -It's very simple, all it does is copy the files and folders from the -installed_datapacks folder inside the game data directory to the temporary -folder for the datapack selector when creating the world. +### Advantages +On the client, this mod works with the ingame resource and data pack selector. +While creating a world, or while paused in Singleplayer, you can choose which +data packs to enable or disable with an interactive screen. -### Why should I use this over other "global datapack" mods? -This mod supports both compressed datapacks (.zip) and uncompressed datapacks -(folders), so you won't have trouble with multiple types of datapacks. You also -get to choose what datapacks to apply during world creation instead of having -all of the datapacks in the folder applied when you create the world. +On the server, all that happens is that the data packs are copied from the +mod's data pack folder to the world data pack folder whenever the server +starts. If you are switching worlds or deleting them to regenerate often, all +you will need to do is switch or delete the world, and the data packs will +carry on if you leave the mod's folder intact. + +### Disadvantages +This mod cannot keep data packs that require feature flags enabled or disabled. +For example, if you did not create a world with the built-in bundle data pack +enabled, and you enable the data pack with the mod, the data pack will only be +temporarily enabled until you quit the world. ### Usage -Step-by-step instructions to use this mod. -1. Insert your desired datapack(s) into .minecraft/installed_datapacks - 1. If you have started the game with this mod once, it should already be - in the game+launcher data directory (.minecraft). +#### Client +1. Insert your desired data pack(s) into `datapacks` in the game's data folder + 1. If you have started the game with this mod installed, it should already + be present. 2. Begin world creation 1. In the game, click Singleplayer, then click Create New World. -3. Manage datapacks - 1. Click the Data Packs button. If you've done everything correctly, the - datapacks will appear on the list on the left! + 2. Alternatively, if you already have a world, open and pause the game. +3. Manage data packs + 1. Click the Data Packs button. On later versions, you may need to check + the 'More' tab. + 2. The data packs should be available on the selector! +#### Server +1. Insert your desired data pack(s) into `datapacks` in the server data folder. + 1. This is probably the root, where eula.txt and server.properties are + located. +2. Start the server + 1. The data packs will be copied to the active world. \ No newline at end of file