Add config
This commit is contained in:
parent
700b2ec265
commit
588dc1a86e
|
|
@ -3,3 +3,6 @@
|
||||||
A Forge 1.16 mod that uses mixins to make the game slightly more performant (and hopefully less buggy too).
|
A Forge 1.16 mod that uses mixins to make the game slightly more performant (and hopefully less buggy too).
|
||||||
|
|
||||||
In the words of asiekierka, questionable "performance improvements" that are not in Forge for probably very good reasons.
|
In the words of asiekierka, questionable "performance improvements" that are not in Forge for probably very good reasons.
|
||||||
|
|
||||||
|
Some fixes are based on prior work in various Forge PRs (check commit history and/or code comments). The config system
|
||||||
|
is directly derived from Sodium and used under the terms of the LGPL-3.0 license.
|
||||||
|
|
@ -0,0 +1,95 @@
|
||||||
|
package org.embeddedt.modernfix.core;
|
||||||
|
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
import org.embeddedt.modernfix.core.config.ModernFixConfig;
|
||||||
|
import org.embeddedt.modernfix.core.config.Option;
|
||||||
|
import org.objectweb.asm.tree.ClassNode;
|
||||||
|
import org.spongepowered.asm.mixin.extensibility.IMixinConfigPlugin;
|
||||||
|
import org.spongepowered.asm.mixin.extensibility.IMixinInfo;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
public class ModernFixMixinPlugin implements IMixinConfigPlugin {
|
||||||
|
private static final String MIXIN_PACKAGE_ROOT = "org.embeddedt.modernfix.mixin.";
|
||||||
|
|
||||||
|
private final Logger logger = LogManager.getLogger("ModernFix");
|
||||||
|
public static ModernFixConfig config = null;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onLoad(String mixinPackage) {
|
||||||
|
try {
|
||||||
|
config = ModernFixConfig.load(new File("./config/modernfix-mixins.properties"));
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException("Could not load configuration file for ModernFix", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.logger.info("Loaded configuration file for ModernFix: {} options available, {} override(s) found",
|
||||||
|
config.getOptionCount(), config.getOptionOverrideCount());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getRefMapperConfig() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean shouldApplyMixin(String targetClassName, String mixinClassName) {
|
||||||
|
if (!mixinClassName.startsWith(MIXIN_PACKAGE_ROOT)) {
|
||||||
|
this.logger.error("Expected mixin '{}' to start with package root '{}', treating as foreign and " +
|
||||||
|
"disabling!", mixinClassName, MIXIN_PACKAGE_ROOT);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
String mixin = mixinClassName.substring(MIXIN_PACKAGE_ROOT.length());
|
||||||
|
Option option = config.getEffectiveOptionForMixin(mixin);
|
||||||
|
|
||||||
|
if (option == null) {
|
||||||
|
this.logger.error("No rules matched mixin '{}', treating as foreign and disabling!", mixin);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (option.isOverridden()) {
|
||||||
|
String source = "[unknown]";
|
||||||
|
|
||||||
|
if (option.isUserDefined()) {
|
||||||
|
source = "user configuration";
|
||||||
|
} else if (option.isModDefined()) {
|
||||||
|
source = "mods [" + String.join(", ", option.getDefiningMods()) + "]";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (option.isEnabled()) {
|
||||||
|
this.logger.warn("Force-enabling mixin '{}' as rule '{}' (added by {}) enables it", mixin,
|
||||||
|
option.getName(), source);
|
||||||
|
} else {
|
||||||
|
this.logger.warn("Force-disabling mixin '{}' as rule '{}' (added by {}) disables it and children", mixin,
|
||||||
|
option.getName(), source);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return option.isEnabled();
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void acceptTargets(Set<String> myTargets, Set<String> otherTargets) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> getMixins() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void preApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void postApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,177 @@
|
||||||
|
package org.embeddedt.modernfix.core.config;
|
||||||
|
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
|
||||||
|
import net.minecraftforge.fml.loading.FMLLoader;
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
public class ModernFixConfig {
|
||||||
|
private static final Logger LOGGER = LogManager.getLogger("ModernFixConfig");
|
||||||
|
|
||||||
|
private final Map<String, Option> options = new HashMap<>();
|
||||||
|
|
||||||
|
private ModernFixConfig() {
|
||||||
|
// 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("feature.measure_time", true);
|
||||||
|
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.trim_model_caches", true);
|
||||||
|
this.addMixinRule("bugfix.concurrency", true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Defines a Mixin rule which can be configured by users and other mods.
|
||||||
|
* @throws IllegalStateException If a rule with that name already exists
|
||||||
|
* @param mixin The name of the mixin package which will be controlled by this rule
|
||||||
|
* @param enabled True if the rule will be enabled by default, otherwise false
|
||||||
|
*/
|
||||||
|
private void addMixinRule(String mixin, boolean enabled) {
|
||||||
|
String name = getMixinRuleName(mixin);
|
||||||
|
|
||||||
|
if (this.options.putIfAbsent(name, new Option(name, enabled, false)) != null) {
|
||||||
|
throw new IllegalStateException("Mixin rule already defined: " + mixin);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void readProperties(Properties props) {
|
||||||
|
for (Map.Entry<Object, Object> entry : props.entrySet()) {
|
||||||
|
String key = (String) entry.getKey();
|
||||||
|
String value = (String) entry.getValue();
|
||||||
|
|
||||||
|
Option option = this.options.get(key);
|
||||||
|
|
||||||
|
if (option == null) {
|
||||||
|
LOGGER.warn("No configuration key exists with name '{}', ignoring", key);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean enabled;
|
||||||
|
|
||||||
|
if (value.equalsIgnoreCase("true")) {
|
||||||
|
enabled = true;
|
||||||
|
} else if (value.equalsIgnoreCase("false")) {
|
||||||
|
enabled = false;
|
||||||
|
} else {
|
||||||
|
LOGGER.warn("Invalid value '{}' encountered for configuration key '{}', ignoring", value, key);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
option.setEnabled(enabled, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the effective option for the specified class name. This traverses the package path of the given mixin
|
||||||
|
* and checks each root for configuration rules. If a configuration rule disables a package, all mixins located in
|
||||||
|
* that package and its children will be disabled. The effective option is that of the highest-priority rule, either
|
||||||
|
* a enable rule at the end of the chain or a disable rule at the earliest point in the chain.
|
||||||
|
*
|
||||||
|
* @return Null if no options matched the given mixin name, otherwise the effective option for this Mixin
|
||||||
|
*/
|
||||||
|
public Option getEffectiveOptionForMixin(String mixinClassName) {
|
||||||
|
int lastSplit = 0;
|
||||||
|
int nextSplit;
|
||||||
|
|
||||||
|
Option rule = null;
|
||||||
|
|
||||||
|
while ((nextSplit = mixinClassName.indexOf('.', lastSplit)) != -1) {
|
||||||
|
String key = getMixinRuleName(mixinClassName.substring(0, nextSplit));
|
||||||
|
|
||||||
|
Option candidate = this.options.get(key);
|
||||||
|
|
||||||
|
if (candidate != null) {
|
||||||
|
rule = candidate;
|
||||||
|
|
||||||
|
if (!rule.isEnabled()) {
|
||||||
|
return rule;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
lastSplit = nextSplit + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rule;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads the configuration file from the specified location. If it does not exist, a new configuration file will be
|
||||||
|
* created. The file on disk will then be updated to include any new options.
|
||||||
|
*/
|
||||||
|
public static ModernFixConfig load(File file) {
|
||||||
|
ModernFixConfig config = new ModernFixConfig();
|
||||||
|
Properties props = new Properties();
|
||||||
|
if(file.exists()) {
|
||||||
|
try (FileInputStream fin = new FileInputStream(file)){
|
||||||
|
props.load(fin);
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException("Could not load config file", e);
|
||||||
|
}
|
||||||
|
config.readProperties(props);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
config.writeConfig(file, props);
|
||||||
|
} catch (IOException e) {
|
||||||
|
LOGGER.warn("Could not write configuration file", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void writeConfig(File file, Properties props) throws IOException {
|
||||||
|
File dir = file.getParentFile();
|
||||||
|
|
||||||
|
if (!dir.exists()) {
|
||||||
|
if (!dir.mkdirs()) {
|
||||||
|
throw new IOException("Could not create parent directories");
|
||||||
|
}
|
||||||
|
} else if (!dir.isDirectory()) {
|
||||||
|
throw new IOException("The parent file is not a directory");
|
||||||
|
}
|
||||||
|
|
||||||
|
try (Writer writer = new FileWriter(file)) {
|
||||||
|
writer.write("# This is the configuration file for ModernFix.\n");
|
||||||
|
writer.write("#\n");
|
||||||
|
writer.write("# The following options are enabled by default and should only be disabled if there is a.\n");
|
||||||
|
writer.write("# compatibility issue. Add a line mixin.example_name=false without the # sign to disable a rule.\n");
|
||||||
|
List<String> lines = this.options.keySet().stream()
|
||||||
|
.filter(key -> !key.equals("mixin.core"))
|
||||||
|
.sorted()
|
||||||
|
.map(key -> "# " + key + "\n")
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
for(String line : lines) {
|
||||||
|
writer.write(line);
|
||||||
|
}
|
||||||
|
for (Map.Entry<Object, Object> entry : props.entrySet()) {
|
||||||
|
String key = (String) entry.getKey();
|
||||||
|
String value = (String) entry.getValue();
|
||||||
|
writer.write(key + "=" + value + "\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String getMixinRuleName(String name) {
|
||||||
|
return "mixin." + name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getOptionCount() {
|
||||||
|
return this.options.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getOptionOverrideCount() {
|
||||||
|
return (int) this.options.values()
|
||||||
|
.stream()
|
||||||
|
.filter(Option::isOverridden)
|
||||||
|
.count();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,63 @@
|
||||||
|
package org.embeddedt.modernfix.core.config;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.LinkedHashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
public class Option {
|
||||||
|
private final String name;
|
||||||
|
|
||||||
|
private Set<String> modDefined = null;
|
||||||
|
private boolean enabled;
|
||||||
|
private boolean userDefined;
|
||||||
|
|
||||||
|
public Option(String name, boolean enabled, boolean userDefined) {
|
||||||
|
this.name = name;
|
||||||
|
this.enabled = enabled;
|
||||||
|
this.userDefined = userDefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEnabled(boolean enabled, boolean userDefined) {
|
||||||
|
this.enabled = enabled;
|
||||||
|
this.userDefined = userDefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addModOverride(boolean enabled, String modId) {
|
||||||
|
this.enabled = enabled;
|
||||||
|
|
||||||
|
if (this.modDefined == null) {
|
||||||
|
this.modDefined = new LinkedHashSet<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.modDefined.add(modId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isEnabled() {
|
||||||
|
return this.enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isOverridden() {
|
||||||
|
return this.isUserDefined() || this.isModDefined();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isUserDefined() {
|
||||||
|
return this.userDefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isModDefined() {
|
||||||
|
return this.modDefined != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return this.name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clearModsDefiningValue() {
|
||||||
|
this.modDefined = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Collection<String> getDefiningMods() {
|
||||||
|
return this.modDefined != null ? Collections.unmodifiableCollection(this.modDefined) : Collections.emptyList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package org.embeddedt.modernfix.mixin;
|
package org.embeddedt.modernfix.mixin.bugfix.concurrency;
|
||||||
|
|
||||||
import it.unimi.dsi.fastutil.objects.ObjectOpenCustomHashSet;
|
import it.unimi.dsi.fastutil.objects.ObjectOpenCustomHashSet;
|
||||||
import net.minecraft.client.renderer.RenderType;
|
import net.minecraft.client.renderer.RenderType;
|
||||||
|
|
@ -0,0 +1,39 @@
|
||||||
|
package org.embeddedt.modernfix.mixin.feature.measure_time;
|
||||||
|
|
||||||
|
import com.mojang.datafixers.util.Function4;
|
||||||
|
import net.minecraft.client.Minecraft;
|
||||||
|
import net.minecraft.resources.IResourceManager;
|
||||||
|
import net.minecraft.util.datafix.codec.DatapackCodec;
|
||||||
|
import net.minecraft.util.registry.DynamicRegistries;
|
||||||
|
import net.minecraft.world.storage.IServerConfiguration;
|
||||||
|
import net.minecraft.world.storage.SaveFormat;
|
||||||
|
import org.embeddedt.modernfix.ModernFix;
|
||||||
|
import org.embeddedt.modernfix.ModernFixClient;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||||
|
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
@Mixin(Minecraft.class)
|
||||||
|
public class MinecraftMixin {
|
||||||
|
private long datapackReloadStartTime;
|
||||||
|
|
||||||
|
@Inject(method = "makeServerStem", at = @At(value = "HEAD"))
|
||||||
|
private void recordReloadStart(DynamicRegistries.Impl p_238189_1_, Function<SaveFormat.LevelSave, DatapackCodec> p_238189_2_, Function4<SaveFormat.LevelSave, DynamicRegistries.Impl, IResourceManager, DatapackCodec, IServerConfiguration> p_238189_3_, boolean p_238189_4_, SaveFormat.LevelSave p_238189_5_, CallbackInfoReturnable<Minecraft.PackManager> cir) {
|
||||||
|
datapackReloadStartTime = System.nanoTime();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Inject(method = "makeServerStem", at = @At(value = "RETURN"))
|
||||||
|
private void recordReloadEnd(DynamicRegistries.Impl p_238189_1_, Function<SaveFormat.LevelSave, DatapackCodec> p_238189_2_, Function4<SaveFormat.LevelSave, DynamicRegistries.Impl, IResourceManager, DatapackCodec, IServerConfiguration> p_238189_3_, boolean p_238189_4_, SaveFormat.LevelSave p_238189_5_, CallbackInfoReturnable<Minecraft.PackManager> cir) {
|
||||||
|
float timeSpentReloading = ((float)(System.nanoTime() - datapackReloadStartTime) / 1000000000f);
|
||||||
|
ModernFix.LOGGER.warn("Datapack reload took " + timeSpentReloading + " seconds.");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Inject(method = "loadWorld(Ljava/lang/String;Lnet/minecraft/util/registry/DynamicRegistries$Impl;Ljava/util/function/Function;Lcom/mojang/datafixers/util/Function4;ZLnet/minecraft/client/Minecraft$WorldSelectionType;Z)V", at = @At("HEAD"), remap = false)
|
||||||
|
private void recordWorldLoadStart(String worldName, DynamicRegistries.Impl dynamicRegistries, Function<SaveFormat.LevelSave, DatapackCodec> levelSaveToDatapackFunction, Function4<SaveFormat.LevelSave, DynamicRegistries.Impl, IResourceManager, DatapackCodec, IServerConfiguration> quadFunction, boolean vanillaOnly, Minecraft.WorldSelectionType selectionType, boolean creating, CallbackInfo ci) {
|
||||||
|
ModernFixClient.worldLoadStartTime = System.nanoTime();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package org.embeddedt.modernfix.mixin;
|
package org.embeddedt.modernfix.mixin.perf.boost_worker_count;
|
||||||
|
|
||||||
import net.minecraft.util.Util;
|
import net.minecraft.util.Util;
|
||||||
import org.embeddedt.modernfix.ModernFix;
|
import org.embeddedt.modernfix.ModernFix;
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package org.embeddedt.modernfix.mixin;
|
package org.embeddedt.modernfix.mixin.perf.parallelize_model_loading;
|
||||||
|
|
||||||
import com.google.common.base.Stopwatch;
|
import com.google.common.base.Stopwatch;
|
||||||
import com.google.common.collect.Sets;
|
import com.google.common.collect.Sets;
|
||||||
|
|
@ -43,11 +43,6 @@ public abstract class ModelBakeryMixin {
|
||||||
|
|
||||||
@Shadow public abstract IUnbakedModel getModel(ResourceLocation modelLocation);
|
@Shadow public abstract IUnbakedModel getModel(ResourceLocation modelLocation);
|
||||||
|
|
||||||
@Shadow @Final public static BlockModel GENERATION_MARKER;
|
|
||||||
@Shadow @Final private static ItemModelGenerator ITEM_MODEL_GENERATOR;
|
|
||||||
@Shadow @Nullable private SpriteMap atlasSet;
|
|
||||||
@Shadow @Final private Map<Triple<ResourceLocation, TransformationMatrix, Boolean>, IBakedModel> bakedCache;
|
|
||||||
@Shadow @Final private Map<ResourceLocation, IBakedModel> bakedTopLevelModels;
|
|
||||||
@Shadow @Final private Map<ResourceLocation, IUnbakedModel> topLevelModels;
|
@Shadow @Final private Map<ResourceLocation, IUnbakedModel> topLevelModels;
|
||||||
private Map<ResourceLocation, BlockModel> deserializedModelCache = null;
|
private Map<ResourceLocation, BlockModel> deserializedModelCache = null;
|
||||||
private boolean useModelCache = false;
|
private boolean useModelCache = false;
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package org.embeddedt.modernfix.mixin;
|
package org.embeddedt.modernfix.mixin.perf.reduce_blockstate_cache_rebuilds;
|
||||||
|
|
||||||
import net.minecraft.block.AbstractBlock;
|
import net.minecraft.block.AbstractBlock;
|
||||||
import org.embeddedt.modernfix.duck.IBlockState;
|
import org.embeddedt.modernfix.duck.IBlockState;
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package org.embeddedt.modernfix.mixin;
|
package org.embeddedt.modernfix.mixin.perf.reduce_blockstate_cache_rebuilds;
|
||||||
|
|
||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
import org.embeddedt.modernfix.ModernFix;
|
import org.embeddedt.modernfix.ModernFix;
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package org.embeddedt.modernfix.mixin;
|
package org.embeddedt.modernfix.mixin.perf.reduce_blockstate_cache_rebuilds;
|
||||||
|
|
||||||
import com.google.common.collect.Multimap;
|
import com.google.common.collect.Multimap;
|
||||||
import net.minecraft.util.ResourceLocation;
|
import net.minecraft.util.ResourceLocation;
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package org.embeddedt.modernfix.mixin;
|
package org.embeddedt.modernfix.mixin.perf.remove_biome_temperature_cache;
|
||||||
|
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.world.biome.Biome;
|
import net.minecraft.world.biome.Biome;
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package org.embeddedt.modernfix.mixin;
|
package org.embeddedt.modernfix.mixin.perf.resourcepacks;
|
||||||
|
|
||||||
import com.google.common.base.Joiner;
|
import com.google.common.base.Joiner;
|
||||||
import net.minecraft.resources.ResourcePackType;
|
import net.minecraft.resources.ResourcePackType;
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package org.embeddedt.modernfix.mixin;
|
package org.embeddedt.modernfix.mixin.perf.resourcepacks;
|
||||||
|
|
||||||
import com.google.common.base.Joiner;
|
import com.google.common.base.Joiner;
|
||||||
import com.google.common.cache.CacheBuilder;
|
import com.google.common.cache.CacheBuilder;
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package org.embeddedt.modernfix.mixin;
|
package org.embeddedt.modernfix.mixin.perf.skip_first_datapack_reload;
|
||||||
|
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.nbt.CompoundNBT;
|
import net.minecraft.nbt.CompoundNBT;
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package org.embeddedt.modernfix.mixin;
|
package org.embeddedt.modernfix.mixin.perf.skip_first_datapack_reload;
|
||||||
|
|
||||||
import com.mojang.datafixers.util.Function4;
|
import com.mojang.datafixers.util.Function4;
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
|
|
@ -25,24 +25,6 @@ import java.util.function.Function;
|
||||||
public abstract class MinecraftMixin {
|
public abstract class MinecraftMixin {
|
||||||
@Shadow public abstract Minecraft.PackManager makeServerStem(DynamicRegistries.Impl dynamicRegistries, Function<SaveFormat.LevelSave, DatapackCodec> worldStorageToDatapackFunction, Function4<SaveFormat.LevelSave, DynamicRegistries.Impl, IResourceManager, DatapackCodec, IServerConfiguration> quadFunction, boolean vanillaOnly, SaveFormat.LevelSave worldStorage) throws InterruptedException, ExecutionException;
|
@Shadow public abstract Minecraft.PackManager makeServerStem(DynamicRegistries.Impl dynamicRegistries, Function<SaveFormat.LevelSave, DatapackCodec> worldStorageToDatapackFunction, Function4<SaveFormat.LevelSave, DynamicRegistries.Impl, IResourceManager, DatapackCodec, IServerConfiguration> quadFunction, boolean vanillaOnly, SaveFormat.LevelSave worldStorage) throws InterruptedException, ExecutionException;
|
||||||
|
|
||||||
private long datapackReloadStartTime;
|
|
||||||
private int registryHash;
|
|
||||||
@Inject(method = "makeServerStem", at = @At(value = "HEAD"))
|
|
||||||
private void recordReloadStart(DynamicRegistries.Impl p_238189_1_, Function<SaveFormat.LevelSave, DatapackCodec> p_238189_2_, Function4<SaveFormat.LevelSave, DynamicRegistries.Impl, IResourceManager, DatapackCodec, IServerConfiguration> p_238189_3_, boolean p_238189_4_, SaveFormat.LevelSave p_238189_5_, CallbackInfoReturnable<Minecraft.PackManager> cir) {
|
|
||||||
datapackReloadStartTime = System.nanoTime();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Inject(method = "makeServerStem", at = @At(value = "RETURN"))
|
|
||||||
private void recordReloadEnd(DynamicRegistries.Impl p_238189_1_, Function<SaveFormat.LevelSave, DatapackCodec> p_238189_2_, Function4<SaveFormat.LevelSave, DynamicRegistries.Impl, IResourceManager, DatapackCodec, IServerConfiguration> p_238189_3_, boolean p_238189_4_, SaveFormat.LevelSave p_238189_5_, CallbackInfoReturnable<Minecraft.PackManager> cir) {
|
|
||||||
float timeSpentReloading = ((float)(System.nanoTime() - datapackReloadStartTime) / 1000000000f);
|
|
||||||
ModernFix.LOGGER.warn("Datapack reload took " + timeSpentReloading + " seconds.");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Inject(method = "loadWorld(Ljava/lang/String;Lnet/minecraft/util/registry/DynamicRegistries$Impl;Ljava/util/function/Function;Lcom/mojang/datafixers/util/Function4;ZLnet/minecraft/client/Minecraft$WorldSelectionType;Z)V", at = @At("HEAD"), remap = false)
|
|
||||||
private void recordWorldLoadStart(String worldName, DynamicRegistries.Impl dynamicRegistries, Function<SaveFormat.LevelSave, DatapackCodec> levelSaveToDatapackFunction, Function4<SaveFormat.LevelSave, DynamicRegistries.Impl, IResourceManager, DatapackCodec, IServerConfiguration> quadFunction, boolean vanillaOnly, Minecraft.WorldSelectionType selectionType, boolean creating, CallbackInfo ci) {
|
|
||||||
ModernFixClient.worldLoadStartTime = System.nanoTime();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Redirect(method = "loadLevel(Ljava/lang/String;)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/util/registry/DynamicRegistries;builtin()Lnet/minecraft/util/registry/DynamicRegistries$Impl;"))
|
@Redirect(method = "loadLevel(Ljava/lang/String;)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/util/registry/DynamicRegistries;builtin()Lnet/minecraft/util/registry/DynamicRegistries$Impl;"))
|
||||||
private DynamicRegistries.Impl useNullRegistry() {
|
private DynamicRegistries.Impl useNullRegistry() {
|
||||||
return null;
|
return null;
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package org.embeddedt.modernfix.mixin;
|
package org.embeddedt.modernfix.mixin.perf.skip_first_datapack_reload;
|
||||||
|
|
||||||
import com.mojang.datafixers.DataFixer;
|
import com.mojang.datafixers.DataFixer;
|
||||||
import net.minecraft.world.storage.SaveFormat;
|
import net.minecraft.world.storage.SaveFormat;
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package org.embeddedt.modernfix.mixin;
|
package org.embeddedt.modernfix.mixin.perf.trim_model_caches;
|
||||||
|
|
||||||
import net.minecraft.client.renderer.model.ModelBakery;
|
import net.minecraft.client.renderer.model.ModelBakery;
|
||||||
import net.minecraft.client.renderer.model.ModelManager;
|
import net.minecraft.client.renderer.model.ModelManager;
|
||||||
|
|
@ -2,24 +2,26 @@
|
||||||
"required": true,
|
"required": true,
|
||||||
"minVersion": "0.8",
|
"minVersion": "0.8",
|
||||||
"package": "org.embeddedt.modernfix.mixin",
|
"package": "org.embeddedt.modernfix.mixin",
|
||||||
|
"plugin": "org.embeddedt.modernfix.core.ModernFixMixinPlugin",
|
||||||
"compatibilityLevel": "JAVA_8",
|
"compatibilityLevel": "JAVA_8",
|
||||||
"refmap": "modernfix.refmap.json",
|
"refmap": "modernfix.refmap.json",
|
||||||
"mixins": [
|
"mixins": [
|
||||||
"BiomeMixin",
|
"feature.measure_time.MinecraftMixin",
|
||||||
"ModFileResourcePackMixin",
|
"perf.remove_biome_temperature_cache.BiomeMixin",
|
||||||
"VanillaPackMixin",
|
"perf.resourcepacks.ModFileResourcePackMixin",
|
||||||
"LevelSaveMixin",
|
"perf.resourcepacks.VanillaPackMixin",
|
||||||
"SaveFormatAccessor",
|
"perf.skip_first_datapack_reload.LevelSaveMixin",
|
||||||
"AbstractBlockStateMixin",
|
"perf.skip_first_datapack_reload.SaveFormatAccessor",
|
||||||
"GameDataMixin",
|
"perf.reduce_blockstate_cache_rebuilds.AbstractBlockStateMixin",
|
||||||
"BlockCallbacksMixin",
|
"perf.reduce_blockstate_cache_rebuilds.GameDataMixin",
|
||||||
"UtilMixin"
|
"perf.reduce_blockstate_cache_rebuilds.BlockCallbacksMixin",
|
||||||
|
"perf.boost_worker_count.UtilMixin"
|
||||||
],
|
],
|
||||||
"client": [
|
"client": [
|
||||||
"MinecraftMixin",
|
"perf.skip_first_datapack_reload.MinecraftMixin",
|
||||||
"RenderTypeMixin",
|
"bugfix.concurrency.RenderTypeMixin",
|
||||||
"ModelBakeryMixin",
|
"perf.parallelize_model_loading.ModelBakeryMixin",
|
||||||
"ModelManagerMixin"
|
"perf.trim_model_caches.ModelManagerMixin"
|
||||||
],
|
],
|
||||||
"injectors": {
|
"injectors": {
|
||||||
"defaultRequire": 1
|
"defaultRequire": 1
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user