diff --git a/build.gradle b/build.gradle index 36682f45..cb8ace92 100644 --- a/build.gradle +++ b/build.gradle @@ -4,7 +4,7 @@ plugins { id 'com.matthewprenger.cursegradle' version '1.4.0' } -sourceCompatibility = targetCompatibility = JavaVersion.VERSION_1_8 +sourceCompatibility = targetCompatibility = JavaVersion.VERSION_17 group = 'org.embeddedt' version = '1.6.0-beta3' @@ -66,10 +66,10 @@ dependencies { forge "net.minecraftforge:forge:${project.forge_version}" modRuntimeOnly "curse.maven:lazydfu-460819:${lazydfu_version}" - modCompileOnly("mezz.jei:jei-${minecraft_version}:${jei_version}") - modRuntimeOnly("mezz.jei:jei-${minecraft_version}:${jei_version}") - modCompileOnly("curse.maven:refinedstorage-243076:${refined_storage_version}") + + // compile against the JEI API but do not include it at runtime + modCompileOnly("mezz.jei:jei-${minecraft_version}-forge:${jei_version}") } tasks.withType(JavaCompile) { @@ -79,10 +79,7 @@ tasks.withType(JavaCompile) { // If Javadoc is generated, this must be specified in that task too. options.encoding = "UTF-8" - // The Minecraft launcher currently installs Java 8 for users, so your mod probably wants to target Java 8 too - // JDK 9 introduced a new way of specifying this that will make sure no newer classes or methods are used. - // We'll use that if it's available, but otherwise we'll use the older option. - def targetVersion = 8 + def targetVersion = 17 if (JavaVersion.current().isJava9Compatible()) { options.release = targetVersion } diff --git a/gradle.properties b/gradle.properties index 2dcde3cd..f0e71827 100644 --- a/gradle.properties +++ b/gradle.properties @@ -8,10 +8,9 @@ org.gradle.jvmargs=-Xmx1G loom.platform=forge mod_id=modernfix -minecraft_version=1.16.5 -forge_version=1.16.5-36.2.39 -lazydfu_version=3249059 -mekanism_version=1.16.5-10.1.2.457 -parchment_version=2022.03.06 -jei_version=7.7.1.153 -refined_storage_version=3807951 \ No newline at end of file +minecraft_version=1.18.2 +forge_version=1.18.2-40.2.1 +lazydfu_version=3544496 +parchment_version=2022.11.06 +refined_storage_version=4392829 +jei_version=10.2.1.283 \ No newline at end of file diff --git a/src/main/java/cpw/mods/modlauncher/ModernFixCachingClassTransformer.java b/src/main/java/cpw/mods/modlauncher/ModernFixCachingClassTransformer.java deleted file mode 100644 index 1e09c60b..00000000 --- a/src/main/java/cpw/mods/modlauncher/ModernFixCachingClassTransformer.java +++ /dev/null @@ -1,213 +0,0 @@ -package cpw.mods.modlauncher; - -import java.io.*; -import java.lang.reflect.Array; -import java.lang.reflect.Field; -import java.nio.charset.StandardCharsets; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; -import java.util.*; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.ForkJoinPool; - -import cpw.mods.modlauncher.api.ITransformer; -import cpw.mods.modlauncher.api.ITransformerActivity; -import cpw.mods.modlauncher.serviceapi.ILaunchPluginService; -import net.minecraftforge.coremod.transformer.CoreModBaseTransformer; -import net.minecraftforge.fml.loading.FMLPaths; -import net.minecraftforge.fml.loading.LoadingModList; -import org.apache.commons.io.FileUtils; -import org.apache.commons.lang3.StringUtils; -import org.apache.commons.lang3.tuple.Pair; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.embeddedt.modernfix.ModernFix; -import org.embeddedt.modernfix.classloading.api.IHashableTransformer; -import org.embeddedt.modernfix.classloading.hashers.CoreModTransformerHasher; -import org.embeddedt.modernfix.classloading.hashers.MixinTransformerHasher; -import org.embeddedt.modernfix.util.FileUtil; -import org.objectweb.asm.Type; -import org.spongepowered.asm.launch.MixinLaunchPluginLegacy; - -import javax.lang.model.SourceVersion; - -public class ModernFixCachingClassTransformer extends ClassTransformer { - public static final Logger LOGGER = LogManager.getLogger("ModernFixCachingTransformer"); - - public static File CLASS_CACHE_FOLDER = null; - private final LaunchPluginHandler pluginHandler; - private final Map plugins; - private final TransformStore transformStore; - private final TransformerAuditTrail auditTrail; - private final TransformingClassLoader transformingClassLoader; - private final HashMap>> transformersByClass; - - private ConcurrentHashMap, byte[]>> transformationCache; - private ForkJoinPool classSaverPool = ForkJoinPool.commonPool(); - - public static final byte[] EMPTY_BYTE_ARRAY = new byte[0]; - - public static ThreadLocal systemHasher = ThreadLocal.withInitial(() -> { - try { - return MessageDigest.getInstance("SHA-256"); - } catch(NoSuchAlgorithmException e) { - throw new RuntimeException(e); - } - }); - - public ModernFixCachingClassTransformer(TransformStore transformStore, LaunchPluginHandler pluginHandler, TransformingClassLoader transformingClassLoader, TransformerAuditTrail trail) { - super(transformStore, pluginHandler, transformingClassLoader, trail); - CLASS_CACHE_FOLDER = FileUtil.childFile(FMLPaths.GAMEDIR.get().resolve("modernfix").resolve("classCacheV1").toFile()); - this.transformStore = transformStore; - this.pluginHandler = pluginHandler; - this.transformingClassLoader = transformingClassLoader; - this.auditTrail = trail; - /* Build a lookup table of all transformers for a given class */ - this.transformersByClass = new HashMap<>(); - try { - Field pluginsField = LaunchPluginHandler.class.getDeclaredField("plugins"); - pluginsField.setAccessible(true); - this.plugins = (Map)pluginsField.get(this.pluginHandler); - Field transformersByTypeField = TransformStore.class.getDeclaredField("transformers"); - transformersByTypeField.setAccessible(true); - Field transformersMapField = TransformList.class.getDeclaredField("transformers"); - transformersMapField.setAccessible(true); - EnumMap> transformersByType = (EnumMap>)transformersByTypeField.get(this.transformStore); - for(TransformList transformList : transformersByType.values()) { - Map>> transformers = (Map>>)transformersMapField.get(transformList); - for(Map.Entry>> entry : transformers.entrySet()) { - String className = entry.getKey().getClassName().getClassName(); - List> transformerList = this.transformersByClass.computeIfAbsent(className, k -> new ArrayList<>()); - transformerList.addAll(entry.getValue()); - } - } - for(List> transformerList : this.transformersByClass.values()) { - transformerList.sort((t1, t2) -> Comparator.naturalOrder().compare(StringUtils.join(t1.labels(), " "), StringUtils.join(t2.labels(), " "))); - } - } catch(ReflectiveOperationException e) { - throw new RuntimeException(e); - } - } - - private ArrayList computeHash(String className, byte[] inputClass, String reason) { - final String internalName = className.replace('.', '/'); - final Type classDesc = Type.getObjectType(internalName); - ArrayList pluginList = new ArrayList<>(); - for(ILaunchPluginService plugin : plugins.values()) { - if(!plugin.handlesClass(classDesc, inputClass.length == 0, reason).isEmpty()) { - pluginList.add(plugin); - } - } - final boolean needsTransforming = transformStore.needsTransforming(internalName); - if (!needsTransforming && pluginList.isEmpty()) { - return null; - } - /* Now compute the hash list for the required transformers */ - ArrayList hashList = new ArrayList<>(); - pluginList.sort((service1, service2) -> Comparator.naturalOrder().compare(service1.name(), service2.name())); - for(ILaunchPluginService service : pluginList) { - byte[] hash = obtainHash(service, className); - if(hash == null) { - return null; - } - hashList.add(hash); - } - if(needsTransforming) { - List> transformers = this.transformersByClass.get(internalName); - if(transformers != null) { - for(ITransformer transformer : transformers) { - byte[] hash = obtainHash(transformer, className); - if(hash == null) { - return null; - } - hashList.add(hash); - } - } - } - /* Hash the class itself last, so that we bail out early if plugins can't hash */ - MessageDigest hasher = systemHasher.get(); - hasher.reset(); - hashList.add(hasher.digest(inputClass)); - return hashList; - } - - /** - * Check the hashed list of transformers and use a cached version of the class if possible. This code needs - * to be very fast as the entire point is to spend very little time doing transformation work that was done before. - * @param inputClass The bytecode to be transformed - * @param className Name of the class - * @param reason Reason for the class being loaded - * @return The transformed version of the class - */ - @Override - public byte[] transform(byte[] inputClass, String className, String reason) { - /* We only want to cache actual transformations */ - if(ITransformerActivity.CLASSLOADING_REASON.equals(reason) || "mixin".equals(reason)) { - final byte[] classToHash = inputClass; - ArrayList hashList = computeHash(className, classToHash, reason); - if(hashList == null) - return super.transform(inputClass, className, reason); - /* Check if the cache contains a transformed class matching these hashes */ - /* TODO maybe sanitize the class name? */ - File cacheLocation = new File(CLASS_CACHE_FOLDER, className.replace('.', '/') + "." + reason); - boolean hashesMatch = true; - try(ObjectInputStream stream = new ObjectInputStream(new FileInputStream(cacheLocation))) { - ArrayList savedHash = (ArrayList)stream.readObject(); - byte[] savedInputClass = (byte[])stream.readObject(); - if(hashList != null) { - for(int i = 0; i < savedHash.size(); i++) { - if(!Arrays.equals(savedHash.get(i), hashList.get(i))) { - hashesMatch = false; - break; - } - } - } else - hashesMatch = false; - if(hashesMatch) - inputClass = savedInputClass; - } catch(IOException | ClassNotFoundException | ClassCastException e) { - if(!(e instanceof FileNotFoundException)) - e.printStackTrace(); - hashesMatch = false; - } - if(!hashesMatch) { - inputClass = super.transform(inputClass, className, reason); - if(hashList != null) { - final byte[] classToSave = inputClass; - final ArrayList hashListToSave = hashList; - classSaverPool.submit(() -> { - cacheLocation.getParentFile().mkdirs(); - try(ObjectOutputStream stream = new ObjectOutputStream(new FileOutputStream(cacheLocation))) { - stream.writeObject(hashListToSave); - stream.writeObject(classToSave); - } catch(IOException e) { - e.printStackTrace(); - } - }); - } - - } - return inputClass; - } - return super.transform(inputClass, className, reason); - } - - private final byte[] FORGE_HASH = LoadingModList.get().getModFileById("forge").getMods().get(0).getVersion().toString().getBytes(StandardCharsets.UTF_8); - - private byte[] obtainHash(Object o, String className) { - if(o instanceof CoreModBaseTransformer) { - return CoreModTransformerHasher.obtainHash((CoreModBaseTransformer)o); - } else if(o instanceof MixinLaunchPluginLegacy) { - return MixinTransformerHasher.obtainHash((MixinLaunchPluginLegacy)o, className); - } else if(o instanceof IHashableTransformer) { - return ((IHashableTransformer)o).getHashForClass(className); - } else if(o.getClass().getName().startsWith("net.minecraftforge.")) { - return FORGE_HASH; - } else { - LOGGER.warn("No hash implementation found for: " + o.getClass().getName()); - return null; - } - } -} diff --git a/src/main/java/org/embeddedt/modernfix/ModernFix.java b/src/main/java/org/embeddedt/modernfix/ModernFix.java index 7e5a53fd..c7a297aa 100644 --- a/src/main/java/org/embeddedt/modernfix/ModernFix.java +++ b/src/main/java/org/embeddedt/modernfix/ModernFix.java @@ -2,21 +2,19 @@ package org.embeddedt.modernfix; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.event.server.ServerStartedEvent; import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.fml.DistExecutor; -import net.minecraftforge.fml.ExtensionPoint; +import net.minecraftforge.fml.IExtensionPoint; import net.minecraftforge.fml.ModLoadingContext; import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.config.ModConfig; -import net.minecraftforge.fml.event.server.FMLServerStartedEvent; -import net.minecraftforge.fml.event.server.FMLServerStartingEvent; import net.minecraftforge.fml.loading.FMLLoader; -import net.minecraftforge.fml.network.FMLNetworkConstants; +import net.minecraftforge.network.NetworkConstants; import org.apache.commons.lang3.tuple.Pair; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.embeddedt.modernfix.core.config.ModernFixConfig; -import org.embeddedt.modernfix.structure.AsyncLocator; import java.lang.management.ManagementFactory; @@ -40,12 +38,12 @@ public class ModernFix { // Register ourselves for server and other game events we are interested in MinecraftForge.EVENT_BUS.register(this); DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> MinecraftForge.EVENT_BUS.register(new ModernFixClient())); - ModLoadingContext.get().registerExtensionPoint(ExtensionPoint.DISPLAYTEST, () -> Pair.of(() -> FMLNetworkConstants.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); } @SubscribeEvent - public void onServerStarted(FMLServerStartedEvent event) { + public void onServerStarted(ServerStartedEvent event) { if(FMLLoader.getDist() == Dist.DEDICATED_SERVER) { float gameStartTime = ManagementFactory.getRuntimeMXBean().getUptime() / 1000f; ModernFix.LOGGER.warn("Dedicated server took " + gameStartTime + " seconds to load"); diff --git a/src/main/java/org/embeddedt/modernfix/ModernFixClient.java b/src/main/java/org/embeddedt/modernfix/ModernFixClient.java index 33974e37..e9d58f1d 100644 --- a/src/main/java/org/embeddedt/modernfix/ModernFixClient.java +++ b/src/main/java/org/embeddedt/modernfix/ModernFixClient.java @@ -3,7 +3,7 @@ package org.embeddedt.modernfix; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.screens.ConnectScreen; import net.minecraft.client.gui.screens.TitleScreen; -import net.minecraftforge.client.event.GuiOpenEvent; +import net.minecraftforge.client.event.ScreenOpenEvent; import net.minecraftforge.event.TickEvent; import net.minecraftforge.eventbus.api.EventPriority; import net.minecraftforge.eventbus.api.SubscribeEvent; @@ -23,10 +23,10 @@ public class ModernFixClient { } @SubscribeEvent(priority = EventPriority.LOWEST) - public void onMultiplayerConnect(GuiOpenEvent event) { - if(event.getGui() instanceof ConnectScreen && !event.isCanceled()) { + public void onMultiplayerConnect(ScreenOpenEvent event) { + if(event.getScreen() instanceof ConnectScreen && !event.isCanceled()) { worldLoadStartTime = System.nanoTime(); - } else if (event.getGui() instanceof TitleScreen && gameStartTimeSeconds < 0) { + } else if (event.getScreen() instanceof TitleScreen && gameStartTimeSeconds < 0) { gameStartTimeSeconds = ManagementFactory.getRuntimeMXBean().getUptime() / 1000f; ModernFix.LOGGER.warn("Game took " + gameStartTimeSeconds + " seconds to start"); } diff --git a/src/main/java/org/embeddedt/modernfix/classloading/ModernFixResourceFinder.java b/src/main/java/org/embeddedt/modernfix/classloading/ModernFixResourceFinder.java deleted file mode 100644 index eaca9b5f..00000000 --- a/src/main/java/org/embeddedt/modernfix/classloading/ModernFixResourceFinder.java +++ /dev/null @@ -1,114 +0,0 @@ -package org.embeddedt.modernfix.classloading; - -import com.google.common.collect.Lists; -import cpw.mods.modlauncher.api.LamdbaExceptionUtils; -import net.minecraftforge.fml.loading.FMLLoader; -import net.minecraftforge.fml.loading.LoadingModList; -import net.minecraftforge.fml.loading.moddiscovery.*; -import net.minecraftforge.forgespi.language.IModInfo; -import net.minecraftforge.forgespi.locating.IModFile; -import net.minecraftforge.forgespi.locating.IModLocator; -import org.apache.commons.lang3.tuple.Pair; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - -import java.io.IOException; -import java.lang.reflect.Field; -import java.net.URL; -import java.nio.file.FileSystem; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.*; -import java.util.regex.Pattern; -import java.util.stream.Stream; - -public class ModernFixResourceFinder { - private static HashMap> urlsForClass = null; - private static final Class MINECRAFT_LOCATOR; - private static Field explodedDirModsField = null; - private static final Logger LOGGER = LogManager.getLogger("ModernFixResourceFinder"); - static { - try { - MINECRAFT_LOCATOR = (Class)Class.forName("net.minecraftforge.fml.loading.moddiscovery.ModDiscoverer$MinecraftLocator"); - } catch(ClassNotFoundException e) { - /* that shouldn't happen */ - throw new RuntimeException(e); - } - } - public static synchronized void init() throws ReflectiveOperationException { - urlsForClass = new HashMap<>(); - LOGGER.info("Start building list of class locations..."); - for(ModFileInfo fileInfo : LoadingModList.get().getModFiles()) { - ModFile file = fileInfo.getFile(); - IModLocator locator = file.getLocator(); - Iterable rootPath = getRootPathForLocator(locator, file); - for(Path root : rootPath) { - try(Stream stream = Files.walk(root)) { - stream - .map(root::relativize) - .forEach(path -> { - String strPath = path.toString(); - URL url = (URL)LamdbaExceptionUtils.uncheck(() -> { - return new URL("modjar://" + fileInfo.getMods().get(0).getModId() + "/" + strPath); - }); - List urlList = urlsForClass.get(strPath); - if(urlList != null) { - if(urlList.size() > 1) - urlList.add(url); - else { - /* Convert singleton to real list */ - ArrayList newList = new ArrayList<>(urlList); - newList.add(url); - urlsForClass.put(strPath, newList); - } - } else { - /* Use a singleton list initially to keep memory usage down */ - urlsForClass.put(strPath, Collections.singletonList(url)); - } - }); - } catch(IOException e) { - throw new RuntimeException(e); - } - } - } - for(List list : urlsForClass.values()) { - if(list instanceof ArrayList) - ((ArrayList)list).trimToSize(); - } - LOGGER.info("Finish building"); - } - - private static Iterable getRootPathForLocator(IModLocator locator, ModFile file) throws ReflectiveOperationException { - if(locator instanceof AbstractJarFileLocator) { - FileSystem modFs = locator.findPath(file, ".").getFileSystem(); - return modFs.getRootDirectories(); - } else if (locator instanceof ExplodedDirectoryLocator) { - if(explodedDirModsField == null) { - explodedDirModsField = ExplodedDirectoryLocator.class.getDeclaredField("mods"); - explodedDirModsField.setAccessible(true); - } - Map>> mods = (Map>>)explodedDirModsField.get(locator); - return mods.get(file).getRight(); - } else if(MINECRAFT_LOCATOR.isAssignableFrom(locator.getClass())) { - Path mcJar = FMLLoader.getMCPaths()[0]; - if(Files.isDirectory(mcJar)) { - return mcJar; - } else { - return locator.findPath(file, ".").getFileSystem().getRootDirectories(); - } - } else - throw new UnsupportedOperationException("Unknown ModLocator type: " + locator.getClass().getName()); - } - - private static final Pattern SLASH_REPLACER = Pattern.compile("/+"); - - public static Enumeration findAllURLsForResource(String input) { - input = SLASH_REPLACER.matcher(input).replaceAll("/"); - List urlList = urlsForClass.get(input); - if(urlList != null) - return Collections.enumeration(urlList); - else { - return Collections.emptyEnumeration(); - } - } -} diff --git a/src/main/java/org/embeddedt/modernfix/classloading/api/IHashableTransformer.java b/src/main/java/org/embeddedt/modernfix/classloading/api/IHashableTransformer.java deleted file mode 100644 index f867a16e..00000000 --- a/src/main/java/org/embeddedt/modernfix/classloading/api/IHashableTransformer.java +++ /dev/null @@ -1,11 +0,0 @@ -package org.embeddedt.modernfix.classloading.api; - -public interface IHashableTransformer { - /** - * Called on an ILaunchPluginService or ITransformer to obtain a unique hash of the transformations that will be applied. - * Used to invalidate the transformation cache when needed. - * @param className Name of class being transformed - * @return A unique hash of the transformations that will be applied - */ - byte[] getHashForClass(String className); -} diff --git a/src/main/java/org/embeddedt/modernfix/classloading/hashers/CoreModTransformerHasher.java b/src/main/java/org/embeddedt/modernfix/classloading/hashers/CoreModTransformerHasher.java deleted file mode 100644 index fa4f602e..00000000 --- a/src/main/java/org/embeddedt/modernfix/classloading/hashers/CoreModTransformerHasher.java +++ /dev/null @@ -1,49 +0,0 @@ -package org.embeddedt.modernfix.classloading.hashers; - -import cpw.mods.modlauncher.ModernFixCachingClassTransformer; -import net.minecraftforge.coremod.CoreMod; -import net.minecraftforge.coremod.transformer.CoreModBaseTransformer; - -import java.io.IOException; -import java.lang.reflect.Field; -import java.nio.file.Files; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; -import java.util.concurrent.ConcurrentHashMap; - -public class CoreModTransformerHasher { - private static final ConcurrentHashMap hashForCoremod; - private static Field coremodField; - - static { - hashForCoremod = new ConcurrentHashMap<>(); - try { - coremodField = CoreModBaseTransformer.class.getDeclaredField("coreMod"); - coremodField.setAccessible(true); - } catch(ReflectiveOperationException e) { - throw new RuntimeException(e); - } - } - - private static byte[] hashCoreMod(CoreMod coreMod) { - byte[] coreModContents; - try { - coreModContents = Files.readAllBytes(coreMod.getPath()); - } catch(IOException e) { - throw new RuntimeException(e); - } - MessageDigest hasher = ModernFixCachingClassTransformer.systemHasher.get(); - hasher.reset(); - return hasher.digest(coreModContents); - } - - public static byte[] obtainHash(CoreModBaseTransformer transformer) { - CoreMod coremod; - try { - coremod = (CoreMod)coremodField.get(transformer); - } catch(ReflectiveOperationException e) { - throw new RuntimeException(e); - } - return hashForCoremod.computeIfAbsent(coremod, CoreModTransformerHasher::hashCoreMod); - } -} diff --git a/src/main/java/org/embeddedt/modernfix/classloading/hashers/MixinTransformerHasher.java b/src/main/java/org/embeddedt/modernfix/classloading/hashers/MixinTransformerHasher.java deleted file mode 100644 index 1716dcd3..00000000 --- a/src/main/java/org/embeddedt/modernfix/classloading/hashers/MixinTransformerHasher.java +++ /dev/null @@ -1,154 +0,0 @@ -package org.embeddedt.modernfix.classloading.hashers; - -import com.google.common.io.Resources; -import cpw.mods.modlauncher.ModernFixCachingClassTransformer; -import org.spongepowered.asm.launch.IClassProcessor; -import org.spongepowered.asm.launch.MixinLaunchPluginLegacy; -import org.spongepowered.asm.mixin.MixinEnvironment; -import org.spongepowered.asm.mixin.extensibility.IMixinInfo; -import org.spongepowered.asm.mixin.injection.invoke.arg.ArgsClassGenerator; -import org.spongepowered.asm.mixin.transformer.ext.Extensions; - -import java.io.IOException; -import java.lang.reflect.Field; -import java.net.URL; -import java.nio.file.Files; -import java.nio.file.Path; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; -import java.util.*; -import java.util.stream.Stream; - -public class MixinTransformerHasher { - private static HashMap hashesByClass = null; - private final static MessageDigest hasher; - - private static Field processorsListField, transformerField, processorField, environmentField; - - private static boolean fixedArgsClassCount = false; - - private static final byte[] NO_MIXINS = new byte[] {(byte)0xde, (byte)0xad, (byte)0xbe, (byte)0xef}; - - static { - try { - hasher = MessageDigest.getInstance("SHA-256"); - } catch (NoSuchAlgorithmException e) { - throw new RuntimeException(e); - } - } - - public static byte[] obtainHash(MixinLaunchPluginLegacy plugin, String className) { - /* FIXME runs too early right now, and therefore doesn't pick up the list of mixins correctly */ - synchronized (MixinTransformerHasher.class) { - if(hashesByClass == null) { - try { - if(processorsListField == null) { - processorsListField = MixinLaunchPluginLegacy.class.getDeclaredField("processors"); - processorsListField.setAccessible(true); - } - List processors = (List) processorsListField.get(plugin); - Object transformHandler = null; - for(IClassProcessor processor : processors) { - if(processor.getClass().getName().equals("org.spongepowered.asm.service.modlauncher.MixinTransformationHandler")) { - transformHandler = processor; - break; - } - } - if(transformHandler == null) - throw new IllegalStateException("Mixin transform handler not found"); - if(transformerField == null) { - transformerField = transformHandler.getClass().getDeclaredField("transformer"); - transformerField.setAccessible(true); - } - Object transformer = transformerField.get(transformHandler); - if(!fixedArgsClassCount) { - Path syntheticFolderPath = ModernFixCachingClassTransformer.CLASS_CACHE_FOLDER.toPath().resolve("org").resolve("spongepowered").resolve("asm").resolve("synthetic"); - if(Files.exists(syntheticFolderPath)) { - Field extensionsField = transformer.getClass().getDeclaredField("extensions"); - extensionsField.setAccessible(true); - Extensions extensions = (Extensions)extensionsField.get(transformer); - ArgsClassGenerator argsGen = extensions.getGenerator(ArgsClassGenerator.class); - Field nextIndexField = ArgsClassGenerator.class.getDeclaredField("nextIndex"); - try(Stream argsStream = Files.find(syntheticFolderPath, 1, (path, attr) -> path.getFileName().toString().startsWith("Args$"))) { - int[] startIndex = new int[1]; - startIndex[0] = 1; - argsStream.forEach(path -> { - String fileName = path.getFileName().toString(); - try { - int idx = Integer.parseInt(fileName.replace("Args$", "")); - startIndex[0] = Math.max(startIndex[0], idx + 1); - } catch(NumberFormatException e) { - ModernFixCachingClassTransformer.LOGGER.warn("Unexpected classname: " + fileName); - } - }); - nextIndexField.setAccessible(true); - nextIndexField.set(argsGen, startIndex[0]); - ModernFixCachingClassTransformer.LOGGER.debug("Patched ArgsClassGenerator to start at index " + startIndex[0]); - } catch(IOException e) { - ModernFixCachingClassTransformer.LOGGER.error("Failed to adjust Mixin synthetic args"); - } - } - - fixedArgsClassCount = true; - } - if(processorField == null) { - processorField = transformer.getClass().getDeclaredField("processor"); - processorField.setAccessible(true); - } - Object processor = processorField.get(transformer); - if(environmentField == null) { - environmentField = processor.getClass().getDeclaredField("currentEnvironment"); - environmentField.setAccessible(true); - } - MixinEnvironment currentEnv = (MixinEnvironment)environmentField.get(processor); - if(currentEnv == null || currentEnv.getPhase() != MixinEnvironment.Phase.DEFAULT) { - return null; /* no hash obtained until mixin is ready */ - } - Field configsField = processor.getClass().getDeclaredField("configs"); - configsField.setAccessible(true); - List configs = (List)configsField.get(processor); - Field mixinsField = Class.forName("org.spongepowered.asm.mixin.transformer.MixinConfig").getDeclaredField("mixins"); - mixinsField.setAccessible(true); - /* getTargetClasses can't be used because it's package-private */ - Field classNamesField = Class.forName("org.spongepowered.asm.mixin.transformer.MixinInfo").getDeclaredField("targetClassNames"); - classNamesField.setAccessible(true); - HashMap> mixinsByClass = new HashMap<>(); - for(Object config : configs) { - List mixins = (List)mixinsField.get(config); - for(IMixinInfo mixin : mixins) { - List targetClassNames = (List)classNamesField.get(mixin); - for(String s : targetClassNames) { - mixinsByClass.computeIfAbsent(s, k -> new ArrayList<>()).add(mixin); - } - } - } - for(ArrayList infos : mixinsByClass.values()) { - infos.sort((info1, info2) -> Comparator.naturalOrder().compare(info1.getClassName(), info2.getClassName())); - } - /* Now go through each class name and hash it */ - HashMap hashesByClassInit = new HashMap<>(); - for(Map.Entry> mixinsForClass : mixinsByClass.entrySet()) { - hasher.reset(); - for(IMixinInfo mixin : mixinsForClass.getValue()) { - URL url = Thread.currentThread().getContextClassLoader().getResource(mixin.getClassName().replace('.', '/') + ".class"); - if(url == null) - throw new IllegalStateException("Can't find " + mixin.getClassName()); - byte[] bytecode; - try { - bytecode = Resources.asByteSource(url).read(); - } catch(IOException e) { - throw new RuntimeException(e); - } - hasher.update(bytecode); - } - hashesByClassInit.put(mixinsForClass.getKey().replace('/', '.'), hasher.digest()); - } - hashesByClass = hashesByClassInit; - } catch(ReflectiveOperationException e) { - throw new RuntimeException(e); - } - } - } - return hashesByClass.getOrDefault(className, NO_MIXINS); - } -} diff --git a/src/main/java/org/embeddedt/modernfix/core/ModernFixMixinPlugin.java b/src/main/java/org/embeddedt/modernfix/core/ModernFixMixinPlugin.java index c9157924..09064e3f 100644 --- a/src/main/java/org/embeddedt/modernfix/core/ModernFixMixinPlugin.java +++ b/src/main/java/org/embeddedt/modernfix/core/ModernFixMixinPlugin.java @@ -1,12 +1,7 @@ package org.embeddedt.modernfix.core; -import com.google.common.io.Resources; -import cpw.mods.modlauncher.*; -import cpw.mods.modlauncher.api.LamdbaExceptionUtils; -import net.minecraftforge.fml.common.ObfuscationReflectionHelper; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import org.embeddedt.modernfix.classloading.ModernFixResourceFinder; import org.embeddedt.modernfix.core.config.ModernFixEarlyConfig; import org.embeddedt.modernfix.core.config.Option; import org.objectweb.asm.tree.ClassNode; @@ -14,14 +9,7 @@ import org.spongepowered.asm.mixin.extensibility.IMixinConfigPlugin; import org.spongepowered.asm.mixin.extensibility.IMixinInfo; import java.io.File; -import java.io.IOException; -import java.lang.reflect.Constructor; -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.net.URL; -import java.net.URLClassLoader; import java.util.*; -import java.util.function.Function; public class ModernFixMixinPlugin implements IMixinConfigPlugin { private static final String MIXIN_PACKAGE_ROOT = "org.embeddedt.modernfix.mixin."; @@ -38,88 +26,11 @@ public class ModernFixMixinPlugin implements IMixinConfigPlugin { this.logger.info("Loaded configuration file for ModernFix: {} options available, {} override(s) found", config.getOptionCount(), config.getOptionOverrideCount()); - - /* We abuse the constructor of a mixin plugin as a safe location to start modifying the classloader */ - /* Swap the transformer for ours */ - ClassLoader loader = Thread.currentThread().getContextClassLoader(); - if(!(loader instanceof TransformingClassLoader)) { - throw new IllegalStateException("Expected a TransformingClassLoader"); - } - try { - if(isOptionEnabled("launch.class_search_cache.ModernFixResourceFinder")) { - Field resourceFinderField = TransformingClassLoader.class.getDeclaredField("resourceFinder"); - /* Construct a new list of resource finders, using similar logic to ML */ - resourceFinderField.setAccessible(true); - Function> resourceFinder = constructResourceFinder(); - /* Merge with the findResources implementation provided by the DelegatedClassLoader */ - Field dclField = TransformingClassLoader.class.getDeclaredField("delegatedClassLoader"); - dclField.setAccessible(true); - URLClassLoader dcl = (URLClassLoader)dclField.get(loader); - resourceFinder = EnumerationHelper.mergeFunctors(resourceFinder, LamdbaExceptionUtils.rethrowFunction(dcl::findResources)); - resourceFinderField.set(loader, resourceFinder); - } - } catch(RuntimeException | ReflectiveOperationException e) { - logger.error("Failed to make classloading changes", e); - } - } - - private Method defineClassMethod = null; - - private Class injectClassIntoSystemLoader(String className) throws ReflectiveOperationException, IOException { - ClassLoader systemLoader = ClassTransformer.class.getClassLoader(); - if(defineClassMethod == null) { - defineClassMethod = ClassLoader.class.getDeclaredMethod("defineClass", String.class, byte[].class, int.class, int.class); - defineClassMethod.setAccessible(true); - } - byte[] newTransformerBytes = Resources.toByteArray(ModernFixMixinPlugin.class.getResource("/" + className.replace('.', '/') + ".class")); - return (Class)defineClassMethod.invoke(systemLoader, className, newTransformerBytes, 0, newTransformerBytes.length); - } - - private Function> constructResourceFinder() throws ReflectiveOperationException { - ModernFixResourceFinder.init(); - Field servicesHandlerField = Launcher.class.getDeclaredField("transformationServicesHandler"); - servicesHandlerField.setAccessible(true); - Object servicesHandler = servicesHandlerField.get(Launcher.INSTANCE); - Field serviceLookupField = servicesHandler.getClass().getDeclaredField("serviceLookup"); - serviceLookupField.setAccessible(true); - Map serviceLookup = (Map)serviceLookupField.get(servicesHandler); - Method getClassLoaderMethod = TransformationServiceDecorator.class.getDeclaredMethod("getClassLoader"); - getClassLoaderMethod.setAccessible(true); - Function> resourceEnumeratorLocator = ModernFixResourceFinder::findAllURLsForResource; - for(TransformationServiceDecorator decorator : serviceLookup.values()) { - Function> func = (Function>)getClassLoaderMethod.invoke(decorator); - if(func != null) { - resourceEnumeratorLocator = EnumerationHelper.mergeFunctors(resourceEnumeratorLocator, EnumerationHelper.fromOptional(func)); - } - } - return resourceEnumeratorLocator; } @Override - public void onLoad(String mixinPackage) { - try { - if(isOptionEnabled("launch.transformer_cache.ModernFixClassTransformer")) { - ClassLoader loader = Thread.currentThread().getContextClassLoader(); - Field classTransformerField = TransformingClassLoader.class.getDeclaredField("classTransformer"); - classTransformerField.setAccessible(true); - ClassTransformer t = (ClassTransformer)classTransformerField.get(loader); - TransformStore store = ObfuscationReflectionHelper.getPrivateValue(ClassTransformer.class, t, "transformers"); - LaunchPluginHandler pluginHandler = ObfuscationReflectionHelper.getPrivateValue(ClassTransformer.class, t, "pluginHandler"); - TransformerAuditTrail trail = ObfuscationReflectionHelper.getPrivateValue(ClassTransformer.class, t, "auditTrail"); - injectClassIntoSystemLoader("org.embeddedt.modernfix.util.FileUtil"); - injectClassIntoSystemLoader("org.embeddedt.modernfix.classloading.api.IHashableTransformer"); - injectClassIntoSystemLoader("org.embeddedt.modernfix.classloading.hashers.CoreModTransformerHasher"); - injectClassIntoSystemLoader("org.embeddedt.modernfix.classloading.hashers.MixinTransformerHasher"); - Class newTransformerClass = injectClassIntoSystemLoader("cpw.mods.modlauncher.ModernFixCachingClassTransformer"); - Constructor constructor = newTransformerClass.getConstructor(TransformStore.class, LaunchPluginHandler.class, TransformingClassLoader.class, TransformerAuditTrail.class); - ClassTransformer newTransformer = (ClassTransformer)constructor.newInstance(store, pluginHandler, loader, trail); - classTransformerField.set(loader, newTransformer); + public void onLoad(String s) { - logger.info("Successfully injected caching transformer"); - } - } catch(RuntimeException | ReflectiveOperationException | IOException e) { - logger.error("Failed to make classloading changes", e); - } } @Override diff --git a/src/main/java/org/embeddedt/modernfix/core/config/ModernFixConfig.java b/src/main/java/org/embeddedt/modernfix/core/config/ModernFixConfig.java index c4e6d610..3dbbc3f6 100644 --- a/src/main/java/org/embeddedt/modernfix/core/config/ModernFixConfig.java +++ b/src/main/java/org/embeddedt/modernfix/core/config/ModernFixConfig.java @@ -7,6 +7,7 @@ import net.minecraftforge.common.ForgeConfigSpec; import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.config.ModConfig; +import net.minecraftforge.fml.event.config.ModConfigEvent; import org.embeddedt.modernfix.ModernFix; import java.util.Collections; @@ -52,7 +53,7 @@ public class ModernFixConfig { } @SubscribeEvent - public static void onModConfigEvent(final ModConfig.ModConfigEvent configEvent) { + public static void onModConfigEvent(final ModConfigEvent configEvent) { if (configEvent.getConfig().getSpec() == COMMON_CONFIG) { bakeConfig(); } diff --git a/src/main/java/org/embeddedt/modernfix/core/config/ModernFixEarlyConfig.java b/src/main/java/org/embeddedt/modernfix/core/config/ModernFixEarlyConfig.java index d4c8e106..0d7d0f65 100644 --- a/src/main/java/org/embeddedt/modernfix/core/config/ModernFixEarlyConfig.java +++ b/src/main/java/org/embeddedt/modernfix/core/config/ModernFixEarlyConfig.java @@ -20,30 +20,20 @@ public class ModernFixEarlyConfig { this.addMixinRule("feature.measure_time", true); this.addMixinRule("feature.reduce_loading_screen_freezes", false); this.addMixinRule("perf.remove_biome_temperature_cache", true); - this.addMixinRule("perf.resourcepacks", true); this.addMixinRule("perf.reduce_blockstate_cache_rebuilds", true); - this.addMixinRule("perf.boost_worker_count", true); - this.addMixinRule("perf.skip_first_datapack_reload", true); this.addMixinRule("perf.parallelize_model_loading", true); this.addMixinRule("perf.parallelize_model_loading.multipart", false); this.addMixinRule("bugfix.concurrency", true); this.addMixinRule("bugfix.edge_chunk_not_saved", true); - this.addMixinRule("bugfix.packet_leak", false); - this.addMixinRule("bugfix.structure_manager_crash", true); - this.addMixinRule("perf.async_jei", true); this.addMixinRule("perf.thread_priorities", true); - this.addMixinRule("perf.preload_block_classes", false); this.addMixinRule("perf.sync_executor_sleep", true); this.addMixinRule("perf.scan_cache", true); - this.addMixinRule("perf.compress_biome_container", true); - this.addMixinRule("perf.nuke_empty_chunk_sections", true); this.addMixinRule("perf.flatten_model_predicates", true); this.addMixinRule("perf.deduplicate_location", false); this.addMixinRule("perf.cache_blockstate_cache_arrays", true); this.addMixinRule("perf.faster_baking", true); this.addMixinRule("perf.cache_model_materials", true); this.addMixinRule("perf.datapack_reload_exceptions", true); - this.addMixinRule("perf.async_locator", true); /* Keep this off if JEI isn't installed to prevent breaking vanilla gameplay */ this.addMixinRule("perf.blast_search_trees", FMLLoader.getLoadingModList().getModFileById("jei") != null); this.addMixinRule("safety", true); diff --git a/src/main/java/org/embeddedt/modernfix/jei/async/IAsyncJeiStarter.java b/src/main/java/org/embeddedt/modernfix/jei/async/IAsyncJeiStarter.java deleted file mode 100644 index 3147af8f..00000000 --- a/src/main/java/org/embeddedt/modernfix/jei/async/IAsyncJeiStarter.java +++ /dev/null @@ -1,8 +0,0 @@ -package org.embeddedt.modernfix.jei.async; - -public interface IAsyncJeiStarter { - static void checkForLoadInterruption() { - if(((JEIReloadThread)Thread.currentThread()).isStopRequested()) - throw new JEILoadingInterruptedException(); - } -} diff --git a/src/main/java/org/embeddedt/modernfix/jei/async/JEILoadingInterruptedException.java b/src/main/java/org/embeddedt/modernfix/jei/async/JEILoadingInterruptedException.java deleted file mode 100644 index 9272c2f5..00000000 --- a/src/main/java/org/embeddedt/modernfix/jei/async/JEILoadingInterruptedException.java +++ /dev/null @@ -1,4 +0,0 @@ -package org.embeddedt.modernfix.jei.async; - -public class JEILoadingInterruptedException extends Error { -} diff --git a/src/main/java/org/embeddedt/modernfix/jei/async/JEIReloadThread.java b/src/main/java/org/embeddedt/modernfix/jei/async/JEIReloadThread.java deleted file mode 100644 index c1b3eaa4..00000000 --- a/src/main/java/org/embeddedt/modernfix/jei/async/JEIReloadThread.java +++ /dev/null @@ -1,18 +0,0 @@ -package org.embeddedt.modernfix.jei.async; - -public class JEIReloadThread extends Thread { - private volatile boolean stopRequested; - - public JEIReloadThread(Runnable runnable, String s) { - super(runnable, s); - this.stopRequested = false; - } - - public void requestStop() { - stopRequested = true; - } - - public boolean isStopRequested() { - return stopRequested; - } -} diff --git a/src/main/java/org/embeddedt/modernfix/mixin/bugfix/concurrency/RenderTypeMixin.java b/src/main/java/org/embeddedt/modernfix/mixin/bugfix/concurrency/RenderTypeMixin.java deleted file mode 100644 index c28f7a1f..00000000 --- a/src/main/java/org/embeddedt/modernfix/mixin/bugfix/concurrency/RenderTypeMixin.java +++ /dev/null @@ -1,25 +0,0 @@ -package org.embeddedt.modernfix.mixin.bugfix.concurrency; - -import it.unimi.dsi.fastutil.objects.ObjectOpenCustomHashSet; -import net.minecraft.client.renderer.RenderType; -import com.mojang.blaze3d.vertex.VertexFormat; -import org.spongepowered.asm.mixin.Final; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Overwrite; -import org.spongepowered.asm.mixin.Shadow; - -@Mixin(RenderType.CompositeRenderType.class) -public class RenderTypeMixin { - @Shadow @Final private static ObjectOpenCustomHashSet INSTANCES; - - /** - * @author embeddedt - * @reason synchronize, can be accessed by multiple mods during modloading - */ - @Overwrite - private static RenderType.CompositeRenderType memoize(String name, VertexFormat format, int drawMode, int bufferSize, boolean useDelegate, boolean needsSorting, RenderType.CompositeState renderState) { - synchronized (INSTANCES){ - return INSTANCES.addOrGet(new RenderType.CompositeRenderType(name, format, drawMode, bufferSize, useDelegate, needsSorting, renderState)); - } - } -} diff --git a/src/main/java/org/embeddedt/modernfix/mixin/bugfix/packet_leak/ClientPlayNetHandlerMixin.java b/src/main/java/org/embeddedt/modernfix/mixin/bugfix/packet_leak/ClientPlayNetHandlerMixin.java deleted file mode 100644 index 5fa5cba0..00000000 --- a/src/main/java/org/embeddedt/modernfix/mixin/bugfix/packet_leak/ClientPlayNetHandlerMixin.java +++ /dev/null @@ -1,31 +0,0 @@ -package org.embeddedt.modernfix.mixin.bugfix.packet_leak; - -import net.minecraft.client.multiplayer.ClientPacketListener; -import net.minecraft.network.FriendlyByteBuf; -import net.minecraft.network.protocol.game.ClientboundCustomPayloadPacket; -import org.embeddedt.modernfix.duck.IClientNetHandler; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Redirect; - -@Mixin(ClientPacketListener.class) -public class ClientPlayNetHandlerMixin implements IClientNetHandler { - private FriendlyByteBuf savedCopy = null; - /** - * @author embeddedt - * @reason Release the packet buffer at the end. Needed in f - */ - @Redirect(method = "handleCustomPayload", at = @At(value = "INVOKE", target = "Lnet/minecraft/network/protocol/game/ClientboundCustomPayloadPacket;getData()Lnet/minecraft/network/FriendlyByteBuf;")) - private FriendlyByteBuf saveCopyForRelease(ClientboundCustomPayloadPacket instance) { - FriendlyByteBuf copy = instance.getData(); - savedCopy = copy; - return copy; - } - - @Override - public FriendlyByteBuf getCopiedCustomBuffer() { - FriendlyByteBuf copy = savedCopy; - savedCopy = null; - return copy; - } -} diff --git a/src/main/java/org/embeddedt/modernfix/mixin/bugfix/packet_leak/SCustomPayloadPlayPacketMixin.java b/src/main/java/org/embeddedt/modernfix/mixin/bugfix/packet_leak/SCustomPayloadPlayPacketMixin.java deleted file mode 100644 index 739ee1d3..00000000 --- a/src/main/java/org/embeddedt/modernfix/mixin/bugfix/packet_leak/SCustomPayloadPlayPacketMixin.java +++ /dev/null @@ -1,43 +0,0 @@ -package org.embeddedt.modernfix.mixin.bugfix.packet_leak; - -import net.minecraft.network.protocol.game.ClientGamePacketListener; -import net.minecraft.network.FriendlyByteBuf; -import net.minecraft.network.protocol.game.ClientboundCustomPayloadPacket; -import net.minecraft.resources.ResourceLocation; -import org.embeddedt.modernfix.duck.IClientNetHandler; -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.Redirect; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -@Mixin(ClientboundCustomPayloadPacket.class) -public class SCustomPayloadPlayPacketMixin { - @Shadow private FriendlyByteBuf data; - - private boolean needsRelease; - - @Inject(method = "(Lnet/minecraft/resources/ResourceLocation;Lnet/minecraft/network/FriendlyByteBuf;)V", at = @At("RETURN")) - private void markNotOwned(ResourceLocation pIdentifier, FriendlyByteBuf pData, CallbackInfo ci) { - this.needsRelease = false; - } - - @Inject(method = "read", at = @At("RETURN")) - private void markOwned(FriendlyByteBuf p_148837_1_, CallbackInfo ci) { - this.needsRelease = true; - } - - @Redirect(method = "handle(Lnet/minecraft/network/protocol/game/ClientGamePacketListener;)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/network/protocol/game/ClientGamePacketListener;handleCustomPayload(Lnet/minecraft/network/protocol/game/ClientboundCustomPayloadPacket;)V")) - private void handleAndFree(ClientGamePacketListener instance, ClientboundCustomPayloadPacket sCustomPayloadPlayPacket) { - try { - instance.handleCustomPayload(sCustomPayloadPlayPacket); - } finally { - FriendlyByteBuf copied = ((IClientNetHandler)instance).getCopiedCustomBuffer(); - if(copied != null) - copied.release(); - } - if(this.needsRelease) - this.data.release(); - } -} diff --git a/src/main/java/org/embeddedt/modernfix/mixin/bugfix/structure_manager_crash/StructureManagerMixin.java b/src/main/java/org/embeddedt/modernfix/mixin/bugfix/structure_manager_crash/StructureManagerMixin.java deleted file mode 100644 index 5aacf946..00000000 --- a/src/main/java/org/embeddedt/modernfix/mixin/bugfix/structure_manager_crash/StructureManagerMixin.java +++ /dev/null @@ -1,27 +0,0 @@ -package org.embeddedt.modernfix.mixin.bugfix.structure_manager_crash; - -import com.mojang.datafixers.DataFixer; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.server.packs.resources.ResourceManager; -import net.minecraft.world.level.levelgen.structure.templatesystem.StructureManager; -import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate; -import net.minecraft.world.level.storage.LevelStorageSource; -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 java.util.Collections; -import java.util.Map; - -@Mixin(StructureManager.class) -public class StructureManagerMixin { - @Shadow @Final private Map structureRepository; - - @Inject(method = "", at = @At("RETURN")) - private void makeStructuresSafe(ResourceManager arg, LevelStorageSource.LevelStorageAccess arg2, DataFixer dataFixer, CallbackInfo ci) { - this.structureRepository = Collections.synchronizedMap(this.structureRepository); - } -} diff --git a/src/main/java/org/embeddedt/modernfix/mixin/feature/measure_time/BootstrapMixin.java b/src/main/java/org/embeddedt/modernfix/mixin/feature/measure_time/BootstrapMixin.java index 53f11afc..0e399bbc 100644 --- a/src/main/java/org/embeddedt/modernfix/mixin/feature/measure_time/BootstrapMixin.java +++ b/src/main/java/org/embeddedt/modernfix/mixin/feature/measure_time/BootstrapMixin.java @@ -2,8 +2,8 @@ package org.embeddedt.modernfix.mixin.feature.measure_time; import com.google.common.base.Stopwatch; import net.minecraft.server.Bootstrap; -import org.apache.logging.log4j.Logger; import org.objectweb.asm.Opcodes; +import org.slf4j.Logger; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; diff --git a/src/main/java/org/embeddedt/modernfix/mixin/feature/measure_time/MinecraftMixin.java b/src/main/java/org/embeddedt/modernfix/mixin/feature/measure_time/MinecraftMixin.java index 5a71b12d..0dfe8de7 100644 --- a/src/main/java/org/embeddedt/modernfix/mixin/feature/measure_time/MinecraftMixin.java +++ b/src/main/java/org/embeddedt/modernfix/mixin/feature/measure_time/MinecraftMixin.java @@ -2,6 +2,7 @@ package org.embeddedt.modernfix.mixin.feature.measure_time; import com.mojang.datafixers.util.Function4; import net.minecraft.client.Minecraft; +import net.minecraft.server.WorldStem; import net.minecraft.server.packs.resources.ResourceManager; import net.minecraft.world.level.DataPackConfig; import net.minecraft.core.RegistryAccess; @@ -21,19 +22,19 @@ import java.util.function.Function; public class MinecraftMixin { private long datapackReloadStartTime; - @Inject(method = "makeServerStem", at = @At(value = "HEAD")) - private void recordReloadStart(RegistryAccess.RegistryHolder p_238189_1_, Function p_238189_2_, Function4 p_238189_3_, boolean p_238189_4_, LevelStorageSource.LevelStorageAccess p_238189_5_, CallbackInfoReturnable cir) { + @Inject(method = "makeWorldStem", at = @At(value = "HEAD")) + private void recordReloadStart(CallbackInfoReturnable cir) { datapackReloadStartTime = System.nanoTime(); } - @Inject(method = "makeServerStem", at = @At(value = "RETURN")) - private void recordReloadEnd(RegistryAccess.RegistryHolder p_238189_1_, Function p_238189_2_, Function4 p_238189_3_, boolean p_238189_4_, LevelStorageSource.LevelStorageAccess p_238189_5_, CallbackInfoReturnable cir) { + @Inject(method = "makeWorldStem", at = @At(value = "RETURN")) + private void recordReloadEnd(CallbackInfoReturnable cir) { float timeSpentReloading = ((float)(System.nanoTime() - datapackReloadStartTime) / 1000000000f); ModernFix.LOGGER.warn("Datapack reload took " + timeSpentReloading + " seconds."); } - @Inject(method = "loadWorld", at = @At("HEAD"), remap = false) - private void recordWorldLoadStart(String worldName, RegistryAccess.RegistryHolder dynamicRegistries, Function levelSaveToDatapackFunction, Function4 quadFunction, boolean vanillaOnly, Minecraft.ExperimentalDialogType selectionType, boolean creating, CallbackInfo ci) { + @Inject(method = "doLoadLevel", at = @At("HEAD"), remap = false) + private void recordWorldLoadStart(CallbackInfo ci) { ModernFixClient.worldLoadStartTime = System.nanoTime(); } } diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/async_jei/ClientLifecycleHandlerMixin.java b/src/main/java/org/embeddedt/modernfix/mixin/perf/async_jei/ClientLifecycleHandlerMixin.java deleted file mode 100644 index 329b0018..00000000 --- a/src/main/java/org/embeddedt/modernfix/mixin/perf/async_jei/ClientLifecycleHandlerMixin.java +++ /dev/null @@ -1,105 +0,0 @@ -package org.embeddedt.modernfix.mixin.perf.async_jei; - -import mezz.jei.api.IModPlugin; -import mezz.jei.api.helpers.IModIdHelper; -import mezz.jei.config.*; -import mezz.jei.config.sorting.RecipeCategorySortingConfig; -import mezz.jei.events.EventBusHelper; -import mezz.jei.events.PlayerJoinedWorldEvent; -import mezz.jei.gui.textures.Textures; -import mezz.jei.ingredients.IIngredientSorter; -import mezz.jei.startup.ClientLifecycleHandler; -import mezz.jei.startup.JeiStarter; -import mezz.jei.startup.NetworkHandler; -import net.minecraft.client.Minecraft; -import net.minecraftforge.client.event.ClientPlayerNetworkEvent; -import org.embeddedt.modernfix.ModernFix; -import org.embeddedt.modernfix.jei.async.JEILoadingInterruptedException; -import org.embeddedt.modernfix.jei.async.JEIReloadThread; -import org.embeddedt.modernfix.util.JEIUtil; -import org.spongepowered.asm.mixin.Final; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Overwrite; -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 java.util.List; - -@Mixin(ClientLifecycleHandler.class) -public class ClientLifecycleHandlerMixin { - @Shadow(remap = false) @Final private JeiStarter starter; - @Shadow(remap = false) @Final private List plugins; - @Shadow(remap = false) @Final private Textures textures; - @Shadow(remap = false) @Final private IClientConfig clientConfig; - @Shadow(remap = false) @Final private IEditModeConfig editModeConfig; - @Shadow(remap = false) @Final private IngredientFilterConfig ingredientFilterConfig; - @Shadow(remap = false) @Final private WorldConfig worldConfig; - @Shadow(remap = false) @Final private BookmarkConfig bookmarkConfig; - @Shadow(remap = false) @Final private IModIdHelper modIdHelper; - @Shadow(remap = false) @Final private RecipeCategorySortingConfig recipeCategorySortingConfig; - @Shadow(remap = false) @Final private IIngredientSorter ingredientSorter; - private volatile JEIReloadThread reloadThread = null; - @Inject(method = "setupJEI", at = @At(value = "INVOKE", target = "Lmezz/jei/startup/ClientLifecycleHandler;startJEI()V"), cancellable = true, remap = false) - private void startAsync(CallbackInfo ci) { - ci.cancel(); - startJEIAsync(() -> Minecraft.getInstance().execute(() -> EventBusHelper.post(new PlayerJoinedWorldEvent()))); - } - - /** - * @author embeddedt - * @reason force JEI starts to be asynchronous - */ - @Overwrite(remap = false) - public void startJEI() { - startJEIAsync(() -> {}); - } - - @Inject(method = "", at = @At("TAIL")) - private void setupCancellationHandler(NetworkHandler networkHandler, Textures textures, CallbackInfo ci) { - EventBusHelper.addListener(this, ClientPlayerNetworkEvent.LoggedOutEvent.class, event -> cancelPreviousStart()); - JEIUtil.registerLoadingRenderer(() -> reloadThread != null); - } - - private void cancelPreviousStart() { - JEIReloadThread currentReloadThread = reloadThread; - if(currentReloadThread != null) { - currentReloadThread.requestStop(); - Minecraft.getInstance().managedBlock(currentReloadThread::isAlive); - reloadThread = null; - } - } - - private static int numReloads = 1; - - private void startJEIAsync(Runnable whenFinishedCb) { - ModernFix.LOGGER.info("JEI restart triggered. Waiting for previous thread to die."); - cancelPreviousStart(); - ModernFix.LOGGER.info("Starting new JEI thread."); - JEIReloadThread newThread = new JEIReloadThread(() -> { - try { - starter.start( - plugins, - textures, - clientConfig, - editModeConfig, - ingredientFilterConfig, - worldConfig, - bookmarkConfig, - modIdHelper, - recipeCategorySortingConfig, - ingredientSorter); - } catch(JEILoadingInterruptedException e) { - ModernFix.LOGGER.warn("JEI loading interrupted prematurely (this is normal)"); - } - whenFinishedCb.run(); - reloadThread = null; - }, "ModernFix JEI Reload Thread " + numReloads++); - newThread.setPriority(Thread.MIN_PRIORITY); - reloadThread = newThread; - newThread.start(); - } - - -} diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/async_jei/IngredientListElementFactoryMixin.java b/src/main/java/org/embeddedt/modernfix/mixin/perf/async_jei/IngredientListElementFactoryMixin.java deleted file mode 100644 index 021562fe..00000000 --- a/src/main/java/org/embeddedt/modernfix/mixin/perf/async_jei/IngredientListElementFactoryMixin.java +++ /dev/null @@ -1,22 +0,0 @@ -package org.embeddedt.modernfix.mixin.perf.async_jei; - -import mezz.jei.api.ingredients.IIngredientType; -import mezz.jei.api.runtime.IIngredientManager; -import mezz.jei.gui.ingredients.IIngredientListElement; -import mezz.jei.ingredients.IngredientListElementFactory; -import net.minecraft.core.NonNullList; -import org.embeddedt.modernfix.jei.async.IAsyncJeiStarter; -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(IngredientListElementFactory.class) -public class IngredientListElementFactoryMixin { - private static int ingredientNum = 0; - @Inject(method = "addToBaseList", at = @At(value = "INVOKE", target = "Lnet/minecraft/core/NonNullList;add(Ljava/lang/Object;)Z")) - private static void checkForInterrupt(NonNullList> baseList, IIngredientManager ingredientManager, IIngredientType ingredientType, CallbackInfo ci) { - if((ingredientNum++ % 100) == 0) - IAsyncJeiStarter.checkForLoadInterruption(); - } -} diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/async_jei/JeiStarterMixin.java b/src/main/java/org/embeddedt/modernfix/mixin/perf/async_jei/JeiStarterMixin.java deleted file mode 100644 index f6e9edd0..00000000 --- a/src/main/java/org/embeddedt/modernfix/mixin/perf/async_jei/JeiStarterMixin.java +++ /dev/null @@ -1,47 +0,0 @@ -package org.embeddedt.modernfix.mixin.perf.async_jei; - -import mezz.jei.api.IModPlugin; -import mezz.jei.api.helpers.IModIdHelper; -import mezz.jei.config.*; -import mezz.jei.config.sorting.RecipeCategorySortingConfig; -import mezz.jei.gui.textures.Textures; -import mezz.jei.ingredients.IIngredientSorter; -import mezz.jei.load.PluginCaller; -import mezz.jei.startup.JeiStarter; -import net.minecraft.client.Minecraft; -import org.embeddedt.modernfix.jei.async.IAsyncJeiStarter; -import org.embeddedt.modernfix.jei.async.JEILoadingInterruptedException; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Overwrite; -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.Redirect; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import org.spongepowered.asm.mixin.injection.callback.CancellationException; - -import java.util.List; -import java.util.concurrent.CompletionException; -import java.util.function.Consumer; - -@Mixin(JeiStarter.class) -public class JeiStarterMixin { - @Shadow(remap = false) private boolean started; - - @Inject(method = "start", at = @At(value = "INVOKE", target = "Lmezz/jei/util/ErrorUtil;checkNotEmpty(Ljava/util/Collection;Ljava/lang/String;)V", ordinal = 0, shift = At.Shift.AFTER), remap = false) - private void setStartedFlag(List plugins, Textures textures, IClientConfig clientConfig, IEditModeConfig editModeConfig, IIngredientFilterConfig ingredientFilterConfig, IWorldConfig worldConfig, BookmarkConfig bookmarkConfig, IModIdHelper modIdHelper, RecipeCategorySortingConfig recipeCategorySortingConfig, IIngredientSorter ingredientSorter, CallbackInfo ci) { - /* We need to set this ASAP so the reload system will restart the async load if needed */ - started = true; - } - - @Redirect(method = "start", at = @At(value = "INVOKE", target = "Lmezz/jei/load/PluginCaller;callOnPlugins(Ljava/lang/String;Ljava/util/List;Ljava/util/function/Consumer;)V"), remap = false) - private void callOnPluginsViaMainThread(String title, List plugins, Consumer func) { - PluginCaller.callOnPlugins(title, plugins, plugin -> { - try { - Minecraft.getInstance().executeBlocking(() -> func.accept(plugin)); - } catch(CancellationException | CompletionException e) { - throw new RuntimeException(e); - } - }); - } -} diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/async_jei/PluginCallerMixin.java b/src/main/java/org/embeddedt/modernfix/mixin/perf/async_jei/PluginCallerMixin.java deleted file mode 100644 index d089afa2..00000000 --- a/src/main/java/org/embeddedt/modernfix/mixin/perf/async_jei/PluginCallerMixin.java +++ /dev/null @@ -1,38 +0,0 @@ -package org.embeddedt.modernfix.mixin.perf.async_jei; - -import mezz.jei.api.IModPlugin; -import mezz.jei.load.PluginCaller; -import net.minecraft.client.Minecraft; -import org.embeddedt.modernfix.ModernFix; -import org.embeddedt.modernfix.core.config.ModernFixConfig; -import org.embeddedt.modernfix.jei.async.IAsyncJeiStarter; -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.Redirect; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -import java.util.List; -import java.util.concurrent.CancellationException; -import java.util.concurrent.CompletionException; -import java.util.function.Consumer; - -@Mixin(PluginCaller.class) -public class PluginCallerMixin { - @Inject(method = "callOnPlugins", at = @At(value = "INVOKE", target = "Ljava/util/Iterator;hasNext()Z"), remap = false) - private static void checkForInterrupt(String title, List plugins, Consumer func, CallbackInfo ci) { - IAsyncJeiStarter.checkForLoadInterruption(); - } - - @SuppressWarnings({"unchecked","rawtypes"}) - @Redirect(method = "callOnPlugins", at = @At(value = "INVOKE", target = "Ljava/util/function/Consumer;accept(Ljava/lang/Object;)V"), remap = false) - private static void runOnMainThreadIfNeeded(Consumer instance, Object pluginObj) { - IModPlugin plugin = (IModPlugin)pluginObj; - if(ModernFixConfig.jeiPluginBlacklist.contains(plugin.getPluginUid())) { - ModernFix.LOGGER.warn("Going to main thread for " + plugin.getPluginUid()); - Minecraft.getInstance().executeBlocking(() -> instance.accept(plugin)); - } else { - instance.accept(plugin); - } - } -} diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/async_jei/RecipeManagerInternalMixin.java b/src/main/java/org/embeddedt/modernfix/mixin/perf/async_jei/RecipeManagerInternalMixin.java deleted file mode 100644 index 75cd87b7..00000000 --- a/src/main/java/org/embeddedt/modernfix/mixin/perf/async_jei/RecipeManagerInternalMixin.java +++ /dev/null @@ -1,18 +0,0 @@ -package org.embeddedt.modernfix.mixin.perf.async_jei; - -import com.google.common.collect.ImmutableListMultimap; -import mezz.jei.recipes.RecipeManagerInternal; -import net.minecraft.resources.ResourceLocation; -import org.embeddedt.modernfix.jei.async.IAsyncJeiStarter; -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(RecipeManagerInternal.class) -public class RecipeManagerInternalMixin { - @Inject(method = "addRecipes", at = @At(value = "INVOKE", target = "Lmezz/jei/recipes/RecipeManagerInternal;addRecipeTyped(Ljava/lang/Object;Lnet/minecraft/resources/ResourceLocation;)V")) - private void checkForInterrupt(ImmutableListMultimap recipes, CallbackInfo ci) { - IAsyncJeiStarter.checkForLoadInterruption(); - } -} diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/async_locator/CommandSourceStackAccess.java b/src/main/java/org/embeddedt/modernfix/mixin/perf/async_locator/CommandSourceStackAccess.java deleted file mode 100644 index e8073943..00000000 --- a/src/main/java/org/embeddedt/modernfix/mixin/perf/async_locator/CommandSourceStackAccess.java +++ /dev/null @@ -1,12 +0,0 @@ -package org.embeddedt.modernfix.mixin.perf.async_locator; - -import net.minecraft.commands.CommandSource; -import net.minecraft.commands.CommandSourceStack; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.gen.Accessor; - -@Mixin(CommandSourceStack.class) -public interface CommandSourceStackAccess { - @Accessor - CommandSource getSource(); -} diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/async_locator/DolphinSwimToTreasureGoalMixin.java b/src/main/java/org/embeddedt/modernfix/mixin/perf/async_locator/DolphinSwimToTreasureGoalMixin.java deleted file mode 100644 index bd79c9a0..00000000 --- a/src/main/java/org/embeddedt/modernfix/mixin/perf/async_locator/DolphinSwimToTreasureGoalMixin.java +++ /dev/null @@ -1,109 +0,0 @@ -package org.embeddedt.modernfix.mixin.perf.async_locator; - -import com.google.common.collect.ImmutableSet; -import net.minecraft.core.BlockPos; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.world.entity.animal.Dolphin; -import net.minecraft.world.level.levelgen.feature.StructureFeature; -import org.embeddedt.modernfix.ModernFix; -import org.embeddedt.modernfix.structure.AsyncLocator; -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.CallbackInfoReturnable; -import org.spongepowered.asm.mixin.injection.callback.LocalCapture; - -@Mixin(targets = "net.minecraft.world.entity.animal.Dolphin$DolphinSwimToTreasureGoal") -public class DolphinSwimToTreasureGoalMixin { - @Final - @Shadow - private Dolphin dolphin; - - @Shadow - private boolean stuck; - - private AsyncLocator.LocateTask locateTask = null; - - /* - Intercept DolphinSwimToTreasureGoal#start call right before it calls ServerLevel#findNearestMapFeature to pass - the logic over to an async task. - */ - @Inject( - method = "start", - at = @At( - value = "INVOKE", - target = "Lnet/minecraft/server/level/ServerLevel;findNearestMapFeature(Lnet/minecraft/world/level/levelgen/feature/StructureFeature;Lnet/minecraft/core/BlockPos;IZ)Lnet/minecraft/core/BlockPos;" - ), - cancellable = true, - locals = LocalCapture.CAPTURE_FAILSOFT - ) - public void findTreasureAsync(CallbackInfo ci, ServerLevel level, BlockPos blockpos) { - ModernFix.LOGGER.debug("Intercepted DolphinSwimToTreasureGoal#start call"); - handleFindTreasureAsync(level, blockpos); - ci.cancel(); - } - - /* - Intercept DolphinSwimToTreasureGoal#canContinueToUse to return true if an async locating task is ongoing so that - the goal isn't ended early due to no treasure pos being set yet. - */ - @Inject( - method = "canContinueToUse", - at = @At(value = "HEAD"), - cancellable = true - ) - public void continueToUseIfLocatingTreasure(CallbackInfoReturnable cir) { - if (locateTask != null) { - ModernFix.LOGGER.debug("Locating task ongoing - returning true for continueToUse()"); - cir.setReturnValue(true); - } - } - - @Inject( - method = "stop", - at = @At(value = "HEAD") - ) - public void stopLocatingTreasure(CallbackInfo ci) { - if (locateTask != null) { - ModernFix.LOGGER.debug("Locating task ongoing - cancelling during stop()"); - locateTask.cancel(); - locateTask = null; - } - } - - /* - Intercept DolphinSwimToTreasureGoal#tick to return early if an async locating task is ongoing so that the - dolphin doesn't try to go towards an old treasure position. - */ - @Inject( - method = "tick", - at = @At(value = "HEAD"), - cancellable = true - ) - public void skipTickingIfLocatingTreasure(CallbackInfo ci) { - if (locateTask != null) { - ModernFix.LOGGER.debug("Locating task ongoing - skipping tick()"); - ci.cancel(); - } - } - - private void handleFindTreasureAsync(ServerLevel level, BlockPos blockPos) { - locateTask = AsyncLocator.locateLevel(level, ImmutableSet.of(StructureFeature.OCEAN_RUIN, StructureFeature.SHIPWRECK), blockPos, 50, false) - .thenOnServerThread(pos -> handleLocationFound(level, pos)); - } - - private void handleLocationFound(ServerLevel level, BlockPos pos) { - locateTask = null; - if (pos != null) { - ModernFix.LOGGER.debug("Location found - updating dolphin treasure pos"); - dolphin.setTreasurePos(pos); - level.broadcastEntityEvent(dolphin, (byte) 38); - } else { - ModernFix.LOGGER.debug("No location found - marking dolphin as stuck"); - stuck = true; - } - } -} diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/async_locator/EnderEyeItemMixin.java b/src/main/java/org/embeddedt/modernfix/mixin/perf/async_locator/EnderEyeItemMixin.java deleted file mode 100644 index 1ff2310d..00000000 --- a/src/main/java/org/embeddedt/modernfix/mixin/perf/async_locator/EnderEyeItemMixin.java +++ /dev/null @@ -1,104 +0,0 @@ -package org.embeddedt.modernfix.mixin.perf.async_locator; - -import net.minecraft.advancements.critereon.UsedEnderEyeTrigger; -import net.minecraft.core.BlockPos; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.server.level.ServerPlayer; -import net.minecraft.stats.Stat; -import net.minecraft.world.InteractionHand; -import net.minecraft.world.InteractionResultHolder; -import net.minecraft.world.entity.player.Player; -import net.minecraft.world.entity.projectile.EyeOfEnder; -import net.minecraft.world.item.EnderEyeItem; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.level.Level; -import net.minecraft.world.level.chunk.ChunkGenerator; -import net.minecraft.world.level.levelgen.feature.StructureFeature; -import net.minecraft.world.phys.HitResult; -import org.embeddedt.modernfix.structure.logic.EnderEyeItemLogic; -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.Redirect; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; -import org.spongepowered.asm.mixin.injection.callback.LocalCapture; - -@Mixin(EnderEyeItem.class) -public class EnderEyeItemMixin { - /* - Intercept EnderEyeItem#use call and return BlockPos.ZERO instead. It won't be used in the EyeOfEnder entity - created later either, as we need to set the actual location ourselves. - */ - @Redirect( - method = "use", - at = @At( - value = "INVOKE", - target = "Lnet/minecraft/world/level/chunk/ChunkGenerator;findNearestMapFeature(Lnet/minecraft/server/level/ServerLevel;Lnet/minecraft/world/level/levelgen/feature/StructureFeature;Lnet/minecraft/core/BlockPos;IZ)Lnet/minecraft/core/BlockPos;" - ) - ) - public BlockPos levelFindNearestMapFeature( - ChunkGenerator generator, - ServerLevel level, - StructureFeature structureFeature, - BlockPos pPos, - int pRadius, - boolean pSkipExistingChunks - ) { - return BlockPos.ZERO; - } - - // Start the async locate task here so we have the eye of ender entity for context - @Inject( - method = "use", - at = @At( - value = "INVOKE", - target = "Lnet/minecraft/world/entity/projectile/EyeOfEnder;setItem(Lnet/minecraft/world/item/ItemStack;)V" - ), - locals = LocalCapture.CAPTURE_FAILEXCEPTION - ) - public void startAsyncLocateTask( - Level pLevel, - Player pPlayer, - InteractionHand pHand, - CallbackInfoReturnable> cir, - ItemStack itemstack, - HitResult hitresult, - BlockPos blockpos, - EyeOfEnder eyeofender - ) { - EnderEyeItemLogic.locateAsync((ServerLevel)pLevel, pPlayer, eyeofender, (EnderEyeItem) (Object) this); - } - - @Redirect( - method = "use", - at = @At( - value = "INVOKE", - target = "Lnet/minecraft/world/entity/projectile/EyeOfEnder;signalTo(Lnet/minecraft/core/BlockPos;)V" - ) - ) - public void eyeOfEnderSignalTo(EyeOfEnder eyeOfEnder, BlockPos blockpos) { - // Do nothing - we'll do this later if a location is found - } - - @Redirect( - method = "use", - at = @At( - value = "INVOKE", - target = "Lnet/minecraft/advancements/critereon/UsedEnderEyeTrigger;trigger(Lnet/minecraft/server/level/ServerPlayer;Lnet/minecraft/core/BlockPos;)V" - ) - ) - public void triggerUsedEnderEyeCriteria(UsedEnderEyeTrigger trigger, ServerPlayer player, BlockPos pos) { - // Do nothing - we'll do this later if a location is found - } - - @Redirect( - method = "use", - at = @At( - value = "INVOKE", - target = "Lnet/minecraft/world/entity/player/Player;awardStat(Lnet/minecraft/stats/Stat;)V" - ) - ) - public void playerAwardStat(Player instance, Stat pStat) { - // Do nothing - we'll do this later if a location is found - } -} diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/async_locator/ExplorationMapFunctionMixin.java b/src/main/java/org/embeddedt/modernfix/mixin/perf/async_locator/ExplorationMapFunctionMixin.java deleted file mode 100644 index 3412fffe..00000000 --- a/src/main/java/org/embeddedt/modernfix/mixin/perf/async_locator/ExplorationMapFunctionMixin.java +++ /dev/null @@ -1,63 +0,0 @@ -package org.embeddedt.modernfix.mixin.perf.async_locator; - -import net.minecraft.core.BlockPos; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.level.levelgen.feature.StructureFeature; -import net.minecraft.world.level.saveddata.maps.MapDecoration; -import net.minecraft.world.level.storage.loot.LootContext; -import net.minecraft.world.level.storage.loot.functions.ExplorationMapFunction; -import net.minecraft.world.phys.Vec3; -import org.embeddedt.modernfix.structure.logic.ExplorationMapFunctionLogic; -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.CallbackInfoReturnable; -import org.spongepowered.asm.mixin.injection.callback.LocalCapture; - -@Mixin(ExplorationMapFunction.class) -public class ExplorationMapFunctionMixin { - @Shadow - @Final - StructureFeature destination; - - @Shadow - @Final - MapDecoration.Type mapDecoration; - - @Shadow - @Final - byte zoom; - - @Shadow - @Final - int searchRadius; - - @Shadow - @Final - boolean skipKnownStructures; - - @Inject( - method = "run", - at = @At( - value = "INVOKE", - target = "Lnet/minecraft/server/level/ServerLevel;findNearestMapFeature(Lnet/minecraft/world/level/levelgen/feature/StructureFeature;Lnet/minecraft/core/BlockPos;IZ)Lnet/minecraft/core/BlockPos;" - ), - locals = LocalCapture.CAPTURE_FAILSOFT, - cancellable = true - ) - public void updateMapAsync( - ItemStack pStack, - LootContext pContext, - CallbackInfoReturnable cir, - Vec3 vec3, - ServerLevel serverlevel - ) { - ItemStack mapStack = ExplorationMapFunctionLogic.updateMapAsync( - serverlevel, new BlockPos(vec3), zoom, searchRadius, skipKnownStructures, mapDecoration, destination - ); - cir.setReturnValue(mapStack); - } -} diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/async_locator/EyeOfEnderAccess.java b/src/main/java/org/embeddedt/modernfix/mixin/perf/async_locator/EyeOfEnderAccess.java deleted file mode 100644 index ee8e8861..00000000 --- a/src/main/java/org/embeddedt/modernfix/mixin/perf/async_locator/EyeOfEnderAccess.java +++ /dev/null @@ -1,11 +0,0 @@ -package org.embeddedt.modernfix.mixin.perf.async_locator; - -import net.minecraft.world.entity.projectile.EyeOfEnder; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.gen.Accessor; - -@Mixin(EyeOfEnder.class) -public interface EyeOfEnderAccess { - @Accessor - void setLife(int life); -} diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/async_locator/EyeOfEnderMixin.java b/src/main/java/org/embeddedt/modernfix/mixin/perf/async_locator/EyeOfEnderMixin.java deleted file mode 100644 index 0b3eadf8..00000000 --- a/src/main/java/org/embeddedt/modernfix/mixin/perf/async_locator/EyeOfEnderMixin.java +++ /dev/null @@ -1,37 +0,0 @@ -package org.embeddedt.modernfix.mixin.perf.async_locator; - -import net.minecraft.world.entity.projectile.EyeOfEnder; -import org.embeddedt.modernfix.structure.logic.EyeOfEnderData; -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(EyeOfEnder.class) -public class EyeOfEnderMixin implements EyeOfEnderData { - private boolean locateTaskOngoing = false; - - @Override - public void setLocateTaskOngoing(boolean locateTaskOngoing) { - this.locateTaskOngoing = locateTaskOngoing; - } - - /* - Intercept EyeOfEnder#tick call and return after the super call if there's an ongoing locate task. This is to - prevent the entity from moving or dying until we have a location result. - */ - @Inject( - method = "tick", - at = @At( - value = "INVOKE", - target = "Lnet/minecraft/world/entity/Entity;tick()V", - shift = At.Shift.AFTER - ), - cancellable = true - ) - public void skipTick(CallbackInfo ci) { - if (locateTaskOngoing) { - ci.cancel(); - } - } -} diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/async_locator/LocateCommandAccess.java b/src/main/java/org/embeddedt/modernfix/mixin/perf/async_locator/LocateCommandAccess.java deleted file mode 100644 index 997c3e70..00000000 --- a/src/main/java/org/embeddedt/modernfix/mixin/perf/async_locator/LocateCommandAccess.java +++ /dev/null @@ -1,15 +0,0 @@ -package org.embeddedt.modernfix.mixin.perf.async_locator; - -import com.mojang.brigadier.exceptions.DynamicCommandExceptionType; -import com.mojang.brigadier.exceptions.SimpleCommandExceptionType; -import net.minecraft.server.commands.LocateCommand; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.gen.Accessor; - -@Mixin(LocateCommand.class) -public interface LocateCommandAccess { - @Accessor("ERROR_FAILED") - static SimpleCommandExceptionType getErrorFailed() { - throw new UnsupportedOperationException(); - } -} diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/async_locator/LocateCommandMixin.java b/src/main/java/org/embeddedt/modernfix/mixin/perf/async_locator/LocateCommandMixin.java deleted file mode 100644 index d02bddf6..00000000 --- a/src/main/java/org/embeddedt/modernfix/mixin/perf/async_locator/LocateCommandMixin.java +++ /dev/null @@ -1,34 +0,0 @@ -package org.embeddedt.modernfix.mixin.perf.async_locator; - -import net.minecraft.commands.CommandSource; -import net.minecraft.commands.CommandSourceStack; -import net.minecraft.server.MinecraftServer; -import net.minecraft.server.commands.LocateCommand; -import net.minecraft.server.level.ServerPlayer; -import net.minecraft.world.level.levelgen.feature.StructureFeature; -import org.embeddedt.modernfix.structure.logic.LocateCommandLogic; -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.CallbackInfoReturnable; -import org.spongepowered.asm.mixin.injection.callback.LocalCapture; - -@Mixin(LocateCommand.class) -public class LocateCommandMixin { - @Inject( - method = "locate", - at = @At( - value = "INVOKE", - target = "Lnet/minecraft/server/level/ServerLevel;findNearestMapFeature(Lnet/minecraft/world/level/levelgen/feature/StructureFeature;Lnet/minecraft/core/BlockPos;IZ)Lnet/minecraft/core/BlockPos;" - ), - cancellable = true, - locals = LocalCapture.CAPTURE_FAILSOFT - ) - private static void findLocationAsync(CommandSourceStack sourceStack, StructureFeature feature, CallbackInfoReturnable cir) { - CommandSource source = ((CommandSourceStackAccess) sourceStack).getSource(); - if (source instanceof ServerPlayer || source instanceof MinecraftServer) { - LocateCommandLogic.locateAsync(sourceStack, feature); - cir.setReturnValue(0); - } - } -} diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/async_locator/MapItemAccess.java b/src/main/java/org/embeddedt/modernfix/mixin/perf/async_locator/MapItemAccess.java deleted file mode 100644 index 890b90b6..00000000 --- a/src/main/java/org/embeddedt/modernfix/mixin/perf/async_locator/MapItemAccess.java +++ /dev/null @@ -1,17 +0,0 @@ -package org.embeddedt.modernfix.mixin.perf.async_locator; - -import net.minecraft.resources.ResourceKey; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.item.MapItem; -import net.minecraft.world.level.Level; -import net.minecraft.world.level.saveddata.maps.MapItemSavedData; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.gen.Invoker; - -@Mixin(MapItem.class) -public interface MapItemAccess { - @Invoker - static MapItemSavedData callCreateAndStoreSavedData(ItemStack pStack, Level pLevel, int pX, int pZ, int pScale, boolean pTrackingPosition, boolean pUnlimitedTracking, ResourceKey pDimension) { - throw new UnsupportedOperationException(); - } -} diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/async_locator/MerchantOfferAccess.java b/src/main/java/org/embeddedt/modernfix/mixin/perf/async_locator/MerchantOfferAccess.java deleted file mode 100644 index d9d5bfb2..00000000 --- a/src/main/java/org/embeddedt/modernfix/mixin/perf/async_locator/MerchantOfferAccess.java +++ /dev/null @@ -1,13 +0,0 @@ -package org.embeddedt.modernfix.mixin.perf.async_locator; - -import net.minecraft.world.item.trading.MerchantOffer; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Mutable; -import org.spongepowered.asm.mixin.gen.Accessor; - -@Mixin(MerchantOffer.class) -public interface MerchantOfferAccess { - @Mutable - @Accessor - void setMaxUses(int maxUses); -} diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/async_locator/TreasureMapForEmeraldsMixin.java b/src/main/java/org/embeddedt/modernfix/mixin/perf/async_locator/TreasureMapForEmeraldsMixin.java deleted file mode 100644 index 9ed5b23a..00000000 --- a/src/main/java/org/embeddedt/modernfix/mixin/perf/async_locator/TreasureMapForEmeraldsMixin.java +++ /dev/null @@ -1,62 +0,0 @@ -package org.embeddedt.modernfix.mixin.perf.async_locator; - -import net.minecraft.world.entity.Entity; -import net.minecraft.world.item.trading.MerchantOffer; -import net.minecraft.world.level.levelgen.feature.StructureFeature; -import net.minecraft.world.level.saveddata.maps.MapDecoration; -import org.embeddedt.modernfix.structure.logic.MerchantLogic; -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.CallbackInfoReturnable; - -import java.util.Locale; -import java.util.Random; - -@Mixin(targets = "net.minecraft.world.entity.npc.VillagerTrades$TreasureMapForEmeralds") -public class TreasureMapForEmeraldsMixin { - @Shadow - @Final - private int emeraldCost; - - @Shadow - @Final - private MapDecoration.Type destinationType; - - @Shadow - @Final - private int maxUses; - - @Shadow - @Final - private int villagerXp; - - @Shadow - @Final - private StructureFeature destination; - - /* - Intercept TreasureMapForEmeralds#getOffer call right before it calls ServerLevel#findNearestMapFeature to pass - the logic over to an async task. Instead of returning the complete map or null, we'll have to always return an - incomplete filled map and later update it with the details when we have them. - */ - @Inject( - method = "getOffer", - at = @At( - value = "INVOKE", - target = "Lnet/minecraft/server/level/ServerLevel;findNearestMapFeature(Lnet/minecraft/world/level/levelgen/feature/StructureFeature;Lnet/minecraft/core/BlockPos;IZ)Lnet/minecraft/core/BlockPos;" - ), - cancellable = true - ) - public void updateMapAsync(Entity pTrader, Random pRand, CallbackInfoReturnable callbackInfo) { - String displayName = "filled_map." + this.destination.getFeatureName().toLowerCase(Locale.ROOT); - MerchantOffer offer = MerchantLogic.updateMapAsync( - pTrader, emeraldCost, displayName, destinationType, maxUses, villagerXp, destination - ); - if (offer != null) { - callbackInfo.setReturnValue(offer); - } - } -} diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/blast_search_trees/IngredientFilterInvoker.java b/src/main/java/org/embeddedt/modernfix/mixin/perf/blast_search_trees/IngredientFilterInvoker.java index cd69f9c5..f426527e 100644 --- a/src/main/java/org/embeddedt/modernfix/mixin/perf/blast_search_trees/IngredientFilterInvoker.java +++ b/src/main/java/org/embeddedt/modernfix/mixin/perf/blast_search_trees/IngredientFilterInvoker.java @@ -1,7 +1,7 @@ package org.embeddedt.modernfix.mixin.perf.blast_search_trees; -import mezz.jei.ingredients.IIngredientListElementInfo; -import mezz.jei.ingredients.IngredientFilter; +import mezz.jei.api.ingredients.ITypedIngredient; +import mezz.jei.common.ingredients.IngredientFilter; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.gen.Invoker; @@ -10,5 +10,5 @@ import java.util.List; @Mixin(IngredientFilter.class) public interface IngredientFilterInvoker { @Invoker(remap = false) - List> invokeGetIngredientListUncached(String filterText); + List> invokeGetIngredientListUncached(String filterText); } diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/boost_worker_count/UtilMixin.java b/src/main/java/org/embeddedt/modernfix/mixin/perf/boost_worker_count/UtilMixin.java deleted file mode 100644 index cf5dd15a..00000000 --- a/src/main/java/org/embeddedt/modernfix/mixin/perf/boost_worker_count/UtilMixin.java +++ /dev/null @@ -1,25 +0,0 @@ -package org.embeddedt.modernfix.mixin.perf.boost_worker_count; - -import net.minecraft.Util; -import org.embeddedt.modernfix.ModernFix; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.Constant; -import org.spongepowered.asm.mixin.injection.ModifyConstant; - -@Mixin(Util.class) -public class UtilMixin { - @ModifyConstant(method = "makeExecutor", constant = @Constant(intValue = 7)) - private static int useHigherThreadCount(int old) { - String requestedMax = System.getProperty("max.bg.threads"); - if(requestedMax != null) { - try { - int newMax = Integer.parseInt(requestedMax); - if(newMax >= 1 && newMax <= 255) - return newMax; - } catch(NumberFormatException e) { - ModernFix.LOGGER.error("max.bg.threads is not a number"); - } - } - return 255; - } -} diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/compress_biome_container/MixinBiomeContainer.java b/src/main/java/org/embeddedt/modernfix/mixin/perf/compress_biome_container/MixinBiomeContainer.java deleted file mode 100644 index 857e593c..00000000 --- a/src/main/java/org/embeddedt/modernfix/mixin/perf/compress_biome_container/MixinBiomeContainer.java +++ /dev/null @@ -1,148 +0,0 @@ -package org.embeddedt.modernfix.mixin.perf.compress_biome_container; - -import it.unimi.dsi.fastutil.objects.Reference2ShortMap; -import it.unimi.dsi.fastutil.objects.Reference2ShortOpenHashMap; -import net.minecraft.util.BitStorage; -import net.minecraft.core.IdMap; -import net.minecraft.world.level.ChunkPos; -import net.minecraft.util.Mth; -import net.minecraft.world.level.biome.Biome; -import net.minecraft.world.level.chunk.ChunkBiomeContainer; -import net.minecraft.world.level.biome.BiomeSource; -import org.spongepowered.asm.mixin.*; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -@Mixin(ChunkBiomeContainer.class) -public class MixinBiomeContainer { - @Mutable - @Shadow - @Final - private Biome[] biomes; - - @Shadow - @Final - private IdMap biomeRegistry; - - @Shadow - @Final - private static int WIDTH_BITS; - - private Biome[] palette; - private BitStorage intArray; - - @Inject(method = "(Lnet/minecraft/core/IdMap;[I)V", at = @At("RETURN")) - private void reinit1(IdMap p_i241970_1_, int[] p_i241970_2_, CallbackInfo ci) { - this.createCompact(); - } - - @Inject(method = "(Lnet/minecraft/core/IdMap;[Lnet/minecraft/world/level/biome/Biome;)V", at = @At("RETURN")) - private void reinit2(IdMap p_i241971_1_, Biome[] p_i241971_2_, CallbackInfo ci) { - this.createCompact(); - } - - @Inject(method = "(Lnet/minecraft/core/IdMap;Lnet/minecraft/world/level/ChunkPos;Lnet/minecraft/world/level/biome/BiomeSource;)V", at = @At("RETURN")) - private void reinit3(IdMap p_i241968_1_, ChunkPos p_i241968_2_, BiomeSource p_i241968_3_, CallbackInfo ci) { - this.createCompact(); - } - - @Inject(method = "(Lnet/minecraft/core/IdMap;Lnet/minecraft/world/level/ChunkPos;Lnet/minecraft/world/level/biome/BiomeSource;[I)V", at = @At("RETURN")) - private void reinit4(IdMap p_i241969_1_, ChunkPos p_i241969_2_, BiomeSource p_i241969_3_, int[] p_i241969_4_, CallbackInfo ci) { - this.createCompact(); - } - - private void createCompact() { - if (this.intArray != null || this.biomes[0] == null) { - return; - } - - Reference2ShortOpenHashMap paletteTable = this.createPalette(); - Biome[] paletteIndexed = new Biome[paletteTable.size()]; - - for (Reference2ShortMap.Entry entry : paletteTable.reference2ShortEntrySet()) { - paletteIndexed[entry.getShortValue()] = entry.getKey(); - } - - int packedIntSize = Math.max(2, Mth.ceillog2(paletteTable.size())); - BitStorage integerArray = new BitStorage(packedIntSize, ChunkBiomeContainer.BIOMES_SIZE); - - Biome prevBiome = null; - short prevId = -1; - - for (int i = 0; i < this.biomes.length; i++) { - Biome biome = this.biomes[i]; - short id; - - if (prevBiome == biome) { - id = prevId; - } else { - id = paletteTable.getShort(biome); - - if (id < 0) { - throw new IllegalStateException("Palette is missing entry: " + biome); - } - - prevId = id; - prevBiome = biome; - } - - integerArray.set(i, id); - } - - this.palette = paletteIndexed; - this.intArray = integerArray; - this.biomes = null; - } - - private Reference2ShortOpenHashMap createPalette() { - Reference2ShortOpenHashMap map = new Reference2ShortOpenHashMap<>(); - map.defaultReturnValue(Short.MIN_VALUE); - - Biome prevObj = null; - short id = 0; - - for (Biome obj : this.biomes) { - if (obj == prevObj) { - continue; - } - - if (map.getShort(obj) < 0) { - map.put(obj, id++); - } - - prevObj = obj; - } - - return map; - } - - /** - * @author JellySquid - * @reason Use paletted lookup - */ - @Overwrite - public int[] writeBiomes() { - int size = this.intArray.getSize(); - int[] array = new int[size]; - - for(int i = 0; i < size; ++i) { - array[i] = this.biomeRegistry.getId(this.palette[this.intArray.get(i)]); - } - - return array; - } - - /** - * @author JellySquid - * @reason Use paletted lookup - */ - @Overwrite - public Biome getNoiseBiome(int biomeX, int biomeY, int biomeZ) { - int x = biomeX & ChunkBiomeContainer.HORIZONTAL_MASK; - int y = Mth.clamp(biomeY, 0, ChunkBiomeContainer.VERTICAL_MASK); - int z = biomeZ & ChunkBiomeContainer.HORIZONTAL_MASK; - - return this.palette[this.intArray.get(y << WIDTH_BITS + WIDTH_BITS | z << WIDTH_BITS | x)]; - } -} diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/datapack_reload_exceptions/LootTableManagerMixin.java b/src/main/java/org/embeddedt/modernfix/mixin/perf/datapack_reload_exceptions/LootTableManagerMixin.java index 02c2a1a2..fae68135 100644 --- a/src/main/java/org/embeddedt/modernfix/mixin/perf/datapack_reload_exceptions/LootTableManagerMixin.java +++ b/src/main/java/org/embeddedt/modernfix/mixin/perf/datapack_reload_exceptions/LootTableManagerMixin.java @@ -1,15 +1,15 @@ package org.embeddedt.modernfix.mixin.perf.datapack_reload_exceptions; import net.minecraft.world.level.storage.loot.LootTables; -import org.apache.logging.log4j.Logger; +import org.slf4j.Logger; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Redirect; @Mixin(LootTables.class) public class LootTableManagerMixin { - @Redirect(method = "*(Lnet/minecraft/resources/IResourceManager;Lcom/google/common/collect/ImmutableMap$Builder;Lnet/minecraft/util/ResourceLocation;Lcom/google/gson/JsonElement;)V", - at = @At(value = "INVOKE", target = "Lorg/apache/logging/log4j/Logger;error(Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Object;)V", remap = false)) + @Redirect(method = "*(Lnet/minecraft/server/packs/resources/ResourceManager;Lcom/google/common/collect/ImmutableMap$Builder;Lnet/minecraft/resources/ResourceLocation;Lcom/google/gson/JsonElement;)V", + at = @At(value = "INVOKE", target = "Lorg/slf4j/Logger;error(Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Object;)V", remap = false)) private void logWithoutStacktrace(Logger instance, String s, Object location, Object exc) { instance.error(s + ": {}", location, exc.toString()); } diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/datapack_reload_exceptions/RecipeManagerMixin.java b/src/main/java/org/embeddedt/modernfix/mixin/perf/datapack_reload_exceptions/RecipeManagerMixin.java index ba928c36..e0bbd844 100644 --- a/src/main/java/org/embeddedt/modernfix/mixin/perf/datapack_reload_exceptions/RecipeManagerMixin.java +++ b/src/main/java/org/embeddedt/modernfix/mixin/perf/datapack_reload_exceptions/RecipeManagerMixin.java @@ -1,14 +1,14 @@ package org.embeddedt.modernfix.mixin.perf.datapack_reload_exceptions; import net.minecraft.world.item.crafting.RecipeManager; -import org.apache.logging.log4j.Logger; +import org.slf4j.Logger; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Redirect; @Mixin(RecipeManager.class) public class RecipeManagerMixin { - @Redirect(method = "apply(Ljava/util/Map;Lnet/minecraft/server/packs/resources/ResourceManager;Lnet/minecraft/util/profiling/ProfilerFiller;)V", at = @At(value = "INVOKE", target = "Lorg/apache/logging/log4j/Logger;error(Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Object;)V", remap = false)) + @Redirect(method = "apply(Ljava/util/Map;Lnet/minecraft/server/packs/resources/ResourceManager;Lnet/minecraft/util/profiling/ProfilerFiller;)V", at = @At(value = "INVOKE", target = "Lorg/slf4j/Logger;error(Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Object;)V", remap = false)) private void silenceException(Logger instance, String s, Object location, Object exc) { instance.error(s + ": {}", location, exc.toString()); } diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/faster_baking/ModelBakeryMixin.java b/src/main/java/org/embeddedt/modernfix/mixin/perf/faster_baking/ModelBakeryMixin.java index 6fb48308..e7eeafe5 100644 --- a/src/main/java/org/embeddedt/modernfix/mixin/perf/faster_baking/ModelBakeryMixin.java +++ b/src/main/java/org/embeddedt/modernfix/mixin/perf/faster_baking/ModelBakeryMixin.java @@ -52,8 +52,6 @@ public abstract class ModelBakeryMixin implements IExtendedModelBakery { @Shadow @Nullable private AtlasSet atlasSet; - @Shadow @Nullable public abstract BakedModel getBakedModel(ResourceLocation pLocation, ModelState pTransform, Function textureGetter); - @Shadow @Final public static ModelResourceLocation MISSING_MODEL_LOCATION; @Shadow @Final private Map, BakedModel> bakedCache; @@ -136,7 +134,7 @@ public abstract class ModelBakeryMixin implements IExtendedModelBakery { TextureAtlas atlastexture = pair.getFirst(); TextureAtlas.Preparations atlastexture$sheetdata = pair.getSecond(); pResourceManager.register(atlastexture.location(), atlastexture); - pResourceManager.bind(atlastexture.location()); + pResourceManager.bindForSetup(atlastexture.location()); atlastexture.updateFilter(atlastexture$sheetdata); } pProfiler.pop(); diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/faster_baking/ModelManagerMixin.java b/src/main/java/org/embeddedt/modernfix/mixin/perf/faster_baking/ModelManagerMixin.java index 1a2283fc..cf053af7 100644 --- a/src/main/java/org/embeddedt/modernfix/mixin/perf/faster_baking/ModelManagerMixin.java +++ b/src/main/java/org/embeddedt/modernfix/mixin/perf/faster_baking/ModelManagerMixin.java @@ -12,8 +12,7 @@ import net.minecraft.client.renderer.texture.TextureManager; import net.minecraft.util.profiling.ProfilerFiller; import net.minecraft.server.packs.resources.ResourceManager; import net.minecraft.resources.ResourceLocation; -import net.minecraftforge.client.model.ModelLoader; -import net.minecraftforge.fml.common.ObfuscationReflectionHelper; +import net.minecraftforge.client.model.ForgeModelBakery; import org.embeddedt.modernfix.duck.IExtendedModelBakery; import org.embeddedt.modernfix.models.LazyBakedModel; import org.spongepowered.asm.mixin.Final; @@ -22,7 +21,6 @@ import org.spongepowered.asm.mixin.Overwrite; 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.CallbackInfoReturnable; import org.spongepowered.asm.mixin.injection.callback.LocalCapture; @@ -44,7 +42,7 @@ public class ModelManagerMixin { @Shadow @Final private BlockModelShaper blockModelShaper; @Inject(method = "prepare(Lnet/minecraft/server/packs/resources/ResourceManager;Lnet/minecraft/util/profiling/ProfilerFiller;)Lnet/minecraft/client/resources/model/ModelBakery;", at = @At(value = "INVOKE", target = "Lnet/minecraft/util/profiling/ProfilerFiller;endTick()V"), locals = LocalCapture.CAPTURE_FAILHARD) - private void fireModelBakeEvent(ResourceManager pResourceManager, ProfilerFiller pProfiler, CallbackInfoReturnable cir, ModelLoader pObject) { + private void fireModelBakeEvent(ResourceManager pResourceManager, ProfilerFiller pProfiler, CallbackInfoReturnable cir, ForgeModelBakery pObject) { pProfiler.push("modelevent"); if (this.atlases != null) { Minecraft.getInstance().executeBlocking(() -> { diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/nuke_empty_chunk_sections/MixinChunk.java b/src/main/java/org/embeddedt/modernfix/mixin/perf/nuke_empty_chunk_sections/MixinChunk.java deleted file mode 100644 index a6b6e1a1..00000000 --- a/src/main/java/org/embeddedt/modernfix/mixin/perf/nuke_empty_chunk_sections/MixinChunk.java +++ /dev/null @@ -1,35 +0,0 @@ -package org.embeddedt.modernfix.mixin.perf.nuke_empty_chunk_sections; - -import net.minecraft.world.level.ChunkPos; -import net.minecraft.world.level.chunk.UpgradeData; -import net.minecraft.world.level.TickList; -import net.minecraft.world.level.Level; -import net.minecraft.world.level.chunk.ChunkBiomeContainer; -import net.minecraft.world.level.chunk.LevelChunk; -import net.minecraft.world.level.chunk.LevelChunkSection; -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 java.util.function.Consumer; - -@Mixin(LevelChunk.class) -public class MixinChunk { - @Shadow @Final private LevelChunkSection[] sections; - - @Inject(method = "(Lnet/minecraft/world/level/Level;Lnet/minecraft/world/level/ChunkPos;Lnet/minecraft/world/level/chunk/ChunkBiomeContainer;Lnet/minecraft/world/level/chunk/UpgradeData;Lnet/minecraft/world/level/TickList;Lnet/minecraft/world/level/TickList;J[Lnet/minecraft/world/level/chunk/LevelChunkSection;Ljava/util/function/Consumer;)V", - at = @At("RETURN")) - private void reinit(Level world, ChunkPos pos, ChunkBiomeContainer container, UpgradeData data, - TickList list1, TickList list2, long inhabited, - LevelChunkSection[] oldSections, Consumer consumer, CallbackInfo ci) { - /* taken from Hydrogen */ - for(int i = 0; i < this.sections.length; i++) { - if(LevelChunkSection.isEmpty(this.sections[i])) { - this.sections[i] = null; - } - } - } -} diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/parallelize_model_loading/BooleanPropertyMixin.java b/src/main/java/org/embeddedt/modernfix/mixin/perf/parallelize_model_loading/BooleanPropertyMixin.java index a5fb1b72..16a6e253 100644 --- a/src/main/java/org/embeddedt/modernfix/mixin/perf/parallelize_model_loading/BooleanPropertyMixin.java +++ b/src/main/java/org/embeddedt/modernfix/mixin/perf/parallelize_model_loading/BooleanPropertyMixin.java @@ -12,7 +12,7 @@ public class BooleanPropertyMixin { * There is no point comparing the immutable sets in any two instances of this class, as they will always be * the same. */ - @Redirect(method = "equals", at = @At(value = "INVOKE", target = "Lcom/google/common/collect/ImmutableSet;equals(Ljava/lang/Object;)Z", remap = false)) + @Redirect(method = "equals", at = @At(value = "INVOKE", target = "Lcom/google/common/collect/ImmutableSet;equals(Ljava/lang/Object;)Z", remap = false), remap = false) private boolean skipEqualityCheck(ImmutableSet instance, Object object) { return true; } diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/parallelize_model_loading/PropertyMixin.java b/src/main/java/org/embeddedt/modernfix/mixin/perf/parallelize_model_loading/PropertyMixin.java index 4ff99e9c..417ed7e1 100644 --- a/src/main/java/org/embeddedt/modernfix/mixin/perf/parallelize_model_loading/PropertyMixin.java +++ b/src/main/java/org/embeddedt/modernfix/mixin/perf/parallelize_model_loading/PropertyMixin.java @@ -25,7 +25,7 @@ public class PropertyMixin { * @author embeddedt * @reason compare hashcodes if generated, use reference equality for speed */ - @Overwrite + @Overwrite(remap = false) public boolean equals(Object p_equals_1_) { if (this == p_equals_1_) { return true; diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/parallelize_model_loading/TransformationMatrixMixin.java b/src/main/java/org/embeddedt/modernfix/mixin/perf/parallelize_model_loading/TransformationMatrixMixin.java index 184b4006..5d02a603 100644 --- a/src/main/java/org/embeddedt/modernfix/mixin/perf/parallelize_model_loading/TransformationMatrixMixin.java +++ b/src/main/java/org/embeddedt/modernfix/mixin/perf/parallelize_model_loading/TransformationMatrixMixin.java @@ -17,7 +17,7 @@ public class TransformationMatrixMixin { * @author embeddedt * @reason use cached hashcode if exists */ - @Overwrite + @Overwrite(remap = false) public int hashCode() { int hash; if(cachedHashCode != null) { diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/preload_block_classes/GameDataMixin.java b/src/main/java/org/embeddedt/modernfix/mixin/perf/preload_block_classes/GameDataMixin.java deleted file mode 100644 index 5f519ffc..00000000 --- a/src/main/java/org/embeddedt/modernfix/mixin/perf/preload_block_classes/GameDataMixin.java +++ /dev/null @@ -1,20 +0,0 @@ -package org.embeddedt.modernfix.mixin.perf.preload_block_classes; - -import net.minecraftforge.fml.ModLoadingStage; -import net.minecraftforge.registries.GameData; -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.CallbackInfoReturnable; - -import java.util.stream.Stream; - -import org.embeddedt.modernfix.util.BlockClassPreloader; - -@Mixin(GameData.class) -public class GameDataMixin { - @Inject(method = "generateRegistryEvents", at = @At("RETURN"), remap = false) - private static void preloadBlockClasses(CallbackInfoReturnable>> cir) { - BlockClassPreloader.preloadClasses(); - } -} diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/resourcepacks/ModFileResourcePackMixin.java b/src/main/java/org/embeddedt/modernfix/mixin/perf/resourcepacks/ModFileResourcePackMixin.java deleted file mode 100644 index 9e11a02a..00000000 --- a/src/main/java/org/embeddedt/modernfix/mixin/perf/resourcepacks/ModFileResourcePackMixin.java +++ /dev/null @@ -1,120 +0,0 @@ -package org.embeddedt.modernfix.mixin.perf.resourcepacks; - -import com.google.common.base.Joiner; -import net.minecraft.server.packs.PackType; -import net.minecraft.resources.ResourceLocation; -import net.minecraftforge.fml.loading.moddiscovery.ModFile; -import net.minecraftforge.fml.packs.ModFileResourcePack; -import org.embeddedt.modernfix.ModernFix; -import org.spongepowered.asm.mixin.Final; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Overwrite; -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.Redirect; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; - -import java.io.IOException; -import java.nio.file.FileSystem; -import java.nio.file.FileVisitOption; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.*; -import java.util.function.Predicate; -import java.util.stream.Collectors; -import java.util.stream.Stream; - -@Mixin(ModFileResourcePack.class) -public abstract class ModFileResourcePackMixin { - @Shadow public abstract Set getNamespaces(PackType type); - - @Shadow(remap = false) @Final private ModFile modFile; - private EnumMap> namespacesByType; - private EnumMap>> rootListingByNamespaceAndType; - private Set containedPaths; - private boolean useNamespaceCaches; - private FileSystem resourcePackFS; - private static Joiner slashJoiner = Joiner.on('/'); - - @Inject(method = "", at = @At("TAIL")) - private void cacheResources(ModFile modFile, CallbackInfo ci) { - this.resourcePackFS = modFile.getLocator().findPath(modFile, "").getFileSystem(); - this.useNamespaceCaches = false; - this.namespacesByType = new EnumMap<>(PackType.class); - for(PackType type : PackType.values()) { - this.namespacesByType.put(type, this.getNamespaces(type)); - } - this.useNamespaceCaches = true; - this.rootListingByNamespaceAndType = new EnumMap<>(PackType.class); - this.containedPaths = new HashSet<>(); - for(PackType type : PackType.values()) { - Set namespaces = this.namespacesByType.get(type); - HashMap> rootListingForNamespaces = new HashMap<>(); - for(String namespace : namespaces) { - try { - Path root = modFile.getLocator().findPath(modFile, type.getDirectory(), namespace).toAbsolutePath(); - try (Stream stream = Files.walk(root)) { - ArrayList rootListingPaths = new ArrayList<>(); - stream - .map(path -> root.relativize(path.toAbsolutePath())) - .filter(this::isValidCachedResourcePath) - .forEach(path -> { - if(!path.toString().endsWith(".mcmeta")) - rootListingPaths.add(path); - String mergedPath = slashJoiner.join(type.getDirectory(), namespace, path); - this.containedPaths.add(mergedPath); - }); - rootListingPaths.trimToSize(); - rootListingForNamespaces.put(namespace, rootListingPaths); - } - } catch(IOException e) { - rootListingForNamespaces.put(namespace, Collections.emptyList()); - } - } - this.rootListingByNamespaceAndType.put(type, rootListingForNamespaces); - } - } - - private boolean isValidCachedResourcePath(Path path) { - String str = path.toString(); - for(int i = 0; i < str.length(); i++) { - if(!ResourceLocation.validPathChar(str.charAt(i))) { - return false; - } - } - return true; - } - - @Inject(method = "getNamespaces", at = @At("HEAD"), cancellable = true) - private void useCacheForNamespaces(PackType type, CallbackInfoReturnable> cir) { - if(useNamespaceCaches) { - cir.setReturnValue(this.namespacesByType.get(type)); - } - } - - @Inject(method = "hasResource(Ljava/lang/String;)Z", at = @At(value = "HEAD"), cancellable = true) - private void useCacheForExistence(String path, CallbackInfoReturnable cir) { - cir.setReturnValue(this.containedPaths.contains(path)); - } - - /** - * @author embeddedt - * @reason Use cached listing of mod resources - */ - @Overwrite - public Collection getResources(PackType type, String resourceNamespace, String pathIn, int maxDepth, Predicate filter) - { - Path inputPath = this.resourcePackFS.getPath(pathIn); - return this.rootListingByNamespaceAndType.get(type).getOrDefault(resourceNamespace, Collections.emptyList()).stream(). - filter(path -> path.getNameCount() <= maxDepth). // Make sure the depth is within bounds - filter(path -> path.startsWith(inputPath)). // Make sure the target path is inside this one - filter(path -> filter.test(path.getFileName().toString())). // Test the file name against the predicate - // Finally we need to form the RL, so use the first name as the domain, and the rest as the path - // It is VERY IMPORTANT that we do not rely on Path.toString as this is inconsistent between operating systems - // Join the path names ourselves to force forward slashes - map(path -> new ResourceLocation(resourceNamespace, slashJoiner.join(path))). - collect(Collectors.toList()); - } -} diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/resourcepacks/VanillaPackMixin.java b/src/main/java/org/embeddedt/modernfix/mixin/perf/resourcepacks/VanillaPackMixin.java deleted file mode 100644 index d3e133a6..00000000 --- a/src/main/java/org/embeddedt/modernfix/mixin/perf/resourcepacks/VanillaPackMixin.java +++ /dev/null @@ -1,76 +0,0 @@ -package org.embeddedt.modernfix.mixin.perf.resourcepacks; - -import com.google.common.base.Joiner; -import com.google.common.cache.CacheBuilder; -import com.google.common.cache.CacheLoader; -import com.google.common.cache.LoadingCache; -import net.minecraft.server.packs.PackType; -import net.minecraft.server.packs.VanillaPackResources; -import net.minecraft.resources.ResourceLocation; -import org.apache.commons.lang3.tuple.Pair; -import org.embeddedt.modernfix.FileWalker; -import org.embeddedt.modernfix.ModernFix; -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.Redirect; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; -import org.spongepowered.asm.mixin.injection.callback.LocalCapture; - -import java.io.IOException; -import java.nio.file.*; -import java.util.*; -import java.util.concurrent.ExecutionException; -import java.util.stream.Stream; - -@Mixin(VanillaPackResources.class) -public class VanillaPackMixin { - @Shadow @Final private static Map JAR_FILESYSTEM_BY_TYPE; - private static LoadingCache, List> pathStreamLoadingCache = CacheBuilder.newBuilder() - .build(FileWalker.INSTANCE); - - private static Set containedPaths = null; - - @Inject(method = "", at = @At("TAIL")) - private void cacheContainedPaths(String[] p_i47912_1_, CallbackInfo ci) { - if(containedPaths != null) - return; - containedPaths = new HashSet<>(); - Joiner slashJoiner = Joiner.on('/'); - for(PackType type : PackType.values()) { - FileSystem fs = JAR_FILESYSTEM_BY_TYPE.get(type); - if(fs == null) - throw new IllegalStateException("No filesystem for vanilla " + type.name() + " assets"); - try { - Path root = fs.getPath(type.getDirectory()).toAbsolutePath(); - try(Stream stream = Files.walk(root)) { - stream - .map(path -> root.relativize(path.toAbsolutePath())) - .forEach(path -> containedPaths.add(slashJoiner.join(type.getDirectory(), path))); - } - } catch(IOException e) { - e.printStackTrace(); - } - } - } - - @Redirect(method = "getResources(Ljava/util/Collection;ILjava/lang/String;Ljava/nio/file/Path;Ljava/lang/String;Ljava/util/function/Predicate;)V", at = @At(value = "INVOKE", target = "Ljava/nio/file/Files;walk(Ljava/nio/file/Path;I[Ljava/nio/file/FileVisitOption;)Ljava/util/stream/Stream;")) - private static Stream useCacheForLoading(Path path, int maxDepth, FileVisitOption[] fileVisitOptions) throws IOException { - try { - return pathStreamLoadingCache.get(Pair.of(path, maxDepth)).stream(); - } catch (ExecutionException e) { - if(e.getCause() instanceof IOException) /* generally always should be */ - throw (IOException)e.getCause(); - else - throw new IOException(e); - } - } - - @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 cir) { - cir.setReturnValue(containedPaths.contains(type.getDirectory() + "/" + location.getNamespace() + "/" + location.getPath())); - } -} diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/skip_first_datapack_reload/LevelSaveMixin.java b/src/main/java/org/embeddedt/modernfix/mixin/perf/skip_first_datapack_reload/LevelSaveMixin.java deleted file mode 100644 index b6f6d978..00000000 --- a/src/main/java/org/embeddedt/modernfix/mixin/perf/skip_first_datapack_reload/LevelSaveMixin.java +++ /dev/null @@ -1,32 +0,0 @@ -package org.embeddedt.modernfix.mixin.perf.skip_first_datapack_reload; - -import net.minecraft.client.Minecraft; -import net.minecraft.nbt.CompoundTag; -import net.minecraft.nbt.NbtIo; -import net.minecraft.world.level.storage.LevelStorageSource; -import net.minecraftforge.fml.common.ObfuscationReflectionHelper; -import org.embeddedt.modernfix.ModernFix; -import org.embeddedt.modernfix.duck.ILevelSave; -import org.embeddedt.modernfix.util.DummyServerConfiguration; -import org.spongepowered.asm.mixin.Final; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; - -import java.nio.file.Path; - -@Mixin(LevelStorageSource.LevelStorageAccess.class) -public class LevelSaveMixin implements ILevelSave { - @Shadow @Final private Path levelPath; - - public void runWorldPersistenceHooks(LevelStorageSource format) { - ((SaveFormatAccessor)format).invokeReadLevelData(this.levelPath.toFile(), (file, dataFixer) -> { - try { - CompoundTag compoundTag = NbtIo.readCompressed(file); - net.minecraftforge.fml.WorldPersistenceHooks.handleWorldDataLoad((LevelStorageSource.LevelStorageAccess)(Object)this, new DummyServerConfiguration(), compoundTag); - } catch (Exception e) { - ModernFix.LOGGER.error("Exception reading {}", file, e); - } - return null; - }); - } -} diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/skip_first_datapack_reload/MinecraftMixin.java b/src/main/java/org/embeddedt/modernfix/mixin/perf/skip_first_datapack_reload/MinecraftMixin.java deleted file mode 100644 index b6a8079e..00000000 --- a/src/main/java/org/embeddedt/modernfix/mixin/perf/skip_first_datapack_reload/MinecraftMixin.java +++ /dev/null @@ -1,49 +0,0 @@ -package org.embeddedt.modernfix.mixin.perf.skip_first_datapack_reload; - -import com.mojang.datafixers.util.Function4; -import net.minecraft.client.Minecraft; -import net.minecraft.server.packs.resources.ResourceManager; -import net.minecraft.world.level.DataPackConfig; -import net.minecraft.core.RegistryAccess; -import net.minecraft.world.level.storage.WorldData; -import net.minecraft.world.level.storage.LevelStorageSource; -import org.embeddedt.modernfix.ModernFix; -import org.embeddedt.modernfix.ModernFixClient; -import org.embeddedt.modernfix.duck.ILevelSave; -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.Redirect; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; - -import java.util.concurrent.ExecutionException; -import java.util.function.Function; - -@Mixin(Minecraft.class) -public abstract class MinecraftMixin { - @Shadow public abstract Minecraft.ServerStem makeServerStem(RegistryAccess.RegistryHolder dynamicRegistries, Function worldStorageToDatapackFunction, Function4 quadFunction, boolean vanillaOnly, LevelStorageSource.LevelStorageAccess worldStorage) throws InterruptedException, ExecutionException; - - @Shadow @Final private LevelStorageSource levelSource; - - @Redirect(method = "loadLevel(Ljava/lang/String;)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/core/RegistryAccess;builtin()Lnet/minecraft/core/RegistryAccess$RegistryHolder;")) - private RegistryAccess.RegistryHolder useNullRegistry() { - return null; - } - - @Redirect(method = "loadWorld", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/Minecraft;makeServerStem(Lnet/minecraft/core/RegistryAccess$RegistryHolder;Ljava/util/function/Function;Lcom/mojang/datafixers/util/Function4;ZLnet/minecraft/world/level/storage/LevelStorageSource$LevelStorageAccess;)Lnet/minecraft/client/Minecraft$ServerStem;", ordinal = 0)) - private Minecraft.ServerStem skipFirstReload(Minecraft client, RegistryAccess.RegistryHolder dynamicRegistries, Function worldStorageToDatapackFunction, Function4 quadFunction, boolean vanillaOnly, LevelStorageSource.LevelStorageAccess levelSave, String worldName, RegistryAccess.RegistryHolder originalRegistries, Function levelSaveToDatapackFunction, Function4 quadFunction2, boolean vanillaOnly2, Minecraft.ExperimentalDialogType selectionType, boolean creating) throws InterruptedException, ExecutionException { - if(!creating) { - ModernFix.LOGGER.warn("Skipping first reload, this is still experimental"); - ModernFix.runningFirstInjection = true; - ((ILevelSave)levelSave).runWorldPersistenceHooks(levelSource); - ModernFix.runningFirstInjection = false; - return null; - } else { - /* allow reload */ - return makeServerStem(dynamicRegistries, worldStorageToDatapackFunction, quadFunction, vanillaOnly, levelSave); - } - } -} diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/skip_first_datapack_reload/SaveFormatAccessor.java b/src/main/java/org/embeddedt/modernfix/mixin/perf/skip_first_datapack_reload/SaveFormatAccessor.java deleted file mode 100644 index ce3ac88f..00000000 --- a/src/main/java/org/embeddedt/modernfix/mixin/perf/skip_first_datapack_reload/SaveFormatAccessor.java +++ /dev/null @@ -1,15 +0,0 @@ -package org.embeddedt.modernfix.mixin.perf.skip_first_datapack_reload; - -import com.mojang.datafixers.DataFixer; -import net.minecraft.world.level.storage.LevelStorageSource; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.gen.Invoker; - -import java.io.File; -import java.util.function.BiFunction; - -@Mixin(LevelStorageSource.class) -public interface SaveFormatAccessor { - @Invoker - T invokeReadLevelData(File saveDir, BiFunction levelDatReader); -} diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/thread_priorities/IntegratedServerMixin.java b/src/main/java/org/embeddedt/modernfix/mixin/perf/thread_priorities/IntegratedServerMixin.java index 10f57276..4f940e86 100644 --- a/src/main/java/org/embeddedt/modernfix/mixin/perf/thread_priorities/IntegratedServerMixin.java +++ b/src/main/java/org/embeddedt/modernfix/mixin/perf/thread_priorities/IntegratedServerMixin.java @@ -3,7 +3,7 @@ package org.embeddedt.modernfix.mixin.perf.thread_priorities; import com.mojang.authlib.GameProfileRepository; import com.mojang.authlib.minecraft.MinecraftSessionService; import net.minecraft.client.Minecraft; -import net.minecraft.server.ServerResources; +import net.minecraft.server.WorldStem; import net.minecraft.server.packs.repository.PackRepository; import net.minecraft.client.server.IntegratedServer; import net.minecraft.server.players.GameProfileCache; @@ -21,9 +21,9 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; @Mixin(IntegratedServer.class) public class IntegratedServerMixin { @Inject(method = "", at = @At("RETURN")) - private void adjustServerPriority(Thread pServerThread, Minecraft pMinecraft, RegistryAccess.RegistryHolder pRegistryHolder, LevelStorageSource.LevelStorageAccess pStorageSource, PackRepository pPackRepository, ServerResources pResources, WorldData pWorldData, MinecraftSessionService pSessionService, GameProfileRepository pProfileRepository, GameProfileCache pProfileCache, ChunkProgressListenerFactory pProgressListenerfactory, 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(); ModernFix.LOGGER.info("Changing server thread priority to " + pri); - pServerThread.setPriority(pri); + thread.setPriority(pri); } } diff --git a/src/main/java/org/embeddedt/modernfix/models/LazyBakedModel.java b/src/main/java/org/embeddedt/modernfix/models/LazyBakedModel.java index d5b87496..3fed6e03 100644 --- a/src/main/java/org/embeddedt/modernfix/models/LazyBakedModel.java +++ b/src/main/java/org/embeddedt/modernfix/models/LazyBakedModel.java @@ -89,11 +89,6 @@ public class LazyBakedModel implements BakedModel { return computeDelegate().getOverrides(); } - @Override - public BakedModel getBakedModel() { - return computeDelegate().getBakedModel(); - } - @Nonnull @Override public List getQuads(@Nullable BlockState state, @Nullable Direction side, @Nonnull Random rand, @Nonnull IModelData extraData) { @@ -101,8 +96,8 @@ public class LazyBakedModel implements BakedModel { } @Override - public boolean isAmbientOcclusion(BlockState state) { - return computeDelegate().isAmbientOcclusion(state); + public boolean useAmbientOcclusion(BlockState state) { + return computeDelegate().useAmbientOcclusion(state); } @Override @@ -122,8 +117,8 @@ public class LazyBakedModel implements BakedModel { } @Override - public TextureAtlasSprite getParticleTexture(@Nonnull IModelData data) { - return computeDelegate().getParticleTexture(data); + public TextureAtlasSprite getParticleIcon(@Nonnull IModelData data) { + return computeDelegate().getParticleIcon(data); } @Override diff --git a/src/main/java/org/embeddedt/modernfix/searchtree/JEIBackedSearchTree.java b/src/main/java/org/embeddedt/modernfix/searchtree/JEIBackedSearchTree.java index b26ff661..835fd425 100644 --- a/src/main/java/org/embeddedt/modernfix/searchtree/JEIBackedSearchTree.java +++ b/src/main/java/org/embeddedt/modernfix/searchtree/JEIBackedSearchTree.java @@ -1,14 +1,15 @@ package org.embeddedt.modernfix.searchtree; -import mezz.jei.Internal; -import mezz.jei.ingredients.IIngredientListElementInfo; -import mezz.jei.ingredients.IngredientFilter; -import mezz.jei.runtime.JeiRuntime; +import mezz.jei.api.ingredients.ITypedIngredient; +import mezz.jei.common.Internal; +import mezz.jei.common.ingredients.IngredientFilter; +import mezz.jei.common.runtime.JeiRuntime; import net.minecraft.world.item.ItemStack; import org.embeddedt.modernfix.mixin.perf.blast_search_trees.IngredientFilterInvoker; import java.util.ArrayList; import java.util.List; +import java.util.Optional; /** * Uses JEI to handle search tree lookups. @@ -23,9 +24,9 @@ public class JEIBackedSearchTree extends DummySearchTree { } @Override public List search(String pSearchText) { - JeiRuntime runtime = Internal.getRuntime(); - if(runtime != null) { - return this.searchJEI(Internal.getIngredientFilter(), pSearchText); + Optional runtime = Internal.getRuntime(); + if(runtime.isPresent()) { + return this.searchJEI((IngredientFilter)runtime.get().getIngredientFilter(), pSearchText); } else { /* Use the default, dummy implementation */ return super.search(pSearchText); @@ -35,10 +36,10 @@ public class JEIBackedSearchTree extends DummySearchTree { private List searchJEI(IngredientFilter filter, String pSearchText) { if(!pSearchText.equals(lastSearchText)) { listCache.clear(); - List> ingredients = ((IngredientFilterInvoker)filter).invokeGetIngredientListUncached(filteringByTag ? ("$" + pSearchText) : pSearchText); - for(IIngredientListElementInfo ingredient : ingredients) { - if(ingredient.getElement().getIngredient() instanceof ItemStack) { - listCache.add((ItemStack)ingredient.getElement().getIngredient()); + List> ingredients = ((IngredientFilterInvoker)filter).invokeGetIngredientListUncached(filteringByTag ? ("$" + pSearchText) : pSearchText); + for(ITypedIngredient ingredient : ingredients) { + if(ingredient.getIngredient() instanceof ItemStack) { + listCache.add((ItemStack)ingredient.getIngredient()); } } lastSearchText = pSearchText; diff --git a/src/main/java/org/embeddedt/modernfix/structure/AsyncLocator.java b/src/main/java/org/embeddedt/modernfix/structure/AsyncLocator.java deleted file mode 100644 index 3cf025d0..00000000 --- a/src/main/java/org/embeddedt/modernfix/structure/AsyncLocator.java +++ /dev/null @@ -1,215 +0,0 @@ -package org.embeddedt.modernfix.structure; - -import com.mojang.datafixers.util.Pair; -import net.minecraft.core.BlockPos; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.server.MinecraftServer; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.world.level.chunk.ChunkGenerator; -import net.minecraft.world.level.levelgen.feature.StructureFeature; -import net.minecraftforge.eventbus.api.SubscribeEvent; -import net.minecraftforge.fml.common.Mod; -import net.minecraftforge.fml.common.thread.SidedThreadGroups; -import net.minecraftforge.fml.event.server.FMLServerAboutToStartEvent; -import net.minecraftforge.fml.event.server.FMLServerStoppingEvent; -import org.embeddedt.modernfix.ModernFix; -import org.jetbrains.annotations.NotNull; - -import java.sql.Struct; -import java.util.Collection; -import java.util.Objects; -import java.util.Optional; -import java.util.Set; -import java.util.concurrent.*; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.function.Consumer; -import java.util.stream.Collectors; - -@Mod.EventBusSubscriber(modid = ModernFix.MODID) -public class AsyncLocator { - private static ExecutorService LOCATING_EXECUTOR_SERVICE = null; - private static final AtomicInteger poolNum = new AtomicInteger(1); - - private AsyncLocator() {} - - private static void setupExecutorService() { - shutdownExecutorService(); - - int threads = 1; // very unlikely we need more than one - ModernFix.LOGGER.info("Starting locating executor service with thread pool size of {}", threads); - LOCATING_EXECUTOR_SERVICE = Executors.newFixedThreadPool( - threads, - new ThreadFactory() { - - private final AtomicInteger threadNum = new AtomicInteger(1); - private final String namePrefix = "asynclocator-" + poolNum.getAndIncrement() + "-thread-"; - - @Override - public Thread newThread(@NotNull Runnable r) { - return new Thread(SidedThreadGroups.SERVER, r, namePrefix + threadNum.getAndIncrement()); - } - } - ); - } - - private static void shutdownExecutorService() { - if (LOCATING_EXECUTOR_SERVICE != null) { - ModernFix.LOGGER.info("Shutting down locating executor service"); - LOCATING_EXECUTOR_SERVICE.shutdown(); - } - } - - @SubscribeEvent - public static void handleServerAboutToStartEvent(FMLServerAboutToStartEvent ignoredEvent) { - setupExecutorService(); - } - - @SubscribeEvent - public static void handleServerStoppingEvent(FMLServerStoppingEvent ignoredEvent) { - shutdownExecutorService(); - } - - /** - * Queues a task to locate a feature using {@link ServerLevel#findNearestMapFeature(TagKey, BlockPos, int, boolean)} - * and returns a {@link LocateTask} with the futures for it. - */ - public static LocateTask locateLevel( - ServerLevel level, - Collection> structure, - BlockPos pos, - int searchRadius, - boolean skipKnownStructures - ) { - ModernFix.LOGGER.debug( - "Creating locate task for {} in {} around {} within {} chunks", - structure, level, pos, searchRadius - ); - CompletableFuture completableFuture = new CompletableFuture<>(); - Future future = LOCATING_EXECUTOR_SERVICE.submit( - () -> doLocateLevel(completableFuture, level, structure, pos, searchRadius, skipKnownStructures) - ); - return new LocateTask<>(level.getServer(), completableFuture, future); - } - - /** - * Queues a task to locate a feature using - * {@link ChunkGenerator#findNearestMapFeature(ServerLevel, HolderSet, BlockPos, int, boolean)} and returns a - * {@link LocateTask} with the futures for it. - */ - public static LocateTask>> locateChunkGen( - ServerLevel level, - Collection> structureSet, - BlockPos pos, - int searchRadius, - boolean skipKnownStructures - ) { - ModernFix.LOGGER.debug( - "Creating locate task for {} in {} around {} within {} chunks", - structureSet, level, pos, searchRadius - ); - CompletableFuture>> completableFuture = new CompletableFuture<>(); - Future future = LOCATING_EXECUTOR_SERVICE.submit( - () -> doLocateChunkGenerator(completableFuture, level, structureSet, pos, searchRadius, skipKnownStructures) - ); - return new LocateTask<>(level.getServer(), completableFuture, future); - } - - private static String structureSetToString(Collection> collection) { - return "[" + collection.stream().map(StructureFeature::getRegistryName).map(ResourceLocation::toString).collect(Collectors.joining(", ")) + "]"; - } - - private static void doLocateLevel( - CompletableFuture completableFuture, - ServerLevel level, - Collection> structureTag, - BlockPos pos, - int searchRadius, - boolean skipExistingChunks - ) { - String structures = structureSetToString(structureTag); - ModernFix.LOGGER.debug( - "Trying to locate {} in {} around {} within {} chunks", - structures, level, pos, searchRadius - ); - Optional thePosition = structureTag.stream() - .map(tag -> level.findNearestMapFeature(tag, pos, searchRadius, skipExistingChunks)) - .filter(Objects::nonNull) - .findFirst(); - if (!thePosition.isPresent()) - ModernFix.LOGGER.debug("No {} found", structures); - else - ModernFix.LOGGER.debug("Found {} at {}", structures, thePosition.get()); - completableFuture.complete(thePosition.orElse(null)); - } - - @SuppressWarnings({"rawtypes", "unchecked" }) - private static void doLocateChunkGenerator( - CompletableFuture>> completableFuture, - ServerLevel level, - Collection> structureSet, - BlockPos pos, - int searchRadius, - boolean skipExistingChunks - ) { - String structures = structureSetToString(structureSet); - ModernFix.LOGGER.debug( - "Trying to locate {} in {} around {} within {} chunks", - structures, level, pos, searchRadius - ); - Optional> foundStructure = structureSet.stream() - .map(feature -> Pair.of(level.getChunkSource().getGenerator() - .findNearestMapFeature(level, feature, pos, searchRadius, skipExistingChunks), (StructureFeature)feature)) - .filter(pair -> pair.getFirst() != null) - .findFirst(); - if (!foundStructure.isPresent()) - ModernFix.LOGGER.debug("No {} found", structures); - else - ModernFix.LOGGER.debug("Found {} at {}", structures, foundStructure.get().getFirst()); - completableFuture.complete((Pair>)(Object)foundStructure.orElse(null)); - } - - /** - * Holder of the futures for an async locate task as well as providing some helper functions. - * The completableFuture will be completed once the call to - * {@link ServerLevel#findNearestMapFeature(TagKey, BlockPos, int, boolean)} has completed, and will hold the - * result of it. - * The taskFuture is the future for the {@link Runnable} itself in the executor service. - */ - public static class LocateTask { - private final MinecraftServer server; - private final CompletableFuture completableFuture; - private final Future taskFuture; - public LocateTask(MinecraftServer server, CompletableFuture completableFuture, Future taskFuture) { - this.server = server; - this.completableFuture = completableFuture; - this.taskFuture = taskFuture; - } - /** - * Helper function that calls {@link CompletableFuture#thenAccept(Consumer)} with the given action. - * Bear in mind that the action will be executed from the task's thread. If you intend to change any game data, - * it's strongly advised you use {@link #thenOnServerThread(Consumer)} instead so that it's queued and executed - * on the main server thread instead. - */ - public LocateTask then(Consumer action) { - completableFuture.thenAccept(action); - return this; - } - - /** - * Helper function that calls {@link CompletableFuture#thenAccept(Consumer)} with the given action on the server - * thread. - */ - public LocateTask thenOnServerThread(Consumer action) { - completableFuture.thenAccept(pos -> server.submit(() -> action.accept(pos))); - return this; - } - - /** - * Helper function that cancels both completableFuture and taskFuture. - */ - public void cancel() { - taskFuture.cancel(true); - completableFuture.cancel(false); - } - } -} diff --git a/src/main/java/org/embeddedt/modernfix/structure/logic/CommonLogic.java b/src/main/java/org/embeddedt/modernfix/structure/logic/CommonLogic.java deleted file mode 100644 index a8d0e438..00000000 --- a/src/main/java/org/embeddedt/modernfix/structure/logic/CommonLogic.java +++ /dev/null @@ -1,92 +0,0 @@ -package org.embeddedt.modernfix.structure.logic; - -import net.minecraft.core.BlockPos; -import net.minecraft.network.chat.TranslatableComponent; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.world.inventory.AbstractContainerMenu; -import net.minecraft.world.inventory.ChestMenu; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.item.Items; -import net.minecraft.world.item.MapItem; -import net.minecraft.world.level.block.entity.BlockEntity; -import net.minecraft.world.level.block.entity.ChestBlockEntity; -import net.minecraft.world.level.saveddata.maps.MapDecoration; -import net.minecraft.world.level.saveddata.maps.MapItemSavedData; -import org.embeddedt.modernfix.mixin.perf.async_locator.MapItemAccess; - -public class CommonLogic { - private CommonLogic() {} - - /** - * Creates an empty "Filled Map", with a hover tooltip name stating that it's locating a feature. - * - * @return The ItemStack - */ - public static ItemStack createEmptyMap() { - ItemStack stack = new ItemStack(Items.FILLED_MAP); - stack.setHoverName(new TranslatableComponent("asynclocator.map.locating")); - return stack; - } - - /** - * Updates the map stack with all the given data. - * - * @param mapStack The map ItemStack to update - * @param level The ServerLevel - * @param pos The feature position - * @param scale The map scale - * @param destinationType The map feature type - */ - public static void updateMap( - ItemStack mapStack, - ServerLevel level, - BlockPos pos, - int scale, - MapDecoration.Type destinationType - ) { - updateMap(mapStack, level, pos, scale, destinationType, null); - } - - /** - * Updates the map stack with all the given data. - * - * @param mapStack The map ItemStack to update - * @param level The ServerLevel - * @param pos The feature position - * @param scale The map scale - * @param destinationType The map feature type - * @param displayName The hover tooltip display name of the ItemStack - */ - public static void updateMap( - ItemStack mapStack, - ServerLevel level, - BlockPos pos, - int scale, - MapDecoration.Type destinationType, - String displayName - ) { - MapItemAccess.callCreateAndStoreSavedData( - mapStack, level, pos.getX(), pos.getZ(), scale, true, true, level.dimension() - ); - MapItem.renderBiomePreviewMap(level, mapStack); - MapItemSavedData.addTargetDecoration(mapStack, pos, "+", destinationType); - if (displayName != null) - mapStack.setHoverName(new TranslatableComponent(displayName)); - } - - /** - * Broadcasts slot changes to all players that have the chest container open. - * Won't do anything if the BlockEntity isn't an instance of {@link ChestBlockEntity}. - */ - public static void broadcastChestChanges(ServerLevel level, BlockEntity be) { - if (!(be instanceof ChestBlockEntity)) - return; - - level.players().forEach(player -> { - AbstractContainerMenu container = player.containerMenu; - if (container instanceof ChestMenu && ((ChestMenu)container).getContainer() == be) { - container.broadcastChanges(); - } - }); - } -} diff --git a/src/main/java/org/embeddedt/modernfix/structure/logic/EnderEyeItemLogic.java b/src/main/java/org/embeddedt/modernfix/structure/logic/EnderEyeItemLogic.java deleted file mode 100644 index d60fce6f..00000000 --- a/src/main/java/org/embeddedt/modernfix/structure/logic/EnderEyeItemLogic.java +++ /dev/null @@ -1,38 +0,0 @@ -package org.embeddedt.modernfix.structure.logic; - -import com.google.common.collect.ImmutableSet; -import net.minecraft.advancements.CriteriaTriggers; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.server.level.ServerPlayer; -import net.minecraft.stats.Stats; -import net.minecraft.world.entity.player.Player; -import net.minecraft.world.entity.projectile.EyeOfEnder; -import net.minecraft.world.item.EnderEyeItem; -import net.minecraft.world.level.levelgen.feature.StructureFeature; -import org.embeddedt.modernfix.mixin.perf.async_locator.EyeOfEnderAccess; -import org.embeddedt.modernfix.structure.AsyncLocator; - -public class EnderEyeItemLogic { - private EnderEyeItemLogic() {} - - public static void locateAsync(ServerLevel level, Player player, EyeOfEnder eyeOfEnder, EnderEyeItem enderEyeItem) { - AsyncLocator.locateChunkGen( - level, - ImmutableSet.of(StructureFeature.STRONGHOLD), - player.blockPosition(), - 100, - false - ).thenOnServerThread(pos -> { - ((EyeOfEnderData) eyeOfEnder).setLocateTaskOngoing(false); - if (pos != null) { - eyeOfEnder.signalTo(pos.getFirst()); - CriteriaTriggers.USED_ENDER_EYE.trigger((ServerPlayer) player, pos.getFirst()); - player.awardStat(Stats.ITEM_USED.get(enderEyeItem)); - } else { - // Set the entity's life to long enough that it dies - ((EyeOfEnderAccess) eyeOfEnder).setLife(Integer.MAX_VALUE - 100); - } - }); - ((EyeOfEnderData) eyeOfEnder).setLocateTaskOngoing(true); - } -} diff --git a/src/main/java/org/embeddedt/modernfix/structure/logic/ExplorationMapFunctionLogic.java b/src/main/java/org/embeddedt/modernfix/structure/logic/ExplorationMapFunctionLogic.java deleted file mode 100644 index 9a946946..00000000 --- a/src/main/java/org/embeddedt/modernfix/structure/logic/ExplorationMapFunctionLogic.java +++ /dev/null @@ -1,111 +0,0 @@ -package org.embeddedt.modernfix.structure.logic; - -import com.google.common.collect.ImmutableSet; -import net.minecraft.core.BlockPos; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.world.item.Item; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.item.Items; -import net.minecraft.world.level.block.entity.BlockEntity; -import net.minecraft.world.level.levelgen.feature.StructureFeature; -import net.minecraft.world.level.saveddata.maps.MapDecoration; -import net.minecraftforge.fml.loading.Java9BackportUtils; -import net.minecraftforge.items.CapabilityItemHandler; -import net.minecraftforge.items.IItemHandler; -import net.minecraftforge.items.IItemHandlerModifiable; -import org.embeddedt.modernfix.ModernFix; -import org.embeddedt.modernfix.structure.AsyncLocator; - -import java.util.function.BiConsumer; - -// TODO: Need to test this -public class ExplorationMapFunctionLogic { - private static final int MAX_STACK_SIZE = 64; - private ExplorationMapFunctionLogic() {} - - public static void invalidateMap(ItemStack mapStack, ServerLevel level, BlockPos pos) { - handleUpdateMapInChest(mapStack, level, pos, (handler, slot) -> { - if (handler instanceof IItemHandlerModifiable) { - ((IItemHandlerModifiable)handler).setStackInSlot(slot, new ItemStack(Items.MAP)); - } else { - handler.extractItem(slot, MAX_STACK_SIZE, false); - handler.insertItem(slot, new ItemStack(Items.MAP), false); - } - }); - } - - public static void updateMap( - ItemStack mapStack, - ServerLevel level, - BlockPos pos, - int scale, - MapDecoration.Type destinationType, - BlockPos invPos - ) { - CommonLogic.updateMap(mapStack, level, pos, scale, destinationType); - // Shouldn't need to set the stack in its slot again, as we're modifying the same instance - handleUpdateMapInChest(mapStack, level, invPos, (handler, slot) -> {}); - } - - public static void handleUpdateMapInChest( - ItemStack mapStack, - ServerLevel level, - BlockPos invPos, - BiConsumer handleSlotFound - ) { - BlockEntity be = level.getBlockEntity(invPos); - if (be != null) { - Java9BackportUtils.ifPresentOrElse(be.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY).resolve(), - itemHandler -> { - for (int i = 0; i < itemHandler.getSlots(); i++) { - ItemStack slotStack = itemHandler.getStackInSlot(i); - if (slotStack == mapStack) { - handleSlotFound.accept(itemHandler, i); - CommonLogic.broadcastChestChanges(level, be); - return; - } - } - }, - () -> ModernFix.LOGGER.warn( - "Couldn't find item handler capability on chest {} at {}", - be.getClass().getSimpleName(), invPos - ) - ); - } else { - ModernFix.LOGGER.warn( - "Couldn't find block entity on chest {} at {}", - level.getBlockState(invPos), invPos - ); - } - } - - public static void handleLocationFound( - ItemStack mapStack, - ServerLevel level, - BlockPos pos, - int scale, - MapDecoration.Type destinationType, - BlockPos invPos - ) { - if (pos == null) { - invalidateMap(mapStack, level, invPos); - } else { - updateMap(mapStack, level, pos, scale, destinationType, invPos); - } - } - - public static ItemStack updateMapAsync( - ServerLevel level, - BlockPos blockPos, - int scale, - int searchRadius, - boolean skipKnownStructures, - MapDecoration.Type destinationType, - StructureFeature destination - ) { - ItemStack mapStack = CommonLogic.createEmptyMap(); - AsyncLocator.locateLevel(level, ImmutableSet.of(destination), blockPos, searchRadius, skipKnownStructures) - .thenOnServerThread(pos -> handleLocationFound(mapStack, level, pos, scale, destinationType, blockPos)); - return mapStack; - } -} diff --git a/src/main/java/org/embeddedt/modernfix/structure/logic/EyeOfEnderData.java b/src/main/java/org/embeddedt/modernfix/structure/logic/EyeOfEnderData.java deleted file mode 100644 index 1853d3e3..00000000 --- a/src/main/java/org/embeddedt/modernfix/structure/logic/EyeOfEnderData.java +++ /dev/null @@ -1,5 +0,0 @@ -package org.embeddedt.modernfix.structure.logic; - -public interface EyeOfEnderData { - void setLocateTaskOngoing(boolean locateTaskOngoing); -} diff --git a/src/main/java/org/embeddedt/modernfix/structure/logic/LocateCommandLogic.java b/src/main/java/org/embeddedt/modernfix/structure/logic/LocateCommandLogic.java deleted file mode 100644 index 173d8d75..00000000 --- a/src/main/java/org/embeddedt/modernfix/structure/logic/LocateCommandLogic.java +++ /dev/null @@ -1,30 +0,0 @@ -package org.embeddedt.modernfix.structure.logic; - -import com.google.common.collect.ImmutableSet; -import net.minecraft.commands.CommandSourceStack; -import net.minecraft.core.BlockPos; -import net.minecraft.network.chat.TextComponent; -import net.minecraft.server.commands.LocateCommand; -import net.minecraft.world.level.levelgen.feature.StructureFeature; -import org.embeddedt.modernfix.mixin.perf.async_locator.LocateCommandAccess; -import org.embeddedt.modernfix.structure.AsyncLocator; - -public class LocateCommandLogic { - private LocateCommandLogic() {} - - public static void locateAsync(CommandSourceStack sourceStack, StructureFeature feature) { - BlockPos originPos = new BlockPos(sourceStack.getPosition()); - AsyncLocator.locateLevel(sourceStack.getLevel(), ImmutableSet.of(feature), originPos, 100, false) - .thenOnServerThread(pair -> { - if (pair != null) { - LocateCommand.showLocateResult(sourceStack, feature.getFeatureName(), originPos, pair, "commands.locate.success"); - } else { - sourceStack.sendFailure( - new TextComponent( - LocateCommandAccess.getErrorFailed().create().getMessage() - ) - ); - } - }); - } -} diff --git a/src/main/java/org/embeddedt/modernfix/structure/logic/MerchantLogic.java b/src/main/java/org/embeddedt/modernfix/structure/logic/MerchantLogic.java deleted file mode 100644 index 5f9ecd35..00000000 --- a/src/main/java/org/embeddedt/modernfix/structure/logic/MerchantLogic.java +++ /dev/null @@ -1,125 +0,0 @@ -package org.embeddedt.modernfix.structure.logic; - -import com.google.common.collect.ImmutableSet; -import net.minecraft.core.BlockPos; -import net.minecraft.network.chat.TranslatableComponent; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.server.level.ServerPlayer; -import net.minecraft.world.entity.Entity; -import net.minecraft.world.entity.npc.AbstractVillager; -import net.minecraft.world.entity.npc.Villager; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.item.Items; -import net.minecraft.world.item.trading.MerchantOffer; -import net.minecraft.world.level.levelgen.feature.StructureFeature; -import net.minecraft.world.level.saveddata.maps.MapDecoration; -import org.embeddedt.modernfix.ModernFix; -import org.embeddedt.modernfix.mixin.perf.async_locator.MerchantOfferAccess; -import org.embeddedt.modernfix.structure.AsyncLocator; - -import java.util.Optional; - -public class MerchantLogic { - private static final boolean REMOVE_OFFER = false; - private MerchantLogic() {} - - public static void invalidateMap(AbstractVillager merchant, ItemStack mapStack) { - mapStack.setHoverName(new TranslatableComponent("asynclocator.map.none")); - Optional offerOptional = merchant.getOffers() - .stream() - .filter(offer -> offer.getResult() == mapStack) - .findFirst(); - if(offerOptional.isPresent()) { - removeOffer(merchant, offerOptional.get()); - } else { - ModernFix.LOGGER.warn("Failed to find merchant offer for map"); - } - } - - public static void removeOffer(AbstractVillager merchant, MerchantOffer offer) { - if (REMOVE_OFFER) { - merchant.getOffers().remove(offer); - } else { - ((MerchantOfferAccess) offer).setMaxUses(0); - offer.setToOutOfStock(); - } - } - - public static void handleLocationFound( - ServerLevel level, - AbstractVillager merchant, - ItemStack mapStack, - String displayName, - MapDecoration.Type destinationType, - BlockPos pos - ) { - if (pos == null) { - invalidateMap(merchant, mapStack); - } else { - CommonLogic.updateMap(mapStack, level, pos, 2, destinationType, displayName); - } - - if (merchant.getTradingPlayer() instanceof ServerPlayer) { - ServerPlayer tradingPlayer = (ServerPlayer)merchant.getTradingPlayer(); - tradingPlayer.sendMerchantOffers( - tradingPlayer.containerMenu.containerId, - merchant.getOffers(), - merchant instanceof Villager ? ((Villager)merchant).getVillagerData().getLevel() : 1, - merchant.getVillagerXp(), - merchant.showProgressBar(), - merchant.canRestock() - ); - } - } - - public static MerchantOffer updateMapAsync( - Entity pTrader, - int emeraldCost, - String displayName, - MapDecoration.Type destinationType, - int maxUses, - int villagerXp, - StructureFeature destination - ) { - return updateMapAsyncInternal( - pTrader, - emeraldCost, - maxUses, - villagerXp, - (level, merchant, mapStack) -> AsyncLocator.locateLevel(level, ImmutableSet.of(destination), merchant.blockPosition(), 100, true) - .thenOnServerThread(pos -> handleLocationFound( - level, - merchant, - mapStack, - displayName, - destinationType, - pos - )) - ); - } - - private static MerchantOffer updateMapAsyncInternal( - Entity trader, int emeraldCost, int maxUses, int villagerXp, MapUpdateTask task - ) { - if (trader instanceof AbstractVillager) { - AbstractVillager merchant = (AbstractVillager)trader; - ItemStack mapStack = CommonLogic.createEmptyMap(); - task.apply((ServerLevel) trader.level, merchant, mapStack); - - return new MerchantOffer( - new ItemStack(Items.EMERALD, emeraldCost), - new ItemStack(Items.COMPASS), - mapStack, - maxUses, - villagerXp, - 0.2F - ); - } else { - return null; - } - } - - public interface MapUpdateTask { - void apply(ServerLevel level, AbstractVillager merchant, ItemStack mapStack); - } -} diff --git a/src/main/java/org/embeddedt/modernfix/util/BlockClassPreloader.java b/src/main/java/org/embeddedt/modernfix/util/BlockClassPreloader.java deleted file mode 100644 index 140de108..00000000 --- a/src/main/java/org/embeddedt/modernfix/util/BlockClassPreloader.java +++ /dev/null @@ -1,90 +0,0 @@ -package org.embeddedt.modernfix.util; - -import com.google.common.base.Stopwatch; -import net.minecraft.world.level.block.state.BlockBehaviour; -import net.minecraft.world.level.block.Block; -import net.minecraftforge.fml.ModList; -import net.minecraftforge.fml.ModWorkManager; -import net.minecraftforge.fml.loading.moddiscovery.ModFile; -import net.minecraftforge.fml.loading.moddiscovery.ModFileInfo; -import net.minecraftforge.forgespi.language.ModFileScanData; -import org.embeddedt.modernfix.ModernFix; -import org.objectweb.asm.Type; - -import java.lang.reflect.Field; -import java.util.*; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.TimeUnit; -import java.util.stream.Collectors; - -public class BlockClassPreloader { - public static void preloadClasses() { - Stopwatch stopwatch = Stopwatch.createStarted(); - ModernFix.LOGGER.warn("Preparing to preload classes..."); - HashMap isABlockClass = new HashMap<>(); - isABlockClass.put(Type.getType(BlockBehaviour.class), true); - isABlockClass.put(Type.getType(Block.class), true); - Field selfField, parentField; - List futures = new ArrayList<>(); - try { - selfField = ModFileScanData.ClassData.class.getDeclaredField("clazz"); - selfField.setAccessible(true); - parentField = ModFileScanData.ClassData.class.getDeclaredField("parent"); - parentField.setAccessible(true); - List currentCandidates = ModList.get().getModFiles().stream() - .map(ModFileInfo::getFile) - .map(ModFile::getScanResult) - .flatMap(data -> data.getClasses().stream()) - .collect(Collectors.toList()); - HashSet blockClasses = new HashSet<>(); - blockClasses.add(Type.getType(BlockBehaviour.class)); - HashSet nonBlockClasses = new HashSet<>(); - int previousSize = -1; - nonBlockClasses.add(Type.getType(Object.class)); - currentCandidates.removeIf(clz -> { - Type self; - try { - self = (Type)selfField.get(clz); - } catch(ReflectiveOperationException e) { - throw new RuntimeException(e); - } - return (nonBlockClasses.contains(self) || blockClasses.contains(self)); - }); - while(blockClasses.size() > previousSize && currentCandidates.size() > 0) { - previousSize = blockClasses.size(); - currentCandidates.removeIf(clz -> { - Type parent, self; - try { - parent = (Type)parentField.get(clz); - self = (Type)selfField.get(clz); - } catch(ReflectiveOperationException e) { - throw new RuntimeException(e); - } - if(nonBlockClasses.contains(parent)) { - nonBlockClasses.add(self); - return true; - } else if(blockClasses.contains(parent)) { - blockClasses.add(self); - futures.add(CompletableFuture.runAsync(() -> { - if(self.getClassName().toLowerCase(Locale.ROOT).contains("mixin")) - return; - try { - Class.forName(self.getClassName()); - } catch(Throwable e) { - ModernFix.LOGGER.warn("Couldn't load " + self.getClassName(), e); - } - }, ModWorkManager.parallelExecutor())); - return true; - } else - return false; - }); - } - futures.forEach(CompletableFuture::join); - } catch(ReflectiveOperationException e) { - throw new RuntimeException(e); - } finally { - ModernFix.LOGGER.warn("Preloading classes took " + stopwatch.elapsed(TimeUnit.MILLISECONDS)/1000f + " seconds"); - stopwatch.stop(); - } - } -} diff --git a/src/main/java/org/embeddedt/modernfix/util/JEIUtil.java b/src/main/java/org/embeddedt/modernfix/util/JEIUtil.java deleted file mode 100644 index 230045ea..00000000 --- a/src/main/java/org/embeddedt/modernfix/util/JEIUtil.java +++ /dev/null @@ -1,30 +0,0 @@ -package org.embeddedt.modernfix.util; - -import com.mojang.blaze3d.vertex.PoseStack; -import mezz.jei.Internal; -import mezz.jei.api.runtime.IIngredientListOverlay; -import mezz.jei.runtime.JeiRuntime; -import net.minecraft.client.Minecraft; -import net.minecraft.client.gui.Gui; -import net.minecraft.network.chat.TranslatableComponent; -import net.minecraftforge.client.event.GuiScreenEvent; -import net.minecraftforge.common.MinecraftForge; -import net.minecraftforge.eventbus.api.SubscribeEvent; - -import java.util.function.Supplier; - -public class JEIUtil { - private static Supplier isLoading = null; - - public static void registerLoadingRenderer(Supplier isLoading) { - JEIUtil.isLoading = isLoading; - MinecraftForge.EVENT_BUS.register(JEIUtil.class); - } - - @SubscribeEvent - public static void renderLoad(GuiScreenEvent.DrawScreenEvent.Post event) { - if(isLoading.get()) { - Gui.drawString(new PoseStack(), Minecraft.getInstance().font, new TranslatableComponent("modernfix.jei_load"), 0, 0, 0xffffff); - } - } -} diff --git a/src/main/java/org/embeddedt/modernfix/util/ModUtil.java b/src/main/java/org/embeddedt/modernfix/util/ModUtil.java index e82d0982..8e09802e 100644 --- a/src/main/java/org/embeddedt/modernfix/util/ModUtil.java +++ b/src/main/java/org/embeddedt/modernfix/util/ModUtil.java @@ -1,16 +1,11 @@ package org.embeddedt.modernfix.util; -import net.minecraftforge.client.event.ModelBakeEvent; -import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.eventbus.EventBus; import net.minecraftforge.eventbus.api.EventListenerHelper; -import net.minecraftforge.eventbus.api.IEventListener; import net.minecraftforge.fml.ModContainer; import net.minecraftforge.fml.ModList; -import net.minecraftforge.fml.ModLoader; -import net.minecraftforge.fml.ModLoadingContext; -import net.minecraftforge.fml.common.ObfuscationReflectionHelper; import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; +import net.minecraftforge.fml.util.ObfuscationReflectionHelper; import org.embeddedt.modernfix.ModernFix; import java.util.*; diff --git a/src/main/java/org/embeddedt/modernfix/util/OrderedParallelModDispatcher.java b/src/main/java/org/embeddedt/modernfix/util/OrderedParallelModDispatcher.java index a08754fe..9c53ac86 100644 --- a/src/main/java/org/embeddedt/modernfix/util/OrderedParallelModDispatcher.java +++ b/src/main/java/org/embeddedt/modernfix/util/OrderedParallelModDispatcher.java @@ -1,16 +1,12 @@ package org.embeddedt.modernfix.util; import com.google.common.base.Preconditions; -import com.google.common.base.Stopwatch; import net.minecraftforge.fml.ModContainer; import net.minecraftforge.fml.ModList; import net.minecraftforge.fml.ModLoadingContext; -import net.minecraftforge.fml.ModWorkManager; -import net.minecraftforge.fml.common.ObfuscationReflectionHelper; import net.minecraftforge.fml.loading.moddiscovery.ModInfo; +import net.minecraftforge.fml.util.ObfuscationReflectionHelper; import net.minecraftforge.forgespi.language.IModInfo; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Marker; import org.apache.logging.log4j.MarkerManager; import org.embeddedt.modernfix.ModernFix; @@ -19,8 +15,6 @@ import java.util.*; import java.util.concurrent.CompletableFuture; import java.util.concurrent.Executor; import java.util.concurrent.Semaphore; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicLong; import java.util.function.Consumer; import java.util.function.Supplier; import java.util.stream.Collectors; @@ -36,7 +30,7 @@ public class OrderedParallelModDispatcher { Set finishedMods = Collections.synchronizedSet(new HashSet<>(modIDsToFilter)); HashMap> submittedFutures = new HashMap<>(); Semaphore jobWaitingSemaphore = new Semaphore(0); - ArrayList remainingModList = new ArrayList<>(ModList.get().getMods()); + ArrayList remainingModList = new ArrayList<>(ModList.get().getMods()); while(remainingModList.size() > 0) { remainingModList.removeIf(modInfo -> { if(finishedMods.contains(modInfo.getModId())) @@ -56,8 +50,7 @@ public class OrderedParallelModDispatcher { ModContainer container = modContainerOpt.get(); ModernFix.LOGGER.debug(DISPATCHER, "Submitting job for " + modInfo.getModId()); submittedFutures.put(modInfo.getModId(), CompletableFuture.runAsync(() -> { - Supplier contextExtension = ObfuscationReflectionHelper.getPrivateValue(ModContainer.class, container, "contextExtension"); - ModLoadingContext.get().setActiveContainer(container, contextExtension.get()); + ModLoadingContext.get().setActiveContainer(container); try { task.accept(modInfo.getModId()); } catch(RuntimeException e) { diff --git a/src/main/resources/META-INF/mods.toml b/src/main/resources/META-INF/mods.toml index 0fbfd925..aa678b20 100644 --- a/src/main/resources/META-INF/mods.toml +++ b/src/main/resources/META-INF/mods.toml @@ -6,7 +6,7 @@ # The name of the mod loader type to load - for regular FML @Mod mods it should be javafml modLoader = "javafml" #mandatory # A version range to match for said mod loader - for regular FML @Mod it will be the forge version -loaderVersion = "[36,)" #mandatory This is typically bumped every Minecraft version by Forge. See our download page for lists of versions. +loaderVersion = "[40,)" #mandatory This is typically bumped every Minecraft version by Forge. See our download page for lists of versions. # The license for you mod. This is mandatory metadata and allows for easier comprehension of your redistributive properties. # Review your options at https://choosealicense.com/. All rights reserved is the default copyright stance, and is thus the default here. license = "GNU LGPL 3.0" @@ -43,7 +43,7 @@ modId = "forge" #mandatory # Does this dependency have to exist - if not, ordering below must be specified mandatory = true #mandatory # The version range of the dependency -versionRange = "[36,)" #mandatory +versionRange = "[40,)" #mandatory # An ordering relationship for the dependency - BEFORE or AFTER required if the relationship is not mandatory ordering = "NONE" # Side this dependency is applied on - BOTH, CLIENT or SERVER @@ -53,13 +53,13 @@ side = "BOTH" modId = "minecraft" mandatory = true # This version range declares a minimum of the current minecraft version up to but not including the next major version -versionRange = "[1.16.5,1.17)" +versionRange = "[1.18.2,1.19)" ordering = "NONE" side = "BOTH" [[dependencies.modernfix]] modId = "jei" mandatory = false # This version range declares a minimum of the current minecraft version up to but not including the next major version -versionRange = "[7.7.1.153,)" +versionRange = "[10,)" ordering = "BEFORE" side = "CLIENT" diff --git a/src/main/resources/modernfix.mixins.json b/src/main/resources/modernfix.mixins.json index 909005af..e59a39ad 100644 --- a/src/main/resources/modernfix.mixins.json +++ b/src/main/resources/modernfix.mixins.json @@ -3,49 +3,27 @@ "minVersion": "0.8", "package": "org.embeddedt.modernfix.mixin", "plugin": "org.embeddedt.modernfix.core.ModernFixMixinPlugin", - "compatibilityLevel": "JAVA_8", + "compatibilityLevel": "JAVA_17", "refmap": "modernfix.refmap.json", "mixins": [ "bugfix.edge_chunk_not_saved.ChunkManagerMixin", - "bugfix.structure_manager_crash.StructureManagerMixin", "perf.remove_biome_temperature_cache.BiomeMixin", - "perf.resourcepacks.ModFileResourcePackMixin", - "perf.resourcepacks.VanillaPackMixin", - "perf.skip_first_datapack_reload.LevelSaveMixin", - "perf.skip_first_datapack_reload.SaveFormatAccessor", "perf.reduce_blockstate_cache_rebuilds.GameDataMixin", "perf.reduce_blockstate_cache_rebuilds.BlockCallbacksMixin", - "perf.boost_worker_count.UtilMixin", "perf.thread_priorities.UtilMixin", - "perf.preload_block_classes.GameDataMixin", "perf.reduce_blockstate_cache_rebuilds.BlocksMixin", "perf.reduce_blockstate_cache_rebuilds.BlockCallbacksMixin", "perf.reduce_blockstate_cache_rebuilds.ShapeCacheMixin", "perf.deduplicate_location.MixinResourceLocation", "perf.sync_executor_sleep.SyncExecutorMixin", - "perf.compress_biome_container.MixinBiomeContainer", - "perf.nuke_empty_chunk_sections.MixinChunk", "perf.cache_blockstate_cache_arrays.AbstractBlockStateCacheMixin", "perf.datapack_reload_exceptions.LootTableManagerMixin", "perf.datapack_reload_exceptions.RecipeManagerMixin", - "perf.async_locator.CommandSourceStackAccess", - "perf.async_locator.DolphinSwimToTreasureGoalMixin", - "perf.async_locator.EnderEyeItemMixin", - "perf.async_locator.ExplorationMapFunctionMixin", - "perf.async_locator.EyeOfEnderAccess", - "perf.async_locator.EyeOfEnderMixin", - "perf.async_locator.LocateCommandAccess", - "perf.async_locator.LocateCommandMixin", - "perf.async_locator.MapItemAccess", - "perf.async_locator.MerchantOfferAccess", - "perf.async_locator.TreasureMapForEmeraldsMixin", "feature.measure_time.BootstrapMixin" ], "client": [ "feature.measure_time.MinecraftMixin", "feature.reduce_loading_screen_freezes.ModelBakeryMixin", - "perf.skip_first_datapack_reload.MinecraftMixin", - "bugfix.concurrency.RenderTypeMixin", "bugfix.concurrency.MinecraftMixin", "perf.parallelize_model_loading.ModelBakeryMixin", "perf.parallelize_model_loading.OBJLoaderMixin", @@ -55,11 +33,6 @@ "perf.parallelize_model_loading.TransformationMatrixMixin", "perf.parallelize_model_loading.BooleanPropertyMixin", "perf.parallelize_model_loading.PropertyMixin", - "perf.async_jei.IngredientListElementFactoryMixin", - "perf.async_jei.ClientLifecycleHandlerMixin", - "perf.async_jei.JeiStarterMixin", - "perf.async_jei.PluginCallerMixin", - "perf.async_jei.RecipeManagerInternalMixin", "perf.thread_priorities.IntegratedServerMixin", "safety.BlockColorsMixin", "perf.flatten_model_predicates.AndConditionMixin", @@ -71,9 +44,7 @@ "perf.faster_baking.BlockModelShapesMixin", "perf.faster_baking.ModelManagerMixin", "perf.cache_model_materials.VanillaModelMixin", - "perf.cache_model_materials.MultipartMixin", - "bugfix.packet_leak.ClientPlayNetHandlerMixin", - "bugfix.packet_leak.SCustomPayloadPlayPacketMixin" + "perf.cache_model_materials.MultipartMixin" ], "injectors": { "defaultRequire": 1