From 90cf39e9d8c4533f47a9838500801372018033d5 Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Wed, 7 Feb 2024 15:49:00 -0500 Subject: [PATCH] 24w06a --- .../embeddedt/modernfix/ModernFixClient.java | 86 +------------------ .../mixin/core/SynchedEntityDataMixin.java | 26 ------ .../MappedRegistryMixin.java | 7 +- .../WallBlockMixin.java | 6 +- .../BlockStateBaseMixin.java | 6 +- .../entity/EntityDataIDSyncHandler.java | 57 ------------ .../modernfix/registry/LifecycleMap.java | 9 +- .../main/resources/modernfix.accesswidener | 3 - gradle.properties | 4 +- 9 files changed, 19 insertions(+), 185 deletions(-) delete mode 100644 common/src/main/java/org/embeddedt/modernfix/common/mixin/core/SynchedEntityDataMixin.java delete mode 100644 common/src/main/java/org/embeddedt/modernfix/entity/EntityDataIDSyncHandler.java diff --git a/common/src/main/java/org/embeddedt/modernfix/ModernFixClient.java b/common/src/main/java/org/embeddedt/modernfix/ModernFixClient.java index 320e2ab9..7d973fb6 100644 --- a/common/src/main/java/org/embeddedt/modernfix/ModernFixClient.java +++ b/common/src/main/java/org/embeddedt/modernfix/ModernFixClient.java @@ -1,17 +1,13 @@ package org.embeddedt.modernfix; -import com.mojang.datafixers.util.Pair; -import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; import net.minecraft.client.Minecraft; import net.minecraft.network.syncher.EntityDataAccessor; -import net.minecraft.network.syncher.SynchedEntityData; import net.minecraft.server.MinecraftServer; import net.minecraft.util.MemoryReserve; import net.minecraft.world.entity.Entity; import org.embeddedt.modernfix.api.constants.IntegrationConstants; import org.embeddedt.modernfix.api.entrypoint.ModernFixClientIntegration; import org.embeddedt.modernfix.core.ModernFixMixinPlugin; -import org.embeddedt.modernfix.packet.EntityIDSyncPacket; import org.embeddedt.modernfix.platform.ModernFixPlatformHooks; import org.embeddedt.modernfix.searchtree.JEIBackedSearchTree; import org.embeddedt.modernfix.searchtree.REIBackedSearchTree; @@ -20,8 +16,7 @@ import org.embeddedt.modernfix.util.ClassInfoManager; import org.embeddedt.modernfix.world.IntegratedWatchdog; import java.lang.management.ManagementFactory; -import java.lang.reflect.Field; -import java.util.*; +import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; public class ModernFixClient { @@ -123,85 +118,6 @@ public class ModernFixClient { } } - /** - * Horrendous hack to allow tracking every synced entity data manager. - * - * This is to ensure we can perform ID fixup on already constructed managers. - */ - public static final Set allEntityDatas = Collections.newSetFromMap(new WeakHashMap<>()); - - private static final Field entriesArrayField; - static { - Field field; - try { - field = SynchedEntityData.class.getDeclaredField("entriesArray"); - field.setAccessible(true); - } catch(ReflectiveOperationException e) { - field = null; - } - entriesArrayField = field; - } - - /** - * Extremely hacky method to detect and correct mismatched entity data parameter IDs on the client and server. - * - * The technique is far from ideal, but it should detect reliably and also not break already constructed entities. - */ - public static void handleEntityIDSync(EntityIDSyncPacket packet) { - Map, List>> info = packet.getFieldInfo(); - boolean fixNeeded = false; - for(Map.Entry, List>> entry : info.entrySet()) { - Class eClass = entry.getKey(); - for(Pair field : entry.getValue()) { - String fieldName = field.getFirst(); - int newId = field.getSecond(); - try { - Field f = eClass.getDeclaredField(fieldName); - f.setAccessible(true); - EntityDataAccessor accessor = (EntityDataAccessor)f.get(null); - if(compareAndSwitchIds(eClass, fieldName, accessor, newId)) - fixNeeded = true; - } catch(NoSuchFieldException e) { - ModernFix.LOGGER.warn("Couldn't find field on {}: {}", eClass, fieldName); - } catch(ReflectiveOperationException e) { - throw new RuntimeException("Unexpected exception", e); - } - } - } - /* Now the ID mappings on synced entity data instances are probably all wrong. Fix that. */ - List dataEntries; - synchronized (allEntityDatas) { - if(fixNeeded) { - dataEntries = new ArrayList<>(allEntityDatas); - for(SynchedEntityData manager : dataEntries) { - Int2ObjectOpenHashMap> fixedMap = new Int2ObjectOpenHashMap<>(); - List> items = new ArrayList<>(manager.itemsById.values()); - for(SynchedEntityData.DataItem item : items) { - fixedMap.put(item.getAccessor().id, item); - } - manager.lock.writeLock().lock(); - try { - manager.itemsById.replaceAll((id, parameter) -> fixedMap.get((int)id)); - if(entriesArrayField != null) { - try { - SynchedEntityData.DataItem[] dataArray = new SynchedEntityData.DataItem[items.size()]; - for(int i = 0; i < dataArray.length; i++) { - dataArray[i] = fixedMap.get(i); - } - entriesArrayField.set(manager, dataArray); - } catch(ReflectiveOperationException e) { - ModernFix.LOGGER.error(e); - } - } - } finally { - manager.lock.writeLock().unlock(); - } - } - } - allEntityDatas.clear(); - } - } - public void onServerStarted(MinecraftServer server) { if(!ModernFixMixinPlugin.instance.isOptionEnabled("feature.integrated_server_watchdog.IntegratedWatchdog")) return; diff --git a/common/src/main/java/org/embeddedt/modernfix/common/mixin/core/SynchedEntityDataMixin.java b/common/src/main/java/org/embeddedt/modernfix/common/mixin/core/SynchedEntityDataMixin.java deleted file mode 100644 index 9737a2f2..00000000 --- a/common/src/main/java/org/embeddedt/modernfix/common/mixin/core/SynchedEntityDataMixin.java +++ /dev/null @@ -1,26 +0,0 @@ -package org.embeddedt.modernfix.common.mixin.core; - -import net.minecraft.network.syncher.SynchedEntityData; -import net.minecraft.world.entity.Entity; -import org.embeddedt.modernfix.ModernFixClient; -import org.embeddedt.modernfix.annotation.ClientOnlyMixin; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -@Mixin(SynchedEntityData.class) -@ClientOnlyMixin -public class SynchedEntityDataMixin { - /** - * Store this in our set of all entity data objects. - * - * Not an ideal solution, but it should guarantee compatibility with mods. - */ - @Inject(method = "", at = @At("RETURN")) - private void storeInSet(Entity arg, CallbackInfo ci) { - synchronized (ModernFixClient.allEntityDatas) { - ModernFixClient.allEntityDatas.add((SynchedEntityData)(Object)this); - } - } -} diff --git a/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/compact_mojang_registries/MappedRegistryMixin.java b/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/compact_mojang_registries/MappedRegistryMixin.java index f6e86477..fc1ce59b 100644 --- a/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/compact_mojang_registries/MappedRegistryMixin.java +++ b/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/compact_mojang_registries/MappedRegistryMixin.java @@ -1,8 +1,9 @@ package org.embeddedt.modernfix.common.mixin.perf.compact_mojang_registries; import com.google.common.collect.ImmutableSet; -import com.mojang.serialization.Lifecycle; import net.minecraft.core.MappedRegistry; +import net.minecraft.core.RegistrationInfo; +import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceLocation; import org.embeddedt.modernfix.annotation.IgnoreOutsideDev; import org.embeddedt.modernfix.registry.LifecycleMap; @@ -22,13 +23,13 @@ public abstract class MappedRegistryMixin { @Shadow @Final @Mutable - private Map lifecycles; + private Map, RegistrationInfo> registrationInfos; private static final ImmutableSet MFIX$NEW_STORAGE_KEYS = ImmutableSet.of(new ResourceLocation("block"), new ResourceLocation("item")); @Inject(method = "(Lnet/minecraft/resources/ResourceKey;Lcom/mojang/serialization/Lifecycle;Z)V", at = @At("RETURN")) private void replaceStorage(CallbackInfo ci) { - this.lifecycles = new LifecycleMap<>(); + this.registrationInfos = new LifecycleMap<>(); /* if(MFIX$NEW_STORAGE_KEYS.contains(this.key().location())) { ModernFixMixinPlugin.instance.logger.info("Using experimental registry storage for {}", this.key()); diff --git a/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/deduplicate_wall_shapes/WallBlockMixin.java b/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/deduplicate_wall_shapes/WallBlockMixin.java index fb8af245..09532efc 100644 --- a/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/deduplicate_wall_shapes/WallBlockMixin.java +++ b/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/deduplicate_wall_shapes/WallBlockMixin.java @@ -25,7 +25,7 @@ import java.util.Map; */ @Mixin(WallBlock.class) public abstract class WallBlockMixin extends Block { - private static Map, Pair, Comparable>, VoxelShape>, StateDefinition>> CACHE_BY_SHAPE_VALS = new HashMap<>(); + private static Map, Pair, Comparable>, VoxelShape>, StateDefinition>> CACHE_BY_SHAPE_VALS = new HashMap<>(); public WallBlockMixin(Properties properties) { super(properties); @@ -34,7 +34,7 @@ public abstract class WallBlockMixin extends Block { @Inject(method = "makeShapes", at = @At("HEAD"), cancellable = true) private synchronized void useCachedShapeMap(float f1, float f2, float f3, float f4, float f5, float f6, CallbackInfoReturnable> cir) { ImmutableList key = ImmutableList.of(f1, f2, f3, f4, f5, f6); - Pair, Comparable>, VoxelShape>, StateDefinition> cache = CACHE_BY_SHAPE_VALS.get(key); + Pair, Comparable>, VoxelShape>, StateDefinition> cache = CACHE_BY_SHAPE_VALS.get(key); // require the properties to be identical if(cache == null || !cache.getSecond().getProperties().equals(this.stateDefinition.getProperties())) return; @@ -55,7 +55,7 @@ public abstract class WallBlockMixin extends Block { return; ImmutableList key = ImmutableList.of(f1, f2, f3, f4, f5, f6); if(!CACHE_BY_SHAPE_VALS.containsKey(key)) { - Map, Comparable>, VoxelShape> cacheByProperties = new HashMap<>(); + Map, Comparable>, VoxelShape> cacheByProperties = new HashMap<>(); Map shapeMap = cir.getReturnValue(); for(Map.Entry entry : shapeMap.entrySet()) { cacheByProperties.put(entry.getKey().getValues(), entry.getValue()); diff --git a/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/reduce_blockstate_cache_rebuilds/BlockStateBaseMixin.java b/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/reduce_blockstate_cache_rebuilds/BlockStateBaseMixin.java index d13e3f44..0bb5801b 100644 --- a/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/reduce_blockstate_cache_rebuilds/BlockStateBaseMixin.java +++ b/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/reduce_blockstate_cache_rebuilds/BlockStateBaseMixin.java @@ -1,7 +1,7 @@ package org.embeddedt.modernfix.common.mixin.perf.reduce_blockstate_cache_rebuilds; -import com.google.common.collect.ImmutableMap; import com.mojang.serialization.MapCodec; +import it.unimi.dsi.fastutil.objects.Reference2ObjectArrayMap; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.state.BlockBehaviour; import net.minecraft.world.level.block.state.BlockState; @@ -16,10 +16,12 @@ import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Redirect; +import java.util.Map; + @Mixin(BlockBehaviour.BlockStateBase.class) public abstract class BlockStateBaseMixin extends StateHolder implements IBlockState { - protected BlockStateBaseMixin(Block object, ImmutableMap, Comparable> immutableMap, MapCodec mapCodec) { + protected BlockStateBaseMixin(Block object, Reference2ObjectArrayMap, Comparable> immutableMap, MapCodec mapCodec) { super(object, immutableMap, mapCodec); } diff --git a/common/src/main/java/org/embeddedt/modernfix/entity/EntityDataIDSyncHandler.java b/common/src/main/java/org/embeddedt/modernfix/entity/EntityDataIDSyncHandler.java deleted file mode 100644 index 9a9bb88d..00000000 --- a/common/src/main/java/org/embeddedt/modernfix/entity/EntityDataIDSyncHandler.java +++ /dev/null @@ -1,57 +0,0 @@ -package org.embeddedt.modernfix.entity; - -import com.mojang.datafixers.util.Pair; -import net.minecraft.network.syncher.EntityDataAccessor; -import net.minecraft.network.syncher.SynchedEntityData; -import net.minecraft.server.level.ServerPlayer; -import net.minecraft.world.entity.Entity; -import org.embeddedt.modernfix.ModernFix; -import org.embeddedt.modernfix.packet.EntityIDSyncPacket; -import org.embeddedt.modernfix.platform.ModernFixPlatformHooks; - -import java.lang.reflect.Field; -import java.lang.reflect.Modifier; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -public class EntityDataIDSyncHandler { - private static Map, List>> fieldsToSyncMap; - - @SuppressWarnings("unchecked") - public static void onDatapackSyncEvent(ServerPlayer targetPlayer) { - if(targetPlayer != null) { - /* Compute the current set of serializer IDs in use and send them */ - if(fieldsToSyncMap == null) { - fieldsToSyncMap = new HashMap<>(); - Map, Integer> entityPoolMap = SynchedEntityData.ENTITY_ID_POOL; - List fieldsToSync = new ArrayList<>(); - for(Class eClass : entityPoolMap.keySet()) { - fieldsToSync.clear(); - try { - Field[] classFields = eClass.getDeclaredFields(); - for(Field field : classFields) { - if(!Modifier.isStatic(field.getModifiers())) - continue; - field.setAccessible(true); - Object o = field.get(null); - if(o != null && EntityDataAccessor.class.isAssignableFrom(o.getClass())) { - fieldsToSync.add(field); - } - } - for(Field field : fieldsToSync) { - int id = ((EntityDataAccessor)field.get(null)).id; - fieldsToSyncMap.computeIfAbsent(eClass, k -> new ArrayList<>()).add(Pair.of(field.getName(), id)); - } - } catch(Throwable e) { - ModernFix.LOGGER.error("Skipping entity ID sync for {}: {}", eClass.getName(), e); - } - } - } - EntityIDSyncPacket packet = new EntityIDSyncPacket(fieldsToSyncMap); - ModernFix.LOGGER.debug("Sending ID correction packet to client with " + fieldsToSyncMap.size() + " classes"); - ModernFixPlatformHooks.INSTANCE.sendPacket(targetPlayer, packet); - } - } -} diff --git a/common/src/main/java/org/embeddedt/modernfix/registry/LifecycleMap.java b/common/src/main/java/org/embeddedt/modernfix/registry/LifecycleMap.java index 76285abd..c81ad2b0 100644 --- a/common/src/main/java/org/embeddedt/modernfix/registry/LifecycleMap.java +++ b/common/src/main/java/org/embeddedt/modernfix/registry/LifecycleMap.java @@ -1,15 +1,16 @@ package org.embeddedt.modernfix.registry; -import com.mojang.serialization.Lifecycle; import it.unimi.dsi.fastutil.objects.Reference2ReferenceOpenHashMap; +import net.minecraft.core.RegistrationInfo; +import net.minecraft.resources.ResourceKey; -public class LifecycleMap extends Reference2ReferenceOpenHashMap { +public class LifecycleMap extends Reference2ReferenceOpenHashMap, RegistrationInfo> { public LifecycleMap() { - this.defaultReturnValue(Lifecycle.stable()); + this.defaultReturnValue(RegistrationInfo.BUILT_IN); } @Override - public Lifecycle put(T t, Lifecycle lifecycle) { + public RegistrationInfo put(ResourceKey t, RegistrationInfo lifecycle) { if(lifecycle != defRetValue) return super.put(t, lifecycle); else { diff --git a/common/src/main/resources/modernfix.accesswidener b/common/src/main/resources/modernfix.accesswidener index 3d6d358a..9539602b 100644 --- a/common/src/main/resources/modernfix.accesswidener +++ b/common/src/main/resources/modernfix.accesswidener @@ -21,9 +21,6 @@ accessible field net/minecraft/client/renderer/texture/Stitcher$Holder height I accessible field net/minecraft/network/syncher/EntityDataAccessor id I mutable field net/minecraft/network/syncher/EntityDataAccessor id I accessible class net/minecraft/client/resources/model/ModelBakery$BlockStateDefinitionException -accessible field net/minecraft/network/syncher/SynchedEntityData itemsById Lit/unimi/dsi/fastutil/ints/Int2ObjectMap; -accessible field net/minecraft/network/syncher/SynchedEntityData ENTITY_ID_POOL Lit/unimi/dsi/fastutil/objects/Object2IntMap; -accessible field net/minecraft/network/syncher/SynchedEntityData lock Ljava/util/concurrent/locks/ReadWriteLock; accessible method net/minecraft/Util makeExecutor (Ljava/lang/String;)Ljava/util/concurrent/ExecutorService; accessible field net/minecraft/server/level/ChunkMap updatingChunkMap Lit/unimi/dsi/fastutil/longs/Long2ObjectLinkedOpenHashMap; accessible field net/minecraft/server/level/ChunkMap visibleChunkMap Lit/unimi/dsi/fastutil/longs/Long2ObjectLinkedOpenHashMap; diff --git a/gradle.properties b/gradle.properties index 11d6e5f4..2195b126 100644 --- a/gradle.properties +++ b/gradle.properties @@ -5,7 +5,7 @@ junit_version=5.10.0-M1 mixinextras_version=0.3.2 mod_id=modernfix -minecraft_version=24w05a +minecraft_version=24w06a enabled_platforms=fabric forge_version=20.4.132-beta # parchment_version=2023.07.09 @@ -15,7 +15,7 @@ rei_version=13.0.678 ctm_version=1.20.1-1.1.8+4 kubejs_version=1902.6.0-build.142 rhino_version=1902.2.2-build.268 -supported_minecraft_versions=24w05a +supported_minecraft_versions=24w06a fabric_loader_version=0.15.6 fabric_api_version=0.91.1+1.20.4