diff --git a/gradle.properties b/gradle.properties index 265f56a..24d59ec 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,7 +2,7 @@ org.gradle.jvmargs = -Xmx2G org.gradle.parallel = true org.gradle.caching = true -mod_version = 4.0.3 +mod_version = 5.2.0 target_version = 1.15.2 archives_name = antiresourcereload maven_group = me.wurgo diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 624cd74..d194b1c 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,8 +1,8 @@ [versions] minecraft = "1.15.2" yarn_mappings = "1.15.2+build.17" -fabric_loader = "0.15.7" -loom = "1.5-SNAPSHOT" +fabric_loader = "0.16.10" +loom = "1.9-SNAPSHOT" vineflower = "1.10.0-SNAPSHOT" [libraries] diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 2ea3535..7cf748e 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.6-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.11-all.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/src/main/java/me/wurgo/antiresourcereload/AntiResourceReload.java b/src/main/java/me/wurgo/antiresourcereload/AntiResourceReload.java index 0f1bc69..7cb9b7b 100644 --- a/src/main/java/me/wurgo/antiresourcereload/AntiResourceReload.java +++ b/src/main/java/me/wurgo/antiresourcereload/AntiResourceReload.java @@ -1,23 +1,26 @@ package me.wurgo.antiresourcereload; import com.google.gson.JsonElement; -import net.fabricmc.api.ModInitializer; -import net.fabricmc.loader.api.FabricLoader; import net.minecraft.loot.LootManager; import net.minecraft.loot.condition.LootConditionManager; import net.minecraft.recipe.RecipeManager; import net.minecraft.resource.ReloadableResourceManager; import net.minecraft.server.ServerAdvancementLoader; +import net.minecraft.server.command.CommandManager; import net.minecraft.server.function.CommandFunctionManager; +import net.minecraft.structure.Structure; import net.minecraft.tag.RegistryTagManager; import net.minecraft.util.Identifier; +import net.minecraft.util.UserCache; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import java.util.Collections; +import java.util.HashMap; import java.util.Map; -public class AntiResourceReload implements ModInitializer { - private static final Logger LOGGER = LogManager.getLogger(FabricLoader.getInstance().getModContainer("antiresourcereload").get().getMetadata().getName()); +public class AntiResourceReload { + private static final Logger LOGGER = LogManager.getLogger(); public static ReloadableResourceManager dataManager; public static RecipeManager recipeManager; @@ -27,14 +30,17 @@ public class AntiResourceReload implements ModInitializer { public static ServerAdvancementLoader advancementLoader; public static CommandFunctionManager commandFunctionManager; public static Map recipes; + + public static CommandManager commandManager; + + public static final Map structures = Collections.synchronizedMap(new HashMap<>()); + + public static UserCache userCache; + + public static boolean hasInitializedShapeCache; public static boolean hasSeenRecipes; - - public static void log(String message) { - LOGGER.info("[" + LOGGER.getName() + "] " + message); - } - @Override - public void onInitialize() { - log("Initializing."); + public static void log(String message) { + LOGGER.info("[AntiResourceReload] {}", message); } } diff --git a/src/main/java/me/wurgo/antiresourcereload/mixin/DefaultResourcePackMixin.java b/src/main/java/me/wurgo/antiresourcereload/mixin/DefaultResourcePackMixin.java new file mode 100644 index 0000000..6e2932f --- /dev/null +++ b/src/main/java/me/wurgo/antiresourcereload/mixin/DefaultResourcePackMixin.java @@ -0,0 +1,28 @@ +package me.wurgo.antiresourcereload.mixin; + +import com.llamalad7.mixinextras.injector.wrapmethod.WrapMethod; +import com.llamalad7.mixinextras.injector.wrapoperation.Operation; +import net.minecraft.resource.DefaultResourcePack; +import net.minecraft.resource.metadata.PackResourceMetadata; +import net.minecraft.resource.metadata.ResourceMetadataReader; +import org.jetbrains.annotations.Nullable; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Unique; + +@Mixin(DefaultResourcePack.class) +public abstract class DefaultResourcePackMixin { + @Nullable + @Unique + private static PackResourceMetadata METADATA; + + @WrapMethod(method = "parseMetadata") + private Object cacheMetadata(ResourceMetadataReader reader, Operation original) { + if (reader != PackResourceMetadata.READER) { + return original.call(reader); + } + if (METADATA == null) { + METADATA = (PackResourceMetadata) original.call(reader); + } + return METADATA; + } +} diff --git a/src/main/java/me/wurgo/antiresourcereload/mixin/IntegratedServerMixin.java b/src/main/java/me/wurgo/antiresourcereload/mixin/IntegratedServerMixin.java new file mode 100644 index 0000000..be2beba --- /dev/null +++ b/src/main/java/me/wurgo/antiresourcereload/mixin/IntegratedServerMixin.java @@ -0,0 +1,27 @@ +package me.wurgo.antiresourcereload.mixin; + +import com.llamalad7.mixinextras.injector.wrapoperation.Operation; +import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; +import me.wurgo.antiresourcereload.AntiResourceReload; +import net.minecraft.server.command.CommandManager; +import net.minecraft.server.integrated.IntegratedServer; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; + +@Mixin(IntegratedServer.class) +public abstract class IntegratedServerMixin { + + @WrapOperation( + method = "", + at = @At( + value = "NEW", + target = "(Z)Lnet/minecraft/server/command/CommandManager;" + ) + ) + private static CommandManager cacheCommandManager(boolean isDedicatedServer, Operation original) { + if (AntiResourceReload.commandManager == null) { + AntiResourceReload.commandManager = original.call(isDedicatedServer); + } + return AntiResourceReload.commandManager; + } +} diff --git a/src/main/java/me/wurgo/antiresourcereload/mixin/MinecraftClientMixin.java b/src/main/java/me/wurgo/antiresourcereload/mixin/MinecraftClientMixin.java new file mode 100644 index 0000000..32bd412 --- /dev/null +++ b/src/main/java/me/wurgo/antiresourcereload/mixin/MinecraftClientMixin.java @@ -0,0 +1,58 @@ +package me.wurgo.antiresourcereload.mixin; + +import com.llamalad7.mixinextras.injector.wrapoperation.Operation; +import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; +import com.mojang.authlib.GameProfileRepository; +import me.wurgo.antiresourcereload.AntiResourceReload; +import net.minecraft.client.MinecraftClient; +import net.minecraft.server.integrated.IntegratedServer; +import net.minecraft.util.UserCache; +import org.jetbrains.annotations.Nullable; +import org.spongepowered.asm.mixin.Mixin; +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 java.io.File; + +@Mixin(MinecraftClient.class) +public abstract class MinecraftClientMixin { + + @Shadow + @Nullable + private IntegratedServer server; + + @Inject( + method = "startIntegratedServer", + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/network/ClientConnection;connectLocal(Ljava/net/SocketAddress;)Lnet/minecraft/network/ClientConnection;" + ) + ) + private void reloadRecipes(CallbackInfo ci) { + // reloading is done when actually joining the world instead of on world creation because of SeedQueue + if (this.server != null && this.server.getRecipeManager() == AntiResourceReload.recipeManager && AntiResourceReload.hasSeenRecipes) { + ((RecipeManagerAccess) AntiResourceReload.recipeManager).antiresourcereload$apply(AntiResourceReload.recipes, null, null); + AntiResourceReload.hasSeenRecipes = false; + } + } + + @WrapOperation( + method = { + "startIntegratedServer", + "joinWorld" + }, + at = @At( + value = "NEW", + target = "(Lcom/mojang/authlib/GameProfileRepository;Ljava/io/File;)Lnet/minecraft/util/UserCache;" + ), + require = 2 + ) + private UserCache cacheUserCache(GameProfileRepository profileRepository, File cacheFile, Operation original) { + if (AntiResourceReload.userCache == null) { + AntiResourceReload.userCache = original.call(profileRepository, cacheFile); + } + return AntiResourceReload.userCache; + } +} diff --git a/src/main/java/me/wurgo/antiresourcereload/mixin/MinecraftServerMixin.java b/src/main/java/me/wurgo/antiresourcereload/mixin/MinecraftServerMixin.java index 9990884..14aadae 100644 --- a/src/main/java/me/wurgo/antiresourcereload/mixin/MinecraftServerMixin.java +++ b/src/main/java/me/wurgo/antiresourcereload/mixin/MinecraftServerMixin.java @@ -1,11 +1,16 @@ package me.wurgo.antiresourcereload.mixin; import com.google.common.collect.Lists; +import com.llamalad7.mixinextras.injector.v2.WrapWithCondition; +import com.llamalad7.mixinextras.injector.wrapoperation.Operation; +import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; import me.wurgo.antiresourcereload.AntiResourceReload; import net.minecraft.loot.LootManager; import net.minecraft.loot.condition.LootConditionManager; import net.minecraft.recipe.RecipeManager; -import net.minecraft.resource.*; +import net.minecraft.resource.ReloadableResourceManager; +import net.minecraft.resource.ResourcePackManager; +import net.minecraft.resource.ResourcePackProfile; import net.minecraft.server.MinecraftServer; import net.minecraft.server.ServerAdvancementLoader; import net.minecraft.server.function.CommandFunctionManager; @@ -17,42 +22,66 @@ import org.spongepowered.asm.mixin.Mutable; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Redirect; import java.util.List; @Mixin(MinecraftServer.class) public abstract class MinecraftServerMixin { - @Shadow protected abstract void reloadDataPacks(LevelProperties levelProperties); - @Mutable @Shadow @Final private ReloadableResourceManager dataManager; - @Mutable @Shadow @Final private RegistryTagManager tagManager; - @Mutable @Shadow @Final private LootConditionManager predicateManager; - @Mutable @Shadow @Final private RecipeManager recipeManager; - @Mutable @Shadow @Final private LootManager lootManager; - @Mutable @Shadow @Final private CommandFunctionManager commandFunctionManager; - @Mutable @Shadow @Final private ServerAdvancementLoader advancementLoader; + @Shadow + @Final + private static Logger LOGGER; - @Shadow @Final private static Logger LOGGER; - @Shadow @Final private ResourcePackManager dataPackManager; + @Shadow + @Final + private ResourcePackManager dataPackManager; - @Redirect( + @Mutable + @Shadow + @Final + private ReloadableResourceManager dataManager; + @Mutable + @Shadow + @Final + private RegistryTagManager tagManager; + @Mutable + @Shadow + @Final + private LootConditionManager predicateManager; + @Mutable + @Shadow + @Final + private RecipeManager recipeManager; + @Mutable + @Shadow + @Final + private LootManager lootManager; + @Mutable + @Shadow + @Final + private CommandFunctionManager commandFunctionManager; + @Mutable + @Shadow + @Final + private ServerAdvancementLoader advancementLoader; + + @WrapOperation( method = "loadWorldDataPacks", at = @At( value = "INVOKE", target = "Lnet/minecraft/server/MinecraftServer;reloadDataPacks(Lnet/minecraft/world/level/LevelProperties;)V" ) ) - private void antiresourcereload_cachedReload(MinecraftServer instance, LevelProperties levelProperties) { - if (levelProperties.getEnabledDataPacks().size() + levelProperties.getDisabledDataPacks().size() != 0) { + private void cachedReload(MinecraftServer server, LevelProperties properties, Operation original) { + if (!properties.getEnabledDataPacks().isEmpty() || !properties.getDisabledDataPacks().isEmpty()) { AntiResourceReload.log("Using data-packs, reloading."); - this.reloadDataPacks(levelProperties); + original.call(server, properties); return; } - + if (AntiResourceReload.dataManager == null) { AntiResourceReload.log("Cached resources unavailable, reloading & caching."); AntiResourceReload.dataManager = this.dataManager; - this.reloadDataPacks(levelProperties); + original.call(server, properties); AntiResourceReload.tagManager = this.tagManager; AntiResourceReload.predicateManager = this.predicateManager; AntiResourceReload.recipeManager = this.recipeManager; @@ -68,16 +97,13 @@ private void antiresourcereload_cachedReload(MinecraftServer instance, LevelProp this.lootManager = AntiResourceReload.lootManager; this.commandFunctionManager = AntiResourceReload.commandFunctionManager; this.advancementLoader = AntiResourceReload.advancementLoader; - if (AntiResourceReload.hasSeenRecipes) { - ((RecipeManagerAccess) this.recipeManager).invokeApply(AntiResourceReload.recipes, null, null); - } // should only be the vanilla pack // logic taken from MinecraftServer#reloadDataPacks List list = Lists.newArrayList(this.dataPackManager.getEnabledProfiles()); for (ResourcePackProfile resourcePackProfile : this.dataPackManager.getProfiles()) { - if (!levelProperties.getDisabledDataPacks().contains(resourcePackProfile.getName()) && !list.contains(resourcePackProfile)) { + if (!properties.getDisabledDataPacks().contains(resourcePackProfile.getName()) && !list.contains(resourcePackProfile)) { LOGGER.info("Found new data pack {}, loading it automatically", resourcePackProfile.getName()); resourcePackProfile.getInitialPosition().insert(list, resourcePackProfile, profile -> profile, false); } @@ -85,4 +111,19 @@ private void antiresourcereload_cachedReload(MinecraftServer instance, LevelProp this.dataPackManager.setEnabledProfiles(list); } } + + @WrapWithCondition( + method = "loadWorldDataPacks", + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/server/MinecraftServer;method_24154()V" + ) + ) + private boolean skipInitializingShapeCache(MinecraftServer server) { + if (!AntiResourceReload.hasInitializedShapeCache) { + AntiResourceReload.hasInitializedShapeCache = true; + return true; + } + return false; + } } diff --git a/src/main/java/me/wurgo/antiresourcereload/mixin/RecipeBookWidgetMixin.java b/src/main/java/me/wurgo/antiresourcereload/mixin/RecipeBookWidgetMixin.java index e1ebf70..93257dd 100644 --- a/src/main/java/me/wurgo/antiresourcereload/mixin/RecipeBookWidgetMixin.java +++ b/src/main/java/me/wurgo/antiresourcereload/mixin/RecipeBookWidgetMixin.java @@ -8,9 +8,13 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; @Mixin(RecipeBookWidget.class) -public class RecipeBookWidgetMixin { - @Inject(method = "initialize", at = @At("HEAD")) - public void antiresourcereload_updateHasSeenRecipes(CallbackInfo ci) { +public abstract class RecipeBookWidgetMixin { + + @Inject( + method = "initialize", + at = @At("HEAD") + ) + public void updateHasSeenRecipes(CallbackInfo ci) { AntiResourceReload.hasSeenRecipes = true; } } diff --git a/src/main/java/me/wurgo/antiresourcereload/mixin/RecipeManagerAccess.java b/src/main/java/me/wurgo/antiresourcereload/mixin/RecipeManagerAccess.java index e4de2e9..86d74dd 100644 --- a/src/main/java/me/wurgo/antiresourcereload/mixin/RecipeManagerAccess.java +++ b/src/main/java/me/wurgo/antiresourcereload/mixin/RecipeManagerAccess.java @@ -12,5 +12,6 @@ @Mixin(RecipeManager.class) public interface RecipeManagerAccess { - @Invoker void invokeApply(Map map, ResourceManager resourceManager, Profiler profiler); + @Invoker("apply") + void antiresourcereload$apply(Map map, ResourceManager resourceManager, Profiler profiler); } diff --git a/src/main/java/me/wurgo/antiresourcereload/mixin/RecipeManagerMixin.java b/src/main/java/me/wurgo/antiresourcereload/mixin/RecipeManagerMixin.java index 41e2f43..710b156 100644 --- a/src/main/java/me/wurgo/antiresourcereload/mixin/RecipeManagerMixin.java +++ b/src/main/java/me/wurgo/antiresourcereload/mixin/RecipeManagerMixin.java @@ -14,12 +14,13 @@ import java.util.Map; @Mixin(RecipeManager.class) -public class RecipeManagerMixin { +public abstract class RecipeManagerMixin { + @Inject( method = "apply(Ljava/util/Map;Lnet/minecraft/resource/ResourceManager;Lnet/minecraft/util/profiler/Profiler;)V", at = @At("HEAD") ) - private void antiresourcereload_setRecipes(Map map, ResourceManager resourceManager, Profiler profiler, CallbackInfo ci) { + private void setRecipes(Map map, ResourceManager resourceManager, Profiler profiler, CallbackInfo ci) { if (AntiResourceReload.dataManager != null && AntiResourceReload.recipeManager == null) { AntiResourceReload.recipes = map; } diff --git a/src/main/java/me/wurgo/antiresourcereload/mixin/StructureManagerMixin.java b/src/main/java/me/wurgo/antiresourcereload/mixin/StructureManagerMixin.java new file mode 100644 index 0000000..7b8d782 --- /dev/null +++ b/src/main/java/me/wurgo/antiresourcereload/mixin/StructureManagerMixin.java @@ -0,0 +1,38 @@ +package me.wurgo.antiresourcereload.mixin; + +import me.wurgo.antiresourcereload.AntiResourceReload; +import net.minecraft.server.MinecraftServer; +import net.minecraft.structure.Structure; +import net.minecraft.structure.StructureManager; +import net.minecraft.util.Identifier; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.ModifyArg; + +import java.util.function.Function; + +@Mixin(StructureManager.class) +public abstract class StructureManagerMixin { + @Shadow + @Final + private MinecraftServer server; + + @ModifyArg( + method = "getStructure", + at = @At( + value = "INVOKE", + target = "Ljava/util/Map;computeIfAbsent(Ljava/lang/Object;Ljava/util/function/Function;)Ljava/lang/Object;" + ), + index = 1 + ) + private Function getCachedStructure(Function function) { + return id -> { + if (AntiResourceReload.dataManager == this.server.getDataManager()) { + return AntiResourceReload.structures.computeIfAbsent(id, function); + } + return function.apply(id); + }; + } +} diff --git a/src/main/resources/antiresourcereload.mixins.json b/src/main/resources/antiresourcereload.mixins.json index cea5c20..3c9d11f 100644 --- a/src/main/resources/antiresourcereload.mixins.json +++ b/src/main/resources/antiresourcereload.mixins.json @@ -4,10 +4,14 @@ "package": "me.wurgo.antiresourcereload.mixin", "compatibilityLevel": "JAVA_8", "client": [ + "DefaultResourcePackMixin", + "IntegratedServerMixin", + "MinecraftClientMixin", "MinecraftServerMixin", "RecipeBookWidgetMixin", "RecipeManagerAccess", - "RecipeManagerMixin" + "RecipeManagerMixin", + "StructureManagerMixin" ], "injectors": { "defaultRequire": 1 diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index 306b5d8..644db99 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -9,24 +9,21 @@ ], "contributors": [ "Pixfumy", - "KingContaria", + "contaria", "Ronkzinho", "jan-leila", "VoidXWalker" ], "contact": { - "homepage": "https://github.com/wurgo" + "homepage": "https://github.com/wurgo", + "sources": "https://github.com/Minecraft-Java-Edition-Speedrunning/antiresourcereload", + "issues": "https://github.com/Minecraft-Java-Edition-Speedrunning/antiresourcereload/issues" }, "license": "MIT", "environment": "client", "mixins": [ "antiresourcereload.mixins.json" ], - "entrypoints": { - "main": [ - "me.wurgo.antiresourcereload.AntiResourceReload" - ] - }, "depends": { "minecraft": [ "1.15.x",