From e68aa90953b334783cfba8e2a7b8c5e8e2e23e7a Mon Sep 17 00:00:00 2001 From: Suiranoil <45388086+Suiranoil@users.noreply.github.com> Date: Fri, 7 Feb 2025 18:59:40 +0300 Subject: [PATCH 01/24] Create bug_report.yaml --- .github/ISSUE_TEMPLATE/bug_report.yaml | 87 ++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/bug_report.yaml diff --git a/.github/ISSUE_TEMPLATE/bug_report.yaml b/.github/ISSUE_TEMPLATE/bug_report.yaml new file mode 100644 index 0000000..4ba4a9b --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.yaml @@ -0,0 +1,87 @@ +name: Bug Report +description: Report a bug encountered with SkinRestorer +title: "[Bug]: " +labels: ["bug"] +body: + - type: markdown + attributes: + value: | + 🐛 **Before submitting:** + - Ensure you're using the latest mod version + - Ensure this bug is reproducible consistently + - Check existing issues for duplicates + + - type: input + id: mod-version + attributes: + label: SkinRestorer Version + description: Exact version of the mod + placeholder: e.g., 2.2.1 + validations: + required: true + + - type: input + id: minecraft-version + attributes: + label: Minecraft Version + description: Full Minecraft version + placeholder: e.g., 1.21.4 + validations: + required: true + + - type: input + id: loader-version + attributes: + label: Mod Loader & Version + description: Fabric/Quilt/Forge/NeoForge version + placeholder: e.g., Fabric 0.15.7 + validations: + required: true + + - type: input + id: java-version + attributes: + label: Java Version + placeholder: e.g. 17, 21 + validations: + required: true + + - type: textarea + id: description + attributes: + label: Bug Description + description: What happened vs what you expected to happen + validations: + required: true + + - type: textarea + id: steps + attributes: + label: Reproduction Steps + placeholder: | + 1. + 2. + 3. + validations: + required: true + + - type: textarea + id: logs + attributes: + label: Relevant Logs + description: | + Please provide any relevant logs, especially error logs from your server console or `latest.log` file. + **Important**: Paste the FULL log content. Use a service like [mclo.gs](https://mclo.gs/). + render: shell + validations: + required: true + + - type: checkboxes + id: confirmations + attributes: + label: Confirmations + options: + - label: I've checked for existing issues + required: true + - label: I've tested without other mods + - label: This bug is reproducible consistently From 9f0fac4b2af67b5dfe05f60633b41e786f214131 Mon Sep 17 00:00:00 2001 From: Suiranoil <45388086+Suiranoil@users.noreply.github.com> Date: Fri, 7 Feb 2025 19:01:03 +0300 Subject: [PATCH 02/24] Create config.yml --- .github/ISSUE_TEMPLATE/config.yml | 1 + 1 file changed, 1 insertion(+) create mode 100644 .github/ISSUE_TEMPLATE/config.yml diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 0000000..3ba13e0 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1 @@ +blank_issues_enabled: false From 8ae29eae89c30b0c43db90b628932b3ff9c77542 Mon Sep 17 00:00:00 2001 From: Suiranoil <45388086+Suiranoil@users.noreply.github.com> Date: Fri, 7 Feb 2025 19:03:47 +0300 Subject: [PATCH 03/24] Update bug_report.yaml --- .github/ISSUE_TEMPLATE/bug_report.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yaml b/.github/ISSUE_TEMPLATE/bug_report.yaml index 4ba4a9b..df885b5 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yaml +++ b/.github/ISSUE_TEMPLATE/bug_report.yaml @@ -73,8 +73,8 @@ body: Please provide any relevant logs, especially error logs from your server console or `latest.log` file. **Important**: Paste the FULL log content. Use a service like [mclo.gs](https://mclo.gs/). render: shell - validations: - required: true + validations: + required: true - type: checkboxes id: confirmations From 74a571b62cce14ad01336902b97f9bdbf219475f Mon Sep 17 00:00:00 2001 From: Suiranoil <45388086+Suiranoil@users.noreply.github.com> Date: Fri, 7 Feb 2025 19:05:37 +0300 Subject: [PATCH 04/24] Update bug_report.yaml --- .github/ISSUE_TEMPLATE/bug_report.yaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yaml b/.github/ISSUE_TEMPLATE/bug_report.yaml index df885b5..0bbbc3b 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yaml +++ b/.github/ISSUE_TEMPLATE/bug_report.yaml @@ -83,5 +83,6 @@ body: options: - label: I've checked for existing issues required: true - - label: I've tested without other mods - label: This bug is reproducible consistently + required: true + - label: I've tested without other mods From 9e175ddabb519b3ccc510eadbafb78bb0debfbbc Mon Sep 17 00:00:00 2001 From: Suiranoil <45388086+Suiranoil@users.noreply.github.com> Date: Fri, 7 Feb 2025 19:09:56 +0300 Subject: [PATCH 05/24] Create feature_request.yaml --- .github/ISSUE_TEMPLATE/feature_request.yaml | 52 +++++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/feature_request.yaml diff --git a/.github/ISSUE_TEMPLATE/feature_request.yaml b/.github/ISSUE_TEMPLATE/feature_request.yaml new file mode 100644 index 0000000..2dc9e90 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.yaml @@ -0,0 +1,52 @@ +name: Feature Request +description: Suggest a new feature for SkinRestorer +title: "[Feature Request]: " +labels: ["enhancement"] +body: + - type: markdown + attributes: + value: | + 💡 **Before submitting:** + - Check existing feature requests for duplicates + - Be clear and concise + - Explain the *why* and the *how* + + - type: textarea + id: description + attributes: + label: Feature Description + description: Detailed description of the feature + validations: + required: true + + - type: textarea + id: motivation + attributes: + label: Motivation + description: Why is this feature needed? What problem does it solve? + validations: + required: true + + - type: textarea + id: use-cases + attributes: + label: Use Cases + description: How would this feature be used and who would benefit? + validations: + required: true + + - type: textarea + id: implementation-ideas + attributes: + label: Implementation Ideas (Optional) + description: Any thoughts on how it could be implemented? + validations: + required: false + + - type: checkboxes + id: confirmations + attributes: + label: Confirmations + options: + - label: I've checked for existing feature requests + required: true From d7fffdab1bf04549209c7faa04a609ce9fff0566 Mon Sep 17 00:00:00 2001 From: Suiranoil <45388086+Suiranoil@users.noreply.github.com> Date: Fri, 7 Feb 2025 19:10:32 +0300 Subject: [PATCH 06/24] Update feature_request.yaml --- .github/ISSUE_TEMPLATE/feature_request.yaml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/feature_request.yaml b/.github/ISSUE_TEMPLATE/feature_request.yaml index 2dc9e90..0e9351e 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.yaml +++ b/.github/ISSUE_TEMPLATE/feature_request.yaml @@ -16,32 +16,32 @@ body: attributes: label: Feature Description description: Detailed description of the feature - validations: - required: true + validations: + required: true - type: textarea id: motivation attributes: label: Motivation description: Why is this feature needed? What problem does it solve? - validations: - required: true + validations: + required: true - type: textarea id: use-cases attributes: label: Use Cases description: How would this feature be used and who would benefit? - validations: - required: true + validations: + required: true - type: textarea id: implementation-ideas attributes: label: Implementation Ideas (Optional) description: Any thoughts on how it could be implemented? - validations: - required: false + validations: + required: false - type: checkboxes id: confirmations From 89b06fcfc7c7a6bde4c3c732bc44b6ecea5165da Mon Sep 17 00:00:00 2001 From: Suiranoil <45388086+Suiranoil@users.noreply.github.com> Date: Fri, 7 Feb 2025 19:11:11 +0300 Subject: [PATCH 07/24] Update config.yml --- .github/ISSUE_TEMPLATE/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index 3ba13e0..0086358 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -1 +1 @@ -blank_issues_enabled: false +blank_issues_enabled: true From d04a3beecfdc7ca33f683ad5c037e58568bc4bb9 Mon Sep 17 00:00:00 2001 From: Suiranoil <45388086+Suiranoil@users.noreply.github.com> Date: Wed, 5 Mar 2025 01:14:47 +0300 Subject: [PATCH 08/24] Update README.md --- README.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 50063e2..a7b6af3 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # SkinRestorer -Modrinth -CurseForge +Modrinth +CurseForge A server-side mod for managing and restoring player skins. @@ -33,7 +33,9 @@ the [commands wiki page](https://github.com/Suiranoil/SkinRestorer/wiki/Commands If you enjoy using **SkinRestorer** and would like to support its development, you can contribute through the following platforms: -[![Ko-fi](https://ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/lionarius) +Ko-fi + +Boosty Bitcoin (BTC): `1Ndbwny8pxdnWXFgadp95fp97y5JqMJKTX` USDT (TRC20): `TGXn8wrqku5KLzwPWQAeH7wgnV4UzwHEae` From 61e1ada760cc5791686b4b77a270235df5f47eaa Mon Sep 17 00:00:00 2001 From: lionarius Date: Thu, 26 Dec 2024 21:04:10 +0300 Subject: [PATCH 09/24] add 1.21.4 to supported versions --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 64c4b05..e75b1fa 100644 --- a/gradle.properties +++ b/gradle.properties @@ -4,7 +4,7 @@ java_version=21 # Common minecraft_version=1.21 -minecraft_version_list=1.21,1.21.1,1.21.2,1.21.3 +minecraft_version_list=1.21,1.21.1,1.21.2,1.21.3,1.21.4 minecraft_version_range=[1.21, 1.22) mod_id=skinrestorer mod_name=SkinRestorer From 8081e443b96eac8fd177ec9f110f649fb1884320 Mon Sep 17 00:00:00 2001 From: lionarius Date: Fri, 7 Feb 2025 21:12:16 +0300 Subject: [PATCH 10/24] update gradle --- gradle/wrapper/gradle-wrapper.properties | 2 +- gradlew | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 9355b41..e18bc25 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.10-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.12.1-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/gradlew b/gradlew index f5feea6..f3b75f3 100644 --- a/gradlew +++ b/gradlew @@ -86,8 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s -' "$PWD" ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum From 583e59f9d88ab88c3f22b63d57c1b4d20632ab95 Mon Sep 17 00:00:00 2001 From: lionarius Date: Fri, 7 Feb 2025 21:13:27 +0300 Subject: [PATCH 11/24] update fabric loom --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index c3dc515..a0595e4 100644 --- a/build.gradle +++ b/build.gradle @@ -1,6 +1,6 @@ plugins { // see https://fabricmc.net/develop/ for new versions - id 'fabric-loom' version '1.8-SNAPSHOT' apply false + id 'fabric-loom' version '1.9-SNAPSHOT' apply false // see https://projects.neoforged.net/neoforged/neogradle for new versions id 'net.neoforged.gradle.userdev' version '7.0.153' apply false // see https://files.minecraftforge.net/net/minecraftforge/gradle/ForgeGradle/ for new versions From c81adc73206964df629b15316210427ed0d6b963 Mon Sep 17 00:00:00 2001 From: lionarius Date: Sun, 16 Feb 2025 01:42:47 +0300 Subject: [PATCH 12/24] use var in SkinCommand --- .../net/lionarius/skinrestorer/command/SkinCommand.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/common/src/main/java/net/lionarius/skinrestorer/command/SkinCommand.java b/common/src/main/java/net/lionarius/skinrestorer/command/SkinCommand.java index abd80df..8dd93ea 100644 --- a/common/src/main/java/net/lionarius/skinrestorer/command/SkinCommand.java +++ b/common/src/main/java/net/lionarius/skinrestorer/command/SkinCommand.java @@ -34,7 +34,7 @@ public final class SkinCommand { private SkinCommand() {} public static void register(CommandDispatcher dispatcher) { - LiteralArgumentBuilder base = + var base = literal("skin") .then(buildSetSubcommand("clear", SkinValue.EMPTY::toProviderContext)) .then(literal("reset") @@ -44,7 +44,7 @@ public final class SkinCommand { ))) .then(literal("refresh").executes(context -> refreshSubcommand(context.getSource()))); - LiteralArgumentBuilder set = literal("set"); + var set = literal("set"); var providers = SkinRestorer.getProvidersRegistry().getPublicProviders(); for (var entry : providers) @@ -92,7 +92,7 @@ public final class SkinCommand { Collection targets, boolean setByOperator ) { - Collection updatedPlayers = new HashSet<>(); + var updatedPlayers = new HashSet(); for (var profile : targets) { SkinValue skin = null; if (SkinRestorer.getSkinStorage().hasSavedSkin(profile.getId())) @@ -199,7 +199,7 @@ public final class SkinCommand { } private static LiteralArgumentBuilder buildSetSubcommand(String name, SkinProvider provider) { - LiteralArgumentBuilder action = literal(name); + var action = literal(name); if (provider.hasVariantSupport()) { for (SkinVariant variant : SkinVariant.values()) { From 226d3f7bcb163c07b523f7cc797612cb2e88aeae Mon Sep 17 00:00:00 2001 From: lionarius Date: Sun, 16 Feb 2025 01:48:06 +0300 Subject: [PATCH 13/24] refactor BuiltInProviderConfig to abstract class --- .../provider/BuiltInProviderConfig.java | 44 ++++++++++++++++--- .../config/provider/ElyByProviderConfig.java | 36 ++------------- .../provider/MineskinProviderConfig.java | 35 ++------------- .../config/provider/MojangProviderConfig.java | 36 ++------------- 4 files changed, 48 insertions(+), 103 deletions(-) diff --git a/common/src/main/java/net/lionarius/skinrestorer/config/provider/BuiltInProviderConfig.java b/common/src/main/java/net/lionarius/skinrestorer/config/provider/BuiltInProviderConfig.java index 198e9f1..c27e84c 100644 --- a/common/src/main/java/net/lionarius/skinrestorer/config/provider/BuiltInProviderConfig.java +++ b/common/src/main/java/net/lionarius/skinrestorer/config/provider/BuiltInProviderConfig.java @@ -1,10 +1,42 @@ package net.lionarius.skinrestorer.config.provider; -public interface BuiltInProviderConfig { +import net.lionarius.skinrestorer.SkinRestorer; +import net.lionarius.skinrestorer.util.gson.GsonPostProcessable; - boolean enabled(); - - String name(); - - CacheConfig cache(); +public abstract class BuiltInProviderConfig implements GsonPostProcessable { + protected boolean enabled; + protected String name; + protected CacheConfig cache; + + public BuiltInProviderConfig(String name, CacheConfig cache) { + this.enabled = true; + this.name = name; + this.cache = cache; + } + + public boolean enabled() { + return enabled; + } + + public String name() { + return name; + } + + public CacheConfig cache() { + return cache; + } + + protected void validate(String defaultName, CacheConfig defaultCache) { + if (this.name == null || this.name.isEmpty()) { + SkinRestorer.LOGGER.warn("Provider name is null or empty, defaulting to '{}'", defaultName); + this.name = defaultName; + } + + if (this.cache == null) { + SkinRestorer.LOGGER.warn("Provider cache is null, using default"); + this.cache = defaultCache; + } else { + this.cache.validate(defaultCache); + } + } } diff --git a/common/src/main/java/net/lionarius/skinrestorer/config/provider/ElyByProviderConfig.java b/common/src/main/java/net/lionarius/skinrestorer/config/provider/ElyByProviderConfig.java index c36caf8..e4a5dfa 100644 --- a/common/src/main/java/net/lionarius/skinrestorer/config/provider/ElyByProviderConfig.java +++ b/common/src/main/java/net/lionarius/skinrestorer/config/provider/ElyByProviderConfig.java @@ -1,46 +1,16 @@ package net.lionarius.skinrestorer.config.provider; -import net.lionarius.skinrestorer.SkinRestorer; import net.lionarius.skinrestorer.skin.provider.ElyBySkinProvider; -import net.lionarius.skinrestorer.util.gson.GsonPostProcessable; -public class ElyByProviderConfig implements BuiltInProviderConfig, GsonPostProcessable { +public final class ElyByProviderConfig extends BuiltInProviderConfig { private static final CacheConfig DEFAULT_CACHE_VALUE = new CacheConfig(true, 60); - private boolean enabled; - private String name; - private CacheConfig cache; - public ElyByProviderConfig() { - this.enabled = true; - this.name = ElyBySkinProvider.PROVIDER_NAME; - this.cache = DEFAULT_CACHE_VALUE; - } - - public boolean enabled() { - return enabled; - } - - public String name() { - return name; - } - - public CacheConfig cache() { - return cache; + super(ElyBySkinProvider.PROVIDER_NAME, DEFAULT_CACHE_VALUE); } @Override public void gsonPostProcess() { - if (this.name == null || this.name.isEmpty()) { - SkinRestorer.LOGGER.warn("Ely.By provider name is null or empty, defaulting to '{}'", ElyBySkinProvider.PROVIDER_NAME); - this.name = ElyBySkinProvider.PROVIDER_NAME; - } - - if (this.cache == null) { - SkinRestorer.LOGGER.warn("Ely.By provider cache is null, using default"); - this.cache = DEFAULT_CACHE_VALUE; - } else { - this.cache.validate(DEFAULT_CACHE_VALUE); - } + super.validate(ElyBySkinProvider.PROVIDER_NAME, DEFAULT_CACHE_VALUE); } } diff --git a/common/src/main/java/net/lionarius/skinrestorer/config/provider/MineskinProviderConfig.java b/common/src/main/java/net/lionarius/skinrestorer/config/provider/MineskinProviderConfig.java index b12ed30..ee7c05b 100644 --- a/common/src/main/java/net/lionarius/skinrestorer/config/provider/MineskinProviderConfig.java +++ b/common/src/main/java/net/lionarius/skinrestorer/config/provider/MineskinProviderConfig.java @@ -2,52 +2,25 @@ package net.lionarius.skinrestorer.config.provider; import net.lionarius.skinrestorer.SkinRestorer; import net.lionarius.skinrestorer.skin.provider.MineskinSkinProvider; -import net.lionarius.skinrestorer.util.gson.GsonPostProcessable; -public class MineskinProviderConfig implements BuiltInProviderConfig, GsonPostProcessable { +public final class MineskinProviderConfig extends BuiltInProviderConfig { private static final CacheConfig DEFAULT_CACHE_VALUE = new CacheConfig(true, 300); - private boolean enabled; - private String name; - private CacheConfig cache; private String apiKey; public MineskinProviderConfig() { - this.enabled = true; - this.name = MineskinSkinProvider.PROVIDER_NAME; - this.cache = DEFAULT_CACHE_VALUE; + super(MineskinSkinProvider.PROVIDER_NAME, DEFAULT_CACHE_VALUE); + this.apiKey = ""; } - public boolean enabled() { - return enabled; - } - - public String name() { - return name; - } - - public CacheConfig cache() { - return cache; - } - public String apiKey() { return apiKey; } @Override public void gsonPostProcess() { - if (this.name == null || this.name.isEmpty()) { - SkinRestorer.LOGGER.warn("Mineskin provider name is null or empty, defaulting to '{}'", MineskinSkinProvider.PROVIDER_NAME); - this.name = MineskinSkinProvider.PROVIDER_NAME; - } - - if (this.cache == null) { - SkinRestorer.LOGGER.warn("Mineskin cache is null, using default"); - this.cache = DEFAULT_CACHE_VALUE; - } else { - this.cache.validate(DEFAULT_CACHE_VALUE); - } + super.validate(MineskinSkinProvider.PROVIDER_NAME, DEFAULT_CACHE_VALUE); if (this.apiKey == null) { SkinRestorer.LOGGER.warn("Mineskin API key is null, defaulting to an empty string"); diff --git a/common/src/main/java/net/lionarius/skinrestorer/config/provider/MojangProviderConfig.java b/common/src/main/java/net/lionarius/skinrestorer/config/provider/MojangProviderConfig.java index 625a55e..20da780 100644 --- a/common/src/main/java/net/lionarius/skinrestorer/config/provider/MojangProviderConfig.java +++ b/common/src/main/java/net/lionarius/skinrestorer/config/provider/MojangProviderConfig.java @@ -1,46 +1,16 @@ package net.lionarius.skinrestorer.config.provider; -import net.lionarius.skinrestorer.SkinRestorer; import net.lionarius.skinrestorer.skin.provider.MojangSkinProvider; -import net.lionarius.skinrestorer.util.gson.GsonPostProcessable; -public class MojangProviderConfig implements BuiltInProviderConfig, GsonPostProcessable { +public final class MojangProviderConfig extends BuiltInProviderConfig { private static final CacheConfig DEFAULT_CACHE_VALUE = new CacheConfig(true, 60); - private boolean enabled; - private String name; - private CacheConfig cache; - public MojangProviderConfig() { - this.enabled = true; - this.name = MojangSkinProvider.PROVIDER_NAME; - this.cache = DEFAULT_CACHE_VALUE; - } - - public boolean enabled() { - return enabled; - } - - public String name() { - return name; - } - - public CacheConfig cache() { - return cache; + super(MojangSkinProvider.PROVIDER_NAME, DEFAULT_CACHE_VALUE); } @Override public void gsonPostProcess() { - if (this.name == null || this.name.isEmpty()) { - SkinRestorer.LOGGER.warn("Mojang provider name is null or empty, defaulting to '{}'", MojangSkinProvider.PROVIDER_NAME); - this.name = MojangSkinProvider.PROVIDER_NAME; - } - - if (this.cache == null) { - SkinRestorer.LOGGER.warn("Mojang provider cache is null, using default"); - this.cache = DEFAULT_CACHE_VALUE; - } else { - this.cache.validate(DEFAULT_CACHE_VALUE); - } + super.validate(MojangSkinProvider.PROVIDER_NAME, DEFAULT_CACHE_VALUE); } } From 33926b15e1aec3a4a8de9a1e29aa0d730bc35751 Mon Sep 17 00:00:00 2001 From: lionarius Date: Tue, 25 Mar 2025 20:28:03 +0300 Subject: [PATCH 14/24] add ServerUtils for scheduling server tasks --- .../skinshuffle/SkinShuffleCompatibility.java | 3 +- .../skinrestorer/util/ServerUtils.java | 37 +++++++++++++++++++ 2 files changed, 39 insertions(+), 1 deletion(-) create mode 100644 common/src/main/java/net/lionarius/skinrestorer/util/ServerUtils.java diff --git a/common/src/main/java/net/lionarius/skinrestorer/compat/skinshuffle/SkinShuffleCompatibility.java b/common/src/main/java/net/lionarius/skinrestorer/compat/skinshuffle/SkinShuffleCompatibility.java index 3b60331..3485def 100644 --- a/common/src/main/java/net/lionarius/skinrestorer/compat/skinshuffle/SkinShuffleCompatibility.java +++ b/common/src/main/java/net/lionarius/skinrestorer/compat/skinshuffle/SkinShuffleCompatibility.java @@ -5,6 +5,7 @@ import net.lionarius.skinrestorer.platform.Services; import net.lionarius.skinrestorer.skin.SkinValue; import net.lionarius.skinrestorer.skin.provider.SkinShuffleSkinProvider; import net.lionarius.skinrestorer.util.PlayerUtils; +import net.lionarius.skinrestorer.util.ServerUtils; import net.minecraft.resources.ResourceLocation; import net.minecraft.server.MinecraftServer; import net.minecraft.server.level.ServerPlayer; @@ -40,7 +41,7 @@ public class SkinShuffleCompatibility { if (!property.hasSignature()) return; - server.execute(() -> { + ServerUtils.scheduleServerTask(server, () -> { SkinRestorer.applySkin( server, Collections.singleton(player.getGameProfile()), diff --git a/common/src/main/java/net/lionarius/skinrestorer/util/ServerUtils.java b/common/src/main/java/net/lionarius/skinrestorer/util/ServerUtils.java new file mode 100644 index 0000000..a93de78 --- /dev/null +++ b/common/src/main/java/net/lionarius/skinrestorer/util/ServerUtils.java @@ -0,0 +1,37 @@ +package net.lionarius.skinrestorer.util; + +import net.minecraft.server.MinecraftServer; + +import java.util.function.Consumer; + +public class ServerUtils { + + private ServerUtils() {} + + public static void scheduleServerTask(MinecraftServer server, Consumer task) { + ServerUtils.scheduleServerTask(server, task, 0); + } + + public static void scheduleServerTask(MinecraftServer server, Runnable task) { + ServerUtils.scheduleServerTask(server, task, 0); + } + + public static void scheduleServerTask(MinecraftServer server, Consumer task, int tickDelay) { + server.execute(new ScheduledTickTask(server, task, server.getTickCount() + tickDelay)); + } + + public static void scheduleServerTask(MinecraftServer server, Runnable task, int tickDelay) { + server.execute(new ScheduledTickTask(server, _server -> task.run(), server.getTickCount() + tickDelay)); + } + + public record ScheduledTickTask(MinecraftServer server, Consumer task, + int tickTarget) implements Runnable { + @Override + public void run() { + if (this.server.getTickCount() >= this.tickTarget) + this.task.accept(this.server); + else + this.server.execute(this); + } + } +} From fee25d2d04a587b1d55bedfd438b96709726106c Mon Sep 17 00:00:00 2001 From: lionarius Date: Tue, 25 Mar 2025 20:30:22 +0300 Subject: [PATCH 15/24] gradle.properties formatting --- gradle.properties | 1 + 1 file changed, 1 insertion(+) diff --git a/gradle.properties b/gradle.properties index e75b1fa..7e890fc 100644 --- a/gradle.properties +++ b/gradle.properties @@ -17,6 +17,7 @@ license=MIT credits= description=A server-side mod for managing skins. +# Dependencies mineskin_client_version=3.0.1-SNAPSHOT # ParchmentMC mappings, see https://parchmentmc.org/docs/getting-started#choose-a-version for new versions From 8136354af116b28421b3f137278fc943c5e7893b Mon Sep 17 00:00:00 2001 From: lionarius Date: Tue, 25 Mar 2025 23:29:45 +0300 Subject: [PATCH 16/24] add skinApplyDelayOnJoin config option (fixes #47 with config) --- .../lionarius/skinrestorer/config/Config.java | 11 +++++++++++ .../skinrestorer/mixin/PlayerListMixin.java | 18 ++++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/common/src/main/java/net/lionarius/skinrestorer/config/Config.java b/common/src/main/java/net/lionarius/skinrestorer/config/Config.java index c22f6bc..d8acb49 100644 --- a/common/src/main/java/net/lionarius/skinrestorer/config/Config.java +++ b/common/src/main/java/net/lionarius/skinrestorer/config/Config.java @@ -18,6 +18,8 @@ public final class Config implements GsonPostProcessable { private boolean refreshSkinOnJoin = true; + private int skinApplyDelayOnJoin = 0; + private boolean fetchSkinOnFirstJoin = true; private FirstJoinSkinProvider firstJoinSkinProvider = FirstJoinSkinProvider.MOJANG; @@ -37,6 +39,10 @@ public final class Config implements GsonPostProcessable { return this.refreshSkinOnJoin; } + public int skinApplyDelayOnJoin() { + return this.skinApplyDelayOnJoin; + } + public boolean fetchSkinOnFirstJoin() { return this.fetchSkinOnFirstJoin; } @@ -82,6 +88,11 @@ public final class Config implements GsonPostProcessable { this.language = "en_us"; } + if (this.skinApplyDelayOnJoin < 0) { + SkinRestorer.LOGGER.warn("SkinApplyDelayOnJoin config is less than 0, defaulting to 0"); + this.skinApplyDelayOnJoin = 0; + } + if (this.firstJoinSkinProvider == null) { SkinRestorer.LOGGER.warn("FirstJoinSkinProvider config is null, defaulting to MOJANG"); this.firstJoinSkinProvider = FirstJoinSkinProvider.MOJANG; diff --git a/common/src/main/java/net/lionarius/skinrestorer/mixin/PlayerListMixin.java b/common/src/main/java/net/lionarius/skinrestorer/mixin/PlayerListMixin.java index ec1f02e..4b02ac5 100644 --- a/common/src/main/java/net/lionarius/skinrestorer/mixin/PlayerListMixin.java +++ b/common/src/main/java/net/lionarius/skinrestorer/mixin/PlayerListMixin.java @@ -1,6 +1,7 @@ package net.lionarius.skinrestorer.mixin; import net.lionarius.skinrestorer.SkinRestorer; +import net.lionarius.skinrestorer.util.ServerUtils; import net.minecraft.network.Connection; import net.minecraft.server.MinecraftServer; import net.minecraft.server.level.ServerPlayer; @@ -9,6 +10,7 @@ import net.minecraft.server.players.PlayerList; 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; @@ -39,6 +41,22 @@ public abstract class PlayerListMixin { @Inject(method = "placeNewPlayer", at = @At("HEAD")) private void placeNewPlayer(Connection connection, ServerPlayer player, CommonListenerCookie cookie, CallbackInfo ci) { + var delay = SkinRestorer.getConfig().skinApplyDelayOnJoin(); + var uuid = player.getUUID(); + + if (delay <= 0) { + skinrestorer$tryApplySkin(server, player); + } else { + ServerUtils.scheduleServerTask(server, () -> { + var actualPlayer = server.getPlayerList().getPlayer(uuid); + if (actualPlayer != null) + skinrestorer$tryApplySkin(server, actualPlayer); + }, delay); + } + } + + @Unique + private static void skinrestorer$tryApplySkin(MinecraftServer server, ServerPlayer player) { if (SkinRestorer.getSkinStorage().hasSavedSkin(player.getUUID())) SkinRestorer.applySkin(server, Collections.singleton(player.getGameProfile()), SkinRestorer.getSkinStorage().getSkin(player.getUUID())); } From ad2177848c8f74db9e465a6e06ce6b7cd823e5ac Mon Sep 17 00:00:00 2001 From: lionarius Date: Wed, 26 Mar 2025 00:54:09 +0300 Subject: [PATCH 17/24] update gradle plugin versions --- build.gradle | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/build.gradle b/build.gradle index a0595e4..c36f7e7 100644 --- a/build.gradle +++ b/build.gradle @@ -1,15 +1,15 @@ plugins { // see https://fabricmc.net/develop/ for new versions - id 'fabric-loom' version '1.9-SNAPSHOT' apply false + id 'fabric-loom' version '1.10-SNAPSHOT' apply false // see https://projects.neoforged.net/neoforged/neogradle for new versions id 'net.neoforged.gradle.userdev' version '7.0.153' apply false // see https://files.minecraftforge.net/net/minecraftforge/gradle/ForgeGradle/ for new versions - id 'net.minecraftforge.gradle' version '6.0.29' apply false + id 'net.minecraftforge.gradle' version '6.0.35' apply false id 'org.parchmentmc.librarian.forgegradle' version '1.+' apply false id 'org.spongepowered.mixin' version '0.7-SNAPSHOT' apply false - id 'me.modmuss50.mod-publish-plugin' version '0.8.1' apply false + id 'me.modmuss50.mod-publish-plugin' version '0.8.4' apply false } allprojects { From 07d620ae2fb781c8fe73ea225f90e8bf995b2136 Mon Sep 17 00:00:00 2001 From: lionarius Date: Wed, 26 Mar 2025 02:15:11 +0300 Subject: [PATCH 18/24] use moddev gradle for neoforge --- build.gradle | 4 +- .../main/groovy/multiloader-publish.gradle | 2 + forge/build.gradle | 4 +- neoforge/build.gradle | 78 ++++++++++--------- 4 files changed, 46 insertions(+), 42 deletions(-) diff --git a/build.gradle b/build.gradle index c36f7e7..36f20ad 100644 --- a/build.gradle +++ b/build.gradle @@ -1,8 +1,8 @@ plugins { // see https://fabricmc.net/develop/ for new versions id 'fabric-loom' version '1.10-SNAPSHOT' apply false - // see https://projects.neoforged.net/neoforged/neogradle for new versions - id 'net.neoforged.gradle.userdev' version '7.0.153' apply false + // see https://projects.neoforged.net/neoforged/moddevgradle for new versions + id 'net.neoforged.moddev' version '2.0.80' apply false // see https://files.minecraftforge.net/net/minecraftforge/gradle/ForgeGradle/ for new versions id 'net.minecraftforge.gradle' version '6.0.35' apply false id 'org.parchmentmc.librarian.forgegradle' version '1.+' apply false diff --git a/buildSrc/src/main/groovy/multiloader-publish.gradle b/buildSrc/src/main/groovy/multiloader-publish.gradle index f759713..8058a7a 100644 --- a/buildSrc/src/main/groovy/multiloader-publish.gradle +++ b/buildSrc/src/main/groovy/multiloader-publish.gradle @@ -5,6 +5,8 @@ plugins { publishMods { if (project.name == 'fabric') file = remapJar.archiveFile + else if (project.name == 'neoforge') + file = jar.archiveFile else file = tasks.named('jarJar').get().archiveFile diff --git a/forge/build.gradle b/forge/build.gradle index 094cc7f..3d033c9 100644 --- a/forge/build.gradle +++ b/forge/build.gradle @@ -40,7 +40,7 @@ minecraft { runs { client { - workingDirectory file('../run/client') + workingDirectory rootProject.file('run/client') ideaModule "${rootProject.name}.${project.name}.main" taskName 'Client' mods { @@ -51,7 +51,7 @@ minecraft { } server { - workingDirectory file('../run/server') + workingDirectory rootProject.file('run/server') ideaModule "${rootProject.name}.${project.name}.main" taskName 'Server' mods { diff --git a/neoforge/build.gradle b/neoforge/build.gradle index 872c927..72eb58a 100644 --- a/neoforge/build.gradle +++ b/neoforge/build.gradle @@ -3,56 +3,58 @@ plugins { id 'idea' id 'eclipse' - id 'net.neoforged.gradle.userdev' + id 'net.neoforged.moddev' id 'multiloader-publish' } -// Automatically enable neoforge AccessTransformers if the file exists -def at = project(':common').file('src/main/resources/META-INF/accesstransformer.cfg') -if (at.exists()) { - minecraft.accessTransformers.file(at) -} - -jarJar.enable() - -tasks.named('jar') { - archiveClassifier = 'thin' -} - -tasks.named('jarJar') { - archiveClassifier = '' -} - -jar.finalizedBy('jarJar') - -dependencies { - implementation "net.neoforged:neoforge:${neoforge_version}" - - implementation(jarJar(group: 'org.mineskin', name: 'java-client', version: mineskin_client_version)) { - jarJar.ranged(it, "[${mineskin_client_version},)") +neoForge { + version = neoforge_version + + // Automatically enable neoforge AccessTransformers if the file exists + def at = project(':common').file('src/main/resources/META-INF/accesstransformer.cfg') + if (at.exists()) { + minecraft.accessTransformers.file(at) } -} -subsystems { parchment { minecraftVersion = parchment_minecraft mappingsVersion = parchment_version } -} -runs { - configureEach { - modSource project.sourceSets.main - systemProperty 'neoforge.enabledGameTestNamespaces', project.mod_id + runs { + configureEach { + ideName = "NeoForge ${it.name.capitalize()} (${project.path})" // Unify the run config names with fabric + } + + client { + client() + gameDirectory = rootProject.file('run/client') + } + + server { + server() + programArgument '--nogui' + gameDirectory = rootProject.file('run/server') + } } - client { - workingDirectory = file('../run/client') - } - - server { - programArgument '--nogui' - workingDirectory = file('../run/server') + mods { + "${mod_id}" { + sourceSet sourceSets.main + } } } + +dependencies { + implementation "net.neoforged:neoforge:${neoforge_version}" + + jarJar(implementation('org.mineskin:java-client')) { + version { + strictly "[${mineskin_client_version},)" + prefer mineskin_client_version + } + } + + additionalRuntimeClasspath "org.mineskin:java-client:${mineskin_client_version}" +} From 2e3b2649b3acb730ba9e27c12219797faa901cda Mon Sep 17 00:00:00 2001 From: lionarius Date: Wed, 26 Mar 2025 02:20:42 +0300 Subject: [PATCH 19/24] update gradle.properties --- gradle.properties | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/gradle.properties b/gradle.properties index 7e890fc..7764bce 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,9 +3,9 @@ group=net.lionarius java_version=21 # Common -minecraft_version=1.21 -minecraft_version_list=1.21,1.21.1,1.21.2,1.21.3,1.21.4 -minecraft_version_range=[1.21, 1.22) +minecraft_version=1.21.5 +minecraft_version_list=1.21.5 +minecraft_version_range=[1.21.5, 1.22) mod_id=skinrestorer mod_name=SkinRestorer mod_version=2.2.1 @@ -21,22 +21,22 @@ description=A server-side mod for managing skins. mineskin_client_version=3.0.1-SNAPSHOT # ParchmentMC mappings, see https://parchmentmc.org/docs/getting-started#choose-a-version for new versions -parchment_minecraft=1.21 -parchment_version=2024.11.10 +parchment_minecraft=1.21.4 +parchment_version=2025.03.23 # Fabric, see https://fabricmc.net/develop/ for new versions fabric_loader_version=0.15.0 -fabric_api_version=0.100.1+1.21 +fabric_api_version=0.119.5+1.21.5 fabric_optional_dependencies=fabric-api # Forge, see https://files.minecraftforge.net/net/minecraftforge/forge/ for new versions -forge_version=51.0.0 -forge_loader_version_range=[51,) +forge_version=55.0.0 +forge_loader_version_range=[55,) # Forge sometimes skips minor minecraft versions (like 1.20.5) -forge_minecraft_version=1.21 +forge_minecraft_version=1.21.5 # NeoForge, see https://projects.neoforged.net/neoforged/neoforge for new versions -neoforge_version=21.0.0-beta +neoforge_version=21.5.0-beta neoforge_loader_version_range=[4,) # Publishing From 516601a8998095965ddd0828ac50dd32391c9f57 Mon Sep 17 00:00:00 2001 From: lionarius Date: Wed, 26 Mar 2025 02:21:27 +0300 Subject: [PATCH 20/24] fix GameProfileRepository interface impl --- .../skin/provider/MojangSkinProvider.java | 23 +++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/common/src/main/java/net/lionarius/skinrestorer/skin/provider/MojangSkinProvider.java b/common/src/main/java/net/lionarius/skinrestorer/skin/provider/MojangSkinProvider.java index 5d902a9..e20f5eb 100644 --- a/common/src/main/java/net/lionarius/skinrestorer/skin/provider/MojangSkinProvider.java +++ b/common/src/main/java/net/lionarius/skinrestorer/skin/provider/MojangSkinProvider.java @@ -5,6 +5,8 @@ import com.google.common.cache.CacheLoader; import com.google.common.cache.LoadingCache; import com.google.common.util.concurrent.UncheckedExecutionException; import com.mojang.authlib.GameProfile; +import com.mojang.authlib.GameProfileRepository; +import com.mojang.authlib.ProfileLookupCallback; import com.mojang.authlib.properties.Property; import com.mojang.authlib.yggdrasil.response.MinecraftProfilePropertiesResponse; import com.mojang.util.UndashedUuid; @@ -46,13 +48,26 @@ public final class MojangSkinProvider implements SkinProvider { throw new IllegalArgumentException(e); } - PROFILE_CACHE = new GameProfileCache((names, callback) -> { - for (var name : names) { + PROFILE_CACHE = new GameProfileCache(new GameProfileRepository() { + @Override + public void findProfilesByNames(String[] names, ProfileLookupCallback callback) { + for (var name : names) { + try { + var profile = MojangSkinProvider.getProfile(name); + callback.onProfileLookupSucceeded(profile); + } catch (IOException e) { + callback.onProfileLookupFailed(name, e); + } + } + } + + @Override + public Optional findProfileByName(String name) { try { var profile = MojangSkinProvider.getProfile(name); - callback.onProfileLookupSucceeded(profile); + return Optional.of(profile); } catch (IOException e) { - callback.onProfileLookupFailed(name, e); + return Optional.empty(); } } }, SkinRestorer.getConfigDir().resolve(PROFILE_CACHE_FILENAME).toFile()); From 3971f2efbf8f207c68f52fe9b4a13fa21a2dad4e Mon Sep 17 00:00:00 2001 From: lionarius Date: Wed, 26 Mar 2025 02:26:25 +0300 Subject: [PATCH 21/24] Revert "fix GameProfileRepository interface impl" This reverts commit 516601a8998095965ddd0828ac50dd32391c9f57. --- .../skin/provider/MojangSkinProvider.java | 23 ++++--------------- 1 file changed, 4 insertions(+), 19 deletions(-) diff --git a/common/src/main/java/net/lionarius/skinrestorer/skin/provider/MojangSkinProvider.java b/common/src/main/java/net/lionarius/skinrestorer/skin/provider/MojangSkinProvider.java index e20f5eb..5d902a9 100644 --- a/common/src/main/java/net/lionarius/skinrestorer/skin/provider/MojangSkinProvider.java +++ b/common/src/main/java/net/lionarius/skinrestorer/skin/provider/MojangSkinProvider.java @@ -5,8 +5,6 @@ import com.google.common.cache.CacheLoader; import com.google.common.cache.LoadingCache; import com.google.common.util.concurrent.UncheckedExecutionException; import com.mojang.authlib.GameProfile; -import com.mojang.authlib.GameProfileRepository; -import com.mojang.authlib.ProfileLookupCallback; import com.mojang.authlib.properties.Property; import com.mojang.authlib.yggdrasil.response.MinecraftProfilePropertiesResponse; import com.mojang.util.UndashedUuid; @@ -48,26 +46,13 @@ public final class MojangSkinProvider implements SkinProvider { throw new IllegalArgumentException(e); } - PROFILE_CACHE = new GameProfileCache(new GameProfileRepository() { - @Override - public void findProfilesByNames(String[] names, ProfileLookupCallback callback) { - for (var name : names) { - try { - var profile = MojangSkinProvider.getProfile(name); - callback.onProfileLookupSucceeded(profile); - } catch (IOException e) { - callback.onProfileLookupFailed(name, e); - } - } - } - - @Override - public Optional findProfileByName(String name) { + PROFILE_CACHE = new GameProfileCache((names, callback) -> { + for (var name : names) { try { var profile = MojangSkinProvider.getProfile(name); - return Optional.of(profile); + callback.onProfileLookupSucceeded(profile); } catch (IOException e) { - return Optional.empty(); + callback.onProfileLookupFailed(name, e); } } }, SkinRestorer.getConfigDir().resolve(PROFILE_CACHE_FILENAME).toFile()); From 2293fc239999a8cb19b2e444a8799304c4734c07 Mon Sep 17 00:00:00 2001 From: lionarius Date: Wed, 26 Mar 2025 02:26:26 +0300 Subject: [PATCH 22/24] Revert "update gradle.properties" This reverts commit 2e3b2649b3acb730ba9e27c12219797faa901cda. --- gradle.properties | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/gradle.properties b/gradle.properties index 7764bce..7e890fc 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,9 +3,9 @@ group=net.lionarius java_version=21 # Common -minecraft_version=1.21.5 -minecraft_version_list=1.21.5 -minecraft_version_range=[1.21.5, 1.22) +minecraft_version=1.21 +minecraft_version_list=1.21,1.21.1,1.21.2,1.21.3,1.21.4 +minecraft_version_range=[1.21, 1.22) mod_id=skinrestorer mod_name=SkinRestorer mod_version=2.2.1 @@ -21,22 +21,22 @@ description=A server-side mod for managing skins. mineskin_client_version=3.0.1-SNAPSHOT # ParchmentMC mappings, see https://parchmentmc.org/docs/getting-started#choose-a-version for new versions -parchment_minecraft=1.21.4 -parchment_version=2025.03.23 +parchment_minecraft=1.21 +parchment_version=2024.11.10 # Fabric, see https://fabricmc.net/develop/ for new versions fabric_loader_version=0.15.0 -fabric_api_version=0.119.5+1.21.5 +fabric_api_version=0.100.1+1.21 fabric_optional_dependencies=fabric-api # Forge, see https://files.minecraftforge.net/net/minecraftforge/forge/ for new versions -forge_version=55.0.0 -forge_loader_version_range=[55,) +forge_version=51.0.0 +forge_loader_version_range=[51,) # Forge sometimes skips minor minecraft versions (like 1.20.5) -forge_minecraft_version=1.21.5 +forge_minecraft_version=1.21 # NeoForge, see https://projects.neoforged.net/neoforged/neoforge for new versions -neoforge_version=21.5.0-beta +neoforge_version=21.0.0-beta neoforge_loader_version_range=[4,) # Publishing From 5d28269b94e29505ff9225e88dad6c694b8a16ab Mon Sep 17 00:00:00 2001 From: lionarius Date: Wed, 26 Mar 2025 02:31:16 +0300 Subject: [PATCH 23/24] pin max 1.21 version --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 7e890fc..ee7c50c 100644 --- a/gradle.properties +++ b/gradle.properties @@ -5,7 +5,7 @@ java_version=21 # Common minecraft_version=1.21 minecraft_version_list=1.21,1.21.1,1.21.2,1.21.3,1.21.4 -minecraft_version_range=[1.21, 1.22) +minecraft_version_range=[1.21, 1.21.4] mod_id=skinrestorer mod_name=SkinRestorer mod_version=2.2.1 From d85942041b4085395754fc94ce9ea26c52bed675 Mon Sep 17 00:00:00 2001 From: lionarius Date: Wed, 26 Mar 2025 02:38:18 +0300 Subject: [PATCH 24/24] drop neoforge 1.20.5-6 support --- settings.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/settings.gradle b/settings.gradle index a5ff64a..bf949e5 100644 --- a/settings.gradle +++ b/settings.gradle @@ -71,4 +71,4 @@ rootProject.name = 'skin-restorer' include('common') include('fabric') include('forge') -include('neoforge') +//include('neoforge')