diff --git a/src/main/java/org/embeddedt/modernfix/ModernFixClient.java b/src/main/java/org/embeddedt/modernfix/ModernFixClient.java index 7b97709a..f0bd2dfc 100644 --- a/src/main/java/org/embeddedt/modernfix/ModernFixClient.java +++ b/src/main/java/org/embeddedt/modernfix/ModernFixClient.java @@ -1,6 +1,7 @@ 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.client.gui.screens.ConnectScreen; import net.minecraft.client.gui.screens.TitleScreen; @@ -105,7 +106,19 @@ public class ModernFixClient { * * This is to ensure we can perform ID fixup on already constructed managers. */ - public static Set allEntityDatas = Collections.newSetFromMap(new WeakHashMap<>()); + 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. @@ -140,12 +153,28 @@ public class ModernFixClient { if(fixNeeded) { dataEntries = new ArrayList<>(allEntityDatas); for(SynchedEntityData manager : dataEntries) { - Map> fixedMap = new HashMap<>(); + Int2ObjectOpenHashMap> fixedMap = new Int2ObjectOpenHashMap<>(); List> items = new ArrayList<>(manager.itemsById.values()); for(SynchedEntityData.DataItem item : items) { fixedMap.put(item.getAccessor().id, item); } - manager.itemsById = fixedMap; + 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(); diff --git a/src/main/java/org/embeddedt/modernfix/mixin/bugfix/mc218112/SynchedEntityDataMixin.java b/src/main/java/org/embeddedt/modernfix/mixin/bugfix/mc218112/SynchedEntityDataMixin.java deleted file mode 100644 index 64b4f16b..00000000 --- a/src/main/java/org/embeddedt/modernfix/mixin/bugfix/mc218112/SynchedEntityDataMixin.java +++ /dev/null @@ -1,34 +0,0 @@ -package org.embeddedt.modernfix.mixin.bugfix.mc218112; - -import net.minecraft.network.syncher.EntityDataAccessor; -import net.minecraft.network.syncher.SynchedEntityData; -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.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import org.spongepowered.asm.mixin.injection.callback.LocalCapture; - -import java.util.Map; -import java.util.concurrent.locks.ReadWriteLock; - -@Mixin(SynchedEntityData.class) -public class SynchedEntityDataMixin { - @Shadow @Final private Map> itemsById; - - @Shadow @Final private ReadWriteLock lock; - - @Shadow private boolean isEmpty; - - @Inject(method = "createDataItem", at = @At(value = "INVOKE", target = "Ljava/util/Map;put(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"), cancellable = true, locals = LocalCapture.CAPTURE_FAILHARD) - private void putWithLock(EntityDataAccessor key, T value, CallbackInfo ci, SynchedEntityData.DataItem item) { - ci.cancel(); - try { - this.itemsById.put(key.getId(), item); - this.isEmpty = false; - } finally { - this.lock.writeLock().unlock(); - } - } -} diff --git a/src/main/resources/META-INF/accesstransformer.cfg b/src/main/resources/META-INF/accesstransformer.cfg index a8145c22..7e921c8a 100644 --- a/src/main/resources/META-INF/accesstransformer.cfg +++ b/src/main/resources/META-INF/accesstransformer.cfg @@ -10,4 +10,5 @@ public net.minecraft.util.concurrent.ThreadTaskExecutor func_213160_bf()V # runA public net.minecraft.server.MinecraftServer field_211151_aa # nextTickTime public net.minecraft.client.Minecraft field_213277_ad # progressListener public-f net.minecraft.network.datasync.DataParameter field_187157_a # id -public-f net.minecraft.network.datasync.EntityDataManager field_187234_c # itemsById \ No newline at end of file +public-f net.minecraft.network.datasync.EntityDataManager field_187234_c # itemsById +public-f net.minecraft.network.datasync.EntityDataManager field_187235_d # lock \ No newline at end of file diff --git a/src/main/resources/modernfix.mixins.json b/src/main/resources/modernfix.mixins.json index b79452ef..d42fa2d3 100644 --- a/src/main/resources/modernfix.mixins.json +++ b/src/main/resources/modernfix.mixins.json @@ -53,7 +53,6 @@ "perf.fast_registry_validation.ForgeRegistryMixin", "perf.cache_strongholds.ChunkGeneratorMixin", "perf.cache_upgraded_structures.StructureManagerMixin", - "bugfix.mc218112.SynchedEntityDataMixin", "perf.cache_strongholds.ServerLevelMixin" ], "client": [