Merge remote-tracking branch 'origin/1.18' into 1.19.2

This commit is contained in:
embeddedt 2023-05-01 10:37:22 -04:00
commit 723bb9d942
No known key found for this signature in database
GPG Key ID: A69433EC199B5613
43 changed files with 292 additions and 149 deletions

View File

@ -118,6 +118,36 @@ tasks.withType(JavaCompile) {
*/
}
processResources {
def mixinFileList = []
def mixinDirectory = file("src/main/java/org/embeddedt/modernfix/mixin")
fileTree(mixinDirectory).visit { FileVisitDetails details ->
if(details.file.isFile()) {
def fileName = mixinDirectory.relativePath(details.file).toString().replaceFirst(/\.java$/, "").replace('/', '.')
mixinFileList << fileName
}
}
def mixinClassesStringB = new StringBuilder()
for(int i = 0; i < mixinFileList.size(); i++) {
mixinClassesStringB.append(" \"")
mixinClassesStringB.append(mixinFileList.get(i))
mixinClassesStringB.append('"')
if(i < (mixinFileList.size() - 1))
mixinClassesStringB.append(',')
mixinClassesStringB.append('\n')
}
def replacements = [
mixin_classes: mixinClassesStringB.toString()
]
inputs.properties replacements
filesMatching("modernfix.mixins.json") {
expand replacements
}
}
task generateChangelog(type: se.bjurr.gitchangelog.plugin.gradle.GitChangelogTask) {
def details = versionDetails();
if(details.commitDistance > 0) {

View File

@ -0,0 +1,11 @@
package org.embeddedt.modernfix.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.CLASS)
@Target(ElementType.TYPE)
public @interface ClientOnlyMixin {
}

View File

@ -0,0 +1,12 @@
package org.embeddedt.modernfix.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.CLASS)
@Target(ElementType.TYPE)
public @interface RequiresMod {
String value() default "";
}

View File

