Merge remote-tracking branch 'origin/main' into 1.18
This commit is contained in:
commit
dbdd0a77a1
|
|
@ -89,6 +89,9 @@ dependencies {
|
||||||
|
|
||||||
// compile against the JEI API but do not include it at runtime
|
// compile against the JEI API but do not include it at runtime
|
||||||
modCompileOnly("mezz.jei:jei-${minecraft_version}-forge:${jei_version}")
|
modCompileOnly("mezz.jei:jei-${minecraft_version}-forge:${jei_version}")
|
||||||
|
modRuntimeOnly("curse.maven:jei-238222:4352925")
|
||||||
|
|
||||||
|
modImplementation("curse.maven:jeresources-240630:3831559")
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks.withType(JavaCompile) {
|
tasks.withType(JavaCompile) {
|
||||||
|
|
|
||||||
|
|
@ -4,18 +4,20 @@ import net.minecraftforge.api.distmarker.Dist;
|
||||||
import net.minecraftforge.common.MinecraftForge;
|
import net.minecraftforge.common.MinecraftForge;
|
||||||
import net.minecraftforge.event.server.ServerStartedEvent;
|
import net.minecraftforge.event.server.ServerStartedEvent;
|
||||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||||
import net.minecraftforge.fml.DistExecutor;
|
import net.minecraftforge.fml.*;
|
||||||
import net.minecraftforge.fml.IExtensionPoint;
|
|
||||||
import net.minecraftforge.fml.ModList;
|
|
||||||
import net.minecraftforge.fml.ModLoadingContext;
|
|
||||||
import net.minecraftforge.fml.common.Mod;
|
import net.minecraftforge.fml.common.Mod;
|
||||||
import net.minecraftforge.fml.config.ModConfig;
|
import net.minecraftforge.fml.config.ModConfig;
|
||||||
|
import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent;
|
||||||
|
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
|
||||||
import net.minecraftforge.fml.loading.FMLLoader;
|
import net.minecraftforge.fml.loading.FMLLoader;
|
||||||
import net.minecraftforge.network.NetworkConstants;
|
import net.minecraftforge.network.NetworkConstants;
|
||||||
import org.apache.commons.lang3.tuple.Pair;
|
import org.apache.commons.lang3.tuple.Pair;
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
import org.embeddedt.modernfix.core.config.ModernFixConfig;
|
import org.embeddedt.modernfix.core.config.ModernFixConfig;
|
||||||
|
import org.embeddedt.modernfix.entity.EntityDataIDSyncHandler;
|
||||||
|
import org.embeddedt.modernfix.packet.PacketHandler;
|
||||||
|
|
||||||
|
|
||||||
import java.lang.management.ManagementFactory;
|
import java.lang.management.ManagementFactory;
|
||||||
import java.util.concurrent.CountDownLatch;
|
import java.util.concurrent.CountDownLatch;
|
||||||
|
|
@ -62,9 +64,30 @@ public class ModernFix {
|
||||||
INSTANCE = this;
|
INSTANCE = this;
|
||||||
// Register ourselves for server and other game events we are interested in
|
// Register ourselves for server and other game events we are interested in
|
||||||
MinecraftForge.EVENT_BUS.register(this);
|
MinecraftForge.EVENT_BUS.register(this);
|
||||||
|
FMLJavaModLoadingContext.get().getModEventBus().addListener(this::commonSetup);
|
||||||
DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> MinecraftForge.EVENT_BUS.register(new ModernFixClient()));
|
DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> MinecraftForge.EVENT_BUS.register(new ModernFixClient()));
|
||||||
ModLoadingContext.get().registerExtensionPoint(IExtensionPoint.DisplayTest.class, () -> new IExtensionPoint.DisplayTest(() -> NetworkConstants.IGNORESERVERONLY, (a, b) -> true));
|
ModLoadingContext.get().registerExtensionPoint(IExtensionPoint.DisplayTest.class, () -> new IExtensionPoint.DisplayTest(() -> NetworkConstants.IGNORESERVERONLY, (a, b) -> true));
|
||||||
ModLoadingContext.get().registerConfig(ModConfig.Type.COMMON, ModernFixConfig.COMMON_CONFIG);
|
ModLoadingContext.get().registerConfig(ModConfig.Type.COMMON, ModernFixConfig.COMMON_CONFIG);
|
||||||
|
|
||||||
|
MinecraftForge.EVENT_BUS.register(EntityDataIDSyncHandler.class);
|
||||||
|
PacketHandler.register();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean dfuModPresent() {
|
||||||
|
for(String modId : new String[] { "lazydfu", "datafixerslayer" }) {
|
||||||
|
if(ModList.get().isLoaded(modId))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SubscribeEvent
|
||||||
|
public void commonSetup(FMLCommonSetupEvent event) {
|
||||||
|
if(!dfuModPresent()) {
|
||||||
|
event.enqueueWork(() -> {
|
||||||
|
ModLoader.get().addWarning(new ModLoadingWarning(ModLoadingContext.get().getActiveContainer().getModInfo(), ModLoadingStage.COMMON_SETUP, "modernfix.no_lazydfu"));
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,15 @@
|
||||||
package org.embeddedt.modernfix;
|
package org.embeddedt.modernfix;
|
||||||
|
|
||||||
|
import com.mojang.datafixers.util.Pair;
|
||||||
|
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||||
|
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;
|
||||||
import net.minecraftforge.client.event.ScreenOpenEvent;
|
import net.minecraftforge.client.event.ScreenOpenEvent;
|
||||||
|
import net.minecraft.network.syncher.EntityDataAccessor;
|
||||||
|
import net.minecraft.network.syncher.SynchedEntityData;
|
||||||
|
import net.minecraft.world.entity.Entity;
|
||||||
import net.minecraftforge.client.event.RenderGameOverlayEvent;
|
import net.minecraftforge.client.event.RenderGameOverlayEvent;
|
||||||
import net.minecraftforge.common.MinecraftForge;
|
import net.minecraftforge.common.MinecraftForge;
|
||||||
import net.minecraftforge.event.TickEvent;
|
import net.minecraftforge.event.TickEvent;
|
||||||
|
|
@ -11,12 +17,17 @@ import net.minecraftforge.eventbus.api.EventPriority;
|
||||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||||
import net.minecraftforge.fml.ModContainer;
|
import net.minecraftforge.fml.ModContainer;
|
||||||
import net.minecraftforge.fml.ModList;
|
import net.minecraftforge.fml.ModList;
|
||||||
|
import net.minecraftforge.network.NetworkEvent;
|
||||||
import org.embeddedt.modernfix.core.ModernFixMixinPlugin;
|
import org.embeddedt.modernfix.core.ModernFixMixinPlugin;
|
||||||
import org.embeddedt.modernfix.load.LoadEvents;
|
import org.embeddedt.modernfix.load.LoadEvents;
|
||||||
|
import org.embeddedt.modernfix.packet.EntityIDSyncPacket;
|
||||||
import org.embeddedt.modernfix.screen.DeferredLevelLoadingScreen;
|
import org.embeddedt.modernfix.screen.DeferredLevelLoadingScreen;
|
||||||
|
|
||||||
import java.lang.management.ManagementFactory;
|
import java.lang.management.ManagementFactory;
|
||||||
import java.util.Optional;
|
import java.lang.reflect.Field;
|
||||||
|
import java.sql.Ref;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
public class ModernFixClient {
|
public class ModernFixClient {
|
||||||
public static long worldLoadStartTime;
|
public static long worldLoadStartTime;
|
||||||
|
|
@ -71,4 +82,78 @@ public class ModernFixClient {
|
||||||
event.getLeft().add(brandingString);
|
event.getLeft().add(brandingString);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the IDs match and remap them if not.
|
||||||
|
* @return true if ID remap was needed
|
||||||
|
*/
|
||||||
|
private static boolean compareAndSwitchIds(Class<? extends Entity> eClass, String fieldName, EntityDataAccessor<?> accessor, int newId) {
|
||||||
|
if(accessor.id != newId) {
|
||||||
|
ModernFix.LOGGER.warn("Corrected ID mismatch on {} field {}. Client had {} but server wants {}.",
|
||||||
|
eClass,
|
||||||
|
fieldName,
|
||||||
|
accessor.id,
|
||||||
|
newId);
|
||||||
|
accessor.id = newId;
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
ModernFix.LOGGER.debug("{} {} ID fine: {}", eClass, fieldName, newId);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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 Set<SynchedEntityData> allEntityDatas = Collections.newSetFromMap(new WeakHashMap<>());
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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, Supplier<NetworkEvent.Context> context) {
|
||||||
|
Map<Class<? extends Entity>, List<Pair<String, Integer>>> info = packet.getFieldInfo();
|
||||||
|
context.get().enqueueWork(() -> {
|
||||||
|
boolean fixNeeded = false;
|
||||||
|
for(Map.Entry<Class<? extends Entity>, List<Pair<String, Integer>>> entry : info.entrySet()) {
|
||||||
|
Class<? extends Entity> eClass = entry.getKey();
|
||||||
|
for(Pair<String, Integer> 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<SynchedEntityData> dataEntries;
|
||||||
|
synchronized (allEntityDatas) {
|
||||||
|
if(fixNeeded) {
|
||||||
|
dataEntries = new ArrayList<>(allEntityDatas);
|
||||||
|
for(SynchedEntityData manager : dataEntries) {
|
||||||
|
Int2ObjectMap<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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
allEntityDatas.clear();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
context.get().setPacketHandled(true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -53,7 +53,7 @@ public class BlockStateCacheHandler {
|
||||||
currentRebuildThread = null;
|
currentRebuildThread = null;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ModernFix.LOGGER.warn("Deferred blockstate cache rebuild");
|
ModernFix.LOGGER.debug("Deferred blockstate cache rebuild");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@ public class ModernFixEarlyConfig {
|
||||||
this.addMixinRule("feature.measure_time", true);
|
this.addMixinRule("feature.measure_time", true);
|
||||||
this.addMixinRule("feature.reduce_loading_screen_freezes", false);
|
this.addMixinRule("feature.reduce_loading_screen_freezes", false);
|
||||||
this.addMixinRule("perf.fast_registry_validation", true);
|
this.addMixinRule("perf.fast_registry_validation", true);
|
||||||
|
this.addMixinRule("perf.use_integrated_resources", true);
|
||||||
this.addMixinRule("perf.remove_biome_temperature_cache", true);
|
this.addMixinRule("perf.remove_biome_temperature_cache", true);
|
||||||
this.addMixinRule("perf.reduce_blockstate_cache_rebuilds", true);
|
this.addMixinRule("perf.reduce_blockstate_cache_rebuilds", true);
|
||||||
this.addMixinRule("perf.parallelize_model_loading", true);
|
this.addMixinRule("perf.parallelize_model_loading", true);
|
||||||
|
|
@ -31,6 +32,7 @@ public class ModernFixEarlyConfig {
|
||||||
this.addMixinRule("perf.cache_upgraded_structures", true);
|
this.addMixinRule("perf.cache_upgraded_structures", true);
|
||||||
this.addMixinRule("bugfix.concurrency", true);
|
this.addMixinRule("bugfix.concurrency", true);
|
||||||
this.addMixinRule("bugfix.edge_chunk_not_saved", true);
|
this.addMixinRule("bugfix.edge_chunk_not_saved", true);
|
||||||
|
this.addMixinRule("perf.async_jei", true);
|
||||||
this.addMixinRule("perf.thread_priorities", true);
|
this.addMixinRule("perf.thread_priorities", true);
|
||||||
this.addMixinRule("perf.sync_executor_sleep", true);
|
this.addMixinRule("perf.sync_executor_sleep", true);
|
||||||
this.addMixinRule("perf.scan_cache", true);
|
this.addMixinRule("perf.scan_cache", true);
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
package org.embeddedt.modernfix.duck.reuse_datapacks;
|
||||||
|
|
||||||
|
import net.minecraft.server.ReloadableServerResources;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
public interface ICachingResourceClient {
|
||||||
|
void setCachedResources(ReloadableServerResources r);
|
||||||
|
void setCachedDataPackConfig(Collection<String> c);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,69 @@
|
||||||
|
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.world.entity.Entity;
|
||||||
|
import net.minecraftforge.event.OnDatapackSyncEvent;
|
||||||
|
import net.minecraftforge.eventbus.api.EventPriority;
|
||||||
|
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||||
|
import net.minecraftforge.fml.util.ObfuscationReflectionHelper;
|
||||||
|
import net.minecraftforge.network.PacketDistributor;
|
||||||
|
import net.minecraftforge.server.ServerLifecycleHooks;
|
||||||
|
import org.embeddedt.modernfix.ModernFix;
|
||||||
|
import org.embeddedt.modernfix.packet.EntityIDSyncPacket;
|
||||||
|
import org.embeddedt.modernfix.packet.PacketHandler;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.lang.reflect.Modifier;
|
||||||
|
import java.lang.reflect.ParameterizedType;
|
||||||
|
import java.lang.reflect.Type;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class EntityDataIDSyncHandler {
|
||||||
|
private static Map<Class<? extends Entity>, List<Pair<String, Integer>>> fieldsToSyncMap;
|
||||||
|
@SubscribeEvent(priority = EventPriority.HIGHEST)
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public static void onDatapackSyncEvent(OnDatapackSyncEvent event) {
|
||||||
|
if(event.getPlayer() != null) {
|
||||||
|
if(!ServerLifecycleHooks.getCurrentServer().isDedicatedServer() && event.getPlayerList().getPlayerCount() == 0) {
|
||||||
|
ModernFix.LOGGER.debug("Not syncing IDs on integrated server");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/* Compute the current set of serializer IDs in use and send them */
|
||||||
|
try {
|
||||||
|
if(fieldsToSyncMap == null) {
|
||||||
|
fieldsToSyncMap = new HashMap<>();
|
||||||
|
Field entityPoolField = ObfuscationReflectionHelper.findField(SynchedEntityData.class, "f_135343_");
|
||||||
|
Map<Class<? extends Entity>, Integer> entityPoolMap = (Map<Class<? extends Entity>, Integer>)entityPoolField.get(null);
|
||||||
|
List<Field> fieldsToSync = new ArrayList<>();
|
||||||
|
for(Class<? extends Entity> eClass : entityPoolMap.keySet()) {
|
||||||
|
fieldsToSync.clear();
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EntityIDSyncPacket packet = new EntityIDSyncPacket(fieldsToSyncMap);
|
||||||
|
ModernFix.LOGGER.debug("Sending ID correction packet to client with " + fieldsToSyncMap.size() + " classes");
|
||||||
|
PacketHandler.INSTANCE.send(PacketDistributor.PLAYER.with(event::getPlayer), packet);
|
||||||
|
} catch(ObfuscationReflectionHelper.UnableToFindFieldException | ReflectiveOperationException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,24 @@
|
||||||
|
package org.embeddedt.modernfix.mixin.core;
|
||||||
|
|
||||||
|
import net.minecraft.network.syncher.SynchedEntityData;
|
||||||
|
import net.minecraft.world.entity.Entity;
|
||||||
|
import org.embeddedt.modernfix.ModernFixClient;
|
||||||
|
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)
|
||||||
|
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 = "<init>", at = @At("RETURN"))
|
||||||
|
private void storeInSet(Entity arg, CallbackInfo ci) {
|
||||||
|
synchronized (ModernFixClient.allEntityDatas) {
|
||||||
|
ModernFixClient.allEntityDatas.add((SynchedEntityData)(Object)this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -9,6 +9,7 @@ import net.minecraft.server.packs.VanillaPackResources;
|
||||||
import net.minecraft.server.packs.metadata.pack.PackMetadataSection;
|
import net.minecraft.server.packs.metadata.pack.PackMetadataSection;
|
||||||
import org.apache.commons.lang3.tuple.Pair;
|
import org.apache.commons.lang3.tuple.Pair;
|
||||||
import org.embeddedt.modernfix.FileWalker;
|
import org.embeddedt.modernfix.FileWalker;
|
||||||
|
import org.embeddedt.modernfix.util.FileUtil;
|
||||||
import org.spongepowered.asm.mixin.Final;
|
import org.spongepowered.asm.mixin.Final;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.Overwrite;
|
import org.spongepowered.asm.mixin.Overwrite;
|
||||||
|
|
@ -71,7 +72,7 @@ public class VanillaPackResourcesMixin {
|
||||||
|
|
||||||
@Inject(method = "hasResource", at = @At(value = "INVOKE", target = "Ljava/lang/Class;getResource(Ljava/lang/String;)Ljava/net/URL;"), cancellable = true)
|
@Inject(method = "hasResource", at = @At(value = "INVOKE", target = "Ljava/lang/Class;getResource(Ljava/lang/String;)Ljava/net/URL;"), cancellable = true)
|
||||||
private void useCacheForExistence(PackType type, ResourceLocation location, CallbackInfoReturnable<Boolean> cir) {
|
private void useCacheForExistence(PackType type, ResourceLocation location, CallbackInfoReturnable<Boolean> cir) {
|
||||||
cir.setReturnValue(containedPaths.contains(type.getDirectory() + "/" + location.getNamespace() + "/" + location.getPath()));
|
cir.setReturnValue(containedPaths.contains(type.getDirectory() + "/" + location.getNamespace() + "/" + FileUtil.normalize(location.getPath())));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,6 @@ public class IntegratedServerMixin {
|
||||||
@Inject(method = "<init>", at = @At("RETURN"))
|
@Inject(method = "<init>", at = @At("RETURN"))
|
||||||
private void adjustServerPriority(Thread thread, Minecraft arg, LevelStorageSource.LevelStorageAccess arg2, PackRepository arg3, WorldStem arg4, MinecraftSessionService minecraftSessionService, GameProfileRepository gameProfileRepository, GameProfileCache arg5, ChunkProgressListenerFactory arg6, CallbackInfo ci) {
|
private void adjustServerPriority(Thread thread, Minecraft arg, LevelStorageSource.LevelStorageAccess arg2, PackRepository arg3, WorldStem arg4, MinecraftSessionService minecraftSessionService, GameProfileRepository gameProfileRepository, GameProfileCache arg5, ChunkProgressListenerFactory arg6, CallbackInfo ci) {
|
||||||
int pri = ModernFixConfig.INTEGRATED_SERVER_PRIORITY.get();
|
int pri = ModernFixConfig.INTEGRATED_SERVER_PRIORITY.get();
|
||||||
ModernFix.LOGGER.info("Changing server thread priority to " + pri);
|
|
||||||
thread.setPriority(pri);
|
thread.setPriority(pri);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
package org.embeddedt.modernfix.mixin.perf.use_integrated_resources;
|
||||||
|
|
||||||
|
import jeresources.util.LootTableHelper;
|
||||||
|
import net.minecraft.server.MinecraftServer;
|
||||||
|
import net.minecraft.world.level.Level;
|
||||||
|
import net.minecraftforge.server.ServerLifecycleHooks;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
|
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||||
|
|
||||||
|
@Mixin(LootTableHelper.class)
|
||||||
|
public class LootTableHelperMixin {
|
||||||
|
@Redirect(method = "getLootTables", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/Level;getServer()Lnet/minecraft/server/MinecraftServer;"))
|
||||||
|
private static MinecraftServer useIntegrated(Level level) {
|
||||||
|
MinecraftServer server = level.getServer();
|
||||||
|
if(server != null)
|
||||||
|
return server;
|
||||||
|
return ServerLifecycleHooks.getCurrentServer();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,78 @@
|
||||||
|
package org.embeddedt.modernfix.packet;
|
||||||
|
|
||||||
|
import com.mojang.datafixers.util.Pair;
|
||||||
|
import net.minecraft.network.FriendlyByteBuf;
|
||||||
|
import net.minecraft.network.syncher.EntityDataAccessor;
|
||||||
|
import net.minecraft.world.entity.Entity;
|
||||||
|
import org.embeddedt.modernfix.ModernFix;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.lang.reflect.Modifier;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
public class EntityIDSyncPacket {
|
||||||
|
private Map<Class<? extends Entity>, List<Pair<String, Integer>>> map;
|
||||||
|
|
||||||
|
public EntityIDSyncPacket(Map<Class<? extends Entity>, List<Pair<String, Integer>>> map) {
|
||||||
|
this.map = map;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<Class<? extends Entity>, List<Pair<String, Integer>>> getFieldInfo() {
|
||||||
|
return this.map;
|
||||||
|
}
|
||||||
|
|
||||||
|
public EntityIDSyncPacket() {
|
||||||
|
this.map = new HashMap<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void serialize(FriendlyByteBuf buf) {
|
||||||
|
buf.writeVarInt(map.keySet().size());
|
||||||
|
for(Map.Entry<Class<? extends Entity>, List<Pair<String, Integer>>> entry : map.entrySet()) {
|
||||||
|
buf.writeUtf(entry.getKey().getName());
|
||||||
|
buf.writeVarInt(entry.getValue().size());
|
||||||
|
for(Pair<String, Integer> field : entry.getValue()) {
|
||||||
|
buf.writeUtf(field.getFirst());
|
||||||
|
buf.writeVarInt(field.getSecond());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public static EntityIDSyncPacket deserialize(FriendlyByteBuf buf) {
|
||||||
|
EntityIDSyncPacket self = new EntityIDSyncPacket();
|
||||||
|
int numEntityClasses = buf.readVarInt();
|
||||||
|
for(int i = 0; i < numEntityClasses; i++) {
|
||||||
|
String clzName = buf.readUtf();
|
||||||
|
try {
|
||||||
|
Class<?> clz;
|
||||||
|
try {
|
||||||
|
clz = Class.forName(clzName);
|
||||||
|
} catch(ClassNotFoundException e) {
|
||||||
|
ModernFix.LOGGER.warn("Entity class not found: {}", clzName);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if(!Entity.class.isAssignableFrom(clz)) {
|
||||||
|
ModernFix.LOGGER.error("Not an entity: " + clzName);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
int numFields = buf.readVarInt();
|
||||||
|
for(int j = 0; j < numFields; j++) {
|
||||||
|
String fieldName = buf.readUtf();
|
||||||
|
int id = buf.readVarInt();
|
||||||
|
Field f = clz.getDeclaredField(fieldName);
|
||||||
|
if(!Modifier.isStatic(f.getModifiers()))
|
||||||
|
continue;
|
||||||
|
f.setAccessible(true);
|
||||||
|
if(!EntityDataAccessor.class.isAssignableFrom(f.get(null).getClass())) {
|
||||||
|
ModernFix.LOGGER.error("Not a data accessor field: " + clz + "." + fieldName);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
self.map.computeIfAbsent((Class<? extends Entity>)clz, k -> new ArrayList<>()).add(Pair.of(fieldName, id));
|
||||||
|
}
|
||||||
|
} catch(ReflectiveOperationException e) {
|
||||||
|
ModernFix.LOGGER.error("Error deserializing packet", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
package org.embeddedt.modernfix.packet;
|
||||||
|
|
||||||
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
import net.minecraftforge.network.NetworkRegistry;
|
||||||
|
import net.minecraftforge.network.simple.SimpleChannel;
|
||||||
|
import org.embeddedt.modernfix.ModernFix;
|
||||||
|
import org.embeddedt.modernfix.ModernFixClient;
|
||||||
|
|
||||||
|
public class PacketHandler {
|
||||||
|
private static final String PROTOCOL_VERSION = "1";
|
||||||
|
public static final SimpleChannel INSTANCE = NetworkRegistry.newSimpleChannel(
|
||||||
|
new ResourceLocation(ModernFix.MODID, "main"),
|
||||||
|
() -> PROTOCOL_VERSION,
|
||||||
|
NetworkRegistry.acceptMissingOr(PROTOCOL_VERSION),
|
||||||
|
NetworkRegistry.acceptMissingOr(PROTOCOL_VERSION)
|
||||||
|
);
|
||||||
|
|
||||||
|
public static void register() {
|
||||||
|
int id = 1;
|
||||||
|
INSTANCE.registerMessage(id++, EntityIDSyncPacket.class, EntityIDSyncPacket::serialize, EntityIDSyncPacket::deserialize, ModernFixClient::handleEntityIDSync);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,10 +1,22 @@
|
||||||
package org.embeddedt.modernfix.util;
|
package org.embeddedt.modernfix.util;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
public class FileUtil {
|
public class FileUtil {
|
||||||
public static File childFile(File file) {
|
public static File childFile(File file) {
|
||||||
file.getParentFile().mkdirs();
|
file.getParentFile().mkdirs();
|
||||||
return file;
|
return file;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static final Pattern SLASH_PATTERN = Pattern.compile("(?:\\\\+|\\/+)");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Normalize a path by removing double slashes, etc.
|
||||||
|
* @param path input path
|
||||||
|
* @return a normalized version of the path
|
||||||
|
*/
|
||||||
|
public static String normalize(String path) {
|
||||||
|
return SLASH_PATTERN.matcher(path).replaceAll("/");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,3 +9,5 @@ public net.minecraft.client.renderer.texture.Stitcher$Holder
|
||||||
public net.minecraft.util.thread.BlockableEventLoop m_18699_()V # runAllTasks
|
public net.minecraft.util.thread.BlockableEventLoop m_18699_()V # runAllTasks
|
||||||
public net.minecraft.server.MinecraftServer f_129726_ # nextTickTime
|
public net.minecraft.server.MinecraftServer f_129726_ # nextTickTime
|
||||||
public net.minecraft.client.Minecraft f_90999_ # progressListener
|
public net.minecraft.client.Minecraft f_90999_ # progressListener
|
||||||
|
public-f net.minecraft.network.syncher.EntityDataAccessor f_135010_ # id
|
||||||
|
public-f net.minecraft.network.syncher.SynchedEntityData f_135345_ # itemsById
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
{
|
{
|
||||||
"modernfix.jei_load": "Loading JEI, this may take a while",
|
"modernfix.jei_load": "Loading JEI, this may take a while",
|
||||||
|
"modernfix.no_lazydfu": "ModernFix detected that DFU rules were compiled on startup. This slows down game launching. Installing LazyDFU to resolve this is highly recommended.",
|
||||||
"asynclocator.map.locating": "Map (Locating...)",
|
"asynclocator.map.locating": "Map (Locating...)",
|
||||||
"asynclocator.map.none": "Map (No nearby feature found)"
|
"asynclocator.map.none": "Map (No nearby feature found)"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
{
|
{
|
||||||
"modernfix.jei_load": "正在加载JEI,这需要一点时间",
|
"modernfix.jei_load": "正在加载JEI,这需要一点时间。",
|
||||||
"asynclocator.map.locating": "地图(正在定位...)",
|
"modernfix.no_lazydfu": "现代化修复检测到DFU规则在游戏启动时已被编译。这会降低游戏启动速度。非常推荐安装DFU载入优化来解决这个问题。",
|
||||||
|
"asynclocator.map.locating": "地图(定位中……)",
|
||||||
"asynclocator.map.none": "地图(未能找到相关地物)"
|
"asynclocator.map.none": "地图(未能找到相关地物)"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,7 @@
|
||||||
],
|
],
|
||||||
"client": [
|
"client": [
|
||||||
"core.MinecraftMixin",
|
"core.MinecraftMixin",
|
||||||
|
"core.SynchedEntityDataMixin",
|
||||||
"feature.measure_time.MinecraftMixin",
|
"feature.measure_time.MinecraftMixin",
|
||||||
"feature.reduce_loading_screen_freezes.ModelBakeryMixin",
|
"feature.reduce_loading_screen_freezes.ModelBakeryMixin",
|
||||||
"bugfix.concurrency.MinecraftMixin",
|
"bugfix.concurrency.MinecraftMixin",
|
||||||
|
|
@ -57,6 +58,7 @@
|
||||||
"perf.cache_model_materials.VanillaModelMixin",
|
"perf.cache_model_materials.VanillaModelMixin",
|
||||||
"perf.cache_model_materials.MultipartMixin",
|
"perf.cache_model_materials.MultipartMixin",
|
||||||
"perf.faster_texture_stitching.StitcherMixin",
|
"perf.faster_texture_stitching.StitcherMixin",
|
||||||
|
"perf.use_integrated_resources.LootTableHelperMixin",
|
||||||
"perf.faster_singleplayer_load.MinecraftServerMixin"
|
"perf.faster_singleplayer_load.MinecraftServerMixin"
|
||||||
],
|
],
|
||||||
"injectors": {
|
"injectors": {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user