Improve compatibility of ID desync fix, and add Roadrunner support
This commit is contained in:
parent
84ba47f174
commit
a54e7b831a
|
|
@ -1,6 +1,7 @@
|
||||||
package org.embeddedt.modernfix;
|
package org.embeddedt.modernfix;
|
||||||
|
|
||||||
import com.mojang.datafixers.util.Pair;
|
import com.mojang.datafixers.util.Pair;
|
||||||
|
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.client.gui.screens.ConnectScreen;
|
import net.minecraft.client.gui.screens.ConnectScreen;
|
||||||
import net.minecraft.client.gui.screens.TitleScreen;
|
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.
|
* 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.
|
* 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) {
|
if(fixNeeded) {
|
||||||
dataEntries = new ArrayList<>(allEntityDatas);
|
dataEntries = new ArrayList<>(allEntityDatas);
|
||||||
for(SynchedEntityData manager : dataEntries) {
|
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());
|
List<SynchedEntityData.DataItem<?>> items = new ArrayList<>(manager.itemsById.values());
|
||||||
for(SynchedEntityData.DataItem<?> item : items) {
|
for(SynchedEntityData.DataItem<?> item : items) {
|
||||||
fixedMap.put(item.getAccessor().id, item);
|
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();
|
allEntityDatas.clear();
|
||||||
|
|
|
||||||
|
|
@ -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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -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.server.MinecraftServer field_211151_aa # nextTickTime
|
||||||
public net.minecraft.client.Minecraft field_213277_ad # progressListener
|
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.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
|
||||||
|
|
@ -53,7 +53,6 @@
|
||||||
"perf.fast_registry_validation.ForgeRegistryMixin",
|
"perf.fast_registry_validation.ForgeRegistryMixin",
|
||||||
"perf.cache_strongholds.ChunkGeneratorMixin",
|
"perf.cache_strongholds.ChunkGeneratorMixin",
|
||||||
"perf.cache_upgraded_structures.StructureManagerMixin",
|
"perf.cache_upgraded_structures.StructureManagerMixin",
|
||||||
"bugfix.mc218112.SynchedEntityDataMixin",
|
|
||||||
"perf.cache_strongholds.ServerLevelMixin"
|
"perf.cache_strongholds.ServerLevelMixin"
|
||||||
],
|
],
|
||||||
"client": [
|
"client": [
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user