From 0e9d024c5d4764aba604f5baeffe785193043ef9 Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Wed, 20 Mar 2024 10:18:45 -0400 Subject: [PATCH 1/7] Do not treat invalid ModelResourceLocations as top-level when baking dynamic models Related: #379 --- .../ModelBakerImplMixin.java | 21 +++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/fabric/src/main/java/org/embeddedt/modernfix/fabric/mixin/perf/dynamic_resources/ModelBakerImplMixin.java b/fabric/src/main/java/org/embeddedt/modernfix/fabric/mixin/perf/dynamic_resources/ModelBakerImplMixin.java index 9ed0bd79..43c86168 100644 --- a/fabric/src/main/java/org/embeddedt/modernfix/fabric/mixin/perf/dynamic_resources/ModelBakerImplMixin.java +++ b/fabric/src/main/java/org/embeddedt/modernfix/fabric/mixin/perf/dynamic_resources/ModelBakerImplMixin.java @@ -1,5 +1,6 @@ package org.embeddedt.modernfix.fabric.mixin.perf.dynamic_resources; +import com.google.common.collect.ImmutableList; import com.llamalad7.mixinextras.injector.wrapoperation.Operation; import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; import net.fabricmc.loader.api.FabricLoader; @@ -75,9 +76,19 @@ public abstract class ModelBakerImplMixin implements IExtendedModelBaker { synchronized (this.field_40571) { /* to emulate vanilla model loading, treat as top-level */ Optional blockOpt = Objects.equals(((ModelResourceLocation)arg).getVariant(), "inventory") ? Optional.empty() : BuiltInRegistries.BLOCK.getOptional(new ResourceLocation(arg.getNamespace(), arg.getPath())); + boolean invalidMRL = false; if(blockOpt.isPresent()) { /* load via lambda for mods that expect blockstate to get loaded */ - for(BlockState state : extendedBakery.getBlockStatesForMRL(blockOpt.get().getStateDefinition(), (ModelResourceLocation)arg)) { + ImmutableList states; + try { + states = extendedBakery.getBlockStatesForMRL(blockOpt.get().getStateDefinition(), (ModelResourceLocation)arg); + } catch(RuntimeException e) { + states = ImmutableList.of(); + invalidMRL = true; + // Fall back to getModel + cir.setReturnValue(this.field_40571.getModel(arg)); + } + for(BlockState state : states) { try { blockStateLoaderHandle.invokeExact(this.field_40571, state); } catch(Throwable e) { @@ -87,9 +98,11 @@ public abstract class ModelBakerImplMixin implements IExtendedModelBaker { } else { this.field_40571.loadTopLevel((ModelResourceLocation)arg); } - cir.setReturnValue(this.field_40571.topLevelModels.getOrDefault(arg, extendedBakery.mfix$getUnbakedMissingModel())); - // avoid leaks - this.field_40571.topLevelModels.clear(); + if(!invalidMRL) { + cir.setReturnValue(this.field_40571.topLevelModels.getOrDefault(arg, extendedBakery.mfix$getUnbakedMissingModel())); + // avoid leaks + this.field_40571.topLevelModels.clear(); + } } } else cir.setReturnValue(this.field_40571.getModel(arg)); From e1ff64785ed747d33af3067c985cebe82cf7a0c8 Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Wed, 20 Mar 2024 14:00:23 -0400 Subject: [PATCH 2/7] Fix "Illegal prefix" error in log when custom class/resource locators are in use --- .../platform/forge/ModernFixPlatformHooksImpl.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/forge/src/main/java/org/embeddedt/modernfix/platform/forge/ModernFixPlatformHooksImpl.java b/forge/src/main/java/org/embeddedt/modernfix/platform/forge/ModernFixPlatformHooksImpl.java index 25aa714c..b9c3fe2b 100644 --- a/forge/src/main/java/org/embeddedt/modernfix/platform/forge/ModernFixPlatformHooksImpl.java +++ b/forge/src/main/java/org/embeddedt/modernfix/platform/forge/ModernFixPlatformHooksImpl.java @@ -55,6 +55,7 @@ import java.nio.file.Path; import java.util.Enumeration; import java.util.Map; import java.util.Optional; +import java.util.Set; import java.util.function.Consumer; import java.util.function.Function; @@ -214,6 +215,12 @@ public class ModernFixPlatformHooksImpl implements ModernFixPlatformHooks { Field serviceLookupField = servicesHandler.getClass().getDeclaredField("serviceLookup"); serviceLookupField.setAccessible(true); Map serviceLookup = (Map)serviceLookupField.get(servicesHandler); + for(String s : new String[] { "classPrefixes", "resourceNames" }) { + // Reset cache fields to avoid class prefixes, etc. being falsely flagged + Field cacheField = TransformationServiceDecorator.class.getDeclaredField(s); + cacheField.setAccessible(true); + ((Set)cacheField.get(null)).clear(); + } Method getClassLoaderMethod = TransformationServiceDecorator.class.getDeclaredMethod("getClassLoader"); getClassLoaderMethod.setAccessible(true); Function> resourceEnumeratorLocator = ModernFixResourceFinder::findAllURLsForResource; From bf74ab5a80375db6143660bc64864d912c9c7024 Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Wed, 20 Mar 2024 14:40:42 -0400 Subject: [PATCH 3/7] Mitigate excessive resource usage from Night Config --- .../config/NightConfigWatchThrottler.java | 56 +++++++++++++++++++ .../forge/ModernFixPlatformHooksImpl.java | 2 + 2 files changed, 58 insertions(+) create mode 100644 forge/src/main/java/org/embeddedt/modernfix/forge/config/NightConfigWatchThrottler.java diff --git a/forge/src/main/java/org/embeddedt/modernfix/forge/config/NightConfigWatchThrottler.java b/forge/src/main/java/org/embeddedt/modernfix/forge/config/NightConfigWatchThrottler.java new file mode 100644 index 00000000..ae75e00f --- /dev/null +++ b/forge/src/main/java/org/embeddedt/modernfix/forge/config/NightConfigWatchThrottler.java @@ -0,0 +1,56 @@ +package org.embeddedt.modernfix.forge.config; + +import com.electronwill.nightconfig.core.file.FileWatcher; +import com.google.common.collect.ForwardingCollection; +import com.google.common.collect.ForwardingMap; +import net.minecraftforge.fml.common.ObfuscationReflectionHelper; + +import java.util.Collection; +import java.util.Iterator; +import java.util.Map; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.locks.LockSupport; + +/** + * Throttle NightConfig's file watching. There are reports of this consuming excessive CPU time + * (example) and the spammed iterator calls + * end up being 10% of allocations when testing in a dev environment. + */ +public class NightConfigWatchThrottler { + private static final long DELAY = TimeUnit.MILLISECONDS.toNanos(1000); + + @SuppressWarnings("rawtypes") + public static void throttle() { + Map watchedDirs = ObfuscationReflectionHelper.getPrivateValue(FileWatcher.class, FileWatcher.defaultInstance(), "watchedDirs"); + ObfuscationReflectionHelper.setPrivateValue(FileWatcher.class, FileWatcher.defaultInstance(), new ForwardingMap() { + @Override + protected Map delegate() { + return watchedDirs; + } + + private Collection cachedValues; + + @Override + public Collection values() { + if(cachedValues == null) { + Collection values = super.values(); + cachedValues = new ForwardingCollection() { + @Override + protected Collection delegate() { + return values; + } + + @Override + public Iterator iterator() { + // iterator() is called at the beginning of each iteration of the watch loop, + // so it is a good spot to inject the delay. + LockSupport.parkNanos(DELAY); + return super.iterator(); + } + }; + } + return cachedValues; + } + }, "watchedDirs"); + } +} diff --git a/forge/src/main/java/org/embeddedt/modernfix/platform/forge/ModernFixPlatformHooksImpl.java b/forge/src/main/java/org/embeddedt/modernfix/platform/forge/ModernFixPlatformHooksImpl.java index b9c3fe2b..3eb8a2c0 100644 --- a/forge/src/main/java/org/embeddedt/modernfix/platform/forge/ModernFixPlatformHooksImpl.java +++ b/forge/src/main/java/org/embeddedt/modernfix/platform/forge/ModernFixPlatformHooksImpl.java @@ -31,6 +31,7 @@ import org.embeddedt.modernfix.api.constants.IntegrationConstants; import org.embeddedt.modernfix.forge.classloading.FastAccessTransformerList; import org.embeddedt.modernfix.forge.classloading.ModernFixResourceFinder; import org.embeddedt.modernfix.forge.config.NightConfigFixer; +import org.embeddedt.modernfix.forge.config.NightConfigWatchThrottler; import org.embeddedt.modernfix.forge.init.ModernFixForge; import org.embeddedt.modernfix.forge.packet.PacketHandler; import org.embeddedt.modernfix.forge.spark.SparkLaunchProfiler; @@ -192,6 +193,7 @@ public class ModernFixPlatformHooksImpl implements ModernFixPlatformHooks { } NightConfigFixer.monitorFileWatcher(); + NightConfigWatchThrottler.throttle(); MixinExtrasBootstrap.init(); } From a0fdb3e6d7250168e1c9979132ff7d1f8bc7dd4f Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Wed, 20 Mar 2024 15:18:22 -0400 Subject: [PATCH 4/7] Update for FML changes --- .../modernfix/forge/config/NightConfigWatchThrottler.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/forge/src/main/java/org/embeddedt/modernfix/forge/config/NightConfigWatchThrottler.java b/forge/src/main/java/org/embeddedt/modernfix/forge/config/NightConfigWatchThrottler.java index ae75e00f..a0283bd2 100644 --- a/forge/src/main/java/org/embeddedt/modernfix/forge/config/NightConfigWatchThrottler.java +++ b/forge/src/main/java/org/embeddedt/modernfix/forge/config/NightConfigWatchThrottler.java @@ -3,7 +3,7 @@ package org.embeddedt.modernfix.forge.config; import com.electronwill.nightconfig.core.file.FileWatcher; import com.google.common.collect.ForwardingCollection; import com.google.common.collect.ForwardingMap; -import net.minecraftforge.fml.common.ObfuscationReflectionHelper; +import net.minecraftforge.fml.util.ObfuscationReflectionHelper; import java.util.Collection; import java.util.Iterator; From 070b7b6d126af5d04cb6a4315d823a2ad6dbc6bb Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Wed, 20 Mar 2024 15:44:28 -0400 Subject: [PATCH 5/7] Add some simple patches to cut down allocation rate when ticking chunks --- .../perf/ticking_chunk_alloc/BatMixin.java | 28 ++++++++++ .../ChunkGeneratorMixin.java | 26 ++++++++++ .../ticking_chunk_alloc/ChunkHolderMixin.java | 40 ++++++++++++++ .../embeddedt/modernfix/util/EitherUtil.java | 52 +++++++++++++++++++ 4 files changed, 146 insertions(+) create mode 100644 common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/ticking_chunk_alloc/BatMixin.java create mode 100644 common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/ticking_chunk_alloc/ChunkGeneratorMixin.java create mode 100644 common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/ticking_chunk_alloc/ChunkHolderMixin.java create mode 100644 common/src/main/java/org/embeddedt/modernfix/util/EitherUtil.java diff --git a/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/ticking_chunk_alloc/BatMixin.java b/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/ticking_chunk_alloc/BatMixin.java new file mode 100644 index 00000000..e3cc0ddc --- /dev/null +++ b/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/ticking_chunk_alloc/BatMixin.java @@ -0,0 +1,28 @@ +package org.embeddedt.modernfix.common.mixin.perf.ticking_chunk_alloc; + +import net.minecraft.world.entity.ambient.Bat; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Redirect; + +import java.time.LocalDate; + +@Mixin(value = Bat.class, priority = 1200) +public class BatMixin { + private static long mfix$lastQueriedTime = -1L; + private static LocalDate mfix$lastQueriedDate = null; + + /** + * @author embeddedt + * @reason avoid excessive allocations from continuously querying the date, only get a new date once every 30 seconds + */ + @Redirect(method = "isHalloween", at = @At(value = "INVOKE", target = "Ljava/time/LocalDate;now()Ljava/time/LocalDate;"), require = 0) + private static LocalDate useCachedLocalDate() { + LocalDate date = mfix$lastQueriedDate; + if(date == null || Math.abs(System.currentTimeMillis() - mfix$lastQueriedTime) > 30000) { + mfix$lastQueriedDate = date = LocalDate.now(); + mfix$lastQueriedTime = System.currentTimeMillis(); + } + return date; + } +} diff --git a/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/ticking_chunk_alloc/ChunkGeneratorMixin.java b/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/ticking_chunk_alloc/ChunkGeneratorMixin.java new file mode 100644 index 00000000..193995f4 --- /dev/null +++ b/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/ticking_chunk_alloc/ChunkGeneratorMixin.java @@ -0,0 +1,26 @@ +package org.embeddedt.modernfix.common.mixin.perf.ticking_chunk_alloc; + +import net.minecraft.world.level.chunk.ChunkGenerator; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Redirect; + +import java.util.Collections; +import java.util.Map; +import java.util.Set; + +@Mixin(ChunkGenerator.class) +public class ChunkGeneratorMixin { + /** + * @author embeddedt + * @reason Avoid allocation if the chunk contains no structures + */ + @Redirect(method = "getMobsAt", at = @At(value = "INVOKE", target = "Ljava/util/Map;entrySet()Ljava/util/Set;"), require = 0) + private Set avoidSetAllocation(Map instance) { + if(instance.isEmpty()) { + return Collections.emptySet(); + } else { + return instance.entrySet(); + } + } +} diff --git a/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/ticking_chunk_alloc/ChunkHolderMixin.java b/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/ticking_chunk_alloc/ChunkHolderMixin.java new file mode 100644 index 00000000..2ea7c2de --- /dev/null +++ b/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/ticking_chunk_alloc/ChunkHolderMixin.java @@ -0,0 +1,40 @@ +package org.embeddedt.modernfix.common.mixin.perf.ticking_chunk_alloc; + +import com.mojang.datafixers.util.Either; +import net.minecraft.server.level.ChunkHolder; +import net.minecraft.world.level.chunk.LevelChunk; +import org.embeddedt.modernfix.util.EitherUtil; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Overwrite; +import org.spongepowered.asm.mixin.Shadow; + +import java.util.concurrent.CompletableFuture; + +@Mixin(value = ChunkHolder.class, priority = 500) +public abstract class ChunkHolderMixin { + @Shadow public abstract CompletableFuture> getTickingChunkFuture(); + + @Shadow public abstract CompletableFuture> getFullChunkFuture(); + + /** + * @author embeddedt + * @reason avoid Optional allocation + */ + @Overwrite + public LevelChunk getTickingChunk() { + CompletableFuture> completableFuture = this.getTickingChunkFuture(); + Either either = completableFuture.getNow(null); + return either == null ? null : EitherUtil.leftOrNull(either); + } + + /** + * @author embeddedt + * @reason avoid Optional allocation + */ + @Overwrite + public LevelChunk getFullChunk() { + CompletableFuture> completableFuture = this.getFullChunkFuture(); + Either either = completableFuture.getNow(null); + return either == null ? null : EitherUtil.leftOrNull(either); + } +} diff --git a/common/src/main/java/org/embeddedt/modernfix/util/EitherUtil.java b/common/src/main/java/org/embeddedt/modernfix/util/EitherUtil.java new file mode 100644 index 00000000..52bc52c2 --- /dev/null +++ b/common/src/main/java/org/embeddedt/modernfix/util/EitherUtil.java @@ -0,0 +1,52 @@ +package org.embeddedt.modernfix.util; + +import com.mojang.datafixers.util.Either; + +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; +import java.lang.invoke.MethodType; +import java.lang.reflect.Field; + +public class EitherUtil { + private static final Class LEFT, RIGHT; + private static final MethodHandle LEFT_VAL, RIGHT_VAL; + + static { + try { + LEFT = Class.forName("com.mojang.datafixers.util.Either$Left"); + RIGHT = Class.forName("com.mojang.datafixers.util.Either$Right"); + Field lvalue = LEFT.getDeclaredField("value"); + lvalue.setAccessible(true); + Field rvalue = RIGHT.getDeclaredField("value"); + rvalue.setAccessible(true); + LEFT_VAL = MethodHandles.publicLookup().unreflectGetter(lvalue).asType(MethodType.methodType(Object.class, Either.class)); + RIGHT_VAL = MethodHandles.publicLookup().unreflectGetter(rvalue).asType(MethodType.methodType(Object.class, Either.class)); + } catch(ReflectiveOperationException e) { + throw new AssertionError("Failed to hook DFU Either", e); + } + } + + @SuppressWarnings("unchecked") + public static L leftOrNull(Either either) { + if(either.getClass() == LEFT) { + try { + return (L)LEFT_VAL.invokeExact(either); + } catch(Throwable e) { + throw new RuntimeException(e); + } + } + return null; + } + + @SuppressWarnings("unchecked") + public static R rightOrNull(Either either) { + if(either.getClass() == RIGHT) { + try { + return (R)RIGHT_VAL.invokeExact(either); + } catch(Throwable e) { + throw new RuntimeException(e); + } + } + return null; + } +} From 1814bd3e1faff1518119a7b5fcf85784c796023d Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Wed, 20 Mar 2024 16:39:24 -0400 Subject: [PATCH 6/7] Reduce overhead of the PotentialSpawns event --- .../ForgeEventFactoryMixin.java | 25 +++++++ .../PotentialSpawnsMixin.java | 68 +++++++++++++++++++ 2 files changed, 93 insertions(+) create mode 100644 forge/src/main/java/org/embeddedt/modernfix/forge/mixin/perf/potential_spawns_alloc/ForgeEventFactoryMixin.java create mode 100644 forge/src/main/java/org/embeddedt/modernfix/forge/mixin/perf/potential_spawns_alloc/PotentialSpawnsMixin.java diff --git a/forge/src/main/java/org/embeddedt/modernfix/forge/mixin/perf/potential_spawns_alloc/ForgeEventFactoryMixin.java b/forge/src/main/java/org/embeddedt/modernfix/forge/mixin/perf/potential_spawns_alloc/ForgeEventFactoryMixin.java new file mode 100644 index 00000000..ca203b86 --- /dev/null +++ b/forge/src/main/java/org/embeddedt/modernfix/forge/mixin/perf/potential_spawns_alloc/ForgeEventFactoryMixin.java @@ -0,0 +1,25 @@ +package org.embeddedt.modernfix.forge.mixin.perf.potential_spawns_alloc; + +import net.minecraft.core.BlockPos; +import net.minecraft.util.random.WeightedRandomList; +import net.minecraft.world.entity.MobCategory; +import net.minecraft.world.level.LevelAccessor; +import net.minecraft.world.level.biome.MobSpawnSettings; +import net.minecraftforge.event.ForgeEventFactory; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Redirect; + +import java.util.List; + +@Mixin(ForgeEventFactory.class) +public class ForgeEventFactoryMixin { + @Redirect(method = "getPotentialSpawns", at = @At(value = "INVOKE", target = "Lnet/minecraft/util/random/WeightedRandomList;create(Ljava/util/List;)Lnet/minecraft/util/random/WeightedRandomList;")) + private static WeightedRandomList reuseOldList(List items, LevelAccessor level, MobCategory category, BlockPos pos, WeightedRandomList oldList) { + // Our patched version of PotentialSpawns will return the same list as unwrap() if no one mutated the list + if(items == oldList.unwrap()) { + return oldList; + } + return WeightedRandomList.create(items); + } +} diff --git a/forge/src/main/java/org/embeddedt/modernfix/forge/mixin/perf/potential_spawns_alloc/PotentialSpawnsMixin.java b/forge/src/main/java/org/embeddedt/modernfix/forge/mixin/perf/potential_spawns_alloc/PotentialSpawnsMixin.java new file mode 100644 index 00000000..9fac5799 --- /dev/null +++ b/forge/src/main/java/org/embeddedt/modernfix/forge/mixin/perf/potential_spawns_alloc/PotentialSpawnsMixin.java @@ -0,0 +1,68 @@ +package org.embeddedt.modernfix.forge.mixin.perf.potential_spawns_alloc; + +import net.minecraft.core.BlockPos; +import net.minecraft.util.random.WeightedRandomList; +import net.minecraft.world.entity.MobCategory; +import net.minecraft.world.level.LevelAccessor; +import net.minecraft.world.level.biome.MobSpawnSettings; +import net.minecraftforge.event.world.WorldEvent; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +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.Inject; +import org.spongepowered.asm.mixin.injection.Redirect; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; + +@Mixin(WorldEvent.PotentialSpawns.class) +public class PotentialSpawnsMixin { + @Shadow(remap = false) @Final @Mutable private List view; + @Shadow(remap = false) @Final @Mutable private List list; + + private static final ArrayList SENTINEL = new ArrayList<>(); + + @Redirect(method = "", at = @At(value = "NEW", target = "java/util/ArrayList", ordinal = 1)) + private ArrayList avoidListAlloc1() { + return SENTINEL; + } + + @Redirect(method = "", at = @At(value = "NEW", target = "java/util/ArrayList", ordinal = 0)) + private ArrayList avoidListAlloc2(Collection c) { + return SENTINEL; + } + + @Redirect(method = "", at = @At(value = "INVOKE", target = "Ljava/util/Collections;unmodifiableList(Ljava/util/List;)Ljava/util/List;")) + private List avoidListAlloc3(List l) { + return null; + } + + @Inject(method = "", at = @At("RETURN")) + private void initializeSmartLists(LevelAccessor level, MobCategory category, BlockPos pos, WeightedRandomList oldList, CallbackInfo ci) { + this.view = oldList.unwrap(); + this.list = null; + } + + private void mfix$populateList() { + if(this.list == null) { + this.list = new ArrayList<>(this.view); + this.view = Collections.unmodifiableList(this.list); + } + } + + @Inject(method = {"addSpawnerData" }, at = @At("HEAD"), remap = false) + private void populateList(MobSpawnSettings.SpawnerData data, CallbackInfo ci) { + mfix$populateList(); + } + + @Inject(method = {"removeSpawnerData" }, at = @At("HEAD"), remap = false) + private void populateList(MobSpawnSettings.SpawnerData data, CallbackInfoReturnable cir) { + mfix$populateList(); + } +} From b916ef5ae9b2e49bd0f5556089d6f31fde576e2f Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Wed, 20 Mar 2024 16:52:34 -0400 Subject: [PATCH 7/7] Update mixin for 1.19 renames --- .../perf/potential_spawns_alloc/PotentialSpawnsMixin.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/forge/src/main/java/org/embeddedt/modernfix/forge/mixin/perf/potential_spawns_alloc/PotentialSpawnsMixin.java b/forge/src/main/java/org/embeddedt/modernfix/forge/mixin/perf/potential_spawns_alloc/PotentialSpawnsMixin.java index 9fac5799..5f8071df 100644 --- a/forge/src/main/java/org/embeddedt/modernfix/forge/mixin/perf/potential_spawns_alloc/PotentialSpawnsMixin.java +++ b/forge/src/main/java/org/embeddedt/modernfix/forge/mixin/perf/potential_spawns_alloc/PotentialSpawnsMixin.java @@ -5,7 +5,7 @@ import net.minecraft.util.random.WeightedRandomList; import net.minecraft.world.entity.MobCategory; import net.minecraft.world.level.LevelAccessor; import net.minecraft.world.level.biome.MobSpawnSettings; -import net.minecraftforge.event.world.WorldEvent; +import net.minecraftforge.event.level.LevelEvent; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mutable; @@ -21,7 +21,7 @@ import java.util.Collection; import java.util.Collections; import java.util.List; -@Mixin(WorldEvent.PotentialSpawns.class) +@Mixin(LevelEvent.PotentialSpawns.class) public class PotentialSpawnsMixin { @Shadow(remap = false) @Final @Mutable private List view; @Shadow(remap = false) @Final @Mutable private List list;