Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ org.gradle.jvmargs=-Xmx2G

# Mod properties
mod_id=modernfix
version=5.27.7-build.1
version=5.27.17-build.1

# Minecraft/Fabric
minecraft_version=26.2
Expand All @@ -19,7 +19,7 @@ mixinextras_version=0.5.4
modmenu_version=20.0.0-beta.2

# For mod sites
supported_minecraft_versions=~26.2-
supported_minecraft_versions=~26.1-

# Build
shadow_version=8.1.1
3 changes: 3 additions & 0 deletions src/main/java/org/embeddedt/modernfix/ModernFix.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import org.embeddedt.modernfix.util.ClassInfoManager;
import org.spongepowered.asm.mixin.MixinEnvironment;

import net.minecraft.client.Minecraft;
import java.lang.management.ManagementFactory;

// The value here should match an entry in the META-INF/mods.toml file
Expand Down Expand Up @@ -51,6 +52,8 @@ public static void runAuditIfRequested() {
if (auditAndExit || Boolean.getBoolean("modernfix.auditMixinsAtStart")) {
MixinEnvironment.getCurrentEnvironment().audit();
if (auditAndExit) {
// Prevents Crash Assistant from treating mixin audit as a crash
Minecraft.getInstance().stop();
System.exit(0);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public class WorldSelectionListMixin {

@Inject(method = "*", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screens/worldselection/WorldSelectionList$WorldListEntry;doDeleteWorld()V", ordinal = 0, shift = At.Shift.AFTER), cancellable = true)
private void preventClosingCreateScreenAfterDelete(CallbackInfo ci) {
if(minecraft.gui.screen() instanceof CreateWorldScreen)
if(minecraft.screen instanceof CreateWorldScreen)
ci.cancel();
}
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
package org.embeddedt.modernfix.common.mixin.feature.measure_time;

import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.Gui;
import net.minecraft.client.gui.screens.Overlay;
import org.embeddedt.modernfix.ModernFixClient;
import org.embeddedt.modernfix.annotation.ClientOnlyMixin;
import org.spongepowered.asm.mixin.Final;
import org.jetbrains.annotations.Nullable;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
Expand All @@ -16,11 +16,11 @@
@ClientOnlyMixin
public class MinecraftMixin {
// TODO re-add datapack reload time measurement
@Shadow @Final public Gui gui;
@Shadow @Nullable public Overlay overlay;

@Inject(method = "tick", at = @At("HEAD"))
private void onClientTick(CallbackInfo ci) {
if(this.gui.overlay() == null && ModernFixClient.INSTANCE != null) {
if(this.overlay == null && ModernFixClient.INSTANCE != null) {
ModernFixClient.INSTANCE.onGameLaunchFinish();
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package org.embeddedt.modernfix.common.mixin.perf.attribute_supplier_dedup;

import net.minecraft.core.Holder;
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
import net.minecraft.world.entity.ai.attributes.Attribute;
import net.minecraft.world.entity.ai.attributes.AttributeInstance;
import net.minecraft.world.entity.ai.attributes.AttributeSupplier;
Expand All @@ -19,15 +19,15 @@ public class AttributeSupplierMixin {
@Shadow
@Final
@Mutable
private Map<Holder<Attribute>, AttributeInstance> instances;
private Map<Attribute, AttributeInstance> instances;

/**
* @author embeddedt
* @reason Java 9's Map.of() implementation is significantly more compact than ImmutableMap, and we do not
* @reason more compact than ImmutableMap due to less wrapper objects, and we do not
* care about insertion order in this context
*/
@Inject(method = "<init>", at = @At("RETURN"))
private void useCompactJavaMap(Map<Holder<Attribute>, AttributeInstance> instances, CallbackInfo ci) {
this.instances = Map.copyOf(this.instances);
private void useCompactJavaMap(Map<Attribute, AttributeInstance> instances, CallbackInfo ci) {
this.instances = new Object2ObjectOpenHashMap<>(this.instances);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,26 +28,28 @@ public class ClientLanguageMixin {
* @reason collect the list of all known language resources
*/
@WrapOperation(method = "loadFrom", at = @At(value = "INVOKE",
target = "Lnet/minecraft/client/resources/language/ClientLanguage;appendFrom(Ljava/lang/String;Ljava/util/List;Ljava/util/Map;)V"))
target = "Lnet/minecraft/client/resources/language/ClientLanguage;appendFrom(Ljava/lang/String;Ljava/util/List;Ljava/util/Map;Ljava/util/Map;)V"))
private static void collectResources(String languageName, List<Resource> resources,
Map<String, String> destinationMap, Operation<Void> original,
Map<String, String> destinationMap,
Map<String, net.minecraft.network.chat.Component> componentMap,
Operation<Void> original,
@Share("usedResources") LocalRef<List<Resource>> usedResources) {
List<Resource> collected = usedResources.get();
if (collected == null) {
collected = new ArrayList<>();
usedResources.set(collected);
}
collected.addAll(resources);
original.call(languageName, resources, destinationMap);
original.call(languageName, resources, destinationMap, componentMap);
}

/**
* @author embeddedt
* @reason figure out which keys are dynamically loaded and which are injected by mixins
*/
@ModifyArg(method = "loadFrom", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/resources/language/ClientLanguage;<init>(Ljava/util/Map;Z)V"), index = 0)
@ModifyArg(method = "loadFrom", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/resources/language/ClientLanguage;<init>(Ljava/util/Map;ZLjava/util/Map;)V"), index = 0)
private static Map<String, String> modifyLanguageMap(Map<String, String> storage, @Share("usedResources") LocalRef<List<Resource>> usedResources) {
List<Resource> collected = Objects.requireNonNullElse(usedResources.get(), List.of());
return DynamicLanguageMap.forVanillaData(storage, collected);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;

import java.util.Map;
import java.util.Objects;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionStage;
import java.util.function.Function;
Expand Down Expand Up @@ -67,6 +68,7 @@ private static Object2IntMap<BlockState> buildModelGroups(BlockColors blockColor
@Overwrite
private static Map<BlockState, BlockStateModel> createBlockStateToModelDispatch(Map<BlockState, BlockStateModel> blockStateModels, BlockStateModel missingModel) {
BlockStateModelMap.resetCache();
Objects.requireNonNull(missingModel);
return new BlockStateModelMap(blockStateModels, missingModel);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package org.embeddedt.modernfix.common.mixin.perf.dynamic_resources;

import net.minecraft.client.resources.model.sprite.TextureSlots;
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.CallbackInfoReturnable;

@Mixin(TextureSlots.class)
@ClientOnlyMixin
public class MixinTextureSlots {
/**
* @author coredex-source
* @reason Return false instead of throwing StringIndexOutOfBoundsException to prevent resource reload from crashing when model points to empty texture string.
*/
@Inject(method = "isTextureReference", at = @At("HEAD"), cancellable = true)
private static void mfix$handleEmptyTextureReference(String string, CallbackInfoReturnable<Boolean> cir) {
if (string == null || string.isEmpty()) {
cir.setReturnValue(false);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,14 @@
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Overwrite;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique;

import java.util.function.Function;

// Update the file when embeddedt patches this file for 26.2 in the neoforge version to keep it conisitent with the upstream changes.
import java.util.function.Supplier;

@Mixin(targets = {"net/minecraft/world/level/levelgen/SurfaceRules$Context"}, priority = 100)
public class SurfaceRulesContextMixin {
@Shadow private long lastUpdateY;

@Shadow private int blockX;

@Shadow private int blockZ;

@Shadow private int blockY;

@Shadow private int waterHeight;
Expand All @@ -30,53 +24,27 @@ public class SurfaceRulesContextMixin {

@Shadow private int stoneDepthAbove;

@Shadow private Holder<Biome> biome;
@Shadow private Supplier<Holder<Biome>> biome;

@Shadow @Final private Function<BlockPos, Holder<Biome>> biomeGetter;

@Shadow @Final private BlockPos.MutableBlockPos pos;

@Unique
private PositionalBiomeGetter modernfix$biomeCache;

/**
* @author embeddedt
* @reason Keep a reusable biome cache helper instead of rebuilding intermediate state
* @reason Reuse supplier object instead of creating new ones every time
*/
@Overwrite
protected void updateY(int stoneDepthAbove, int stoneDepthBelow, int waterHeight, int blockY) {
public void updateY(int stoneDepthAbove, int stoneDepthBelow, int waterHeight, int blockX, int blockY, int blockZ) {
++this.lastUpdateY;

var getter = this.modernfix$biomeCache;
var getter = this.biome;
if(getter == null) {
this.modernfix$biomeCache = getter = new PositionalBiomeGetter(this.biomeGetter, this.pos);
this.biome = getter = new PositionalBiomeGetter(this.biomeGetter, this.pos);
}

getter.update(this.blockX, blockY, this.blockZ);
this.biome = null;
((PositionalBiomeGetter)getter).update(blockX, blockY, blockZ);
this.blockY = blockY;
this.waterHeight = waterHeight;
this.stoneDepthBelow = stoneDepthBelow;
this.stoneDepthAbove = stoneDepthAbove;
}

/**
* @author coredex
* @reason Reuse a single positional getter object for biome lookups
*/
@Overwrite
protected Holder<Biome> getBiome() {
var biome = this.biome;
if(biome == null) {
var getter = this.modernfix$biomeCache;
if(getter == null) {
this.modernfix$biomeCache = getter = new PositionalBiomeGetter(this.biomeGetter, this.pos);
}

getter.update(this.blockX, this.blockY, this.blockZ);
this.biome = biome = getter.get();
}

return biome;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,7 @@ private ModernFixEarlyConfig(File file) {
disableIfModPresent("mixin.bugfix.paper_chunk_patches", "c2me");
disableIfModPresent("mixin.bugfix.preserve_early_window_pos", "better_loading_screen");
disableIfModPresent("mixin.perf.dynamic_dfu", "litematica");
disableIfModPresent("mixin.perf.cache_strongholds", "littletiles", "c2me");
disableIfModPresent("mixin.perf.cache_strongholds", "littletiles", "c2me", "flashback");
// content overlap
disableIfModPresent("mixin.perf.deduplicate_wall_shapes", "dashloader");
disableIfModPresent("mixin.perf.nbt_memory_usage", "c2me");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

import java.util.Collection;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

/**
Expand All @@ -18,6 +19,10 @@
public record BlockStateModelMap(Map<BlockState, BlockStateModel> modelMap,
BlockStateModel fallbackModel) implements Map<BlockState, BlockStateModel> {

public BlockStateModelMap {
Objects.requireNonNull(fallbackModel);
}

@Override
public int size() {
return Block.BLOCK_STATE_REGISTRY.size();
Expand Down Expand Up @@ -55,6 +60,12 @@ public BlockStateModel get(Object o) {
}
}

@Override
public BlockStateModel getOrDefault(Object key, BlockStateModel defaultValue) {
var value = get(key);
return value != fallbackModel ? value : defaultValue;
}

@Override
public @Nullable BlockStateModel put(BlockState blockState, BlockStateModel blockStateModel) {
var oldModel = modelMap.put(blockState, blockStateModel);
Expand Down Expand Up @@ -102,4 +113,4 @@ public static void resetCache() {
((IModelHoldingBlockState) state).mfix$setModel(null);
}
}
}
}
Loading
Loading