diff --git a/gradle.properties b/gradle.properties index 85102e6d2..978c8a1ba 100644 --- a/gradle.properties +++ b/gradle.properties @@ -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 @@ -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 diff --git a/src/main/java/org/embeddedt/modernfix/ModernFix.java b/src/main/java/org/embeddedt/modernfix/ModernFix.java index a1fdf9b6e..ae0bd8360 100644 --- a/src/main/java/org/embeddedt/modernfix/ModernFix.java +++ b/src/main/java/org/embeddedt/modernfix/ModernFix.java @@ -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 @@ -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); } } diff --git a/src/main/java/org/embeddedt/modernfix/common/mixin/bugfix/world_screen_skipped/WorldSelectionListMixin.java b/src/main/java/org/embeddedt/modernfix/common/mixin/bugfix/world_screen_skipped/WorldSelectionListMixin.java index 2f67c46ef..7d816acd2 100644 --- a/src/main/java/org/embeddedt/modernfix/common/mixin/bugfix/world_screen_skipped/WorldSelectionListMixin.java +++ b/src/main/java/org/embeddedt/modernfix/common/mixin/bugfix/world_screen_skipped/WorldSelectionListMixin.java @@ -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(); } } diff --git a/src/main/java/org/embeddedt/modernfix/common/mixin/feature/measure_time/MinecraftMixin.java b/src/main/java/org/embeddedt/modernfix/common/mixin/feature/measure_time/MinecraftMixin.java index f5b5f8514..53c3b8466 100644 --- a/src/main/java/org/embeddedt/modernfix/common/mixin/feature/measure_time/MinecraftMixin.java +++ b/src/main/java/org/embeddedt/modernfix/common/mixin/feature/measure_time/MinecraftMixin.java @@ -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; @@ -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(); } } diff --git a/src/main/java/org/embeddedt/modernfix/common/mixin/perf/attribute_supplier_dedup/AttributeSupplierMixin.java b/src/main/java/org/embeddedt/modernfix/common/mixin/perf/attribute_supplier_dedup/AttributeSupplierMixin.java index c214cba0e..d4d0901b5 100644 --- a/src/main/java/org/embeddedt/modernfix/common/mixin/perf/attribute_supplier_dedup/AttributeSupplierMixin.java +++ b/src/main/java/org/embeddedt/modernfix/common/mixin/perf/attribute_supplier_dedup/AttributeSupplierMixin.java @@ -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; @@ -19,15 +19,15 @@ public class AttributeSupplierMixin { @Shadow @Final @Mutable - private Map, AttributeInstance> instances; + private Map 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 = "", at = @At("RETURN")) - private void useCompactJavaMap(Map, AttributeInstance> instances, CallbackInfo ci) { - this.instances = Map.copyOf(this.instances); + private void useCompactJavaMap(Map instances, CallbackInfo ci) { + this.instances = new Object2ObjectOpenHashMap<>(this.instances); } } \ No newline at end of file diff --git a/src/main/java/org/embeddedt/modernfix/common/mixin/perf/dynamic_languages/ClientLanguageMixin.java b/src/main/java/org/embeddedt/modernfix/common/mixin/perf/dynamic_languages/ClientLanguageMixin.java index 0d62a7340..97332bc14 100644 --- a/src/main/java/org/embeddedt/modernfix/common/mixin/perf/dynamic_languages/ClientLanguageMixin.java +++ b/src/main/java/org/embeddedt/modernfix/common/mixin/perf/dynamic_languages/ClientLanguageMixin.java @@ -28,9 +28,11 @@ 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 resources, - Map destinationMap, Operation original, + Map destinationMap, + Map componentMap, + Operation original, @Share("usedResources") LocalRef> usedResources) { List collected = usedResources.get(); if (collected == null) { @@ -38,16 +40,16 @@ private static void collectResources(String languageName, List resourc 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;(Ljava/util/Map;Z)V"), index = 0) + @ModifyArg(method = "loadFrom", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/resources/language/ClientLanguage;(Ljava/util/Map;ZLjava/util/Map;)V"), index = 0) private static Map modifyLanguageMap(Map storage, @Share("usedResources") LocalRef> usedResources) { List collected = Objects.requireNonNullElse(usedResources.get(), List.of()); return DynamicLanguageMap.forVanillaData(storage, collected); } -} +} \ No newline at end of file diff --git a/src/main/java/org/embeddedt/modernfix/common/mixin/perf/dynamic_resources/MixinModelManager.java b/src/main/java/org/embeddedt/modernfix/common/mixin/perf/dynamic_resources/MixinModelManager.java index b44603d97..3d0bd20bb 100644 --- a/src/main/java/org/embeddedt/modernfix/common/mixin/perf/dynamic_resources/MixinModelManager.java +++ b/src/main/java/org/embeddedt/modernfix/common/mixin/perf/dynamic_resources/MixinModelManager.java @@ -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; @@ -67,6 +68,7 @@ private static Object2IntMap buildModelGroups(BlockColors blockColor @Overwrite private static Map createBlockStateToModelDispatch(Map blockStateModels, BlockStateModel missingModel) { BlockStateModelMap.resetCache(); + Objects.requireNonNull(missingModel); return new BlockStateModelMap(blockStateModels, missingModel); } } diff --git a/src/main/java/org/embeddedt/modernfix/common/mixin/perf/dynamic_resources/MixinTextureSlots.java b/src/main/java/org/embeddedt/modernfix/common/mixin/perf/dynamic_resources/MixinTextureSlots.java new file mode 100644 index 000000000..1bc85f29f --- /dev/null +++ b/src/main/java/org/embeddedt/modernfix/common/mixin/perf/dynamic_resources/MixinTextureSlots.java @@ -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 cir) { + if (string == null || string.isEmpty()) { + cir.setReturnValue(false); + } + } +} diff --git a/src/main/java/org/embeddedt/modernfix/common/mixin/perf/worldgen_allocation/SurfaceRulesContextMixin.java b/src/main/java/org/embeddedt/modernfix/common/mixin/perf/worldgen_allocation/SurfaceRulesContextMixin.java index 2a18c710b..c2be9c3df 100644 --- a/src/main/java/org/embeddedt/modernfix/common/mixin/perf/worldgen_allocation/SurfaceRulesContextMixin.java +++ b/src/main/java/org/embeddedt/modernfix/common/mixin/perf/worldgen_allocation/SurfaceRulesContextMixin.java @@ -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; @@ -30,53 +24,27 @@ public class SurfaceRulesContextMixin { @Shadow private int stoneDepthAbove; - @Shadow private Holder biome; + @Shadow private Supplier> biome; @Shadow @Final private Function> 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 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; - } } 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 df00865ba..b89a988ee 100644 --- a/src/main/java/org/embeddedt/modernfix/core/config/ModernFixEarlyConfig.java +++ b/src/main/java/org/embeddedt/modernfix/core/config/ModernFixEarlyConfig.java @@ -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"); diff --git a/src/main/java/org/embeddedt/modernfix/dynresources/BlockStateModelMap.java b/src/main/java/org/embeddedt/modernfix/dynresources/BlockStateModelMap.java index 35398a0dd..5542f319f 100644 --- a/src/main/java/org/embeddedt/modernfix/dynresources/BlockStateModelMap.java +++ b/src/main/java/org/embeddedt/modernfix/dynresources/BlockStateModelMap.java @@ -9,6 +9,7 @@ import java.util.Collection; import java.util.Map; +import java.util.Objects; import java.util.Set; /** @@ -18,6 +19,10 @@ public record BlockStateModelMap(Map modelMap, BlockStateModel fallbackModel) implements Map { + public BlockStateModelMap { + Objects.requireNonNull(fallbackModel); + } + @Override public int size() { return Block.BLOCK_STATE_REGISTRY.size(); @@ -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); @@ -102,4 +113,4 @@ public static void resetCache() { ((IModelHoldingBlockState) state).mfix$setModel(null); } } -} +} \ No newline at end of file diff --git a/src/main/java/org/embeddedt/modernfix/dynresources/DynamicModelSystem.java b/src/main/java/org/embeddedt/modernfix/dynresources/DynamicModelSystem.java index a21c9f422..e8f0fba5c 100644 --- a/src/main/java/org/embeddedt/modernfix/dynresources/DynamicModelSystem.java +++ b/src/main/java/org/embeddedt/modernfix/dynresources/DynamicModelSystem.java @@ -4,28 +4,24 @@ import com.google.common.cache.CacheLoader; import com.google.common.cache.LoadingCache; import com.google.common.collect.Maps; -import com.google.common.collect.Sets; import it.unimi.dsi.fastutil.objects.AbstractObject2IntMap; import it.unimi.dsi.fastutil.objects.Object2IntMap; import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; import it.unimi.dsi.fastutil.objects.ObjectSet; import it.unimi.dsi.fastutil.objects.ObjectSets; -import it.unimi.dsi.fastutil.objects.ReferenceSets; -// import net.fabricmc.fabric.impl.client.model.loading.UnbakedModelDeserializerRegistry; // Disabled by FRAPI +import net.fabricmc.fabric.impl.client.model.loading.UnbakedModelDeserializerRegistry; import net.minecraft.client.color.block.BlockColors; import net.minecraft.client.renderer.item.ClientItem; -import net.minecraft.client.renderer.block.dispatch.BlockStateModel; -import net.minecraft.client.resources.model.cuboid.CuboidModel; -import net.minecraft.client.resources.model.cuboid.ItemModelGenerator; import net.minecraft.client.resources.model.BlockStateModelLoader; import net.minecraft.client.resources.model.ClientItemInfoLoader; -import net.minecraft.client.resources.model.cuboid.MissingCuboidModel; import net.minecraft.client.resources.model.ModelDiscovery; import net.minecraft.client.resources.model.ModelManager; import net.minecraft.client.resources.model.ResolvedModel; import net.minecraft.client.resources.model.UnbakedModel; -import net.minecraft.resources.FileToIdConverter; +import net.minecraft.client.resources.model.cuboid.ItemModelGenerator; +import net.minecraft.client.resources.model.cuboid.MissingCuboidModel; import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.resources.FileToIdConverter; import net.minecraft.resources.Identifier; import net.minecraft.server.packs.resources.Resource; import net.minecraft.world.level.block.Block; @@ -41,6 +37,8 @@ import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.Objects; +import java.util.Optional; import java.util.Set; import java.util.function.BiFunction; import java.util.function.Function; @@ -52,47 +50,80 @@ public class DynamicModelSystem { private static final FileToIdConverter ITEM_LISTER = FileToIdConverter.json("items"); public static final boolean DEBUG_DYNAMIC_MODEL_LOADING = Boolean.getBoolean("modernfix.debugDynamicModelLoading"); - - public static Map createDynamicUnbakedModelMap(Map resourceMap) { - LoadingCache unbakedModelCache = CacheBuilder.newBuilder().softValues().maximumSize(1000).build(new CacheLoader<>() { + + private interface ResultLoader { + RESULT load(Identifier file, @Nullable RESOURCE resource) throws Exception; + } + + private static Map createCachedResourceBackedMap(Map resourceMap, + FileToIdConverter converter, + String debugName, + ResultLoader loader) { + LoadingCache> resultCache = CacheBuilder.newBuilder().softValues().maximumSize(1000).build(new CacheLoader<>() { @Override - public UnbakedModel load(Identifier key) throws Exception { - var resource = resourceMap.get(MODEL_LISTER.idToFile(key)); + public Optional load(Identifier id) throws Exception { + var file = converter.idToFile(id); + var resource = resourceMap.get(file); if (resource == null) { - throw new IllegalArgumentException("Model " + key + " does not exist in map"); + return Optional.empty(); } if (DEBUG_DYNAMIC_MODEL_LOADING) { - ModernFix.LOGGER.info("Loading unbaked model {}", key); - } - try (Reader reader = resource.openAsReader()) { - // return UnbakedModelDeserializerRegistry.deserialize(reader); // Disabled by FRAPI - return CuboidModel.fromStream(reader); + ModernFix.LOGGER.info("Loading {} {}", debugName, id); } + return Optional.of(loader.load(file, resource)); + } + }); + Set idSet = resourceMap.keySet().stream().map(converter::fileToId).collect(Collectors.toUnmodifiableSet()); + return new DynamicRegistryMap<>(idSet, key -> { + if (key == null) { + return null; + } + try { + return resultCache.getUnchecked(key).orElse(null); + } catch (RuntimeException e) { + ModernFix.LOGGER.error("Error loading {} {} from cache", debugName, key); + throw e; + } + }); + } + + public static Map createDynamicUnbakedModelMap(Map resourceMap) { + return createCachedResourceBackedMap(resourceMap, MODEL_LISTER, "unbaked model", (id, resource) -> { + Objects.requireNonNull(resource, "unbaked model not present"); + try (Reader reader = resource.openAsReader()) { + return UnbakedModelDeserializerRegistry.deserialize(reader); + } catch (RuntimeException e) { + ModernFix.LOGGER.warn("Failed to deserialize unbaked model {}, using missing model", id, e); + return MissingCuboidModel.missingModel(); } }); - Set unbakedIdSet = resourceMap.keySet().stream().map(MODEL_LISTER::fileToId).collect(Collectors.toUnmodifiableSet()); - return Maps.asMap(unbakedIdSet, key -> key != null ? unbakedModelCache.getUnchecked(key) : null); } public interface SingleBlockStateEntryLoader { BlockStateModelLoader.LoadedModels loadEntry(Identifier identifier, List blockstateResources); } - private static Set getAllBlockStates() { - return ((IdMapperAccessor) Block.BLOCK_STATE_REGISTRY).getReferenceMap().keySet(); - } - public static BlockStateModelLoader.LoadedModels createDynamicBlockStateLoadedModels(Map> resourceMap, SingleBlockStateEntryLoader entryLoader) { - LoadingCache definitionCache = CacheBuilder.newBuilder().softValues().maximumSize(1000).build(new CacheLoader<>() { + public static Set getAllBlockStates() { + var blockStateSet = ((IdMapperAccessor) Block.BLOCK_STATE_REGISTRY).getReferenceMap().keySet(); + return new AbstractSet<>() { @Override - public BlockStateModelLoader.LoadedModels load(Identifier key) throws Exception { - if (DEBUG_DYNAMIC_MODEL_LOADING) { - ModernFix.LOGGER.info("Loading blockstate definition for {}", key); - } - var file = BLOCKSTATE_LISTER.idToFile(key); - var resources = resourceMap.getOrDefault(file, List.of()); - return entryLoader.loadEntry(file, resources); + public Iterator iterator() { + // We explicitly override iterator() and handle it differently so that mods iterating the maps + // are likely to work with the same block many times in a row, which hits our caches better + return BuiltInRegistries.BLOCK.stream().flatMap(b -> b.getStateDefinition().getPossibleStates().stream()).iterator(); } - }); + @Override + public boolean contains(Object o) { + return blockStateSet.contains(o); + } + @Override + public int size() { + return blockStateSet.size(); + } + }; + } + public static BlockStateModelLoader.LoadedModels createDynamicBlockStateLoadedModels(Map> resourceMap, SingleBlockStateEntryLoader entryLoader) { + var blockStateDefinitions = createCachedResourceBackedMap(resourceMap, BLOCKSTATE_LISTER, "blockstate definition", entryLoader::loadEntry); var staticDefinitions = BlockStateDefinitionsAccessor.getStaticDefinitions(); var staticIdentifiers = staticDefinitions.entrySet() .stream() @@ -104,8 +135,12 @@ public BlockStateModelLoader.LoadedModels load(Identifier key) throws Exception if (identifier == null) { identifier = BuiltInRegistries.BLOCK.getKey(state.getBlock()); } - var loadedModels = definitionCache.getUnchecked(identifier); - return loadedModels.models().get(state); + var loadedModels = blockStateDefinitions.get(identifier); + if (loadedModels != null) { + return loadedModels.models().get(state); + } else { + return null; + } })); } @@ -114,34 +149,8 @@ public interface SingleClientItemEntryLoader { } public static ClientItemInfoLoader.LoadedClientInfos createDynamicClientInfos(Map resourceMap, SingleClientItemEntryLoader entryLoader) { - Set itemIdSet = resourceMap.keySet().stream().map(ITEM_LISTER::fileToId).collect(Collectors.toUnmodifiableSet()); - LoadingCache clientItemCache = CacheBuilder.newBuilder().softValues().maximumSize(1000).build(new CacheLoader<>() { - @Override - public Object load(Identifier key) { - Identifier fileId = ITEM_LISTER.idToFile(key); - Resource resource = resourceMap.get(fileId); - if (resource == null) { - return NULL_SENTINEL; - } - if (DEBUG_DYNAMIC_MODEL_LOADING) { - ModernFix.LOGGER.info("Loading client item info {}", key); - } - try { - ClientItem result = entryLoader.loadEntry(fileId, resource); - return result != null ? result : NULL_SENTINEL; - } catch (RuntimeException e) { - ModernFix.LOGGER.warn("Failed to build dynamic client item info for {}", key, e); - return NULL_SENTINEL; - } - } - }); - return new ClientItemInfoLoader.LoadedClientInfos(Maps.asMap(itemIdSet, key -> { - if (key == null) { - return null; - } - Object value = clientItemCache.getUnchecked(key); - return value == NULL_SENTINEL ? null : (ClientItem) value; - })); + var clientItems = createCachedResourceBackedMap(resourceMap, ITEM_LISTER, "client item info", entryLoader::loadEntry); + return new ClientItemInfoLoader.LoadedClientInfos(clientItems); } public record DynamicResolver(Map inputModels, @@ -207,7 +216,7 @@ public int getInt(Object key) { } } - private static final Object NULL_SENTINEL = new Object(); + private static final Object NULL_BAKED = new Object(); public static Map createDynamicBakedRegistry(Map input, BiFunction baker) { // TODO: support persistence of overrides @@ -215,20 +224,24 @@ public static Map createDynamicBakedRegistry(Map input, Bi @Override public Object load(K key) throws Exception { var unbaked = input.get(key); - if (unbaked != null) { - if (DEBUG_DYNAMIC_MODEL_LOADING) { - ModernFix.LOGGER.info("Baking {}", key); - } - return baker.apply(key, unbaked); - } else { - return NULL_SENTINEL; + if (unbaked == null) { + return NULL_BAKED; + } + if (DEBUG_DYNAMIC_MODEL_LOADING) { + ModernFix.LOGGER.info("Baking {}", key); + } + var bakerResult = baker.apply(key, unbaked); + if (bakerResult == null) { + ModernFix.LOGGER.warn("Baker has returned null for {}", key); + return NULL_BAKED; } + return bakerResult; } }); return new DynamicRegistryMap<>(input.keySet(), k -> { if (k != null) { Object value = bakedCache.getUnchecked(k); - if (value == NULL_SENTINEL) { + if (value == NULL_BAKED) { value = null; } return (V) value; @@ -237,4 +250,4 @@ public Object load(K key) throws Exception { } }); } -} \ No newline at end of file +} diff --git a/src/main/java/org/embeddedt/modernfix/dynresources/DynamicRegistryMap.java b/src/main/java/org/embeddedt/modernfix/dynresources/DynamicRegistryMap.java index 65c8e6efd..5f9f6722a 100644 --- a/src/main/java/org/embeddedt/modernfix/dynresources/DynamicRegistryMap.java +++ b/src/main/java/org/embeddedt/modernfix/dynresources/DynamicRegistryMap.java @@ -9,6 +9,7 @@ import java.util.Collections; import java.util.Iterator; import java.util.Map; +import java.util.Objects; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.function.Function; @@ -73,6 +74,19 @@ public V get(Object o) { } } + @Override + public V getOrDefault(Object o, V defaultValue) { + Object value = overrides.get(o); + if (value == NULL_OVERRIDE) { + return null; + } else if (value != null) { + return (V) value; + } else { + var fallback = fallbackGetter.apply((K)o); + return fallback != null ? fallback : defaultValue; + } + } + @Override public @Nullable V put(K k, V v) { if (v == null) { @@ -158,4 +172,4 @@ public int size() { return DynamicRegistryMap.this.size(); } } -} +} \ No newline at end of file diff --git a/src/main/java/org/embeddedt/modernfix/screen/ModernFixConfigScreen.java b/src/main/java/org/embeddedt/modernfix/screen/ModernFixConfigScreen.java index 99fa1a7c0..f5b1cd6ef 100644 --- a/src/main/java/org/embeddedt/modernfix/screen/ModernFixConfigScreen.java +++ b/src/main/java/org/embeddedt/modernfix/screen/ModernFixConfigScreen.java @@ -37,7 +37,7 @@ protected void init() { @Override public void onClose() { - this.minecraft.gui.setScreen(lastScreen); + this.minecraft.setScreen(lastScreen); } @Override diff --git a/src/main/java/org/embeddedt/modernfix/screen/ModernFixOptionInfoScreen.java b/src/main/java/org/embeddedt/modernfix/screen/ModernFixOptionInfoScreen.java index 7cf37899c..262cb1a47 100644 --- a/src/main/java/org/embeddedt/modernfix/screen/ModernFixOptionInfoScreen.java +++ b/src/main/java/org/embeddedt/modernfix/screen/ModernFixOptionInfoScreen.java @@ -35,7 +35,7 @@ protected void init() { @Override public void onClose() { - this.minecraft.gui.setScreen(lastScreen); + this.minecraft.setScreen(lastScreen); } private void drawMultilineString(GuiGraphicsExtractor guiGraphics, Font fr, Component str, int x, int y) { diff --git a/src/main/java/org/embeddedt/modernfix/screen/OptionList.java b/src/main/java/org/embeddedt/modernfix/screen/OptionList.java index b41f644e4..7eaddf91e 100644 --- a/src/main/java/org/embeddedt/modernfix/screen/OptionList.java +++ b/src/main/java/org/embeddedt/modernfix/screen/OptionList.java @@ -108,7 +108,7 @@ public CategoryEntry(Component component) { public void extractContent(GuiGraphicsExtractor guiGraphics, int mouseX, int mouseY, boolean isMouseOver, float partialTicks) { Font var10000 = OptionList.this.minecraft.font; - float x = (float)(OptionList.this.minecraft.gui.screen().width / 2 - this.width / 2); + float x = (float)(OptionList.this.minecraft.screen.width / 2 - this.width / 2); int y = getY() + getHeight() - 10; guiGraphics.text(var10000, this.name, (int)x, y, -1); /* @@ -165,7 +165,7 @@ public OptionEntry(String optionName, Option option) { updateStatus(); this.helpButton = new Button.Builder(Component.literal("?"), (arg) -> { mainScreen.setLastScrollAmount(scrollAmount()); - Minecraft.getInstance().gui.setScreen(new ModernFixOptionInfoScreen(mainScreen, optionName)); + Minecraft.getInstance().setScreen(new ModernFixOptionInfoScreen(mainScreen, optionName)); }).pos(75, 0).size(20, 20).build(); String helpKey = "modernfix.option." + optionName; String helpText = I18n.get(helpKey); diff --git a/src/main/resources/assets/modernfix/lang/pt_br.json b/src/main/resources/assets/modernfix/lang/pt_br.json new file mode 100644 index 000000000..787be35a4 --- /dev/null +++ b/src/main/resources/assets/modernfix/lang/pt_br.json @@ -0,0 +1,139 @@ +{ + "key.modernfix": "ModernFix", + "key.modernfix.config": "Abrir tela de configuração", + "modernfix.jei_load": "Carregando JEI, isso pode demorar um pouco", + "modernfix.no_lazydfu": "O LazyDFU não está instalado. Se o Minecraft precisar atualizar os dados do jogo de uma versão mais antiga, poderá haver um lag perceptível.", + "modernfix.no_ferritecore": "O FerriteCore não está instalado. O uso da memória será muito alto.", + "modernfix.connectedness_dynresoruces": "O Connectedness e a opção de recursos dinâmicos do ModernFix não são compatíveis. Remova o Connectedness ou desative os recursos dinâmicos na configuração do ModernFix.", + "modernfix.perf_mod_warning": "Os avisos de mod do ModernFix podem ser desativados desativando mixin.feature.warn_missing_perf_mods na configuração do ModernFix.", + "modernfix.redirector_installed": "O ModernFix detectou que o Redirector está instalado. O Redirector é conhecido por causar muitos problemas estranhos e difíceis de depurar, e sua remoção é altamente recomendada.", + "modernfix.config": "Configuração de Mixin do ModernFix", + "modernfix.config.done_restart": "Concluído (reinicialização necessária)", + "modernfix.config.wiki": "Abrir wiki", + "modernfix.message.reload_config": "Foi detectada uma alteração no arquivo de configuração do mod. Para evitar o carregamento de arquivos que ainda não foram salvos, o recarregamento deve ser acionado com a execução de /mfrc.", + "modernfix.option.on": "ligado", + "modernfix.option.off": "desligado", + "modernfix.option.disabled": "desativado", + "modernfix.option.enabled": "ativado", + "modernfix.option.mod_override": " por mods [%s]", + "modernfix.config.not_default": " (modificado)", + "asynclocator.map.locating": "Mapa (Localizando...)", + "asynclocator.map.none": "Mapa (Nenhum recurso próximo foi encontrado)", + "modernfix.option.category.performance": "Performance", + "modernfix.option.category.performance.description": "Recursos que ajudam a melhorar a performance do jogo/inicialização", + "modernfix.option.category.bugfixes": "Correções de Bugs", + "modernfix.option.category.bugfixes.description": "Correções de bugs essenciais para melhorar a estabilidade do jogo", + "modernfix.option.category.troubleshooting": "Solução de problemas/Utilidades", + "modernfix.option.category.troubleshooting.description": "Recursos destinados a auxiliar no diagnóstico de problemas", + "modernfix.option.category.expert_only": "Somente para Especialistas", + "modernfix.option.category.expert_only.description": "Não mude a menos que saiba o que está fazendo", + "modernfix.option.name.mixin.perf.async_jei": "Carregamento de JEI em segundo plano", + "modernfix.option.mixin.perf.async_jei": "Somente na versão 1.16. **Uma otimização importante.** Corrige o JEI para executar o recarregamento em um thread em segundo plano, eliminando completamente o longo atraso que ele adiciona ao carregamento do mundo.", + "modernfix.option.mixin.perf.async_locator": "Somente na versão 1.16. Faz o backporte dos patches do mod Async Locator para eliminar os congelamentos do servidor associados a `/locate`, geração de tabela de saques etc.", + "modernfix.option.mixin.perf.biome_zoomer": "Somente na versão 1.16. Pequena otimização para melhorar o desempenho do zoomer de bioma usando a lógica da versão 1.18.", + "modernfix.option.mixin.perf.blast_search_trees": "Todas as versões. Se o REI ou o JEI estiverem instalados, a construção das árvores de pesquisa originais para pesquisa criativa será desativada, e a pesquisa será feita usando as implementações de pesquisa desses mods. Isso economiza vários segundos durante o carregamento do mundo e provavelmente também economiza um pouco de RAM (embora eu não tenha medido).", + "modernfix.option.mixin.perf.boost_worker_count": "Somente na versão 1.16. Remove o limite codificado na contagem de threads do trabalhador, de forma semelhante ao que a Mojang fez na versão 1.18.", + "modernfix.option.mixin.perf.cache_blockstate_cache_arrays": "Todas as versões. Evita a criação de novas cópias de matrizes de enum sempre que um cache de estado de bloco é inicializado. É uma otimização pequena, mas fácil de fazer.", + "modernfix.option.mixin.perf.cache_model_materials": "Todas as versões. Memorizam a coleção `RenderMaterial` (textura) e a lista de dependências que os modelos retornam, em vez de exigir que sejam recalculados em cada solicitação. Ajuda a acelerar o processo de carregamento/criação de modelos.", + "modernfix.option.mixin.perf.cache_strongholds": "Todas as versões. Salva a lista gerada de posições de fortaleza com o mundo, em vez de gerá-la novamente a cada carregamento do mundo. Economiza um pouco de tempo na versão 1.16 e um pouco mais nas versões 1.18 e 1.19.", + "modernfix.option.mixin.perf.cache_upgraded_structures": "Todas as versões. Muitos mods enviam arquivos de estrutura desatualizados, o que exige que o jogo os atualize usando o DFU toda vez que forem carregados. Isso pode ser bastante lento. Esse patch adiciona lógica para salvar a versão atualizada da estrutura e reutilizá-la no próximo carregamento. Para lidar com o caso em que o mod altera um arquivo de estrutura, mas não o nome, o hash do arquivo original é comparado com a versão em cache e, se eles não corresponderem, a estrutura será atualizada novamente.", + "modernfix.option.mixin.perf.compress_biome_container": "Somente na versão 1.16. Pequena otimização emprestada do Hydrogen, que tenta economizar espaço no contêiner do bioma quando possível. Isso é desativado automaticamente se mods conflitantes como BetterEnd ou Chocolate estiverem instalados.", + "modernfix.option.mixin.perf.datapack_reload_exceptions": "Todas as versões. Reduz o spam de registro e possivelmente melhora um pouco a velocidade de carregamento ao não imprimir os rastreamentos de pilha de algumas exceções comumente lançadas durante o recarregamento do pacote de dados (por exemplo, itens ausentes em tabelas/receitas de saque). A mensagem ainda é impressa.", + "modernfix.option.mixin.perf.dedicated_reload_executor": "Todas as versões. Move o recarregamento do pacote de recursos e do pacote de dados para um pool de trabalho dedicado em vez de usar os threads padrão do `Worker-Main`. Isso permite que os mods do Smooth Boot ainda melhorem potencialmente o desempenho do jogador único em tempo de execução, sem tornar o lançamento mais lento devido a uma contagem limitada de threads.", + "modernfix.option.mixin.perf.deduplicate_location": "Todas as versões, mas desativado por padrão devido ao impacto no tempo de carregamento. Deduplica os namespaces e os caminhos do local do recurso. Isso economiza RAM, mas também aumenta um pouco o custo de construção de um novo `ResourceLocation`.", + "modernfix.option.mixin.perf.dynamic_dfu": "Todas as versões. Modifica a inicialização do DFU para que ocorra na primeira vez que algo precisar ser atualizado. Isso parece semelhante ao LazyDFU, mas é implementado de forma diferente, pois evita o carregamento de *qualquer* classe/estrutura de dados do DFU, enquanto o LazyDFU apenas desativa a otimização de regras. Essencialmente, essa opção é uma versão mais segura do DataFixerSlayer, pois ele ainda carregará o DFU quando necessário. Normalmente, você deve continuar a usar o LazyDFU mesmo com essa opção ativada, pois, caso contrário, a otimização das regras do DFU causará lag.", + "modernfix.option.mixin.perf.dynamic_resources": "Todas as versões. Veja https://github.com/embeddedt/ModernFix/wiki/Dynamic-Resources-FAQ.", + "modernfix.option.mixin.perf.dynamic_sounds": "Todas as versões. Permite que o jogo descarregue sons, em vez de os sons persistirem indefinidamente após serem carregados.", + "modernfix.option.mixin.perf.dynamic_structure_manager": "Todas as versões. Permite que o jogo descarregue os arquivos de estrutura após a conclusão da geração, em vez de mantê-los carregados para sempre.", + "modernfix.option.mixin.perf.fast_registry_validation": "Todas as versões. O Forge procura desnecessariamente um método por meio de reflexão toda vez que um registro é validado. Esse patch simplesmente armazena em cache o valor retornado, pois ele será o mesmo todas as vezes.", + "modernfix.option.mixin.perf.faster_font_loading": "Todas as versões. Otimiza o renderizador de fontes para carregar fontes mais rapidamente, acelerando o recarregamento de recursos.", + "modernfix.option.mixin.perf.faster_item_rendering": "Todas as versões. Evita a renderização das laterais dos itens nas GUIs. (Isso pode triplicar o FPS com um mod como o REI/JEI instalado em GPUs mais fracas, se houver itens suficientes visíveis. Desativado por padrão, pois é novo e não foi muito testado, mas deve ser seguro. O problema mais provável é que os itens fiquem completamente invisíveis nas GUIs ou apareçam achatados no mundo.", + "modernfix.option.mixin.perf.faster_texture_loading": "Todas as versões anteriores à 1.19.4. Evita a leitura de texturas duas vezes (a primeira vez usando um caminho de código muito lento) e, em vez disso, faz um carregamento mais rápido (semelhante ao 1.19.3+).", + "modernfix.option.mixin.perf.faster_texture_stitching": "Todas as versões. Permite que o jogo use um sistema de costura de textura mais rápido, originalmente escrito por SuperCoder79 para lwjgl3ify na versão 1.7.10, o que pode economizar algum tempo durante o carregamento. Raramente, foi relatado que ele causa artefatos estranhos em blocos ou em GUIs, o que pode ser um bug do Sodium.", + "modernfix.option.mixin.perf.jeresources_startup": "1.16 apenas. Otimiza o Just Enough Resources para não recriar desnecessariamente entidades de aldeões várias vezes para a mesma profissão, o que economiza tempo durante a inicialização do JEI.", + "modernfix.option.mixin.perf.kubejs": "1.16 apenas. Otimizações no KubeJS para evitar cópias desnecessárias de `ItemStack`, etc., o que reduz o tempo necessário para carregar pacotes de dados.", + "modernfix.option.mixin.perf.model_optimizations": "Todas as versões. Implementa otimizações para acelerar o processo de carregamento do modelo.", + "modernfix.option.mixin.perf.nbt_memory_usage": "Todas as versões. Usa um mapa de apoio mais eficiente para tags NBT compostas que deduplica os nomes das chaves e também usa um mapa de matriz para compostos muito pequenos. Isso reduz a sobrecarga de armazenamento de muitas tags compostas na memória.", + "modernfix.option.mixin.perf.nuke_empty_chunk_sections": "Somente na versão 1.16, inspirado no Hydrogen. Evita armazenar seções de pedaços cheios de ar na memória, marcando-os como vazios.", + "modernfix.option.mixin.perf.reduce_blockstate_cache_rebuilds": "Todas as versões.**As versões mais recentes do Minecraft (após a 1.12) implementaram um sistema de cache de blockstate que armazena em cache informações usadas com frequência sobre um blockstate, como se ele é sólido, sua forma de colisão etc. A reconstrução desse cache é bastante rápida na versão original (leva apenas um ou dois segundos), mas é bastante lenta com muitos mods instalados, pois há muito mais blockstates presentes no jogo que precisam ter seus caches reconstruídos.\n\nEsse problema é exacerbado pelo Forge, pois o cache é reconstruído em muitos pontos em que os dados quase certamente não seriam usados antes da próxima reconstrução. Os exemplos incluem logo antes de chegar ao menu principal (durante o estágio \"Freezing data\"), bem como várias (!) vezes quando um mundo está sendo carregado.\n\nO ModernFix resolve esse gargalo de desempenho tornando as reconstruções de cache preguiçosas. Cada blockstate reconstrói seu cache na primeira vez em que os dados são acessados. Em qualquer ponto em que o Vanilla ou o Forge tentariam reconstruir caches para todos os blockstates, isso é redirecionado para simplesmente invalidar o cache em cada blockstate.\n\nIsso não deve ter nenhum impacto no TPS após a conclusão da inicialização.", + "modernfix.option.mixin.perf.remove_biome_temperature_cache": "Todas as versões. Remove o cache de temperatura do bioma como o Lithium faz nas versões modernas.", + "modernfix.option.mixin.perf.resourcepacks": "Todas as versões. **Uma otimização importante.** As inicializações em versões modernas sofrem um grande gargalo devido ao acesso ao sistema de arquivos. Muitas solicitações são feitas com frequência aos pacotes de recursos para listar recursos ou verificar se um determinado recurso existe, e cada uma delas resulta em uma chamada de API de arquivo muito lenta.\n\nModernFix elimina completamente a maior parte do gargalo aqui, simplesmente armazenando em cache uma listagem de todos os recursos existentes nos pacotes de recursos fornecidos por mods e vanilla. O cache é reconstruído na recarga do recurso (exceto para os recursos vanilla, já que eles nunca devem ser alterados enquanto o jogo estiver em execução).\n\nNão há problemas de compatibilidade conhecidos com esse patch, exceto para o OptiFine (seus recursos CTM não são carregados corretamente). No entanto, não recomendo usar o OptiFine em nenhum cenário, pois ele adiciona vários minutos ao tempo de inicialização e não foi testado com o ModernFix.", + "modernfix.option.mixin.perf.reuse_datapacks": "Somente na versão 1.16. Tenta acelerar a troca entre mundos de um jogador ignorando a recarga do pacote de dados quando possível. Pode causar problemas de compatibilidade com alguns mods, mas atualmente está ativado por padrão.", + "modernfix.option.mixin.perf.rewrite_registry": "Todas as versões. **Substitui agressivamente alguns componentes internos do sistema de registro do Forge por versões mais rápidas, mas atualmente causa congelamentos ao carregar alguns modpacks. Desativado por padrão por motivos óbvios.", + "modernfix.option.mixin.perf.skip_first_datapack_reload": "Somente nas versões 1.16 e 1.19. **Uma otimização importante.**\n\nNo meio do ciclo de desenvolvimento da versão 1.16, a Forge corrigiu o jogo para recarregar os pacotes de dados duas vezes ao carregar um mundo existente, a fim de corrigir um problema com a mudança de ID de bioma. Infelizmente, o recarregamento dos pacotes de dados costuma levar mais de 30 segundos e, portanto, isso afeta gravemente o tempo de carregamento do mundo.\n\nO ModernFix faz as alterações necessárias para evitar esse recarregamento, com base no PR #8163 inacabado da Forge.\n\nEssa alteração foi removida pela Forge na versão 1.18, mas um patch semelhante foi adicionado *novamente* na versão 1.19 para corrigir os pacotes de dados de mods que não estavam sendo carregados ao criar novos mundos para um jogador. Felizmente, o problema está localizado na tela de criação de mundos na versão 1.19, e os mundos existentes exigem apenas uma única recarga. No entanto, isso ainda dobra a duração do pico de atraso ao clicar em \"Criar novo mundo\" na versão 1.19 e, portanto, o ModernFix faz novamente alterações para não executar um recarregamento redundante.", + "modernfix.option.mixin.perf.state_definition_construct": "Todas as versões. Ativado somente se o FerriteCore estiver instalado. Aproveita o manuseio de blockstates do FerriteCore para acelerar sua criação. Isso pode ajudar a acelerar o lançamento com mods que adicionam muitos blockstates, como mods de mobília.", + "modernfix.option.mixin.perf.sync_executor_sleep": "Todas as versões. Evita que o thread principal gire ociosamente, consumindo um núcleo da CPU enquanto aguarda a conclusão dos workers de carregamento de mods.", + "modernfix.option.mixin.perf.thread_priorities": "Todas as versões. Ajusta as prioridades dos threads do servidor e do trabalhador para que sejam menores que as do thread do cliente. Isso ajuda a melhorar a estabilidade do FPS em máquinas com poucos núcleos de CPU, desde que a implementação Java em uso respeite as prioridades.", + "modernfix.option.mixin.perf.use_integrated_resources": "Principalmente para a versão 1.16. Corrige o JEResources para usar os dados da tabela de saque do servidor integrado ao jogar com um jogador, em vez de recarregar inutilmente as tabelas de saque. Economiza mais alguns segundos durante a inicialização do JEI.", + "modernfix.option.mixin.bugfix.concurrency": "Os patches deste grupo corrigem problemas relacionados à concorrência no Minecraft e/ou no Forge. A maioria deles resulta em crashes raros e difíceis de diagnosticar durante o carregamento.", + "modernfix.option.mixin.bugfix.edge_chunk_not_saved": "Essa opção é uma porte do mod SuperCoder's Chunk Saving Fix (porque eu não sabia que ele já estava disponível para o Forge na época).", + "modernfix.option.mixin.bugfix.mc218112": "Essa opção corrige um deadlock que pode ocorrer se uma exceção for lançada durante o processamento dos dados da entidade. O Vanilla não desbloqueia corretamente o gerenciador de dados quando deveria. Isso é registrado como MC-218112 no rastreador de bugs e foi corrigido pela Mojang na versão 1.17.", + "modernfix.option.mixin.bugfix.packet_leak": "**Experimental**, não ativado por padrão. Uma tentativa de correção para o problema de vazamento de memória que ocorre depois de jogar por tempo suficiente na versão 1.16.", + "modernfix.option.mixin.bugfix.paper_chunk_patches": "1.18 e mais recentes. **Uma otimização importante.** Porta um patch do Paper que corrige problemas na versão 1.17 com o carregamento de chunks que exigem grandes quantidades de memória e geram muitas instâncias de `CompletableFuture`. As versões 1.18+ agora podem carregar mundos com apenas 400 MB de memória, como na versão 1.16.", + "modernfix.option.mixin.bugfix.tf_cme_on_load": "Corrige o Twilight Forest para executar a configuração do cliente sem segurança de thread usando o thread principal como deveria, em vez do thread de trabalho do FML.", + "modernfix.option.mixin.feature.branding": "Adiciona o ModernFix à lista de marcas na tela de título e também à tela F3.", + "modernfix.option.mixin.feature.direct_stack_trace": "Normalmente desativado, pode ser ativado para forçar o despejo do rastreamento de pilha bruto no registro quando ocorrer um crash. Ocasionalmente, o sistema de relatório de falhas do Vanilla não funciona corretamente e fornece um relatório/traço de pilha totalmente irrelevante.", + "modernfix.option.mixin.feature.measure_time": "Usa algumas injeções para medir o tempo de carregamento do mundo, o tempo de recarregamento do datapack, o tempo de recarregamento de recursos, o tempo de bootstrap e adiciona os ganchos necessários para ativar a lógica do profiler não utilizado do Vanilla para recarregamento de recursos, se assim configurado.", + "modernfix.option.mixin.feature.spam_thread_dump": "**Para ser usado somente para fins de depuração.** Faz com que um despejo de thread seja enviado para o registro a cada 60 segundos. Isso pode ajudar a diagnosticar congelamentos inexplicáveis durante o carregamento/jogo.", + "modernfix.option.mixin.bugfix.chunk_deadlock": "Tenta evitar deadlocks do sistema de chunk ou fornecer informações adicionais de depuração no registro quando eles ocorrem. Esses deadlocks geralmente se manifestam como um congelamento indefinido do servidor (por exemplo, entidades que não se movem), enquanto o cliente continua a funcionar perfeitamente.", + "modernfix.option.mixin.bugfix.chunk_deadlock.valhesia": "Corrige o Valhesia Structures para corrigir um problema em seu código que causa frequentes deadlocks de worldgen/chunkloading.", + "modernfix.option.mixin.bugfix.cofh_core_crash": "Corrige um problema de multithreading no CoFH Core que pode causar falhas raras durante o lançamento.", + "modernfix.option.mixin.bugfix.ctm_resourceutil_cme": "Corrige um problema de multithreading no ConnectedTexturesMod que pode causar falhas raras durante a inicialização.", + "modernfix.option.mixin.bugfix.ender_dragon_leak": "Corrige um vazamento de memória no Vanilla causado pelo dragão ender que retém uma referência ao mundo do cliente anterior.", + "modernfix.option.mixin.bugfix.entity_load_deadlock": "Corrige muitos problemas em que EntityJoinWorldEvent/EntityJoinLevelEvent causam um impasse no worldgen, adiando ligeiramente o carregamento da entidade. No entanto, não deve causar nenhuma mudança de comportamento perceptível no jogo.", + "modernfix.option.mixin.bugfix.fix_config_crashes": "Corrige o fato de as configurações do Forge serem ocasionalmente corrompidas ao iniciar o jogo.", + "modernfix.option.mixin.bugfix.item_cache_flag": "Corrige MC-258939", + "modernfix.option.mixin.bugfix.preserve_early_window_pos": "Faz com que a janela do jogo mantenha o tamanho existente quando o controle é transferido do carregamento inicial do Forge para o código do Minecraft. Corrige o teletransporte da janela de volta para o centro da tela depois de ser arrastada, etc.", + "modernfix.option.mixin.bugfix.refinedstorage.te_bug": "Corrige o fato de os blocos de armazenamento externo do Refined Storage ocasionalmente não mostrarem o conteúdo das gavetas, etc. quando carregados. Backport do PR #3435 do Refined Storage, que foi aplicado somente à versão 1.18 e posteriores.", + "modernfix.option.mixin.bugfix.remove_block_chunkloading": "Corrige os porcos zumbis que mantêm o chunk 0, 0 carregado perpetuamente no Forge. Backport do Forge PR #8583.", + "modernfix.option.mixin.bugfix.starlight_emptiness": "Corrige uma falha ocasional do Starlight devido ao fato de os mapas de vazio não serem inicializados. Backport da mesma correção no Starlight para 1.18.x.", + "modernfix.option.mixin.core": "Patches principais necessários para que o ModernFix funcione", + "modernfix.option.mixin.devenv": "Patches usados durante a execução em um ambiente de desenvolvimento, para aprimoramento da velocidade e/ou testes", + "modernfix.option.mixin.safety": "Correções de simultaneidade para evitar crashes durante o lançamento", + "modernfix.option.mixin.feature.integrated_server_watchdog": "Adiciona o watchdog vanilla também aos mundos de um jogador, mas apenas imprime os rastreamentos de pilha em vez de encerrar o mundo à força. Essa versão inclui a funcionalidade do Fullstack Watchdog, mas o último ainda é necessário para o modo multijogador.", + "modernfix.option.mixin.feature.snapshot_easter_egg": "Adiciona recursos de easter egg (não afeta os visuais ou o comportamento da versão original) ao ser executado em uma versão snapshot.", + "modernfix.option.mixin.feature.spark_profile_launch": "Se estiver ativado, e uma versão compatível do Spark estiver instalada, toda a sequência de lançamento será perfilada até o menu principal.", + "modernfix.option.mixin.feature.warn_missing_perf_mods": "Mostra um aviso na inicialização se outros mods de desempenho considerados essenciais e altamente compatíveis não estiverem presentes", + "modernfix.option.mixin.launch.class_search_cache": "Substitui o localizador de recursos do Forge (usado para localizar o jogo e um código de mod) por uma versão significativamente mais rápida, acelerando o lançamento", + "modernfix.option.mixin.perf.clear_fabric_mapping_tables": "Reduz o uso da memória limpando as estruturas de dados de mapeamento no Fabric Loader que são redundantes ou raramente usadas pelos mods. Desativado por padrão por motivos de compatibilidade.", + "modernfix.option.mixin.perf.clear_mixin_classinfo": "Força o carregamento de todos os mixins quando o lançamento é concluído e, em seguida, limpa as estruturas de dados do mixin para remover a maior parte do espaço de memória do Mixin. Desativado por padrão por motivos de compatibilidade.", + "modernfix.option.mixin.perf.deduplicate_wall_shapes": "Faz com que a maioria dos blocos de parede compartilhe o mesmo objeto de forma em vez de cada um ter sua própria cópia. Pode reduzir substancialmente o uso da memória quando muitos blocos de parede são adicionados por mods.", + "modernfix.option.mixin.perf.dynamic_resources.ae2": "Patch de compatibilidade do AE2 para recursos dinâmicos", + "modernfix.option.mixin.perf.dynamic_resources.ctm": "Patch de compatibilidade CTM para recursos dinâmicos", + "modernfix.option.mixin.perf.dynamic_resources.rs": "Patch de compatibilidade de Refined Storage para recursos dinâmicos", + "modernfix.option.mixin.perf.dynamic_resources.supermartijncore": "Patch de compatibilidade do SuperMartijn642CoreLib para recursos dinâmicos", + "modernfix.option.mixin.perf.dynamic_resources.diagonalfences": "Patch de compatibilidade do Diagonal Fences para recursos dinâmicos", + "modernfix.option.mixin.perf.faster_advancements": "Reescreve a lógica de verificação de conquistas para ser mais rápida e não causar StackOverflowError em pacotes grandes. Porte do Advancements Debug do Fabric.", + "modernfix.option.mixin.perf.patchouli_deduplicate_books": "Corrige os livros do Patchouli que armazenam muitos itens vazios com tags NBT, reduzindo o uso da memória.", + "modernfix.option.mixin.perf.remove_spawn_chunks": "Remove completamente os chunks de spawn do jogo. Eles não são mais carregados, ao contrário do Ksyxis.", + "modernfix.option.mixin.perf.use_integrated_resources.jepb": "", + "modernfix.option.mixin.perf.use_integrated_resources.jeresources": "", + "modernfix.option.mixin.bugfix.blueprint_modif_memory_leak": "Corrige o ObjectModificationManager do Blueprint que vaza recursos do vanilla, reduzindo o uso de memória. Apesar de a correção ter sido contribuída no PR #195, ainda não foi feito um lançamento.", + "modernfix.option.mixin.bugfix.removed_dimensions": "Corrige a falha do jogo ao carregar mundos se os mods de dimensão forem removidos. Backport do Forge PR #8959.", + "modernfix.option.mixin.perf.compact_bit_storage": "Corrige o desperdício de memória causado por alguns servidores legados (por exemplo, Hypixel) que enviam pedaços vazios como se contivessem blocos. Reduz significativamente o uso de memória nesses servidores.", + "modernfix.option.mixin.perf.deduplicate_climate_parameters": "Desduplica os objetos de parâmetros climáticos usados pelo novo sistema de biomas, o que pode economizar cerca de 2 MB mas também torna a recarga do pacote de dados um pouco mais lenta.", + "modernfix.option.mixin.perf.dynamic_entity_renderers": "Constrói modelos de entidades na primeira vez em que são vistos, em vez de durante o lançamento. Alguns mods não são compatíveis com essa opção e causarão crashes no EntityRenderer.", + "modernfix.option.mixin.perf.twilightforest.structure_spawn_fix": "Corrige o lag causado pelo fato de o worldgen da Twilight Forest verificar as estruturas de forma muito ineficiente", + "modernfix.option.mixin.perf.fast_forge_dummies": "Acelera o congelamento do registro do Forge durante a inicialização usando um caminho de código mais rápido", + "modernfix.option.mixin.perf.tag_id_caching": "Acelera o uso de entradas de tags armazenando em cache o objeto de localização em vez de recriá-lo todas as vezes", + "modernfix.option.mixin.feature.disable_unihex_font": "Remover a fonte Unicode, economiza 10 MB mas faz com que os caracteres especiais não sejam mais renderizados", + "modernfix.option.mixin.bugfix.world_leaks": "Reduz o uso da memória de mundos antigos do lado do cliente que não são necessários após a troca de dimensões. Normalmente esses mundos são coletados do lixo na versão original, mas os mods às vezes mantêm referências a eles.", + "modernfix.option.mixin.perf.compact_mojang_registries": "(Fabric) Opção experimental que reduz o uso de memória dos registros em cerca de 50%. Não é útil na maioria dos modpacks a menos que eles contenham milhões de blocos e itens.", + "modernfix.option.mixin.perf.dynamic_block_codecs": "Evita o armazenamento de um codec para cada bloco(estado) e em vez disso gera e armazena em cache em tempo real quando necessário. Em geral não vale a pena ativá-lo a menos que você tenha um milhão de blocos/itens.", + "modernfix.option.mixin.perf.faster_command_suggestions": "Mitiga o lag quando há centenas de milhares de sugestões durante a digitação de um comando", + "modernfix.option.mixin.perf.mojang_registry_size": "Corrige um problema que fazia com que o registro de blocos/itens ficasse mais lento proporcionalmente ao número já registrado. Isso melhora o tempo de inicialização.", + "modernfix.option.mixin.perf.cache_profile_texture_url": "Evita a criação inútil de um objeto de URL e acelera a renderização do bloco de crânio.", + "modernfix.option.mixin.bugfix.entity_pose_stack": "Corrige o problema #9118 do Forge, em que os mods podem causar falhas de renderização sem depuração ao empurrar a pilha de matrizes sem abri-la.", + "modernfix.option.mixin.bugfix.file_dialog_title": "Corrige um problema de segurança com a caixa de diálogo do arquivo de configurações do worldgen", + "modernfix.option.mixin.bugfix.forge_vehicle_packets": "Corrige um bug introduzido por um patch do Forge que faz com que quantidades excessivas de pacotes de dados de pedaços sejam enviadas ao jogador se ele estiver dirigindo um veículo em uma borda de pedaços.", + "modernfix.option.mixin.bugfix.mantle_model_cme": "Corrige um bug no Mantle que pode causar falhas aleatórias de ConcurrentModificationException ao renderizar o conteúdo do Tinkers Construct.", + "modernfix.option.mixin.bugfix.model_data_manager_cme": "Contorna as falhas de projeto no sistema Forge ModelDataManager que podem causar problemas inesperados de simultaneidade.", + "modernfix.option.mixin.bugfix.recipe_book_type_desync": "Corrige o fato de os clientes do Forge serem desconectados ao se conectarem a um servidor vanilla se os mods adicionarem tipos de entrada de livros de receitas personalizados.", + "modernfix.option.mixin.bugfix.unsafe_modded_shape_caches": "Corrige várias ConcurrentModificationExceptions que podem ocorrer em mods de conteúdo ao computar formas de blocos", + "modernfix.option.mixin.feature.stalled_chunk_load_detection": "Essa opção pode ajudar a detectar a causa do congelamento do carregamento de blocos. No entanto, deixá-la ativada pode causar um desempenho ligeiramente pior.", + "modernfix.option.mixin.perf.fix_loop_spin_waiting": "Corrige a função de espera integrada do Minecraft que consome quantidades excessivas de recursos da CPU.", + "modernfix.option.mixin.perf.forge_cap_retrieval": "Pequena micro-otimização que torna a recuperação de dados de entidades personalizadas um pouco mais eficiente no Forge.", + "modernfix.option.mixin.perf.forge_registry_lambda": "Corrige falhas no Forge que levam a uma alocação excessiva em métodos de registro quente.", + "modernfix.option.mixin.bugfix.restore_old_dragon_movement": "Corrige o MC-272431, que rastreia o fato de o dragão ender não poder mergulhar no portal, como acontecia na versão 1.13 e anteriores. Isso faz com que o dragão voe de forma um pouco diferente da que os jogadores modernos estão acostumados e também corrige o ciclo único, que não é ativado por padrão. Agradecemos a Jukitsu por identificar a regressão no código original.", + "modernfix.option.mixin.bugfix.missing_block_entities": "O Hypixel envia chunks para o cliente que estão faltando alguns dados de entidade de bloco, o que faz com que os baús etc. pareçam invisíveis. Isso 'corrige' o problema criando os dados necessários no cliente. Não tem efeito em servidores com comportamento adequado ou em um único jogador." +} \ No newline at end of file diff --git a/src/main/resources/modernfix-common.mixins.json b/src/main/resources/modernfix-common.mixins.json index d321531ad..eee8cc02a 100644 --- a/src/main/resources/modernfix-common.mixins.json +++ b/src/main/resources/modernfix-common.mixins.json @@ -104,6 +104,7 @@ "perf.dynamic_resources.MixinClientItemInfoLoader", "perf.dynamic_resources.MixinModelBakery", "perf.dynamic_resources.MixinModelManager", + "perf.dynamic_resources.MixinTextureSlots", "perf.dynamic_resources.ModelDiscoveryAccessor", "perf.dynamic_sounds.SoundBufferLibraryMixin", "perf.encoder_cache_leak.ClientConfigurationPacketListenerImplMixin",