Improve compatibility of ID desync fix, and add Roadrunner support

This commit is contained in:
embeddedt 2023-03-04 09:10:12 -05:00
parent 84ba47f174
commit a54e7b831a
No known key found for this signature in database
GPG Key ID: A69433EC199B5613
4 changed files with 34 additions and 39 deletions

View File

@ -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<SynchedEntityData> allEntityDatas = Collections.newSetFromMap(new WeakHashMap<>());
public static final Set<SynchedEntityData> 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<Integer, SynchedEntityData.DataItem<?>> fixedMap = new HashMap<>();
Int2ObjectOpenHashMap<SynchedEntityData.DataItem<?>> fixedMap = new Int2ObjectOpenHashMap<>();
List<SynchedEntityData.DataItem<?>> 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();

View File

@ -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<Integer, SynchedEntityData.DataItem<?>> 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 <T> void putWithLock(EntityDataAccessor<T> key, T value, CallbackInfo ci, SynchedEntityData.DataItem<T> item) {
ci.cancel();
try {
this.itemsById.put(key.getId(), item);
this.isEmpty = false;
} finally {
this.lock.writeLock().unlock();
}
}
}

View File

@ -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
public-f net.minecraft.network.datasync.EntityDataManager field_187234_c # itemsById
public-f net.minecraft.network.datasync.EntityDataManager field_187235_d # lock

View File

@ -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": [