@ -80,7 +80,10 @@ public class ModernFixMixinPlugin implements IMixinConfigPlugin {
}
String mixin = mixinClassName.substring(MIXIN_PACKAGE_ROOT.length());
return isOptionEnabled(mixin);
if(!isOptionEnabled(mixin))
return false;
String disabledBecauseMod = config.getPermanentlyDisabledMixins().get(mixin);
return disabledBecauseMod == null;
}
public boolean isOptionEnabled(String mixin) {

View File

@ -1,17 +1,31 @@
package org.embeddedt.modernfix.core.config;
import com.google.common.base.Splitter;
import com.google.common.collect.ImmutableMap;
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.fml.loading.FMLLoader;
import net.minecraftforge.fml.loading.moddiscovery.ExplodedDirectoryLocator;
import net.minecraftforge.fml.loading.moddiscovery.MinecraftLocator;
import net.minecraftforge.fml.loading.moddiscovery.ModInfo;
import net.minecraftforge.forgespi.locating.IModLocator;
import net.minecraftforge.forgespi.locating.IModProvider;
import net.minecraftforge.forgespi.locating.IModFile;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.embeddedt.modernfix.ModernFix;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.tree.AnnotationNode;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.TypeAnnotationNode;
import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class ModernFixEarlyConfig {
private static final Logger LOGGER = LogManager.getLogger("ModernFixConfig");
@ -39,64 +53,126 @@ public class ModernFixEarlyConfig {
return FMLLoader.getLoadingModList().getModFileById(modId) != null;
}
private static final String MIXIN_DESC = "Lorg/spongepowered/asm/mixin/Mixin;";
private static final String MIXIN_CLIENT_ONLY_DESC = "Lorg/embeddedt/modernfix/annotation/ClientOnlyMixin;";
private static final String MIXIN_REQUIRES_MOD_DESC = "Lorg/embeddedt/modernfix/annotation/RequiresMod;";
private final Set<String> mixinOptions = new ObjectOpenHashSet<>();
private final Map<String, String> mixinsMissingMods = new Object2ObjectOpenHashMap<>();
public Map<String, String> getPermanentlyDisabledMixins() {
return mixinsMissingMods;
}
private void scanForAndBuildMixinOptions() {
IModFile file = FMLLoader.getLoadingModList().getModFileById("modernfix").getFile();
Path mixinFolder = file.findResource("org", "embeddedt", "modernfix", "mixin");
try(Stream<Path> mixinFiles = Files.find(mixinFolder, Integer.MAX_VALUE, (p, a) -> true)) {
Splitter dotSplitter = Splitter.on('.');
// filter via toString
mixinFiles
.filter(p -> {
Path fileName = p.getFileName();
return fileName != null && fileName.toString().endsWith(".class");
})
.forEach(path -> {
try(InputStream stream = Files.newInputStream(path)) {
ClassReader reader = new ClassReader(stream);
ClassNode node = new ClassNode();
reader.accept(node, ClassReader.SKIP_CODE | ClassReader.SKIP_FRAMES | ClassReader.SKIP_DEBUG);
if(node.invisibleAnnotations == null)
return;
boolean isMixin = false, isClientOnly = false, requiredModPresent = true;
String requiredModId = "";
for(AnnotationNode annotation : node.invisibleAnnotations) {
if(Objects.equals(annotation.desc, MIXIN_DESC)) {
isMixin = true;
} else if(Objects.equals(annotation.desc, MIXIN_CLIENT_ONLY_DESC)) {
isClientOnly = true;
} else if(Objects.equals(annotation.desc, MIXIN_REQUIRES_MOD_DESC)) {
for(int i = 0; i < annotation.values.size(); i += 2) {
if(annotation.values.get(i).equals("value")) {
String modId = (String)annotation.values.get(i + 1);
if(modId != null) {
requiredModPresent = modPresent(modId);
requiredModId = modId;
}
break;
}
}
}
}
if(isMixin) {
String mixinClassName = node.name.replace("org/embeddedt/modernfix/mixin/", "").replace('/', '.');
if(!requiredModPresent)
mixinsMissingMods.put(mixinClassName, requiredModId);
else if(isClientOnly && FMLLoader.getDist() != Dist.CLIENT)
mixinsMissingMods.put(mixinClassName, "[not client]");
List<String> mixinOptionNames = dotSplitter.splitToList(mixinClassName);
StringBuilder optionBuilder = new StringBuilder(mixinClassName.length());
optionBuilder.append("mixin");
for(int i = 0; i < mixinOptionNames.size() - 1; i++) {
optionBuilder.append('.');
optionBuilder.append(mixinOptionNames.get(i));
mixinOptions.add(optionBuilder.toString());
}
}
} catch(IOException e) {
ModernFix.LOGGER.error("Error scanning file " + path, e);
}
});
} catch(IOException e) {
ModernFix.LOGGER.error("Error scanning for mixins", e);
}
}
private static final boolean shouldReplaceSearchTrees;
private static final boolean isDevEnv = !FMLLoader.isProduction() && FMLLoader.getLoadingModList().getModFileById("modernfix").getFile().getProvider() instanceof ExplodedDirectoryLocator;;
static {
shouldReplaceSearchTrees = modPresent("jei");
}
private static final ImmutableMap<String, Boolean> DEFAULT_SETTING_OVERRIDES = ImmutableMap.<String, Boolean>builder()
.put("mixin.perf.dynamic_resources", false)
.put("mixin.feature.reduce_loading_screen_freezes", false)
.put("mixin.feature.direct_stack_trace", false)
.put("mixin.perf.rewrite_registry", false)
.put("mixin.perf.clear_mixin_classinfo", false)
.put("mixin.perf.compress_blockstate", false)
.put("mixin.bugfix.packet_leak", false)
.put("mixin.perf.deduplicate_location", false)
.put("mixin.perf.preload_block_classes", false)
.put("mixin.perf.faster_singleplayer_load", false)
.put("mixin.perf.blast_search_trees", shouldReplaceSearchTrees)
.put("mixin.devenv", isDevEnv)
.put("mixin.perf.remove_spawn_chunks", isDevEnv)
.build();
private ModernFixEarlyConfig(File file) {
this.configFile = file;
this.scanForAndBuildMixinOptions();
for(String optionName : mixinOptions) {
boolean defaultEnabled = DEFAULT_SETTING_OVERRIDES.getOrDefault(optionName, true);
this.options.putIfAbsent(optionName, new Option(optionName, defaultEnabled, false));
}
// Defines the default rules which can be configured by the user or other mods.
// You must manually add a rule for any new mixins not covered by an existing package rule.
this.addMixinRule("core", true); // TODO: Don't actually allow the user to disable this
this.addMixinRule("perf.modern_resourcepacks", true);
this.addMixinRule("feature.branding", true);
this.addMixinRule("feature.measure_time", true);
this.addMixinRule("feature.reduce_loading_screen_freezes", false);
this.addMixinRule("feature.direct_stack_trace", false);
this.addMixinRule("perf.fast_registry_validation", true);
this.addMixinRule("perf.skip_first_datapack_reload", true);
// not stable yet
this.addMixinRule("perf.rewrite_registry", false);
this.addMixinRule("perf.remove_biome_temperature_cache", true);
this.addMixinRule("perf.reduce_blockstate_cache_rebuilds", true);
this.addMixinRule("perf.model_optimizations", true);
this.addMixinRule("perf.dynamic_resources", false);
this.addMixinRule("perf.dynamic_entity_renderers", true);
this.addMixinRule("perf.dedicated_reload_executor", true);
/* Use a simpler ArrayMap if FerriteCore is using the map intelligently anyway */
this.addMixinRule("perf.state_definition_construct", modPresent("ferritecore"));
this.addMixinRule("perf.cache_strongholds", true);
this.addMixinRule("perf.clear_mixin_classinfo", false);
this.addMixinRule("perf.cache_upgraded_structures", true);
this.addMixinRule("perf.compress_blockstate", false);
this.addMixinRule("bugfix.concurrency", true);
this.addMixinRule("bugfix.edge_chunk_not_saved", true);
this.addMixinRule("perf.fast_forge_dummies", true);
this.addMixinRule("perf.dynamic_structure_manager", true);
this.addMixinRule("bugfix.chunk_deadlock", true);
this.addMixinRule("bugfix.remove_block_chunkloading", true);
this.addMixinRule("bugfix.paper_chunk_patches", true);
this.addMixinRule("perf.thread_priorities", true);
this.addMixinRule("perf.scan_cache", true);
this.addMixinRule("perf.kubejs", modPresent("kubejs"));
this.addMixinRule("perf.flatten_model_predicates", true);
this.addMixinRule("perf.tag_id_caching", true);
this.addMixinRule("perf.deduplicate_location", false);
this.addMixinRule("perf.cache_blockstate_cache_arrays", true);
this.addMixinRule("perf.cache_model_materials", true);
this.addMixinRule("perf.nbt_memory_usage", true);
this.addMixinRule("perf.patchouli_deduplicate_books", modPresent("patchouli"));
this.addMixinRule("perf.datapack_reload_exceptions", true);
this.addMixinRule("perf.dynamic_dfu", true);
this.addMixinRule("perf.faster_texture_stitching", true);
this.addMixinRule("perf.faster_texture_loading", true);
this.addMixinRule("perf.faster_font_loading", true);
/* off by default in 1.18 because it doesn't work as well */
this.addMixinRule("perf.faster_singleplayer_load", false);
/* Keep this off if JEI/REI isn't installed to prevent breaking vanilla gameplay */
this.addMixinRule("perf.blast_search_trees", FMLLoader.getLoadingModList().getModFileById("jei") != null || FMLLoader.getLoadingModList().getModFileById("roughlyenoughitems") != null);
this.addMixinRule("safety", true);
this.addMixinRule("launch.class_search_cache", true);
IModProvider mfLocator = FMLLoader.getLoadingModList().getModFileById("modernfix").getFile().getProvider();
boolean isDevEnv = !FMLLoader.isProduction() && (mfLocator instanceof ExplodedDirectoryLocator || mfLocator instanceof MinecraftLocator);
this.addMixinRule("devenv", isDevEnv);
this.addMixinRule("perf.remove_spawn_chunks", isDevEnv);
/*
this.addMixinRule("perf.use_integrated_resources.jepb", modPresent("jepb"));
this.addMixinRule("perf.use_integrated_resources.jeresources", modPresent("jeresources"));
this.addMixinRule("perf.jeresources_startup", modPresent("jeresources"));
this.addMixinRule("perf.state_definition_construct", modPresent("ferritecore"));
this.addMixinRule("bugfix.starlight_emptiness", modPresent("starlight"));
this.addMixinRule("bugfix.chunk_deadlock.valhesia", modPresent("valhelsia_structures"));
this.addMixinRule("bugfix.tf_cme_on_load", modPresent("twilightforest"));
this.addMixinRule("bugfix.refinedstorage", modPresent("refinedstorage"));
this.addMixinRule("perf.async_jei", modPresent("jei"));
this.addMixinRule("perf.patchouli_deduplicate_books", modPresent("patchouli"));
this.addMixinRule("perf.kubejs", modPresent("kubejs"));
*/
/* Mod compat */
disableIfModPresent("mixin.perf.thread_priorities", "smoothboot");

View File

@ -3,11 +3,13 @@ package org.embeddedt.modernfix.mixin.bugfix.concurrency;
import net.minecraft.client.Minecraft;
import net.minecraft.util.thread.BlockableEventLoop;
import org.embeddedt.modernfix.ModernFix;
import org.embeddedt.modernfix.annotation.ClientOnlyMixin;
import org.spongepowered.asm.mixin.Mixin;
import java.util.function.BooleanSupplier;
@Mixin(Minecraft.class)
@ClientOnlyMixin
public abstract class MinecraftMixin<R extends Runnable> extends BlockableEventLoop<R> {
protected MinecraftMixin(String p_i50403_1_) {

View File

@ -5,6 +5,7 @@ import net.minecraft.server.WorldStem;
import net.minecraft.server.packs.repository.PackRepository;
import net.minecraft.world.level.storage.LevelStorageSource;
import org.embeddedt.modernfix.ModernFix;
import org.embeddedt.modernfix.annotation.ClientOnlyMixin;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
@ -14,6 +15,7 @@ import java.util.concurrent.CountDownLatch;
import java.util.function.Function;
@Mixin(Minecraft.class)
@ClientOnlyMixin
public class MinecraftMixin {
@Inject(method = "m_231380_", at = @At("HEAD"), remap = false)
private void setLatch(String string, LevelStorageSource.LevelStorageAccess arg, PackRepository arg2, WorldStem arg3, CallbackInfo ci) {

View File

@ -3,12 +3,14 @@ package org.embeddedt.modernfix.mixin.core;
import net.minecraft.network.syncher.SynchedEntityData;
import net.minecraft.world.entity.Entity;
import org.embeddedt.modernfix.ModernFixClient;
import org.embeddedt.modernfix.annotation.ClientOnlyMixin;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(SynchedEntityData.class)
@ClientOnlyMixin
public class SynchedEntityDataMixin {
/**
* Store this in our set of all entity data objects.

View File

@ -4,10 +4,12 @@ import com.mojang.authlib.minecraft.UserApiService;
import com.mojang.authlib.yggdrasil.YggdrasilAuthenticationService;
import net.minecraft.client.Minecraft;
import net.minecraft.client.main.GameConfig;
import org.embeddedt.modernfix.annotation.ClientOnlyMixin;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Overwrite;
@Mixin(Minecraft.class)
@ClientOnlyMixin
public class MinecraftMixin {
@Overwrite
private UserApiService createUserApiService(YggdrasilAuthenticationService yggdrasilAuthenticationService, GameConfig arg) {

View File

@ -2,11 +2,13 @@ package org.embeddedt.modernfix.mixin.devenv;
import com.mojang.text2speech.Narrator;
import net.minecraft.client.GameNarrator;
import org.embeddedt.modernfix.annotation.ClientOnlyMixin;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
@Mixin(GameNarrator.class)
@ClientOnlyMixin
public class NarratorMixin {
@Redirect(method = "<init>", at = @At(value = "INVOKE", target = "Lcom/mojang/text2speech/Narrator;getNarrator()Lcom/mojang/text2speech/Narrator;", remap = false))
private Narrator useDummyNarrator() {

View File

@ -10,6 +10,7 @@ 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.annotation.ClientOnlyMixin;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
@ -19,6 +20,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import java.util.function.Function;
@Mixin(Minecraft.class)
@ClientOnlyMixin
public class MinecraftMixin {
/* not supported in 1.19
private long datapackReloadStartTime;

View File

@ -4,6 +4,7 @@ import net.minecraft.client.Minecraft;
import net.minecraft.client.resources.model.ModelBakery;
import net.minecraft.Util;
import net.minecraftforge.fml.loading.progress.StartupMessageManager;
import org.embeddedt.modernfix.annotation.ClientOnlyMixin;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
@ -13,6 +14,7 @@ import java.util.concurrent.CompletableFuture;
import java.util.function.Consumer;
@Mixin(ModelBakery.class)
@ClientOnlyMixin
public class ModelBakeryMixin {
@Redirect(method = "uploadTextures", at = @At(value = "INVOKE", target = "Ljava/util/Set;forEach(Ljava/util/function/Consumer;)V", ordinal = 0))
private void bakeAndTickGUI(Set instance, Consumer consumer) {

View File

@ -2,12 +2,14 @@ package org.embeddedt.modernfix.mixin.perf.async_jei;
import com.mojang.blaze3d.platform.InputConstants;
import com.mojang.blaze3d.systems.RenderSystem;
import org.embeddedt.modernfix.annotation.RequiresMod;
import org.lwjgl.glfw.GLFW;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
@Mixin(InputConstants.class)
@RequiresMod("jei")
public class InputConstantsMixin {
@Redirect(method = "isKeyDown", at = @At(value = "INVOKE", target = "Lorg/lwjgl/glfw/GLFW;glfwGetKey(JI)I", remap = false))
private static int offThreadKeyFetch(long win, int k) {

View File

@ -6,6 +6,7 @@ import net.minecraftforge.fml.ModContainer;
import net.minecraftforge.fml.ModList;
import net.minecraftforge.forgespi.language.IModFileInfo;
import org.embeddedt.modernfix.ModernFix;
import org.embeddedt.modernfix.annotation.ClientOnlyMixin;
import org.embeddedt.modernfix.searchtree.DummySearchTree;
import org.embeddedt.modernfix.searchtree.JEIBackedSearchTree;
import org.embeddedt.modernfix.searchtree.REIBackedSearchTree;
@ -19,6 +20,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import java.util.Optional;
@Mixin(Minecraft.class)
@ClientOnlyMixin
public class MinecraftMixin {
@Shadow @Final private SearchRegistry searchRegistry;

View File

@ -3,6 +3,7 @@ package org.embeddedt.modernfix.mixin.perf.cache_model_materials;
import com.mojang.datafixers.util.Either;
import net.minecraft.client.renderer.block.model.BlockModel;
import net.minecraft.client.resources.model.Material;
import org.embeddedt.modernfix.annotation.ClientOnlyMixin;
import org.embeddedt.modernfix.duck.ICachedMaterialsModel;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@ -19,6 +20,7 @@ import java.util.Map;
import java.util.Set;
@Mixin(BlockModel.class)
@ClientOnlyMixin
public class BlockModelMixin {
@Shadow @Final @Mutable public Map<String, Either<Material, String>> textureMap;

View File

@ -2,6 +2,7 @@ package org.embeddedt.modernfix.mixin.perf.cache_model_materials;
import net.minecraft.client.renderer.block.model.multipart.MultiPart;
import net.minecraft.resources.ResourceLocation;
import org.embeddedt.modernfix.annotation.ClientOnlyMixin;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
@ -10,6 +11,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import java.util.Collection;
@Mixin(MultiPart.class)
@ClientOnlyMixin
public class MultipartMixin {
private Collection<ResourceLocation> dependencyCache = null;
@Inject(method = "getDependencies", at = @At("HEAD"), cancellable = true)

View File

@ -7,6 +7,7 @@ import net.minecraft.client.resources.model.Material;
import net.minecraft.client.renderer.block.model.MultiVariant;
import net.minecraft.client.renderer.block.model.multipart.MultiPart;
import net.minecraft.resources.ResourceLocation;
import org.embeddedt.modernfix.annotation.ClientOnlyMixin;
import org.embeddedt.modernfix.duck.ICachedMaterialsModel;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
@ -19,6 +20,7 @@ import java.util.Set;
import java.util.function.Function;
@Mixin(value = {MultiVariant.class, MultiPart.class, BlockModel.class})
@ClientOnlyMixin
public class VanillaModelMixin implements ICachedMaterialsModel {
private Collection<Material> materialsCache = null;

View File

@ -2,6 +2,7 @@ package org.embeddedt.modernfix.mixin.perf.dedicated_reload_executor;
import net.minecraft.client.Minecraft;
import org.embeddedt.modernfix.ModernFix;
import org.embeddedt.modernfix.annotation.ClientOnlyMixin;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
@ -10,6 +11,7 @@ import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
@Mixin(Minecraft.class)
@ClientOnlyMixin
public class MinecraftMixin {
@Redirect(method = { "<init>", "reloadResourcePacks(Z)Ljava/util/concurrent/CompletableFuture;" }, at = @At(value = "INVOKE", target = "Lnet/minecraft/Util;backgroundExecutor()Ljava/util/concurrent/ExecutorService;", ordinal = 0))
private ExecutorService getResourceReloadExecutor() {

View File

@ -3,6 +3,7 @@ package org.embeddedt.modernfix.mixin.perf.dynamic_resources;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonElement;
import net.minecraft.client.renderer.block.model.BlockElementFace;
import org.embeddedt.modernfix.annotation.ClientOnlyMixin;
import org.embeddedt.modernfix.dynamicresources.UVController;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
@ -11,6 +12,7 @@ import org.spongepowered.asm.mixin.injection.Redirect;
import java.lang.reflect.Type;
@Mixin(BlockElementFace.Deserializer.class)
@ClientOnlyMixin
public class BlockElementFaceDeserializerMixin {
@Redirect(method = "deserialize(Lcom/google/gson/JsonElement;Ljava/lang/reflect/Type;Lcom/google/gson/JsonDeserializationContext;)Lnet/minecraft/client/renderer/block/model/BlockElementFace;",

View File

@ -12,6 +12,7 @@ import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.properties.Property;
import org.embeddedt.modernfix.annotation.ClientOnlyMixin;
import org.embeddedt.modernfix.dynamicresources.ModelLocationCache;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
@ -27,6 +28,7 @@ import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap;
@Mixin(BlockModelShaper.class)
@ClientOnlyMixin
public class BlockModelShaperMixin {
@Shadow @Final private ModelManager modelManager;

View File

@ -8,6 +8,7 @@ import net.minecraft.core.Holder;
import net.minecraft.world.item.Item;
import net.minecraftforge.client.model.ForgeItemModelShaper;
import net.minecraftforge.registries.ForgeRegistries;
import org.embeddedt.modernfix.annotation.ClientOnlyMixin;
import org.embeddedt.modernfix.dynamicresources.ModelLocationCache;
import org.embeddedt.modernfix.util.ItemMesherMap;
import org.jetbrains.annotations.NotNull;
@ -23,6 +24,7 @@ import java.util.Map;
import java.util.Set;
@Mixin(ForgeItemModelShaper.class)
@ClientOnlyMixin
public abstract class ItemModelShaperMixin extends ItemModelShaper {
@Shadow @Final @Mutable private Map<Holder.Reference<Item>, ModelResourceLocation> locations;

View File

@ -4,11 +4,13 @@ import net.minecraft.client.renderer.ItemModelShaper;
import net.minecraft.client.renderer.entity.ItemRenderer;
import net.minecraft.client.resources.model.ModelResourceLocation;
import net.minecraft.world.item.Item;
import org.embeddedt.modernfix.annotation.ClientOnlyMixin;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
@Mixin(ItemRenderer.class)
@ClientOnlyMixin
public class ItemRendererMixin {
/**
* Don't waste space putting all these locations into the cache, compute them on demand later.

View File

@ -44,6 +44,7 @@ import net.minecraftforge.resource.DelegatingPackResources;
import net.minecraftforge.resource.PathPackResources;
import org.apache.commons.lang3.tuple.Triple;
import org.embeddedt.modernfix.ModernFix;
import org.embeddedt.modernfix.annotation.ClientOnlyMixin;
import org.embeddedt.modernfix.duck.IExtendedModelBakery;
import org.embeddedt.modernfix.dynamicresources.*;
import org.objectweb.asm.Opcodes;
@ -72,6 +73,7 @@ import java.util.stream.Stream;
/* high priority so that our injectors are added before other mods' */
@Mixin(value = ModelBakery.class, priority = 600)
@ClientOnlyMixin
public abstract class ModelBakeryMixin implements IExtendedModelBakery {
private static final boolean debugDynamicModelLoading = Boolean.getBoolean("modernfix.debugDynamicModelLoading");

View File

@ -5,6 +5,8 @@ import appeng.init.client.InitAutoRotatingModel;
import net.minecraft.client.resources.model.BakedModel;
import net.minecraft.client.resources.model.ModelBakery;
import net.minecraftforge.common.MinecraftForge;
import org.embeddedt.modernfix.annotation.ClientOnlyMixin;
import org.embeddedt.modernfix.annotation.RequiresMod;
import org.embeddedt.modernfix.dynamicresources.DynamicModelBakeEvent;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
@ -17,6 +19,8 @@ import java.util.Map;
import java.util.function.Function;
@Mixin(InitAutoRotatingModel.class)
@RequiresMod("appliedenergistics2")
@ClientOnlyMixin
public class RegistrationMixin {
@Shadow @Final private static Map<String, Function<BakedModel, BakedModel>> CUSTOMIZERS;
@Inject(method = "init", at = @At("TAIL"), remap = false)

View File

@ -20,6 +20,8 @@ import net.minecraftforge.eventbus.api.EventPriority;
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
import net.minecraftforge.registries.ForgeRegistries;
import org.embeddedt.modernfix.ModernFix;
import org.embeddedt.modernfix.annotation.ClientOnlyMixin;
import org.embeddedt.modernfix.annotation.RequiresMod;
import org.embeddedt.modernfix.duck.IExtendedModelBakery;
import org.embeddedt.modernfix.dynamicresources.DynamicModelBakeEvent;
import org.spongepowered.asm.mixin.Final;
@ -37,6 +39,8 @@ import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Predicate;
@Mixin(CTMPackReloadListener.class)
@RequiresMod("ctm")
@ClientOnlyMixin
public abstract class CTMPackReloadListenerMixin {
/* caches the original render checks */
@Shadow @Final private static Map<Holder.Reference<Block>, Predicate<RenderType>> blockRenderChecks;

View File

@ -9,6 +9,8 @@ import net.minecraft.client.resources.model.UnbakedModel;
import net.minecraft.resources.ResourceLocation;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import org.embeddedt.modernfix.annotation.ClientOnlyMixin;
import org.embeddedt.modernfix.annotation.RequiresMod;
import org.embeddedt.modernfix.dynamicresources.DynamicModelBakeEvent;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
@ -28,6 +30,8 @@ import java.io.IOException;
import java.util.*;
@Mixin(TextureMetadataHandler.class)
@RequiresMod("ctm")
@ClientOnlyMixin
public abstract class TextureMetadataHandlerMixin {
@Shadow @Nonnull protected abstract BakedModel wrap(ResourceLocation loc, UnbakedModel model, BakedModel object, ModelBakery loader) throws IOException;

View File

@ -5,6 +5,8 @@ import com.refinedmods.refinedstorage.setup.ClientSetup;
import net.minecraft.client.resources.model.ModelResourceLocation;
import net.minecraft.resources.ResourceLocation;
import net.minecraftforge.common.MinecraftForge;
import org.embeddedt.modernfix.annotation.ClientOnlyMixin;
import org.embeddedt.modernfix.annotation.RequiresMod;
import org.embeddedt.modernfix.dynamicresources.DynamicModelBakeEvent;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
@ -14,6 +16,8 @@ import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(ClientSetup.class)
@RequiresMod("refinedstorage")
@ClientOnlyMixin
public class ClientSetupMixin {
@Shadow @Final private static BakedModelOverrideRegistry BAKED_MODEL_OVERRIDE_REGISTRY;

View File

@ -8,6 +8,8 @@ import net.minecraft.resources.ResourceLocation;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
import org.embeddedt.modernfix.annotation.ClientOnlyMixin;
import org.embeddedt.modernfix.annotation.RequiresMod;
import org.embeddedt.modernfix.dynamicresources.DynamicModelBakeEvent;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
@ -25,6 +27,8 @@ import java.util.function.Supplier;
import java.util.stream.Stream;
@Mixin(ClientRegistrationHandler.class)
@RequiresMod("supermartijn642corelib")
@ClientOnlyMixin
public class ClientRegistrationHandlerMixin {
@Shadow @Final private List<Pair<Supplier<Stream<ResourceLocation>>, Function<BakedModel, BakedModel>>> modelOverwrites;

View File

@ -3,6 +3,7 @@ package org.embeddedt.modernfix.mixin.perf.faster_font_loading;
import com.mojang.blaze3d.platform.NativeImage;
import net.minecraft.client.gui.font.providers.LegacyUnicodeBitmapsProvider;
import net.minecraft.resources.ResourceLocation;
import org.embeddedt.modernfix.annotation.ClientOnlyMixin;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
@ -21,6 +22,7 @@ import java.util.Map;
* only to do it again later.
*/
@Mixin(LegacyUnicodeBitmapsProvider.class)
@ClientOnlyMixin
public abstract class LegacyUnicodeBitmapsProviderMixin {
@Shadow protected abstract ResourceLocation getSheetLocation(int i);

View File

@ -14,6 +14,7 @@ import net.minecraftforge.fml.ModLoader;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.tuple.Triple;
import org.embeddedt.modernfix.ModernFix;
import org.embeddedt.modernfix.annotation.ClientOnlyMixin;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
@ -29,6 +30,7 @@ import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;
@Mixin(TextureAtlas.class)
@ClientOnlyMixin
public abstract class TextureAtlasMixin {
@Shadow protected abstract ResourceLocation getResourceLocation(ResourceLocation location);

View File

@ -5,6 +5,7 @@ import it.unimi.dsi.fastutil.objects.ObjectArrayList;
import net.minecraft.client.renderer.texture.Stitcher;
import net.minecraftforge.fml.ModLoader;
import org.embeddedt.modernfix.ModernFix;
import org.embeddedt.modernfix.annotation.ClientOnlyMixin;
import org.embeddedt.modernfix.textures.StbStitcher;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
@ -20,6 +21,7 @@ import java.util.List;
import java.util.Set;
@Mixin(Stitcher.class)
@ClientOnlyMixin
public class StitcherMixin {
@Shadow @Final private Set<Stitcher.Holder> texturesToBeStitched;

View File

@ -2,6 +2,7 @@ package org.embeddedt.modernfix.mixin.perf.kubejs;
import dev.latvian.mods.kubejs.recipe.RecipesEventJS;
import org.embeddedt.modernfix.ModernFix;
import org.embeddedt.modernfix.annotation.RequiresMod;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
@ -13,6 +14,7 @@ import java.util.Collection;
import java.util.Map;
@Mixin(RecipesEventJS.class)
@RequiresMod("kubejs")
public class RecipeEventJSMixin {
/**

View File

@ -4,6 +4,7 @@ import net.minecraft.resources.ResourceLocation;
import net.minecraftforge.client.model.obj.ObjLoader;
import net.minecraftforge.client.model.obj.ObjMaterialLibrary;
import net.minecraftforge.client.model.obj.ObjModel;
import org.embeddedt.modernfix.annotation.ClientOnlyMixin;
import org.objectweb.asm.Opcodes;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
@ -16,6 +17,7 @@ import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
@Mixin(ObjLoader.class)
@ClientOnlyMixin
public class OBJLoaderMixin {
@Final
@Mutable

View File

@ -4,6 +4,7 @@ import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.client.renderer.block.model.multipart.Selector;
import net.minecraft.world.level.block.state.StateDefinition;
import org.embeddedt.modernfix.annotation.ClientOnlyMixin;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
@ -13,6 +14,7 @@ import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Predicate;
@Mixin(Selector.class)
@ClientOnlyMixin
public class SelectorMixin {
private ConcurrentHashMap<StateDefinition<Block, BlockState>, Predicate<BlockState>> predicateCache = new ConcurrentHashMap<>();
@Inject(method = "getPredicate", at = @At("HEAD"), cancellable = true)

View File

@ -2,6 +2,7 @@ package org.embeddedt.modernfix.mixin.perf.model_optimizations;
import com.mojang.math.Matrix4f;
import com.mojang.math.Transformation;
import org.embeddedt.modernfix.annotation.ClientOnlyMixin;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Overwrite;
@ -10,6 +11,7 @@ import org.spongepowered.asm.mixin.Shadow;
import java.util.Objects;
@Mixin(Transformation.class)
@ClientOnlyMixin
public class TransformationMatrixMixin {
@Shadow @Final private Matrix4f matrix;
private Integer cachedHashCode = null;

View File

@ -4,6 +4,8 @@ import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;
import net.minecraftforge.fml.util.ObfuscationReflectionHelper;
import org.embeddedt.modernfix.ModernFix;
import org.embeddedt.modernfix.annotation.ClientOnlyMixin;
import org.embeddedt.modernfix.annotation.RequiresMod;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
@ -23,6 +25,8 @@ import java.lang.reflect.Field;
import java.util.List;
@Mixin(ClientBookRegistry.class)
@RequiresMod("patchouli")
@ClientOnlyMixin
public class ClientBookRegistryMixin {
@Inject(method = "reload", at = @At("RETURN"), remap = false)
private void performDeduplication(CallbackInfo ci) {

View File

@ -8,6 +8,7 @@ import net.minecraft.client.server.IntegratedServer;
import net.minecraft.server.level.progress.ChunkProgressListenerFactory;
import net.minecraft.world.level.storage.LevelStorageSource;
import org.embeddedt.modernfix.ModernFix;
import org.embeddedt.modernfix.annotation.ClientOnlyMixin;
import org.embeddedt.modernfix.core.config.ModernFixConfig;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
@ -15,6 +16,7 @@ import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(IntegratedServer.class)
@ClientOnlyMixin
public class IntegratedServerMixin {
@Inject(method = "<init>", at = @At("RETURN"))
private void adjustServerPriority(Thread thread, Minecraft arg, LevelStorageSource.LevelStorageAccess arg2, PackRepository arg3, WorldStem arg4, Services arg5, ChunkProgressListenerFactory arg6, CallbackInfo ci) {

View File

@ -4,6 +4,7 @@ import net.minecraft.world.level.block.Block;
import net.minecraft.client.Minecraft;
import net.minecraft.client.color.block.BlockColors;
import net.minecraft.client.color.block.BlockColor;
import org.embeddedt.modernfix.annotation.ClientOnlyMixin;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
@ -13,6 +14,7 @@ import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
@Mixin(value = BlockColors.class, priority = 700)
@ClientOnlyMixin
public class BlockColorsMixin {
private Lock mapLock = new ReentrantLock();
@Inject(method = "register", at = @At("HEAD"))

View File

@ -1,6 +1,7 @@
package org.embeddedt.modernfix.mixin.safety;
import net.minecraft.client.color.item.ItemColors;
import org.embeddedt.modernfix.annotation.ClientOnlyMixin;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
@ -10,6 +11,7 @@ import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
@Mixin(value = ItemColors.class, priority = 700)
@ClientOnlyMixin
public class ItemColorsMixin {
private Lock mapLock = new ReentrantLock();
@Inject(method = "register", at = @At("HEAD"))

View File

@ -1,11 +1,16 @@
package org.embeddedt.modernfix.packet;
import net.minecraft.resources.ResourceLocation;
import net.minecraftforge.network.NetworkEvent;
import net.minecraftforge.network.NetworkRegistry;
import net.minecraftforge.network.simple.SimpleChannel;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.fml.DistExecutor;
import org.embeddedt.modernfix.ModernFix;
import org.embeddedt.modernfix.ModernFixClient;
import java.util.function.Supplier;
public class PacketHandler {
private static final String PROTOCOL_VERSION = "1";
public static final SimpleChannel INSTANCE = NetworkRegistry.newSimpleChannel(
@ -17,6 +22,10 @@ public class PacketHandler {
public static void register() {
int id = 1;
INSTANCE.registerMessage(id++, EntityIDSyncPacket.class, EntityIDSyncPacket::serialize, EntityIDSyncPacket::deserialize, ModernFixClient::handleEntityIDSync);
INSTANCE.registerMessage(id++, EntityIDSyncPacket.class, EntityIDSyncPacket::serialize, EntityIDSyncPacket::deserialize, PacketHandler::handleSyncPacket);
}
private static void handleSyncPacket(EntityIDSyncPacket packet, Supplier<NetworkEvent.Context> contextSupplier) {
DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> ModernFixClient.handleEntityIDSync(packet, contextSupplier));
}
}

View File

@ -184,17 +184,19 @@ public class StbStitcher {
STBRectPack.stbrp_pack_rects(ctx, rectBuf);
for (STBRPRect rect : rectBuf) {
Stitcher.Holder holder = holders[rect.id()];
// Ensure that everything is properly packed!
if (!rect.was_packed()) {
Stitcher.Holder holder = holders[rect.id()];
throw new StitcherException(holder.spriteInfo,
Stream.of(holders).map(arg -> arg.spriteInfo).collect(ImmutableList.toImmutableList()));
}
}
for (STBRPRect rect : rectBuf) {
Stitcher.Holder holder = holders[rect.id()];
// Initialize the sprite now with the position and size that we've calculated so far
infoList.add(new LoadableSpriteInfo(holder.spriteInfo, longestWidth, longestHeight, getX(rect), getY(rect)));
//holder.spriteInfo.initSprite(size, size, rect.x(), rect.y(), false);
}
return Pair.of(Pair.of(longestWidth, longestHeight), infoList);

View File

@ -1,6 +1,13 @@
{
"modernfix.jei_load": "正在加载JEI这需要一点时间。",
"modernfix.no_lazydfu": "现代化修复检测到DFU规则在游戏启动时已被编译。这会降低游戏启动速度。非常推荐安装DFU载入优化来解决这个问题。",
"key.modernfix": "现代化修复",
"key.modernfix.config": "打开配置屏幕",
"modernfix.jei_load": "正在加载JEI这可能会花费一段时间。",
"modernfix.no_lazydfu": "未检测到DFU载入优化。如果Minecraft需要从旧版本更新游戏数据可能会出现极大的延迟。",
"modernfix.config": "现代化修复Mixin配置",
"modernfix.config.done_restart": "完成(生效需重启)",
"modernfix.option.on": "开启",
"modernfix.option.off": "关闭",
"modernfix.config.not_default": " (已修改)",
"asynclocator.map.locating": "地图(定位中……)",
"asynclocator.map.none": "地图(未能找到相关地物)"
"asynclocator.map.none": "地图(未能在附近找到相关地物)"
}

View File

@ -6,94 +6,7 @@
"compatibilityLevel": "JAVA_17",
"refmap": "modernfix.refmap.json",
"mixins": [
"core.BootstrapMixin",
"bugfix.edge_chunk_not_saved.ChunkManagerMixin",
"perf.modern_resourcepacks.VanillaPackResourcesMixin",
"perf.modern_resourcepacks.PathPackResourcesMixin",
"perf.modern_resourcepacks.ResourceCacheManagerMixin",
"bugfix.paper_chunk_patches.ChunkMapMixin",
"bugfix.paper_chunk_patches.ChunkHolderMixin",
"bugfix.paper_chunk_patches.SortedArraySetMixin",
"perf.dynamic_structure_manager.StructureManagerMixin",
"bugfix.chunk_deadlock.ServerChunkCacheMixin",
"perf.dedicated_reload_executor.MinecraftServerMixin",
"perf.fast_forge_dummies.NamespacedHolderHelperMixin",
"perf.dynamic_dfu.DataFixersMixin",
"perf.remove_biome_temperature_cache.BiomeMixin",
"perf.reduce_blockstate_cache_rebuilds.GameDataMixin",
"perf.reduce_blockstate_cache_rebuilds.BlockCallbacksMixin",
"perf.thread_priorities.UtilMixin",
"perf.reduce_blockstate_cache_rebuilds.BlocksMixin",
"perf.reduce_blockstate_cache_rebuilds.BlockStateBaseMixin",
"perf.deduplicate_location.MixinResourceLocation",
"perf.cache_blockstate_cache_arrays.AbstractBlockStateCacheMixin",
"perf.datapack_reload_exceptions.LootTableManagerMixin",
"perf.datapack_reload_exceptions.RecipeManagerMixin",
"feature.measure_time.BootstrapMixin",
"feature.measure_time.SimpleReloadableResourceManagerMixin",
"feature.measure_time.ProfiledReloadInstanceMixin",
"feature.measure_time.ReloadableServerResourcesMixin",
"feature.branding.BrandingControlMixin",
"feature.direct_stack_trace.CrashReportMixin",
"perf.nbt_memory_usage.CompoundTagMixin",
"perf.kubejs.RecipeEventJSMixin",
"perf.tag_id_caching.TagEntryMixin",
"perf.tag_id_caching.TagOrElementLocationMixin",
"perf.fast_registry_validation.ForgeRegistryMixin",
"perf.rewrite_registry.ForgeRegistryMixin",
"perf.rewrite_registry.ForgeRegistrySnapshotMixin",
"perf.fast_registry_validation.ResourceKeyMixin",
"perf.cache_strongholds.ChunkGeneratorMixin",
"perf.cache_upgraded_structures.StructureManagerMixin",
"perf.cache_strongholds.ServerLevelMixin",
"perf.state_definition_construct.StateDefinitionMixin",
"perf.compress_blockstate.BlockStateBaseMixin",
"perf.compress_blockstate.BlockBehaviourMixin",
"perf.remove_spawn_chunks.ServerChunkCacheAccessor",
"perf.remove_spawn_chunks.MinecraftServerMixin",
"perf.remove_spawn_chunks.ServerLevelMixin",
"devenv.GameDataMixin"
],
"client": [
"core.MinecraftMixin",
"core.SynchedEntityDataMixin",
"feature.measure_time.MinecraftMixin",
"feature.reduce_loading_screen_freezes.ModelBakeryMixin",
"bugfix.concurrency.MinecraftMixin",
"perf.dedicated_reload_executor.CreateWorldScreenMixin",
"perf.dedicated_reload_executor.MinecraftMixin",
"perf.dedicated_reload_executor.WorldOpenFlowsMixin",
"perf.dynamic_resources.BlockElementFaceDeserializerMixin",
"perf.dynamic_resources.BlockModelShaperMixin",
"perf.dynamic_resources.ItemModelShaperMixin",
"perf.dynamic_resources.ItemRendererMixin",
"perf.dynamic_resources.ModelBakeryMixin",
"perf.dynamic_resources.ae2.RegistrationMixin",
"perf.dynamic_resources.rs.ClientSetupMixin",
"perf.dynamic_resources.ctm.TextureMetadataHandlerMixin",
"perf.dynamic_resources.ctm.CTMPackReloadListenerMixin",
"perf.dynamic_resources.supermartijncore.ClientRegistrationHandlerMixin",
"perf.dynamic_entity_renderers.EntityRenderersMixin",
"perf.model_optimizations.OBJLoaderMixin",
"perf.model_optimizations.SelectorMixin",
"perf.model_optimizations.TransformationMatrixMixin",
"perf.model_optimizations.BooleanPropertyMixin",
"perf.model_optimizations.PropertyMixin",
"perf.patchouli_deduplicate_books.ClientBookRegistryMixin",
"perf.thread_priorities.IntegratedServerMixin",
"safety.BlockColorsMixin",
"safety.ItemColorsMixin",
"perf.blast_search_trees.MinecraftMixin",
"perf.blast_search_trees.IngredientFilterInvoker",
"perf.cache_model_materials.VanillaModelMixin",
"perf.cache_model_materials.BlockModelMixin",
"perf.cache_model_materials.MultipartMixin",
"perf.faster_texture_stitching.StitcherMixin",
"perf.faster_texture_loading.TextureAtlasMixin",
"perf.faster_font_loading.LegacyUnicodeBitmapsProviderMixin",
"perf.skip_first_datapack_reload.CreateWorldScreenMixin",
"devenv.MinecraftMixin",
"devenv.NarratorMixin"
${mixin_classes}
],
"injectors": {
"defaultRequire": 1